@Test public void testRemoveHostId() throws InterruptedException { ReplicationSink rSink = new ReplicationSink(); SinkManager.add(rSink); // start removal in background and send replication confirmations final AtomicBoolean success = new AtomicBoolean(false); Thread remover = new Thread() { public void run() { try { ss.removeNode(removalId.toString()); } catch (Exception e) { System.err.println(e); e.printStackTrace(); return; } success.set(true); } }; remover.start(); Thread.sleep(1000); // make sure removal is waiting for confirmation assertTrue(tmd.isLeaving(removalhost)); assertEquals(1, tmd.getLeavingEndpoints().size()); for (InetAddress host : hosts) { MessageOut msg = new MessageOut( host, MessagingService.Verb.REPLICATION_FINISHED, null, null, Collections.<String, byte[]>emptyMap()); MessagingService.instance().sendRR(msg, FBUtilities.getBroadcastAddress()); } remover.join(); assertTrue(success.get()); assertTrue(tmd.getLeavingEndpoints().isEmpty()); }
@Test public void testStateJumpToNormal() throws UnknownHostException { StorageService ss = StorageService.instance; TokenMetadata tmd = ss.getTokenMetadata(); tmd.clearUnsafe(); IPartitioner partitioner = RandomPartitioner.instance; VersionedValue.VersionedValueFactory valueFactory = new VersionedValue.VersionedValueFactory(partitioner); ArrayList<Token> endpointTokens = new ArrayList<Token>(); ArrayList<Token> keyTokens = new ArrayList<Token>(); List<InetAddress> hosts = new ArrayList<InetAddress>(); List<UUID> hostIds = new ArrayList<UUID>(); // create a ring or 5 nodes Util.createInitialRing(ss, partitioner, endpointTokens, keyTokens, hosts, hostIds, 6); // node 2 leaves ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.leaving(Collections.singleton(endpointTokens.get(2)))); assertTrue(tmd.isLeaving(hosts.get(2))); assertEquals(endpointTokens.get(2), tmd.getToken(hosts.get(2))); // back to normal Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(2)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.normal(Collections.singleton(keyTokens.get(2)))); assertTrue(tmd.getLeavingEndpoints().isEmpty()); assertEquals(keyTokens.get(2), tmd.getToken(hosts.get(2))); // node 3 goes through leave and left and then jumps to normal at its new token ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.leaving(Collections.singleton(keyTokens.get(2)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.left(Collections.singleton(keyTokens.get(2)), Gossiper.computeExpireTime())); Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(4)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.normal(Collections.singleton(keyTokens.get(4)))); assertTrue(tmd.getBootstrapTokens().isEmpty()); assertTrue(tmd.getLeavingEndpoints().isEmpty()); assertEquals(keyTokens.get(4), tmd.getToken(hosts.get(2))); }