@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))); }
@Test public void testStateJumpToLeaving() 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 with _different_ token Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(0)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.leaving(Collections.singleton(keyTokens.get(0)))); assertEquals(keyTokens.get(0), tmd.getToken(hosts.get(2))); assertTrue(tmd.isLeaving(hosts.get(2))); assertNull(tmd.getEndpoint(endpointTokens.get(2))); // go to boostrap Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(1)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.bootstrapping(Collections.<Token>singleton(keyTokens.get(1)))); assertFalse(tmd.isLeaving(hosts.get(2))); assertEquals(1, tmd.getBootstrapTokens().size()); assertEquals(hosts.get(2), tmd.getBootstrapTokens().get(keyTokens.get(1))); // jump to leaving again ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.leaving(Collections.singleton(keyTokens.get(1)))); assertEquals(hosts.get(2), tmd.getEndpoint(keyTokens.get(1))); assertTrue(tmd.isLeaving(hosts.get(2))); assertTrue(tmd.getBootstrapTokens().isEmpty()); // go to state left ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.left(Collections.singleton(keyTokens.get(1)), Gossiper.computeExpireTime())); assertFalse(tmd.isMember(hosts.get(2))); assertFalse(tmd.isLeaving(hosts.get(2))); }
@Test public void testStateJumpToBootstrap() 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, 7); // node 2 leaves ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.leaving(Collections.singleton(endpointTokens.get(2)))); // don't bother to test pending ranges here, that is extensively tested by other // tests. Just check that the node is in appropriate lists. assertTrue(tmd.isMember(hosts.get(2))); assertTrue(tmd.isLeaving(hosts.get(2))); assertTrue(tmd.getBootstrapTokens().isEmpty()); // Bootstrap the node immedidiately to keyTokens.get(4) without going through STATE_LEFT Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(4)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.bootstrapping(Collections.<Token>singleton(keyTokens.get(4)))); assertFalse(tmd.isMember(hosts.get(2))); assertFalse(tmd.isLeaving(hosts.get(2))); assertEquals(hosts.get(2), tmd.getBootstrapTokens().get(keyTokens.get(4))); // Bootstrap node hosts.get(3) to keyTokens.get(1) Gossiper.instance.injectApplicationState( hosts.get(3), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(1)))); ss.onChange( hosts.get(3), ApplicationState.STATUS, valueFactory.bootstrapping(Collections.<Token>singleton(keyTokens.get(1)))); assertFalse(tmd.isMember(hosts.get(3))); assertFalse(tmd.isLeaving(hosts.get(3))); assertEquals(hosts.get(2), tmd.getBootstrapTokens().get(keyTokens.get(4))); assertEquals(hosts.get(3), tmd.getBootstrapTokens().get(keyTokens.get(1))); // Bootstrap node hosts.get(2) further to keyTokens.get(3) Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(3)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.bootstrapping(Collections.<Token>singleton(keyTokens.get(3)))); assertFalse(tmd.isMember(hosts.get(2))); assertFalse(tmd.isLeaving(hosts.get(2))); assertEquals(hosts.get(2), tmd.getBootstrapTokens().get(keyTokens.get(3))); assertNull(tmd.getBootstrapTokens().get(keyTokens.get(4))); assertEquals(hosts.get(3), tmd.getBootstrapTokens().get(keyTokens.get(1))); // Go to normal again for both nodes Gossiper.instance.injectApplicationState( hosts.get(3), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(2)))); Gossiper.instance.injectApplicationState( hosts.get(2), ApplicationState.TOKENS, valueFactory.tokens(Collections.singleton(keyTokens.get(3)))); ss.onChange( hosts.get(2), ApplicationState.STATUS, valueFactory.normal(Collections.singleton(keyTokens.get(3)))); ss.onChange( hosts.get(3), ApplicationState.STATUS, valueFactory.normal(Collections.singleton(keyTokens.get(2)))); assertTrue(tmd.isMember(hosts.get(2))); assertFalse(tmd.isLeaving(hosts.get(2))); assertEquals(keyTokens.get(3), tmd.getToken(hosts.get(2))); assertTrue(tmd.isMember(hosts.get(3))); assertFalse(tmd.isLeaving(hosts.get(3))); assertEquals(keyTokens.get(2), tmd.getToken(hosts.get(3))); assertTrue(tmd.getBootstrapTokens().isEmpty()); }