@Test public void testJoinMessageReceivedForDisconnectedHost() throws Exception { final AtomicInteger counter1 = new AtomicInteger(0); final AtomicInteger counter2 = new AtomicInteger(0); connector1.subscribe(String.class.getName(), new CountingCommandHandler(counter1)); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); connector2.subscribe(String.class.getName(), new CountingCommandHandler(counter2)); connector2.connect(80); assertTrue("Connector 2 failed to connect", connector2.awaitJoined()); // wait for both connectors to have the same view waitForConnectorSync(); ConsistentHash hashBefore = connector1.getConsistentHash(); // secretly insert an illegal message channel1 .getReceiver() .receive( new Message( channel1.getAddress(), new IpAddress(12345), new JoinMessage(10, Collections.<String>emptySet()))); ConsistentHash hash2After = connector1.getConsistentHash(); assertEquals("That message should not have changed the ring", hashBefore, hash2After); }
@SuppressWarnings("unchecked") @Test(timeout = 30000) public void testConnectAndDispatchMessages_Balanced() throws Exception { assertNull(connector1.getNodeName()); assertNull(connector2.getNodeName()); final AtomicInteger counter1 = new AtomicInteger(0); final AtomicInteger counter2 = new AtomicInteger(0); connector1.subscribe(String.class.getName(), new CountingCommandHandler(counter1)); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); connector2.subscribe(String.class.getName(), new CountingCommandHandler(counter2)); connector2.connect(80); assertTrue("Connector 2 failed to connect", connector2.awaitJoined()); // wait for both connectors to have the same view waitForConnectorSync(); List<FutureCallback> callbacks = new ArrayList<>(); for (int t = 0; t < 100; t++) { FutureCallback<Object, Object> callback = new FutureCallback<>(); String message = "message" + t; if ((t & 1) == 0) { connector1.send(message, new GenericCommandMessage<>(message), callback); } else { connector2.send(message, new GenericCommandMessage<>(message), callback); } callbacks.add(callback); } for (FutureCallback callback : callbacks) { assertEquals("The Reply!", callback.get()); } assertEquals(100, counter1.get() + counter2.get()); System.out.println("Node 1 got " + counter1.get()); System.out.println("Node 2 got " + counter2.get()); verify(mockCommandBus1, atMost(40)) .dispatch(any(CommandMessage.class), isA(CommandCallback.class)); verify(mockCommandBus2, atLeast(60)) .dispatch(any(CommandMessage.class), isA(CommandCallback.class)); assertEquals(connector1.getMembers(), connector2.getMembers()); assertNotNull(connector1.getNodeName()); assertNotNull(connector2.getNodeName()); assertNotEquals(connector1.getNodeName(), connector2.getNodeName()); }
@Test public void testConnectorRecoversWhenGossipRouterReconnects() throws Exception { final AtomicInteger counter1 = new AtomicInteger(0); final AtomicInteger counter2 = new AtomicInteger(0); connector1.subscribe(String.class.getName(), new CountingCommandHandler<String>(counter1)); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); connector2.subscribe(Long.class.getName(), new CountingCommandHandler<Long>(counter2)); connector2.connect(80); assertTrue("Connector 2 failed to connect", connector2.awaitJoined()); // the nodes joined, but didn't detect eachother gossipRouter.start(); // now, they should detect eachother and start syncing their state waitForConnectorSync(60); }
@Test(timeout = 300000) public void testHashChangeNotification() throws Exception { connector1.connect(10); connector2.connect(10); // wait for both connectors to have the same view waitForConnectorSync(); // connector 1 joined ConsistentHash notify1 = hashChangeListener.notifications.poll(5, TimeUnit.SECONDS); // connector 2 joined ConsistentHash notify2 = hashChangeListener.notifications.poll(5, TimeUnit.SECONDS); // Self and other node have joined assertEquals(connector1.getConsistentHash(), notify2); channel2.close(); // Other node has left ConsistentHash notify3 = hashChangeListener.notifications.poll(5, TimeUnit.SECONDS); assertEquals(connector1.getConsistentHash(), notify3); }
@Test(timeout = 30000) public void testRingsProperlySynchronized_ChannelAlreadyConnected() throws Exception { final AtomicInteger counter1 = new AtomicInteger(0); final AtomicInteger counter2 = new AtomicInteger(0); connector1.subscribe(String.class.getName(), new CountingCommandHandler(counter1)); channel1.connect(clusterName); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); connector2.subscribe(Long.class.getName(), new CountingCommandHandler(counter2)); channel2.connect(clusterName); connector2.connect(80); assertTrue("Connector 2 failed to connect", connector2.awaitJoined()); waitForConnectorSync(); FutureCallback<Object, Object> callback1 = new FutureCallback<>(); connector1.send("1", new GenericCommandMessage<>("Hello"), callback1); FutureCallback<Object, Object> callback2 = new FutureCallback<>(); connector1.send("1", new GenericCommandMessage<>(1L), callback2); FutureCallback<Object, Object> callback3 = new FutureCallback<>(); connector2.send("1", new GenericCommandMessage<>("Hello"), callback3); FutureCallback<Object, Object> callback4 = new FutureCallback<>(); connector2.send("1", new GenericCommandMessage<>(1L), callback4); assertEquals("The Reply!", callback1.get()); assertEquals("The Reply!", callback2.get()); assertEquals("The Reply!", callback3.get()); assertEquals("The Reply!", callback4.get()); assertTrue(connector1.getConsistentHash().equals(connector2.getConsistentHash())); }
@Test public void testSetupOfReplyingCallback() throws InterruptedException { final String mockPayload = "DummyString"; final CommandMessage<String> commandMessage = new GenericCommandMessage<>(mockPayload); final DispatchMessage dispatchMessage = new DispatchMessage(commandMessage, serializer, true); final Message message = new Message(channel1.getAddress(), dispatchMessage); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); channel1.getReceiver().receive(message); // Verify that the newly introduced ReplyingCallBack class is being wired in. Actual behaviour // of ReplyingCallback is tested in its unit tests verify(mockCommandBus1).dispatch(any(), any(ReplyingCallback.class)); }
@Test(expected = ConnectionFailedException.class, timeout = 30000) public void testRingsProperlySynchronized_ChannelAlreadyConnectedToOtherCluster() throws Exception { channel1.connect("other"); connector1.connect(20); }