}
@Test
public void testMulitipleAutomaticBootstraps() throws IOException
{
StorageService ss = StorageService.instance;
generateFakeEndpoints(5);
InetAddress[] addrs = new InetAddress[]
{
InetAddress.getByName("127.0.0.2"),
InetAddress.getByName("127.0.0.3"),
InetAddress.getByName("127.0.0.4"),
InetAddress.getByName("127.0.0.5"),
};
InetAddress[] bootstrapAddrs = new InetAddress[]
{
InetAddress.getByName("127.0.0.12"),
InetAddress.getByName("127.0.0.13"),
InetAddress.getByName("127.0.0.14"),
InetAddress.getByName("127.0.0.15"),
};
UUID[] bootstrapHostIds = new UUID[]
{
UUID.randomUUID(),
UUID.randomUUID(),
UUID.randomUUID(),
UUID.randomUUID(),
};
Map<InetAddress, Double> load = new HashMap<InetAddress, Double>();
for (int i = 0; i < addrs.length; i++)
{
Gossiper.instance.initializeNodeUnsafe(addrs[i], UUID.randomUUID(), 1);
load.put(addrs[i], (double)i+2);
// also make bootstrapping nodes present in gossip
Gossiper.instance.initializeNodeUnsafe(bootstrapAddrs[i], UUID.randomUUID(), 1);
}
// give every node a bootstrap source.
for (int i = 3; i >=0; i--)
{
InetAddress bootstrapSource = BootStrapper.getBootstrapSource(ss.getTokenMetadata(), load);
assert bootstrapSource != null;
assert bootstrapSource.equals(addrs[i]) : String.format("expected %s but got %s for %d", addrs[i], bootstrapSource, i);
assert !ss.getTokenMetadata().getBootstrapTokens().containsValue(bootstrapSource);
Range<Token> range = ss.getPrimaryRangeForEndpoint(bootstrapSource);
Token token = StorageService.getPartitioner().midpoint(range.left, range.right);
assert range.contains(token);
Gossiper.instance.injectApplicationState(bootstrapAddrs[i], ApplicationState.TOKENS, ss.valueFactory.tokens(Collections.singleton(token)));
ss.onChange(bootstrapAddrs[i],
ApplicationState.STATUS,
StorageService.instance.valueFactory.bootstrapping(Collections.<Token>singleton(token)));
}
// any further attempt to bootsrtap should fail since every node in the cluster is splitting.
try
{
BootStrapper.getBootstrapSource(ss.getTokenMetadata(), load);
throw new AssertionError("This bootstrap should have failed.");
}
catch (RuntimeException ex)
{
// success!
}
// indicate that one of the nodes is done. see if the node it was bootstrapping from is still available.
Range<Token> range = ss.getPrimaryRangeForEndpoint(addrs[2]);
Token token = StorageService.getPartitioner().midpoint(range.left, range.right);
ss.onChange(bootstrapAddrs[2],
ApplicationState.STATUS,
StorageService.instance.valueFactory.normal(Collections.singleton(token)));
load.put(bootstrapAddrs[2], 0d);
InetAddress addr = BootStrapper.getBootstrapSource(ss.getTokenMetadata(), load);
assert addr != null && addr.equals(addrs[2]);
}