Repository: incubator-ratis Updated Branches: refs/heads/master d960d1e7f -> 813db4b78
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfo.java ---------------------------------------------------------------------- diff --git a/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfo.java b/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfo.java index 6d82942..b7deb9a 100644 --- a/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfo.java +++ b/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfo.java @@ -17,7 +17,7 @@ */ package org.apache.raft.statemachine; -import org.apache.raft.server.RaftConfiguration; +import org.apache.raft.server.impl.RaftConfiguration; import org.apache.raft.server.protocol.TermIndex; import org.apache.raft.server.storage.FileInfo; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfoImpl.java ---------------------------------------------------------------------- diff --git a/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfoImpl.java b/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfoImpl.java index af8ba0e..670bfc7 100644 --- a/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfoImpl.java +++ b/raft-server/src/main/java/org/apache/raft/statemachine/SnapshotInfoImpl.java @@ -17,7 +17,7 @@ */ package org.apache.raft.statemachine; -import org.apache.raft.server.RaftConfiguration; +import org.apache.raft.server.impl.RaftConfiguration; import org.apache.raft.server.protocol.TermIndex; import org.apache.raft.server.storage.FileInfo; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/main/java/org/apache/raft/statemachine/StateMachine.java ---------------------------------------------------------------------- diff --git a/raft-server/src/main/java/org/apache/raft/statemachine/StateMachine.java b/raft-server/src/main/java/org/apache/raft/statemachine/StateMachine.java index dc18175..935a83a 100644 --- a/raft-server/src/main/java/org/apache/raft/statemachine/StateMachine.java +++ b/raft-server/src/main/java/org/apache/raft/statemachine/StateMachine.java @@ -17,20 +17,20 @@ */ package org.apache.raft.statemachine; -import java.io.Closeable; -import java.io.IOException; -import java.util.Collection; -import java.util.concurrent.CompletableFuture; - import org.apache.raft.conf.RaftProperties; import org.apache.raft.protocol.Message; import org.apache.raft.protocol.RaftClientReply; import org.apache.raft.protocol.RaftClientRequest; -import org.apache.raft.server.RaftConfiguration; import org.apache.raft.server.RaftServerConfigKeys; +import org.apache.raft.server.impl.RaftConfiguration; import org.apache.raft.server.storage.RaftStorage; import org.apache.raft.util.LifeCycle; +import java.io.Closeable; +import java.io.IOException; +import java.util.Collection; +import java.util.concurrent.CompletableFuture; + public interface StateMachine extends Closeable { /** * Initializes the State Machine with the given properties and storage. The state machine is http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/main/java/org/apache/raft/statemachine/TermIndexTracker.java ---------------------------------------------------------------------- diff --git a/raft-server/src/main/java/org/apache/raft/statemachine/TermIndexTracker.java b/raft-server/src/main/java/org/apache/raft/statemachine/TermIndexTracker.java index 1548e1d..694eef4 100644 --- a/raft-server/src/main/java/org/apache/raft/statemachine/TermIndexTracker.java +++ b/raft-server/src/main/java/org/apache/raft/statemachine/TermIndexTracker.java @@ -20,7 +20,7 @@ package org.apache.raft.statemachine; import com.google.common.base.Preconditions; import org.apache.raft.server.protocol.TermIndex; -import static org.apache.raft.server.RaftServerConstants.INVALID_LOG_INDEX; +import static org.apache.raft.server.impl.RaftServerConstants.INVALID_LOG_INDEX; /** * Tracks the term index that is applied to the StateMachine for simple state machines with http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/MiniRaftCluster.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/MiniRaftCluster.java b/raft-server/src/test/java/org/apache/raft/MiniRaftCluster.java index 80cfa1f..4f0871f 100644 --- a/raft-server/src/test/java/org/apache/raft/MiniRaftCluster.java +++ b/raft-server/src/test/java/org/apache/raft/MiniRaftCluster.java @@ -23,7 +23,11 @@ import org.apache.raft.client.RaftClientRequestSender; import org.apache.raft.client.impl.RaftClientImpl; import org.apache.raft.conf.RaftProperties; import org.apache.raft.protocol.RaftPeer; -import org.apache.raft.server.*; +import org.apache.raft.server.RaftServerConfigKeys; +import org.apache.raft.server.impl.DelayLocalExecutionInjection; +import org.apache.raft.server.impl.RaftConfiguration; +import org.apache.raft.server.impl.RaftServer; +import org.apache.raft.server.impl.RaftServerRpc; import org.apache.raft.server.storage.MemoryRaftLog; import org.apache.raft.server.storage.RaftLog; import org.apache.raft.statemachine.BaseStateMachine; @@ -40,7 +44,7 @@ import java.io.IOException; import java.util.*; import java.util.stream.Collectors; -import static org.apache.raft.server.RaftServerConfigKeys.*; +import static org.apache.raft.server.RaftServerConfigKeys.RAFT_SERVER_RPC_TIMEOUT_MIN_MS_DEFAULT; public abstract class MiniRaftCluster { public static final Logger LOG = LoggerFactory.getLogger(MiniRaftCluster.class); http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/RaftBasicTests.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/RaftBasicTests.java b/raft-server/src/test/java/org/apache/raft/RaftBasicTests.java index 5a35afe..921e063 100644 --- a/raft-server/src/test/java/org/apache/raft/RaftBasicTests.java +++ b/raft-server/src/test/java/org/apache/raft/RaftBasicTests.java @@ -20,12 +20,8 @@ package org.apache.raft; import org.apache.raft.RaftTestUtil.SimpleMessage; import org.apache.raft.client.RaftClient; import org.apache.raft.conf.RaftProperties; -import org.apache.raft.server.RaftServer; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.apache.raft.server.impl.RaftServer; +import org.junit.*; import org.junit.rules.Timeout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/RaftNotLeaderExceptionBaseTest.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/RaftNotLeaderExceptionBaseTest.java b/raft-server/src/test/java/org/apache/raft/RaftNotLeaderExceptionBaseTest.java index 46a30c7..8a249e9 100644 --- a/raft-server/src/test/java/org/apache/raft/RaftNotLeaderExceptionBaseTest.java +++ b/raft-server/src/test/java/org/apache/raft/RaftNotLeaderExceptionBaseTest.java @@ -25,15 +25,11 @@ import org.apache.raft.client.impl.RaftClientImpl; import org.apache.raft.protocol.RaftClientReply; import org.apache.raft.protocol.RaftClientRequest; import org.apache.raft.protocol.RaftPeer; -import org.apache.raft.server.RaftServer; +import org.apache.raft.server.impl.RaftServer; import org.apache.raft.server.simulation.RequestHandler; import org.apache.raft.server.storage.RaftLog; import org.apache.raft.util.RaftUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import org.junit.rules.Timeout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,7 +38,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; -import static org.apache.raft.server.RaftServerConstants.DEFAULT_SEQNUM; +import static org.apache.raft.server.impl.RaftServerConstants.DEFAULT_SEQNUM; public abstract class RaftNotLeaderExceptionBaseTest { static { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/RaftTestUtil.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/RaftTestUtil.java b/raft-server/src/test/java/org/apache/raft/RaftTestUtil.java index ff7921d..92bf5c4 100644 --- a/raft-server/src/test/java/org/apache/raft/RaftTestUtil.java +++ b/raft-server/src/test/java/org/apache/raft/RaftTestUtil.java @@ -20,10 +20,10 @@ package org.apache.raft; import com.google.common.base.Preconditions; import org.apache.commons.lang.RandomStringUtils; import org.apache.raft.protocol.Message; -import org.apache.raft.server.BlockRequestHandlingInjection; -import org.apache.raft.server.DelayLocalExecutionInjection; -import org.apache.raft.server.RaftServer; import org.apache.raft.server.RaftServerConfigKeys; +import org.apache.raft.server.impl.BlockRequestHandlingInjection; +import org.apache.raft.server.impl.DelayLocalExecutionInjection; +import org.apache.raft.server.impl.RaftServer; import org.apache.raft.shaded.com.google.protobuf.ByteString; import org.apache.raft.shaded.proto.RaftProtos.LogEntryProto; import org.apache.raft.shaded.proto.RaftProtos.SMLogEntryProto; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/BlockRequestHandlingInjection.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/BlockRequestHandlingInjection.java b/raft-server/src/test/java/org/apache/raft/server/BlockRequestHandlingInjection.java deleted file mode 100644 index e1de3e5..0000000 --- a/raft-server/src/test/java/org/apache/raft/server/BlockRequestHandlingInjection.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.raft.server; - -import org.apache.raft.RaftTestUtil; -import org.apache.raft.util.CodeInjectionForTesting; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** Inject code to block a server from handling incoming requests. */ -public class BlockRequestHandlingInjection implements CodeInjectionForTesting.Code { - private static final BlockRequestHandlingInjection INSTANCE = - new BlockRequestHandlingInjection(); - - static { - CodeInjectionForTesting.put(RaftServer.REQUEST_VOTE, INSTANCE); - CodeInjectionForTesting.put(RaftServer.APPEND_ENTRIES, INSTANCE); - CodeInjectionForTesting.put(RaftServer.INSTALL_SNAPSHOT, INSTANCE); - } - - public static BlockRequestHandlingInjection getInstance() { - return INSTANCE; - } - - private final Map<String, Boolean> requestors = new ConcurrentHashMap<>(); - private final Map<String, Boolean> repliers = new ConcurrentHashMap<>(); - - private BlockRequestHandlingInjection() {} - - public void blockRequestor(String requestor) { - requestors.put(requestor, true); - } - - public void unblockRequestor(String requestor) { - requestors.remove(requestor); - } - - public void blockReplier(String replier) { - repliers.put(replier, true); - } - - public void unblockReplier(String replier) { - repliers.remove(replier); - } - - public void unblockAll() { - requestors.clear(); - repliers.clear(); - } - - @Override - public boolean execute(String localId, String remoteId, Object... args) { - if (shouldBlock(localId, remoteId)) { - try { - RaftTestUtil.block(() -> shouldBlock(localId, remoteId)); - return true; - } catch (InterruptedException e) { - LOG.debug("Interrupted while blocking request handling from " + remoteId - + " to " + localId); - } - } - return false; - } - - private boolean shouldBlock(String localId, String remoteId) { - return repliers.containsKey(localId) || requestors.containsKey(remoteId); - } -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/DelayLocalExecutionInjection.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/DelayLocalExecutionInjection.java b/raft-server/src/test/java/org/apache/raft/server/DelayLocalExecutionInjection.java deleted file mode 100644 index 612b75f..0000000 --- a/raft-server/src/test/java/org/apache/raft/server/DelayLocalExecutionInjection.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.raft.server; - -import org.apache.raft.RaftTestUtil; -import org.apache.raft.util.CodeInjectionForTesting; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -/** Inject code to delay particular servers. */ -public class DelayLocalExecutionInjection implements CodeInjectionForTesting.Code { - private final Map<String, AtomicInteger> delays = new ConcurrentHashMap<>(); - - public DelayLocalExecutionInjection(String method) { - CodeInjectionForTesting.put(method, this); - } - - public void clear() { - delays.clear(); - } - - public void setDelayMs(String id, int delayMs) { - AtomicInteger d = delays.get(id); - if (d == null) { - delays.put(id, d = new AtomicInteger()); - } - d.set(delayMs); - } - - public void removeDelay(String id) { - delays.remove(id); - } - - @Override - public boolean execute(String localId, String remoteId, Object... args) { - final AtomicInteger d = delays.get(localId); - if (d == null) { - return false; - } - LOG.info("{} delay {} ms, args={}", localId, d.get(), - Arrays.toString(args)); - try { - RaftTestUtil.delay(d::get); - } catch (InterruptedException e) { - LOG.debug("Interrupted while delaying " + localId); - } - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/RaftReconfigurationBaseTest.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/RaftReconfigurationBaseTest.java b/raft-server/src/test/java/org/apache/raft/server/RaftReconfigurationBaseTest.java deleted file mode 100644 index 1be0cd7..0000000 --- a/raft-server/src/test/java/org/apache/raft/server/RaftReconfigurationBaseTest.java +++ /dev/null @@ -1,576 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.raft.server; - -import org.apache.log4j.Level; -import org.apache.raft.MiniRaftCluster; -import org.apache.raft.MiniRaftCluster.PeerChanges; -import org.apache.raft.RaftTestUtil; -import org.apache.raft.RaftTestUtil.SimpleMessage; -import org.apache.raft.client.RaftClient; -import org.apache.raft.client.RaftClientRequestSender; -import org.apache.raft.client.impl.RaftClientImpl; -import org.apache.raft.conf.RaftProperties; -import org.apache.raft.protocol.*; -import org.apache.raft.server.simulation.RequestHandler; -import org.apache.raft.server.storage.RaftLog; -import org.apache.raft.util.RaftUtils; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.mockito.internal.util.reflection.Whitebox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import static java.util.Arrays.asList; -import static org.apache.raft.MiniRaftCluster.logSyncDelay; -import static org.apache.raft.server.RaftServerConstants.DEFAULT_SEQNUM; -import static org.apache.raft.server.RaftServerTestUtil.waitAndCheckNewConf; -import static org.apache.raft.shaded.proto.RaftProtos.LogEntryProto.LogEntryBodyCase.CONFIGURATIONENTRY; - -public abstract class RaftReconfigurationBaseTest { - static { - RaftUtils.setLogLevel(RaftServer.LOG, Level.DEBUG); - RaftUtils.setLogLevel(RequestHandler.LOG, Level.DEBUG); - RaftUtils.setLogLevel(RaftClient.LOG, Level.DEBUG); - } - static final Logger LOG = LoggerFactory.getLogger(RaftReconfigurationBaseTest.class); - - protected static final RaftProperties prop = new RaftProperties(); - - @BeforeClass - public static void setup() { - // set a small gap for tests - prop.setInt(RaftServerConfigKeys.RAFT_SERVER_STAGING_CATCHUP_GAP_KEY, 10); - } - - public abstract MiniRaftCluster getCluster(int peerNum) throws IOException; - - private static int getStagingGap() { - return prop.getInt(RaftServerConfigKeys.RAFT_SERVER_STAGING_CATCHUP_GAP_KEY, - RaftServerConfigKeys.RAFT_SERVER_STAGING_CATCHUP_GAP_DEFAULT); - } - - /** - * add 2 new peers (3 peers -> 5 peers), no leader change - */ - @Test - public void testAddPeers() throws Exception { - LOG.info("Start testAddPeers"); - MiniRaftCluster cluster = getCluster(3); - cluster.start(); - try { - RaftTestUtil.waitForLeader(cluster); - - // add new peers - RaftPeer[] allPeers = cluster.addNewPeers(2, true).allPeersInNewConf; - - // trigger setConfiguration - SetConfigurationRequest request = new SetConfigurationRequest("client", - cluster.getLeader().getId(), DEFAULT_SEQNUM, allPeers); - LOG.info("Start changing the configuration: {}", request); - cluster.getLeader().setConfiguration(request); - - // wait for the new configuration to take effect - waitAndCheckNewConf(cluster, allPeers, 0, null); - } finally { - cluster.shutdown(); - } - } - - /** - * remove 2 peers (5 peers -> 3 peers), no leader change - */ - @Test - public void testRemovePeers() throws Exception { - LOG.info("Start testRemovePeers"); - MiniRaftCluster cluster = getCluster(5); - cluster.start(); - try { - RaftTestUtil.waitForLeader(cluster); - - // remove peers, leader still included in the new conf - RaftPeer[] allPeers = cluster - .removePeers(2, false, Collections.emptyList()).allPeersInNewConf; - - // trigger setConfiguration - SetConfigurationRequest request = new SetConfigurationRequest("client", - cluster.getLeader().getId(), DEFAULT_SEQNUM, allPeers); - LOG.info("Start changing the configuration: {}", request); - cluster.getLeader().setConfiguration(request); - - // wait for the new configuration to take effect - waitAndCheckNewConf(cluster, allPeers, 2, null); - } finally { - cluster.shutdown(); - } - } - - /** - * 5 peers -> 5 peers, remove 2 old, add 2 new, no leader change - */ - @Test - public void testAddRemovePeers() throws Exception { - LOG.info("Start testAddRemovePeers"); - testAddRemovePeers(false); - } - - @Test - public void testLeaderStepDown() throws Exception { - LOG.info("Start testLeaderStepDown"); - testAddRemovePeers(true); - } - - 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 - SetConfigurationRequest request = new SetConfigurationRequest("client", - cluster.getLeader().getId(), DEFAULT_SEQNUM, allPeers); - LOG.info("Start changing the configuration: {}", request); - cluster.getLeader().setConfiguration(request); - - // wait for the new configuration to take effect - waitAndCheckNewConf(cluster, allPeers, 2, null); - } finally { - cluster.shutdown(); - } - } - - @Test(timeout = 30000) - public void testReconfTwice() throws Exception { - LOG.info("Start testReconfTwice"); - final MiniRaftCluster cluster = getCluster(3); - cluster.start(); - try { - RaftTestUtil.waitForLeader(cluster); - final String leaderId = cluster.getLeader().getId(); - final RaftClient client = cluster.createClient("client", 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.getServers().stream().filter(RaftServer::isAlive) - .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(); - } - } - - @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 String leaderId = cluster.getLeader().getId(); - final RaftClient client = cluster.createClient("client", leaderId); - - PeerChanges c1 = cluster.addNewPeers(2, false); - - LOG.info("Start changing the configuration: {}", - asList(c1.allPeersInNewConf)); - Assert.assertFalse(cluster.getLeader().getRaftConf().isTransitional()); - - final RaftClientRequestSender sender = ((RaftClientImpl)client).getRequestSender(); - final SetConfigurationRequest request = new SetConfigurationRequest( - "client", leaderId, DEFAULT_SEQNUM, 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()); - - // resend the same request, make sure the server has correctly reset its - // 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(); - } - } - - @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 String leaderId = cluster.getLeader().getId(); - final RaftClient client = cluster.createClient("client", 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()).getState().getLog() - .getEntries(0, Long.MAX_VALUE)); - } - } finally { - cluster.shutdown(); - } - } - - /** - * 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 String leaderId = cluster.getLeader().getId(); - final RaftClient client = cluster.createClient("client", 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(); - } - } - - static void assertSuccess(final AtomicReference<Boolean> success) { - final String s = "success=" + success; - Assert.assertNotNull(s, success.get()); - Assert.assertTrue(s, success.get()); - } - - /** - * When a request's new configuration is the same with the current one, make - * sure we return success immediately and no log entry is recorded. - */ - @Test - public void testNoChangeRequest() throws Exception { - LOG.info("Start testNoChangeRequest"); - // originally 3 peers - final MiniRaftCluster cluster = getCluster(3); - try { - cluster.start(); - RaftTestUtil.waitForLeader(cluster); - - final String leaderId = cluster.getLeader().getId(); - final RaftClient client = cluster.createClient("client", leaderId); - client.send(new SimpleMessage("m")); - - final long committedIndex = cluster.getLeader().getState().getLog() - .getLastCommittedIndex(); - final RaftConfiguration confBefore = cluster.getLeader().getRaftConf(); - - // no real configuration change in the request - RaftClientReply reply = client.setConfiguration(cluster.getPeers() - .toArray(new RaftPeer[0])); - Assert.assertTrue(reply.isSuccess()); - Assert.assertEquals(committedIndex, cluster.getLeader().getState() - .getLog().getLastCommittedIndex()); - Assert.assertSame(confBefore, cluster.getLeader().getRaftConf()); - client.close(); - } finally { - cluster.shutdown(); - } - } - - /** - * Make sure a setConfiguration request is rejected if a configuration change - * is still in progress (i.e., has not been committed yet). - */ - @Test - public void testOverlappedSetConfRequests() throws Exception { - LOG.info("Start testOverlappedSetConfRequests"); - // originally 3 peers - final MiniRaftCluster cluster = getCluster(3); - try { - cluster.start(); - RaftTestUtil.waitForLeader(cluster); - - final String leaderId = cluster.getLeader().getId(); - - RaftPeer[] newPeers = cluster.addNewPeers(2, true).allPeersInNewConf; - - // delay every peer's logSync so that the setConf request is delayed - cluster.getPeers() - .forEach(peer -> logSyncDelay.setDelayMs(peer.getId(), 1000)); - - final CountDownLatch latch = new CountDownLatch(1); - final RaftPeer[] peersInRequest2 = cluster.getPeers().toArray(new RaftPeer[0]); - AtomicBoolean caughtException = new AtomicBoolean(false); - new Thread(() -> { - try(final RaftClient client2 = cluster.createClient("client2", leaderId)) { - latch.await(); - LOG.info("client2 starts to change conf"); - final RaftClientRequestSender sender2 = ((RaftClientImpl)client2).getRequestSender(); - sender2.sendRequest(new SetConfigurationRequest( - "client2", leaderId, DEFAULT_SEQNUM, peersInRequest2)); - } catch (ReconfigurationInProgressException e) { - caughtException.set(true); - } catch (Exception e) { - LOG.warn("Got unexpected exception when client2 changes conf", e); - } - }).start(); - - AtomicBoolean confChanged = new AtomicBoolean(false); - new Thread(() -> { - try(final RaftClient client1 = cluster.createClient("client1", leaderId)) { - LOG.info("client1 starts to change conf"); - confChanged.set(client1.setConfiguration(newPeers).isSuccess()); - } catch (IOException e) { - LOG.warn("Got unexpected exception when client1 changes conf", e); - } - }).start(); - Thread.sleep(100); - latch.countDown(); - - for (int i = 0; i < 10 && !confChanged.get(); i++) { - Thread.sleep(1000); - } - Assert.assertTrue(confChanged.get()); - Assert.assertTrue(caughtException.get()); - } finally { - logSyncDelay.clear(); - cluster.shutdown(); - } - } - - /** - * Test a scenario where the follower truncates its log entries which causes - * configuration change. - */ - @Test - public void testRevertConfigurationChange() throws Exception { - LOG.info("Start testRevertConfigurationChange"); - // originally 3 peers - final MiniRaftCluster cluster = getCluster(5); - try { - cluster.start(); - RaftTestUtil.waitForLeader(cluster); - - final String leaderId = cluster.getLeader().getId(); - - final RaftLog log = cluster.getServer(leaderId).getState().getLog(); - Thread.sleep(1000); - Assert.assertEquals(0, log.getLatestFlushedIndex()); - - // we block the incoming msg for the leader and block its requests to - // followers, so that we force the leader change and the old leader will - // not know - LOG.info("start blocking the leader"); - BlockRequestHandlingInjection.getInstance().blockReplier(leaderId); - cluster.setBlockRequestsFrom(leaderId, true); - - PeerChanges change = cluster.removePeers(1, false, new ArrayList<>()); - - AtomicBoolean gotNotLeader = new AtomicBoolean(false); - new Thread(() -> { - try(final RaftClient client = cluster.createClient("client1", leaderId)) { - LOG.info("client starts to change conf"); - final RaftClientRequestSender sender = ((RaftClientImpl)client).getRequestSender(); - RaftClientReply reply = sender.sendRequest(new SetConfigurationRequest( - "client", leaderId, DEFAULT_SEQNUM, change.allPeersInNewConf)); - if (reply.isNotLeader()) { - gotNotLeader.set(true); - } - } catch (IOException e) { - LOG.warn("Got unexpected exception when client1 changes conf", e); - } - }).start(); - - // wait till the old leader persist the new conf - for (int i = 0; i < 10 && log.getLatestFlushedIndex() < 1; i++) { - Thread.sleep(500); - } - Assert.assertEquals(1, log.getLatestFlushedIndex()); - Assert.assertEquals(CONFIGURATIONENTRY, - log.getLastEntry().getLogEntryBodyCase()); - - // unblock the old leader - BlockRequestHandlingInjection.getInstance().unblockReplier(leaderId); - cluster.setBlockRequestsFrom(leaderId, false); - - // the client should get NotLeaderException - for (int i = 0; i < 10 && !gotNotLeader.get(); i++) { - Thread.sleep(500); - } - Assert.assertTrue(gotNotLeader.get()); - - // the old leader should have truncated the setConf from the log - boolean newState = false; - for (int i = 0; i < 10 && !newState; i++) { - Thread.sleep(500); - newState = log.getLastCommittedIndex() == 1 && - log.getLastEntry().getLogEntryBodyCase() != CONFIGURATIONENTRY; - } - Assert.assertTrue(newState); - } finally { - cluster.shutdown(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/RaftServerTestUtil.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/RaftServerTestUtil.java b/raft-server/src/test/java/org/apache/raft/server/RaftServerTestUtil.java deleted file mode 100644 index d52e3ad..0000000 --- a/raft-server/src/test/java/org/apache/raft/server/RaftServerTestUtil.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.raft.server; - -import org.apache.raft.MiniRaftCluster; -import org.apache.raft.RaftTestUtil; -import org.apache.raft.protocol.RaftPeer; -import org.junit.Assert; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collection; - -public class RaftServerTestUtil { - static final Logger LOG = LoggerFactory.getLogger(RaftServerTestUtil.class); - - public static void waitAndCheckNewConf(MiniRaftCluster cluster, - RaftPeer[] peers, int numOfRemovedPeers, Collection<String> deadPeers) - throws Exception { - final long sleepMs = cluster.getMaxTimeout() * (numOfRemovedPeers + 2); - RaftTestUtil.attempt(3, sleepMs, - () -> waitAndCheckNewConf(cluster, peers, deadPeers)); - } - private static void waitAndCheckNewConf(MiniRaftCluster cluster, - RaftPeer[] peers, Collection<String> deadPeers) - throws Exception { - LOG.info(cluster.printServers()); - Assert.assertNotNull(cluster.getLeader()); - - int numIncluded = 0; - int deadIncluded = 0; - final RaftConfiguration current = RaftConfiguration.newBuilder() - .setConf(peers).setLogEntryIndex(0).build(); - for (RaftServer server : cluster.getServers()) { - if (deadPeers != null && deadPeers.contains(server.getId())) { - if (current.containsInConf(server.getId())) { - deadIncluded++; - } - continue; - } - if (current.containsInConf(server.getId())) { - numIncluded++; - Assert.assertTrue(server.getRaftConf().isStable()); - Assert.assertTrue(server.getRaftConf().hasNoChange(peers)); - } else { - Assert.assertFalse(server.getId() + " is still running: " + server, - server.isAlive()); - } - } - Assert.assertEquals(peers.length, numIncluded + deadIncluded); - } -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/impl/BlockRequestHandlingInjection.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/impl/BlockRequestHandlingInjection.java b/raft-server/src/test/java/org/apache/raft/server/impl/BlockRequestHandlingInjection.java new file mode 100644 index 0000000..0980e93 --- /dev/null +++ b/raft-server/src/test/java/org/apache/raft/server/impl/BlockRequestHandlingInjection.java @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.raft.server.impl; + +import org.apache.raft.RaftTestUtil; +import org.apache.raft.util.CodeInjectionForTesting; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** Inject code to block a server from handling incoming requests. */ +public class BlockRequestHandlingInjection implements CodeInjectionForTesting.Code { + private static final BlockRequestHandlingInjection INSTANCE = + new BlockRequestHandlingInjection(); + + static { + CodeInjectionForTesting.put(RaftServer.REQUEST_VOTE, INSTANCE); + CodeInjectionForTesting.put(RaftServer.APPEND_ENTRIES, INSTANCE); + CodeInjectionForTesting.put(RaftServer.INSTALL_SNAPSHOT, INSTANCE); + } + + public static BlockRequestHandlingInjection getInstance() { + return INSTANCE; + } + + private final Map<String, Boolean> requestors = new ConcurrentHashMap<>(); + private final Map<String, Boolean> repliers = new ConcurrentHashMap<>(); + + private BlockRequestHandlingInjection() {} + + public void blockRequestor(String requestor) { + requestors.put(requestor, true); + } + + public void unblockRequestor(String requestor) { + requestors.remove(requestor); + } + + public void blockReplier(String replier) { + repliers.put(replier, true); + } + + public void unblockReplier(String replier) { + repliers.remove(replier); + } + + public void unblockAll() { + requestors.clear(); + repliers.clear(); + } + + @Override + public boolean execute(String localId, String remoteId, Object... args) { + if (shouldBlock(localId, remoteId)) { + try { + RaftTestUtil.block(() -> shouldBlock(localId, remoteId)); + return true; + } catch (InterruptedException e) { + LOG.debug("Interrupted while blocking request handling from " + remoteId + + " to " + localId); + } + } + return false; + } + + private boolean shouldBlock(String localId, String remoteId) { + return repliers.containsKey(localId) || requestors.containsKey(remoteId); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/impl/DelayLocalExecutionInjection.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/impl/DelayLocalExecutionInjection.java b/raft-server/src/test/java/org/apache/raft/server/impl/DelayLocalExecutionInjection.java new file mode 100644 index 0000000..26b89d8 --- /dev/null +++ b/raft-server/src/test/java/org/apache/raft/server/impl/DelayLocalExecutionInjection.java @@ -0,0 +1,67 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.raft.server.impl; + +import org.apache.raft.RaftTestUtil; +import org.apache.raft.util.CodeInjectionForTesting; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** Inject code to delay particular servers. */ +public class DelayLocalExecutionInjection implements CodeInjectionForTesting.Code { + private final Map<String, AtomicInteger> delays = new ConcurrentHashMap<>(); + + public DelayLocalExecutionInjection(String method) { + CodeInjectionForTesting.put(method, this); + } + + public void clear() { + delays.clear(); + } + + public void setDelayMs(String id, int delayMs) { + AtomicInteger d = delays.get(id); + if (d == null) { + delays.put(id, d = new AtomicInteger()); + } + d.set(delayMs); + } + + public void removeDelay(String id) { + delays.remove(id); + } + + @Override + public boolean execute(String localId, String remoteId, Object... args) { + final AtomicInteger d = delays.get(localId); + if (d == null) { + return false; + } + LOG.info("{} delay {} ms, args={}", localId, d.get(), + Arrays.toString(args)); + try { + RaftTestUtil.delay(d::get); + } catch (InterruptedException e) { + LOG.debug("Interrupted while delaying " + localId); + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/impl/RaftReconfigurationBaseTest.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/impl/RaftReconfigurationBaseTest.java b/raft-server/src/test/java/org/apache/raft/server/impl/RaftReconfigurationBaseTest.java new file mode 100644 index 0000000..30f1e15 --- /dev/null +++ b/raft-server/src/test/java/org/apache/raft/server/impl/RaftReconfigurationBaseTest.java @@ -0,0 +1,577 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.raft.server.impl; + +import org.apache.log4j.Level; +import org.apache.raft.MiniRaftCluster; +import org.apache.raft.MiniRaftCluster.PeerChanges; +import org.apache.raft.RaftTestUtil; +import org.apache.raft.RaftTestUtil.SimpleMessage; +import org.apache.raft.client.RaftClient; +import org.apache.raft.client.RaftClientRequestSender; +import org.apache.raft.client.impl.RaftClientImpl; +import org.apache.raft.conf.RaftProperties; +import org.apache.raft.protocol.*; +import org.apache.raft.server.RaftServerConfigKeys; +import org.apache.raft.server.simulation.RequestHandler; +import org.apache.raft.server.storage.RaftLog; +import org.apache.raft.util.RaftUtils; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.internal.util.reflection.Whitebox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import static java.util.Arrays.asList; +import static org.apache.raft.MiniRaftCluster.logSyncDelay; +import static org.apache.raft.server.impl.RaftServerConstants.DEFAULT_SEQNUM; +import static org.apache.raft.server.impl.RaftServerTestUtil.waitAndCheckNewConf; +import static org.apache.raft.shaded.proto.RaftProtos.LogEntryProto.LogEntryBodyCase.CONFIGURATIONENTRY; + +public abstract class RaftReconfigurationBaseTest { + static { + RaftUtils.setLogLevel(RaftServer.LOG, Level.DEBUG); + RaftUtils.setLogLevel(RequestHandler.LOG, Level.DEBUG); + RaftUtils.setLogLevel(RaftClient.LOG, Level.DEBUG); + } + static final Logger LOG = LoggerFactory.getLogger(RaftReconfigurationBaseTest.class); + + protected static final RaftProperties prop = new RaftProperties(); + + @BeforeClass + public static void setup() { + // set a small gap for tests + prop.setInt(RaftServerConfigKeys.RAFT_SERVER_STAGING_CATCHUP_GAP_KEY, 10); + } + + public abstract MiniRaftCluster getCluster(int peerNum) throws IOException; + + private static int getStagingGap() { + return prop.getInt(RaftServerConfigKeys.RAFT_SERVER_STAGING_CATCHUP_GAP_KEY, + RaftServerConfigKeys.RAFT_SERVER_STAGING_CATCHUP_GAP_DEFAULT); + } + + /** + * add 2 new peers (3 peers -> 5 peers), no leader change + */ + @Test + public void testAddPeers() throws Exception { + LOG.info("Start testAddPeers"); + MiniRaftCluster cluster = getCluster(3); + cluster.start(); + try { + RaftTestUtil.waitForLeader(cluster); + + // add new peers + RaftPeer[] allPeers = cluster.addNewPeers(2, true).allPeersInNewConf; + + // trigger setConfiguration + SetConfigurationRequest request = new SetConfigurationRequest("client", + cluster.getLeader().getId(), DEFAULT_SEQNUM, allPeers); + LOG.info("Start changing the configuration: {}", request); + cluster.getLeader().setConfiguration(request); + + // wait for the new configuration to take effect + waitAndCheckNewConf(cluster, allPeers, 0, null); + } finally { + cluster.shutdown(); + } + } + + /** + * remove 2 peers (5 peers -> 3 peers), no leader change + */ + @Test + public void testRemovePeers() throws Exception { + LOG.info("Start testRemovePeers"); + MiniRaftCluster cluster = getCluster(5); + cluster.start(); + try { + RaftTestUtil.waitForLeader(cluster); + + // remove peers, leader still included in the new conf + RaftPeer[] allPeers = cluster + .removePeers(2, false, Collections.emptyList()).allPeersInNewConf; + + // trigger setConfiguration + SetConfigurationRequest request = new SetConfigurationRequest("client", + cluster.getLeader().getId(), DEFAULT_SEQNUM, allPeers); + LOG.info("Start changing the configuration: {}", request); + cluster.getLeader().setConfiguration(request); + + // wait for the new configuration to take effect + waitAndCheckNewConf(cluster, allPeers, 2, null); + } finally { + cluster.shutdown(); + } + } + + /** + * 5 peers -> 5 peers, remove 2 old, add 2 new, no leader change + */ + @Test + public void testAddRemovePeers() throws Exception { + LOG.info("Start testAddRemovePeers"); + testAddRemovePeers(false); + } + + @Test + public void testLeaderStepDown() throws Exception { + LOG.info("Start testLeaderStepDown"); + testAddRemovePeers(true); + } + + 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 + SetConfigurationRequest request = new SetConfigurationRequest("client", + cluster.getLeader().getId(), DEFAULT_SEQNUM, allPeers); + LOG.info("Start changing the configuration: {}", request); + cluster.getLeader().setConfiguration(request); + + // wait for the new configuration to take effect + waitAndCheckNewConf(cluster, allPeers, 2, null); + } finally { + cluster.shutdown(); + } + } + + @Test(timeout = 30000) + public void testReconfTwice() throws Exception { + LOG.info("Start testReconfTwice"); + final MiniRaftCluster cluster = getCluster(3); + cluster.start(); + try { + RaftTestUtil.waitForLeader(cluster); + final String leaderId = cluster.getLeader().getId(); + final RaftClient client = cluster.createClient("client", 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.getServers().stream().filter(RaftServer::isAlive) + .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(); + } + } + + @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 String leaderId = cluster.getLeader().getId(); + final RaftClient client = cluster.createClient("client", leaderId); + + PeerChanges c1 = cluster.addNewPeers(2, false); + + LOG.info("Start changing the configuration: {}", + asList(c1.allPeersInNewConf)); + Assert.assertFalse(cluster.getLeader().getRaftConf().isTransitional()); + + final RaftClientRequestSender sender = ((RaftClientImpl)client).getRequestSender(); + final SetConfigurationRequest request = new SetConfigurationRequest( + "client", leaderId, DEFAULT_SEQNUM, 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()); + + // resend the same request, make sure the server has correctly reset its + // 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(); + } + } + + @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 String leaderId = cluster.getLeader().getId(); + final RaftClient client = cluster.createClient("client", 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()).getState().getLog() + .getEntries(0, Long.MAX_VALUE)); + } + } finally { + cluster.shutdown(); + } + } + + /** + * 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 String leaderId = cluster.getLeader().getId(); + final RaftClient client = cluster.createClient("client", 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(); + } + } + + static void assertSuccess(final AtomicReference<Boolean> success) { + final String s = "success=" + success; + Assert.assertNotNull(s, success.get()); + Assert.assertTrue(s, success.get()); + } + + /** + * When a request's new configuration is the same with the current one, make + * sure we return success immediately and no log entry is recorded. + */ + @Test + public void testNoChangeRequest() throws Exception { + LOG.info("Start testNoChangeRequest"); + // originally 3 peers + final MiniRaftCluster cluster = getCluster(3); + try { + cluster.start(); + RaftTestUtil.waitForLeader(cluster); + + final String leaderId = cluster.getLeader().getId(); + final RaftClient client = cluster.createClient("client", leaderId); + client.send(new SimpleMessage("m")); + + final long committedIndex = cluster.getLeader().getState().getLog() + .getLastCommittedIndex(); + final RaftConfiguration confBefore = cluster.getLeader().getRaftConf(); + + // no real configuration change in the request + RaftClientReply reply = client.setConfiguration(cluster.getPeers() + .toArray(new RaftPeer[0])); + Assert.assertTrue(reply.isSuccess()); + Assert.assertEquals(committedIndex, cluster.getLeader().getState() + .getLog().getLastCommittedIndex()); + Assert.assertSame(confBefore, cluster.getLeader().getRaftConf()); + client.close(); + } finally { + cluster.shutdown(); + } + } + + /** + * Make sure a setConfiguration request is rejected if a configuration change + * is still in progress (i.e., has not been committed yet). + */ + @Test + public void testOverlappedSetConfRequests() throws Exception { + LOG.info("Start testOverlappedSetConfRequests"); + // originally 3 peers + final MiniRaftCluster cluster = getCluster(3); + try { + cluster.start(); + RaftTestUtil.waitForLeader(cluster); + + final String leaderId = cluster.getLeader().getId(); + + RaftPeer[] newPeers = cluster.addNewPeers(2, true).allPeersInNewConf; + + // delay every peer's logSync so that the setConf request is delayed + cluster.getPeers() + .forEach(peer -> logSyncDelay.setDelayMs(peer.getId(), 1000)); + + final CountDownLatch latch = new CountDownLatch(1); + final RaftPeer[] peersInRequest2 = cluster.getPeers().toArray(new RaftPeer[0]); + AtomicBoolean caughtException = new AtomicBoolean(false); + new Thread(() -> { + try(final RaftClient client2 = cluster.createClient("client2", leaderId)) { + latch.await(); + LOG.info("client2 starts to change conf"); + final RaftClientRequestSender sender2 = ((RaftClientImpl)client2).getRequestSender(); + sender2.sendRequest(new SetConfigurationRequest( + "client2", leaderId, DEFAULT_SEQNUM, peersInRequest2)); + } catch (ReconfigurationInProgressException e) { + caughtException.set(true); + } catch (Exception e) { + LOG.warn("Got unexpected exception when client2 changes conf", e); + } + }).start(); + + AtomicBoolean confChanged = new AtomicBoolean(false); + new Thread(() -> { + try(final RaftClient client1 = cluster.createClient("client1", leaderId)) { + LOG.info("client1 starts to change conf"); + confChanged.set(client1.setConfiguration(newPeers).isSuccess()); + } catch (IOException e) { + LOG.warn("Got unexpected exception when client1 changes conf", e); + } + }).start(); + Thread.sleep(100); + latch.countDown(); + + for (int i = 0; i < 10 && !confChanged.get(); i++) { + Thread.sleep(1000); + } + Assert.assertTrue(confChanged.get()); + Assert.assertTrue(caughtException.get()); + } finally { + logSyncDelay.clear(); + cluster.shutdown(); + } + } + + /** + * Test a scenario where the follower truncates its log entries which causes + * configuration change. + */ + @Test + public void testRevertConfigurationChange() throws Exception { + LOG.info("Start testRevertConfigurationChange"); + // originally 3 peers + final MiniRaftCluster cluster = getCluster(5); + try { + cluster.start(); + RaftTestUtil.waitForLeader(cluster); + + final String leaderId = cluster.getLeader().getId(); + + final RaftLog log = cluster.getServer(leaderId).getState().getLog(); + Thread.sleep(1000); + Assert.assertEquals(0, log.getLatestFlushedIndex()); + + // we block the incoming msg for the leader and block its requests to + // followers, so that we force the leader change and the old leader will + // not know + LOG.info("start blocking the leader"); + BlockRequestHandlingInjection.getInstance().blockReplier(leaderId); + cluster.setBlockRequestsFrom(leaderId, true); + + PeerChanges change = cluster.removePeers(1, false, new ArrayList<>()); + + AtomicBoolean gotNotLeader = new AtomicBoolean(false); + new Thread(() -> { + try(final RaftClient client = cluster.createClient("client1", leaderId)) { + LOG.info("client starts to change conf"); + final RaftClientRequestSender sender = ((RaftClientImpl)client).getRequestSender(); + RaftClientReply reply = sender.sendRequest(new SetConfigurationRequest( + "client", leaderId, DEFAULT_SEQNUM, change.allPeersInNewConf)); + if (reply.isNotLeader()) { + gotNotLeader.set(true); + } + } catch (IOException e) { + LOG.warn("Got unexpected exception when client1 changes conf", e); + } + }).start(); + + // wait till the old leader persist the new conf + for (int i = 0; i < 10 && log.getLatestFlushedIndex() < 1; i++) { + Thread.sleep(500); + } + Assert.assertEquals(1, log.getLatestFlushedIndex()); + Assert.assertEquals(CONFIGURATIONENTRY, + log.getLastEntry().getLogEntryBodyCase()); + + // unblock the old leader + BlockRequestHandlingInjection.getInstance().unblockReplier(leaderId); + cluster.setBlockRequestsFrom(leaderId, false); + + // the client should get NotLeaderException + for (int i = 0; i < 10 && !gotNotLeader.get(); i++) { + Thread.sleep(500); + } + Assert.assertTrue(gotNotLeader.get()); + + // the old leader should have truncated the setConf from the log + boolean newState = false; + for (int i = 0; i < 10 && !newState; i++) { + Thread.sleep(500); + newState = log.getLastCommittedIndex() == 1 && + log.getLastEntry().getLogEntryBodyCase() != CONFIGURATIONENTRY; + } + Assert.assertTrue(newState); + } finally { + cluster.shutdown(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/impl/RaftServerTestUtil.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/impl/RaftServerTestUtil.java b/raft-server/src/test/java/org/apache/raft/server/impl/RaftServerTestUtil.java new file mode 100644 index 0000000..b30ddc9 --- /dev/null +++ b/raft-server/src/test/java/org/apache/raft/server/impl/RaftServerTestUtil.java @@ -0,0 +1,67 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.raft.server.impl; + +import org.apache.raft.MiniRaftCluster; +import org.apache.raft.RaftTestUtil; +import org.apache.raft.protocol.RaftPeer; +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; + +public class RaftServerTestUtil { + static final Logger LOG = LoggerFactory.getLogger(RaftServerTestUtil.class); + + public static void waitAndCheckNewConf(MiniRaftCluster cluster, + RaftPeer[] peers, int numOfRemovedPeers, Collection<String> deadPeers) + throws Exception { + final long sleepMs = cluster.getMaxTimeout() * (numOfRemovedPeers + 2); + RaftTestUtil.attempt(3, sleepMs, + () -> waitAndCheckNewConf(cluster, peers, deadPeers)); + } + private static void waitAndCheckNewConf(MiniRaftCluster cluster, + RaftPeer[] peers, Collection<String> deadPeers) + throws Exception { + LOG.info(cluster.printServers()); + Assert.assertNotNull(cluster.getLeader()); + + int numIncluded = 0; + int deadIncluded = 0; + final RaftConfiguration current = RaftConfiguration.newBuilder() + .setConf(peers).setLogEntryIndex(0).build(); + for (RaftServer server : cluster.getServers()) { + if (deadPeers != null && deadPeers.contains(server.getId())) { + if (current.containsInConf(server.getId())) { + deadIncluded++; + } + continue; + } + if (current.containsInConf(server.getId())) { + numIncluded++; + Assert.assertTrue(server.getRaftConf().isStable()); + Assert.assertTrue(server.getRaftConf().hasNoChange(peers)); + } else { + Assert.assertFalse(server.getId() + " is still running: " + server, + server.isAlive()); + } + } + Assert.assertEquals(peers.length, numIncluded + deadIncluded); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/simulation/MiniRaftClusterWithSimulatedRpc.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/simulation/MiniRaftClusterWithSimulatedRpc.java b/raft-server/src/test/java/org/apache/raft/server/simulation/MiniRaftClusterWithSimulatedRpc.java index fd6f6fb..360fe1e 100644 --- a/raft-server/src/test/java/org/apache/raft/server/simulation/MiniRaftClusterWithSimulatedRpc.java +++ b/raft-server/src/test/java/org/apache/raft/server/simulation/MiniRaftClusterWithSimulatedRpc.java @@ -21,7 +21,7 @@ import org.apache.raft.MiniRaftCluster; import org.apache.raft.client.RaftClientRequestSender; import org.apache.raft.conf.RaftProperties; import org.apache.raft.protocol.RaftPeer; -import org.apache.raft.server.RaftServer; +import org.apache.raft.server.impl.RaftServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/simulation/SimulatedServerRpc.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/simulation/SimulatedServerRpc.java b/raft-server/src/test/java/org/apache/raft/server/simulation/SimulatedServerRpc.java index bbb90f3..ed522d4 100644 --- a/raft-server/src/test/java/org/apache/raft/server/simulation/SimulatedServerRpc.java +++ b/raft-server/src/test/java/org/apache/raft/server/simulation/SimulatedServerRpc.java @@ -22,9 +22,9 @@ import org.apache.raft.protocol.RaftClientReply; import org.apache.raft.protocol.RaftClientRequest; import org.apache.raft.protocol.RaftPeer; import org.apache.raft.protocol.SetConfigurationRequest; -import org.apache.raft.server.RaftServer; -import org.apache.raft.server.RaftServerRpc; -import org.apache.raft.server.RequestDispatcher; +import org.apache.raft.server.impl.RaftServer; +import org.apache.raft.server.impl.RaftServerRpc; +import org.apache.raft.server.impl.RequestDispatcher; import org.apache.raft.shaded.proto.RaftProtos.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftReconfigurationWithSimulatedRpc.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftReconfigurationWithSimulatedRpc.java b/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftReconfigurationWithSimulatedRpc.java index 2fd71c7..b0eb456 100644 --- a/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftReconfigurationWithSimulatedRpc.java +++ b/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftReconfigurationWithSimulatedRpc.java @@ -18,7 +18,7 @@ package org.apache.raft.server.simulation; import org.apache.raft.MiniRaftCluster; -import org.apache.raft.server.RaftReconfigurationBaseTest; +import org.apache.raft.server.impl.RaftReconfigurationBaseTest; import java.io.IOException; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftWithSimulatedRpc.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftWithSimulatedRpc.java b/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftWithSimulatedRpc.java index c772f59..669226a 100644 --- a/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftWithSimulatedRpc.java +++ b/raft-server/src/test/java/org/apache/raft/server/simulation/TestRaftWithSimulatedRpc.java @@ -21,7 +21,7 @@ import org.apache.log4j.Level; import org.apache.raft.RaftBasicTests; import org.apache.raft.client.RaftClient; import org.apache.raft.conf.RaftProperties; -import org.apache.raft.server.RaftServer; +import org.apache.raft.server.impl.RaftServer; import org.apache.raft.util.RaftUtils; import java.io.IOException; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogReadWrite.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogReadWrite.java b/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogReadWrite.java index 9fe15bc..fa17696 100644 --- a/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogReadWrite.java +++ b/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogReadWrite.java @@ -21,8 +21,8 @@ import org.apache.raft.RaftTestUtil; import org.apache.raft.RaftTestUtil.SimpleOperation; import org.apache.raft.conf.RaftProperties; import org.apache.raft.protocol.ChecksumException; -import org.apache.raft.server.RaftServerConstants; -import org.apache.raft.server.RaftServerConstants.StartupOption; +import org.apache.raft.server.impl.RaftServerConstants; +import org.apache.raft.server.impl.RaftServerConstants.StartupOption; import org.apache.raft.shaded.com.google.protobuf.CodedOutputStream; import org.apache.raft.shaded.proto.RaftProtos.LogEntryProto; import org.apache.raft.util.FileUtils; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogSegment.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogSegment.java b/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogSegment.java index c0814e9..470f80f 100644 --- a/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogSegment.java +++ b/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftLogSegment.java @@ -21,7 +21,7 @@ import org.apache.raft.RaftTestUtil; import org.apache.raft.RaftTestUtil.SimpleOperation; import org.apache.raft.conf.RaftProperties; import org.apache.raft.server.RaftServerConfigKeys; -import org.apache.raft.server.RaftServerConstants.StartupOption; +import org.apache.raft.server.impl.RaftServerConstants.StartupOption; import org.apache.raft.shaded.proto.RaftProtos.LogEntryProto; import org.apache.raft.shaded.proto.RaftProtos.SMLogEntryProto; import org.apache.raft.util.FileUtils; @@ -37,10 +37,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.apache.raft.server.RaftServerConfigKeys.RAFT_LOG_SEGMENT_MAX_SIZE_KEY; -import static org.apache.raft.server.RaftServerConfigKeys.RAFT_LOG_SEGMENT_PREALLOCATED_SIZE_KEY; -import static org.apache.raft.server.RaftServerConfigKeys.RAFT_LOG_WRITE_BUFFER_SIZE_KEY; -import static org.apache.raft.server.RaftServerConstants.INVALID_LOG_INDEX; +import static org.apache.raft.server.RaftServerConfigKeys.*; +import static org.apache.raft.server.impl.RaftServerConstants.INVALID_LOG_INDEX; import static org.apache.raft.server.storage.LogSegment.getEntrySize; /** http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftStorage.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftStorage.java b/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftStorage.java index ee5f481..1b14199 100644 --- a/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftStorage.java +++ b/raft-server/src/test/java/org/apache/raft/server/storage/TestRaftStorage.java @@ -20,8 +20,8 @@ package org.apache.raft.server.storage; import org.apache.raft.RaftTestUtil; import org.apache.raft.conf.RaftProperties; import org.apache.raft.io.nativeio.NativeIO; -import org.apache.raft.server.RaftServerConstants.StartupOption; import org.apache.raft.server.RaftServerConfigKeys; +import org.apache.raft.server.impl.RaftServerConstants.StartupOption; import org.apache.raft.server.protocol.TermIndex; import org.apache.raft.server.storage.RaftStorageDirectory.StorageState; import org.apache.raft.statemachine.SimpleStateMachineStorage; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/server/storage/TestSegmentedRaftLog.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/server/storage/TestSegmentedRaftLog.java b/raft-server/src/test/java/org/apache/raft/server/storage/TestSegmentedRaftLog.java index 0f36a72..264ba8e 100644 --- a/raft-server/src/test/java/org/apache/raft/server/storage/TestSegmentedRaftLog.java +++ b/raft-server/src/test/java/org/apache/raft/server/storage/TestSegmentedRaftLog.java @@ -22,9 +22,9 @@ import org.apache.raft.MiniRaftCluster; import org.apache.raft.RaftTestUtil; import org.apache.raft.RaftTestUtil.SimpleOperation; import org.apache.raft.conf.RaftProperties; -import org.apache.raft.server.ConfigurationManager; import org.apache.raft.server.RaftServerConfigKeys; -import org.apache.raft.server.RaftServerConstants; +import org.apache.raft.server.impl.ConfigurationManager; +import org.apache.raft.server.impl.RaftServerConstants; import org.apache.raft.shaded.proto.RaftProtos.LogEntryProto; import org.apache.raft.util.FileUtils; import org.apache.raft.util.ProtoUtils; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/statemachine/RaftSnapshotBaseTest.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/statemachine/RaftSnapshotBaseTest.java b/raft-server/src/test/java/org/apache/raft/statemachine/RaftSnapshotBaseTest.java index 4e7dce9..41ae9af 100644 --- a/raft-server/src/test/java/org/apache/raft/statemachine/RaftSnapshotBaseTest.java +++ b/raft-server/src/test/java/org/apache/raft/statemachine/RaftSnapshotBaseTest.java @@ -25,8 +25,8 @@ import org.apache.raft.client.RaftClient; import org.apache.raft.conf.RaftProperties; import org.apache.raft.protocol.RaftClientReply; import org.apache.raft.protocol.SetConfigurationRequest; -import org.apache.raft.server.RaftServer; -import org.apache.raft.server.RaftServerTestUtil; +import org.apache.raft.server.impl.RaftServer; +import org.apache.raft.server.impl.RaftServerTestUtil; import org.apache.raft.server.simulation.RequestHandler; import org.apache.raft.server.storage.RaftLog; import org.apache.raft.server.storage.RaftStorageDirectory; @@ -48,7 +48,7 @@ import java.util.List; import static org.apache.raft.server.RaftServerConfigKeys.RAFT_SERVER_AUTO_SNAPSHOT_ENABLED_KEY; import static org.apache.raft.server.RaftServerConfigKeys.RAFT_SERVER_SNAPSHOT_TRIGGER_THRESHOLD_KEY; -import static org.apache.raft.server.RaftServerConstants.DEFAULT_SEQNUM; +import static org.apache.raft.server.impl.RaftServerConstants.DEFAULT_SEQNUM; public abstract class RaftSnapshotBaseTest { static { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/statemachine/SimpleStateMachine4Testing.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/statemachine/SimpleStateMachine4Testing.java b/raft-server/src/test/java/org/apache/raft/statemachine/SimpleStateMachine4Testing.java index d745522..227ea58 100644 --- a/raft-server/src/test/java/org/apache/raft/statemachine/SimpleStateMachine4Testing.java +++ b/raft-server/src/test/java/org/apache/raft/statemachine/SimpleStateMachine4Testing.java @@ -25,7 +25,7 @@ import org.apache.raft.io.MD5Hash; import org.apache.raft.protocol.Message; import org.apache.raft.protocol.RaftClientReply; import org.apache.raft.protocol.RaftClientRequest; -import org.apache.raft.server.RaftServerConstants; +import org.apache.raft.server.impl.RaftServerConstants; import org.apache.raft.server.protocol.TermIndex; import org.apache.raft.server.storage.LogInputStream; import org.apache.raft.server.storage.LogOutputStream; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/c36810ed/raft-server/src/test/java/org/apache/raft/statemachine/TestStateMachine.java ---------------------------------------------------------------------- diff --git a/raft-server/src/test/java/org/apache/raft/statemachine/TestStateMachine.java b/raft-server/src/test/java/org/apache/raft/statemachine/TestStateMachine.java index ad606bf..c9dd99c 100644 --- a/raft-server/src/test/java/org/apache/raft/statemachine/TestStateMachine.java +++ b/raft-server/src/test/java/org/apache/raft/statemachine/TestStateMachine.java @@ -24,8 +24,8 @@ import org.apache.raft.client.RaftClient; import org.apache.raft.conf.RaftProperties; import org.apache.raft.protocol.Message; import org.apache.raft.protocol.RaftClientRequest; -import org.apache.raft.server.RaftServer; import org.apache.raft.server.RaftServerConfigKeys; +import org.apache.raft.server.impl.RaftServer; import org.apache.raft.server.simulation.MiniRaftClusterWithSimulatedRpc; import org.apache.raft.shaded.proto.RaftProtos.SMLogEntryProto; import org.apache.raft.util.RaftUtils;
