package org.corfudb.runtime.clients; import com.google.common.collect.ImmutableSet; import org.corfudb.infrastructure.AbstractServer; import org.corfudb.infrastructure.LayoutServer; import org.corfudb.infrastructure.TestLayoutBuilder; import org.corfudb.runtime.exceptions.AlreadyBootstrappedException; import org.corfudb.runtime.exceptions.NoBootstrapException; import org.corfudb.runtime.exceptions.OutrankedException; import org.corfudb.runtime.view.Layout; import org.junit.Test; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Created by mwei on 12/21/15. */ public class LayoutClientTest extends AbstractClientTest { LayoutClient client; @Override Set<AbstractServer> getServersForTest() { return new ImmutableSet.Builder<AbstractServer>() .add(new LayoutServer(defaultServerContext())) .build(); } @Override Set<IClient> getClientsForTest() { client = new LayoutClient(); return new ImmutableSet.Builder<IClient>() .add(new BaseClient()) .add(client) .build(); } @Test public void nonBootstrappedServerThrowsException() { assertThatThrownBy(() -> { client.getLayout().get(); }).hasCauseInstanceOf(NoBootstrapException.class); } @Test public void bootstrapServerInstallsNewLayout() throws Exception { assertThat(client.bootstrapLayout(TestLayoutBuilder.single(SERVERS.PORT_0)).get()) .isEqualTo(true); assertThat(client.getLayout().get().asJSONString()) .isEqualTo(TestLayoutBuilder.single(SERVERS.PORT_0).asJSONString()); } @Test public void cannotBootstrapServerTwice() throws Exception { assertThat(client.bootstrapLayout(TestLayoutBuilder.single(SERVERS.PORT_0)).get()) .isEqualTo(true); assertThatThrownBy(() -> client.bootstrapLayout(TestLayoutBuilder.single(SERVERS.PORT_0)).get()) .hasCauseInstanceOf(AlreadyBootstrappedException.class); } @Test public void canGetNewLayoutInDifferentEpoch() throws Exception { Layout l = TestLayoutBuilder.single(SERVERS.PORT_0); final long NEW_EPOCH = 42L; l.setEpoch(NEW_EPOCH); assertThat(client.bootstrapLayout(l).get()) .isEqualTo(true); assertThat(client.getLayout().get().getEpoch()) .isEqualTo(NEW_EPOCH); } final long RANK_LOW = 5L; final long RANK_HIGH = 10L; @Test public void prepareRejectsLowerRanks() throws Exception { Layout layout = TestLayoutBuilder.single(SERVERS.PORT_0); assertThat(client.bootstrapLayout(layout).get()) .isEqualTo(true); long epoch = layout.getEpoch(); assertThat(client.prepare(epoch, RANK_HIGH).get() != null) .isEqualTo(true); assertThatThrownBy(() -> { client.prepare(epoch, RANK_LOW).get(); }).hasCauseInstanceOf(OutrankedException.class); assertThatThrownBy(() -> { client.prepare(epoch, 2L).get(); }).hasCauseInstanceOf(OutrankedException.class); } @Test public void proposeRejectsLowerRanks() throws Exception { Layout layout = TestLayoutBuilder.single(SERVERS.PORT_0); long epoch = layout.getEpoch(); assertThat(client.bootstrapLayout(layout).get()) .isEqualTo(true); assertThat(client.prepare(epoch, RANK_HIGH).get() != null) .isEqualTo(true); assertThatThrownBy(() -> { client.propose(epoch, RANK_LOW, layout).get(); }).hasCauseInstanceOf(OutrankedException.class); assertThat(client.propose(epoch, RANK_HIGH, TestLayoutBuilder.single(SERVERS.PORT_0)).get()) .isEqualTo(true); } @Test public void proposeRejectsAlreadyProposed() throws Exception { Layout layout = TestLayoutBuilder.single(SERVERS.PORT_0); long epoch = layout.getEpoch(); assertThat(client.bootstrapLayout(layout).get()) .isEqualTo(true); assertThat(client.prepare(epoch, RANK_HIGH).get() != null) .isEqualTo(true); client.propose(epoch, RANK_HIGH, layout).get(); assertThatThrownBy(() -> { client.propose(epoch, RANK_LOW, layout).get(); }).hasCauseInstanceOf(OutrankedException.class); assertThatThrownBy(() -> { client.propose(epoch, RANK_HIGH, layout).get(); }).hasCauseInstanceOf(OutrankedException.class); } @Test public void commitReturnsAck() throws Exception { Layout layout = TestLayoutBuilder.single(SERVERS.PORT_0); long epoch = layout.getEpoch(); assertThat(client.bootstrapLayout(layout).get()) .isEqualTo(true); assertThat(client.prepare(epoch, RANK_HIGH).get() != null) .isEqualTo(true); final long TEST_EPOCH = 777; layout.setEpoch(TEST_EPOCH); assertThat(client.committed(TEST_EPOCH, layout).get()) .isEqualTo(true); } }