@Test
    public void testPreVote() throws Exception {
        List<PeerId> peers = TestUtils.generatePeers(3);

        final TestCluster cluster = new TestCluster("unitest", this.dataPath, peers);

        for (final PeerId peer : peers) {
            assertTrue(cluster.start(peer.getEndpoint()));
        }

        cluster.waitLeader();
        // get leader
        Node leader = cluster.getLeader();
        final long savedTerm = ((NodeImpl) leader).getCurrentTerm();
        assertNotNull(leader);
        // apply tasks to leader
        this.sendTestTaskAndWait(leader);

        cluster.ensureSame();

        final List<Node> followers = cluster.getFollowers();
        assertEquals(2, followers.size());

        final PeerId followerPeer = followers.get(0).getNodeId().getPeerId();
        final Endpoint followerAddr = followerPeer.getEndpoint();

        // remove follower
        LOG.info("Remove follower {}", followerPeer);
        CountDownLatch latch = new CountDownLatch(1);
        leader.removePeer(followerPeer, new ExpectClosure(latch));
        waitLatch(latch);

        this.sendTestTaskAndWait(leader, 10, RaftError.SUCCESS);

        Thread.sleep(2000);

        // add follower
        LOG.info("Add follower {}", followerAddr);
        peers = TestUtils.generatePeers(3);
        assertTrue(peers.remove(followerPeer));
        latch = new CountDownLatch(1);
        leader.addPeer(followerPeer, new ExpectClosure(latch));
        waitLatch(latch);
        leader = cluster.getLeader();
        assertNotNull(leader);
        // leader term should not be changed.
        assertEquals(savedTerm, ((NodeImpl) leader).getCurrentTerm());
        cluster.stopAll();
    }
Test rollback stateMachine with readIndex for issue 317:
https://github.com/sofastack/sofa-jraft/issues/317
jraft-core/src/test/java/com/alipay/sofa/jraft/core/NodeTest.java