SimpleMessage[] generateMsgs(int num) { SimpleMessage[] msgs = new SimpleMessage[num * 6]; for (int i = 0; i < num; i++) { for (int j = 0; j < 6; j++) { byte[] bytes = new byte[1024 * (j + 1)]; Arrays.fill(bytes, (byte) j); msgs[i * 6 + j] = new SimpleMessage(new String(bytes)); } } return msgs; }
static SimpleMessage[] generateMsgs(int num) { SimpleMessage[] msgs = new SimpleMessage[num * 6]; for (int i = 0; i < num; i++) { for (int j = 0; j < 6; j++) { byte[] bytes = new byte[1024 * (j + 1)]; Arrays.fill(bytes, (byte) (j + '0')); msgs[i * 6 + j] = new SimpleMessage(new String(bytes)); } } return msgs; }
@Override public CompletableFuture<Message> applyTransaction(TransactionContext trx) { CompletableFuture<Message> future = new CompletableFuture<Message>(); if (blockOnApply) { synchronized (objectToWait) { try { objectToWait.wait(); } catch (InterruptedException e) { throw new RuntimeException(); } } } future.complete(new RaftTestUtil.SimpleMessage("done")); return future; }
void sendRequests(List<CompletableFuture<RaftClientReply>> replies, List<CompletableFuture<WatchReplies>> watches) { for(int i = 0; i < numMessages; i++) { final String message = "m" + i; log.info("SEND_REQUEST {}: message={}", i, message); final CompletableFuture<RaftClientReply> replyFuture = writeClient.sendAsync(new RaftTestUtil.SimpleMessage(message)); replies.add(replyFuture); final CompletableFuture<WatchReplies> watchFuture = new CompletableFuture<>(); watches.add(watchFuture); replyFuture.thenAccept(reply -> { final long logIndex = reply.getLogIndex(); log.info("SEND_WATCH: message={}, logIndex={}", message, logIndex); watchFuture.complete(new WatchReplies(logIndex, watchMajorityClient.sendWatchAsync(logIndex, ReplicationLevel.MAJORITY), watchAllClient.sendWatchAsync(logIndex, ReplicationLevel.ALL), watchMajorityCommittedClient.sendWatchAsync(logIndex, ReplicationLevel.MAJORITY_COMMITTED), watchAllCommittedClient.sendWatchAsync(logIndex, ReplicationLevel.ALL_COMMITTED), log)); }); } }
void runTestNoChangeRequest(CLUSTER cluster) throws Exception { final RaftServerImpl leader = RaftTestUtil.waitForLeader(cluster); try(final RaftClient client = cluster.createClient(leader.getId())) { client.send(new SimpleMessage("m")); final RaftLog leaderLog = leader.getState().getLog(); final long committedIndex = leaderLog.getLastCommittedIndex(); final RaftConfiguration confBefore = cluster.getLeader().getRaftConf(); // no real configuration change in the request final RaftClientReply reply = client.setConfiguration(cluster.getPeers().toArray(RaftPeer.emptyArray())); Assert.assertTrue(reply.isSuccess()); final long newCommittedIndex = leaderLog.getLastCommittedIndex(); for(long i = committedIndex + 1; i <= newCommittedIndex; i++) { final LogEntryProto e = leaderLog.get(i); Assert.assertTrue(e.hasMetadataEntry()); } Assert.assertSame(confBefore, cluster.getLeader().getRaftConf()); client.close(); } }
void runTestBasicRetry(CLUSTER cluster) throws Exception { RaftTestUtil.waitForLeader(cluster); final RaftPeerId leaderId = cluster.getLeaderAndSendFirstMessage(false).getId(); long oldLastApplied = cluster.getLeader().getState().getLastAppliedIndex(); final RaftClient client = cluster.createClient(leaderId); final RaftClientRpc rpc = client.getClientRpc(); final long callId = 999; final long seqNum = 111; RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, seqNum, new SimpleMessage("message")); assertReply(rpc.sendRequest(r), client, callId); // retry with the same callId for (int i = 0; i < 5; i++) { assertReply(rpc.sendRequest(r), client, callId); } assertServer(cluster, client.getId(), callId, oldLastApplied); client.close(); }
@Test public void testLogAppenderBufferCapacity() throws Exception { RaftTestUtil.waitForLeader(cluster); final RaftPeerId leaderId = cluster.getLeader().getId(); final RaftClient client = cluster.createClient(leaderId); byte[] bytes = new byte[8192]; Arrays.fill(bytes, (byte) 1); SimpleMessage msg = new SimpleMessage(new String(bytes)); try { client.send(msg); Assert.fail("Expected StateMachineException not thrown"); } catch (StateMachineException sme) { Assert.assertTrue(sme.getMessage() .contains("exceeds the max buffer limit")); } } }
static void assertLeaderContent(MiniRaftCluster cluster) throws Exception { final RaftServerImpl leader = RaftTestUtil.waitForLeader(cluster); final RaftLog leaderLog = leader.getState().getLog(); final long lastIndex = leaderLog.getLastEntryTermIndex().getIndex(); final LogEntryProto e = leaderLog.get(lastIndex); Assert.assertTrue(e.hasMetadataEntry()); Assert.assertEquals(leaderLog.getLastCommittedIndex() - 1, e.getMetadataEntry().getCommitIndex()); final LogEntryProto[] entries = SimpleStateMachine4Testing.get(leader).getContent(); long message = 0; for (int i = 0; i < entries.length; i++) { LOG.info("{}) {} {}", i, message, entries[i]); if (entries[i].hasStateMachineLogEntry()) { final SimpleMessage m = new SimpleMessage("m" + message++); Assert.assertArrayEquals(m.getContent().toByteArray(), entries[i].getStateMachineLogEntry().getLogData().toByteArray()); } } }
@Test public void testHandleStateMachineException() throws Exception { final RaftProperties prop = getProperties(); prop.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY, StateMachineWithException.class, StateMachine.class); final MiniRaftCluster cluster = newCluster(3); cluster.start(); RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId(); try(final RaftClient client = cluster.createClient(leaderId)) { client.send(new RaftTestUtil.SimpleMessage("m")); fail("Exception expected"); } catch (StateMachineException e) { e.printStackTrace(); Assert.assertTrue(e.getCause().getMessage().contains("Fake Exception")); } cluster.shutdown(); }
static void assertLeaderContent(MiniRaftCluster cluster) throws InterruptedException { final RaftServerImpl leader = RaftTestUtil.waitForLeader(cluster); Assert.assertEquals(SNAPSHOT_TRIGGER_THRESHOLD * 2, leader.getState().getLog().getLastCommittedIndex()); final LogEntryProto[] entries = SimpleStateMachine4Testing.get(leader).getContent(); for (int i = 1; i < SNAPSHOT_TRIGGER_THRESHOLD * 2 - 1; i++) { Assert.assertEquals(i+1, entries[i].getIndex()); Assert.assertArrayEquals( new SimpleMessage("m" + i).getContent().toByteArray(), entries[i].getSmLogEntry().getData().toByteArray()); } }
static void sendMessage(String message, RaftClient client) throws IOException { final RaftClientReply reply = client.send(new SimpleMessage(message)); Assert.assertTrue(reply.isSuccess()); }
public static SimpleMessage[] create(int numMessages, String prefix) { final SimpleMessage[] messages = new SimpleMessage[numMessages]; for (int i = 0; i < messages.length; i++) { messages[i] = new SimpleMessage(prefix + i); } return messages; }
RaftClientReply assertNotLeaderException(RaftPeerId expectedSuggestedLeader, String messageId, RaftPeerId server, RaftClientRpc rpc, CLUSTER cluster) throws IOException { final SimpleMessage message = new SimpleMessage(messageId); final RaftClientReply reply = rpc.sendRequest(cluster.newRaftClientRequest(ClientId.randomId(), server, message)); Assert.assertNotNull(reply); Assert.assertFalse(reply.isSuccess()); final NotLeaderException nle = reply.getNotLeaderException(); Objects.requireNonNull(nle); Assert.assertEquals(expectedSuggestedLeader, nle.getSuggestedLeader().getId()); return reply; }
@Override public CompletableFuture<Message> applyTransaction(TransactionContext trx) { LogEntryProto entry = Objects.requireNonNull(trx.getLogEntry()); put(entry); updateLastAppliedTermIndex(entry.getTerm(), entry.getIndex()); return CompletableFuture.completedFuture( new SimpleMessage(entry.getIndex() + " OK")); }
void runTestLogAppenderBufferCapacity(CLUSTER cluster) throws Exception { final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId(); byte[] bytes = new byte[8192]; Arrays.fill(bytes, (byte) 1); SimpleMessage msg = new SimpleMessage(new String(bytes)); try (RaftClient client = cluster.createClient(leaderId)) { testFailureCase("testLogAppenderBufferCapacity", () -> client.send(msg), StateMachineException.class, RaftLogIOException.class); } } }
@Test public void testHandleStateMachineException() throws Exception { setAndStart(cluster); final RaftPeerId leaderId = cluster.getLeader().getId(); try(final RaftClient client = cluster.createClient(leaderId)) { client.send(new SimpleMessage("m")); fail("Exception expected"); } catch (StateMachineException e) { e.printStackTrace(); Assert.assertTrue(e.getCause().getMessage().contains("Fake Exception")); } }
public RaftServerImpl getLeaderAndSendFirstMessage(boolean ignoreException) throws IOException { final RaftServerImpl leader = getLeader(); try(RaftClient client = createClient(leader.getId())) { client.send(new RaftTestUtil.SimpleMessage("first msg to make leader ready")); } catch (IOException e) { if (!ignoreException) { throw e; } } return leader; }
@Override public CompletableFuture<Message> applyTransaction(TransactionContext trx) { LogEntryProto entry = Objects.requireNonNull(trx.getLogEntry()); list.add(entry); updateLastAppliedTermIndex(entry.getTerm(), entry.getIndex()); return CompletableFuture.completedFuture( new SimpleMessage(entry.getIndex() + " OK")); }
public static SimpleMessage[] create(int numMessages, String prefix) { final SimpleMessage[] messages = new SimpleMessage[numMessages]; for (int i = 0; i < messages.length; i++) { messages[i] = new SimpleMessage(prefix + i); } return messages; }
public RaftServerImpl getLeaderAndSendFirstMessage(boolean ignoreException) throws IOException { final RaftServerImpl leader = getLeader(); try(RaftClient client = createClient(leader.getId())) { client.send(new RaftTestUtil.SimpleMessage("first msg to make leader ready")); } catch (IOException e) { if (!ignoreException) { throw e; } } return leader; }