Search in sources :

Example 6 with MiniRaftCluster

use of org.apache.ratis.MiniRaftCluster in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testBootstrapReconf.

@Test
public void testBootstrapReconf() throws Exception {
    LOG.info("Start testBootstrapReconf");
    // originally 3 peers
    final MiniRaftCluster cluster = getCluster(3);
    cluster.start();
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftPeerId leaderId = cluster.getLeader().getId();
        final RaftClient client = cluster.createClient(leaderId);
        // submit some msgs before reconf
        for (int i = 0; i < getStagingGap() * 2; i++) {
            RaftClientReply reply = client.send(new SimpleMessage("m" + i));
            Assert.assertTrue(reply.isSuccess());
        }
        PeerChanges c1 = cluster.addNewPeers(2, true);
        LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
        final AtomicReference<Boolean> success = new AtomicReference<>();
        Thread clientThread = new Thread(() -> {
            try {
                RaftClientReply reply = client.setConfiguration(c1.allPeersInNewConf);
                success.set(reply.isSuccess());
                client.close();
            } catch (IOException ioe) {
                LOG.error("FAILED", ioe);
            }
        });
        clientThread.start();
        Thread.sleep(5000);
        LOG.info(cluster.printServers());
        assertSuccess(success);
        final RaftLog leaderLog = cluster.getLeader().getState().getLog();
        for (RaftPeer newPeer : c1.newPeers) {
            Assert.assertArrayEquals(leaderLog.getEntries(0, Long.MAX_VALUE), cluster.getServer(newPeer.getId()).getImpl().getState().getLog().getEntries(0, Long.MAX_VALUE));
        }
    } finally {
        cluster.shutdown();
    }
}
Also used : SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.storage.RaftLog) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 7 with MiniRaftCluster

use of org.apache.ratis.MiniRaftCluster in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testAddRemovePeers.

private void testAddRemovePeers(boolean leaderStepdown) throws Exception {
    MiniRaftCluster cluster = getCluster(5);
    cluster.start();
    try {
        RaftTestUtil.waitForLeader(cluster);
        PeerChanges change = cluster.addNewPeers(2, true);
        RaftPeer[] allPeers = cluster.removePeers(2, leaderStepdown, asList(change.newPeers)).allPeersInNewConf;
        // trigger setConfiguration
        cluster.setConfiguration(allPeers);
        // wait for the new configuration to take effect
        waitAndCheckNewConf(cluster, allPeers, 2, null);
    } finally {
        cluster.shutdown();
    }
}
Also used : MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges)

Example 8 with MiniRaftCluster

use of org.apache.ratis.MiniRaftCluster in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testReconfTwice.

@Test(timeout = 30000)
public void testReconfTwice() throws Exception {
    LOG.info("Start testReconfTwice");
    final MiniRaftCluster cluster = getCluster(3);
    cluster.start();
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftPeerId leaderId = cluster.getLeader().getId();
        final RaftClient client = cluster.createClient(leaderId);
        // submit some msgs before reconf
        for (int i = 0; i < getStagingGap() * 2; i++) {
            RaftClientReply reply = client.send(new SimpleMessage("m" + i));
            Assert.assertTrue(reply.isSuccess());
        }
        final AtomicBoolean reconf1 = new AtomicBoolean(false);
        final AtomicBoolean reconf2 = new AtomicBoolean(false);
        final AtomicReference<RaftPeer[]> finalPeers = new AtomicReference<>(null);
        final AtomicReference<RaftPeer[]> deadPeers = new AtomicReference<>(null);
        CountDownLatch latch = new CountDownLatch(1);
        Thread clientThread = new Thread(() -> {
            try {
                PeerChanges c1 = cluster.addNewPeers(2, true);
                LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
                RaftClientReply reply = client.setConfiguration(c1.allPeersInNewConf);
                reconf1.set(reply.isSuccess());
                PeerChanges c2 = cluster.removePeers(2, true, asList(c1.newPeers));
                finalPeers.set(c2.allPeersInNewConf);
                deadPeers.set(c2.removedPeers);
                LOG.info("Start changing the configuration again: {}", asList(c2.allPeersInNewConf));
                reply = client.setConfiguration(c2.allPeersInNewConf);
                reconf2.set(reply.isSuccess());
                latch.countDown();
                client.close();
            } catch (IOException ignored) {
            }
        });
        clientThread.start();
        latch.await();
        Assert.assertTrue(reconf1.get());
        Assert.assertTrue(reconf2.get());
        waitAndCheckNewConf(cluster, finalPeers.get(), 2, null);
        // check configuration manager's internal state
        // each reconf will generate two configurations: (old, new) and (new)
        cluster.getServerAliveStream().forEach(server -> {
            ConfigurationManager confManager = (ConfigurationManager) Whitebox.getInternalState(server.getState(), "configurationManager");
            // each reconf will generate two configurations: (old, new) and (new)
            Assert.assertEquals(5, confManager.numOfConf());
        });
    } finally {
        cluster.shutdown();
    }
}
Also used : SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 9 with MiniRaftCluster

use of org.apache.ratis.MiniRaftCluster in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testKillLeaderDuringReconf.

/**
 * kill the leader before reconfiguration finishes. Make sure the client keeps
 * retrying.
 */
@Test
public void testKillLeaderDuringReconf() throws Exception {
    LOG.info("Start testKillLeaderDuringReconf");
    // originally 3 peers
    final MiniRaftCluster cluster = getCluster(3);
    cluster.start();
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftPeerId leaderId = cluster.getLeader().getId();
        final RaftClient client = cluster.createClient(leaderId);
        PeerChanges c1 = cluster.addNewPeers(2, false);
        PeerChanges c2 = cluster.removePeers(2, false, asList(c1.newPeers));
        LOG.info("Start changing the configuration: {}", asList(c2.allPeersInNewConf));
        final AtomicReference<Boolean> success = new AtomicReference<>();
        final AtomicBoolean clientRunning = new AtomicBoolean(true);
        Thread clientThread = new Thread(() -> {
            try {
                boolean r = false;
                while (clientRunning.get() && !r) {
                    r = client.setConfiguration(c2.allPeersInNewConf).isSuccess();
                }
                success.set(r);
                client.close();
            } catch (IOException ignored) {
            }
        });
        clientThread.start();
        // the leader cannot generate the (old, new) conf, and it will keep
        // bootstrapping the 2 new peers since they have not started yet
        LOG.info(cluster.printServers());
        Assert.assertFalse(cluster.getLeader().getRaftConf().isTransitional());
        // only the first empty entry got committed
        final long committedIndex = cluster.getLeader().getState().getLog().getLastCommittedIndex();
        Assert.assertTrue("committedIndex is " + committedIndex, committedIndex <= 1);
        LOG.info("kill the current leader");
        final String oldLeaderId = RaftTestUtil.waitAndKillLeader(cluster, true);
        LOG.info("start the two new peers: {}", Arrays.asList(c1.newPeers));
        for (RaftPeer np : c1.newPeers) {
            cluster.startServer(np.getId());
        }
        Thread.sleep(3000);
        // the client should get the NotLeaderException from the first leader, and
        // will retry the same setConfiguration request
        waitAndCheckNewConf(cluster, c2.allPeersInNewConf, 2, Collections.singletonList(oldLeaderId));
        clientRunning.set(false);
    // Assert.assertTrue(success.get());
    } finally {
        cluster.shutdown();
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 10 with MiniRaftCluster

use of org.apache.ratis.MiniRaftCluster in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testReconfTimeout.

@Test
public void testReconfTimeout() throws Exception {
    LOG.info("Start testReconfTimeout");
    // originally 3 peers
    final MiniRaftCluster cluster = getCluster(3);
    cluster.start();
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftPeerId leaderId = cluster.getLeader().getId();
        final RaftClient client = cluster.createClient(leaderId);
        PeerChanges c1 = cluster.addNewPeers(2, false);
        LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
        Assert.assertFalse(cluster.getLeader().getRaftConf().isTransitional());
        final RaftClientRpc sender = client.getClientRpc();
        final SetConfigurationRequest request = cluster.newSetConfigurationRequest(client.getId(), leaderId, c1.allPeersInNewConf);
        try {
            sender.sendRequest(request);
            Assert.fail("did not get expected exception");
        } catch (IOException e) {
            Assert.assertTrue("Got exception " + e, e instanceof ReconfigurationTimeoutException);
        }
        // the two new peers have not started yet, the bootstrapping must timeout
        LOG.info(cluster.printServers());
        // state so that we still get timeout instead of in-progress exception
        try {
            sender.sendRequest(request);
            Assert.fail("did not get expected exception");
        } catch (IOException e) {
            Assert.assertTrue("Got exception " + e, e instanceof ReconfigurationTimeoutException);
        }
        // start the two new peers
        LOG.info("Start new peers");
        for (RaftPeer np : c1.newPeers) {
            cluster.startServer(np.getId());
        }
        Assert.assertTrue(client.setConfiguration(c1.allPeersInNewConf).isSuccess());
        client.close();
    } finally {
        cluster.shutdown();
    }
}
Also used : MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) IOException(java.io.IOException) RaftClient(org.apache.ratis.client.RaftClient) RaftClientRpc(org.apache.ratis.client.RaftClientRpc) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Aggregations

MiniRaftCluster (org.apache.ratis.MiniRaftCluster)13 BaseTest (org.apache.ratis.BaseTest)11 Test (org.junit.Test)11 RaftClient (org.apache.ratis.client.RaftClient)9 IOException (java.io.IOException)6 PeerChanges (org.apache.ratis.MiniRaftCluster.PeerChanges)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 SimpleMessage (org.apache.ratis.RaftTestUtil.SimpleMessage)3 RaftClientRpc (org.apache.ratis.client.RaftClientRpc)2 RaftGroup (org.apache.ratis.protocol.RaftGroup)2 RaftGroupId (org.apache.ratis.protocol.RaftGroupId)2 RaftPeer (org.apache.ratis.protocol.RaftPeer)2 RaftPeerId (org.apache.ratis.protocol.RaftPeerId)2 RaftLog (org.apache.ratis.server.storage.RaftLog)2 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 List (java.util.List)1 CountDownLatch (java.util.concurrent.CountDownLatch)1