*/
private void testReplication(Number160 lKey, int replicationFactor, boolean nRoot, int[][] joins, int[][] leaves)
throws IOException, InterruptedException {
List<PeerDHT> peers = new ArrayList<PeerDHT>(joins.length);
IndirectReplication ind = null;
ChannelCreator cc = null;
try {
char[] letters = { 'a', 'b', 'c', 'd' };
StorageMemory storage = new StorageMemory();
for (int i = 0; i < joins.length; i++) {
if(i == 0) {
PeerDHT peer = new PeerBuilderDHT(new PeerBuilder(new Number160("0x" + letters[i])).ports(Ports.DEFAULT_PORT + i)
.start()).storage(storage).start();
ind = new IndirectReplication(peer).replicationFactor(replicationFactor).nRoot(nRoot).start();
peers.add(peer);
} else {
PeerDHT peer = new PeerBuilderDHT(new PeerBuilder(new Number160("0x" + letters[i])).ports(Ports.DEFAULT_PORT + i)
.start()).start();
new IndirectReplication(peer).replicationFactor(replicationFactor).nRoot(nRoot).start();
peers.add(peer);
}
}
PeerDHT master = peers.get(0);
// attach test listener for test verification
final AtomicInteger replicateOther = new AtomicInteger(0);
final AtomicInteger replicateI = new AtomicInteger(0);
final AtomicInteger replicateWe = new AtomicInteger(0);
ind.addResponsibilityListener(new ResponsibilityListener() {
@Override
public FutureDone<?> otherResponsible(final Number160 locationKey, final PeerAddress other) {
replicateOther.incrementAndGet();
return null;
}
@Override
public void meResponsible(final Number160 locationKey) {
replicateI.incrementAndGet();
}
@Override
public void meResponsible(Number160 locationKey, PeerAddress newPeer) {
replicateWe.incrementAndGet();
}
});
// create test data with given location key
Map<Number160, Data> dataMap = new HashMap<Number160, Data>();
dataMap.put(Number160.ZERO, new Data("string"));
PutBuilder putBuilder = new PutBuilder(master, lKey);
putBuilder.domainKey(Number160.ZERO);
putBuilder.dataMapContent(dataMap);
putBuilder.versionKey(Number160.ZERO);
FutureChannelCreator fcc = master.peer().connectionBean().reservation().create(0, 1);
fcc.awaitUninterruptibly();
cc = fcc.channelCreator();
// put test data
FutureResponse fr = master.storeRPC().put(master.peerAddress(), putBuilder, cc);
fr.awaitUninterruptibly();
Assert.assertEquals(joins[0][0], replicateI.get());
replicateI.set(0);
Assert.assertEquals(joins[0][1], replicateWe.get());
replicateWe.set(0);
Assert.assertEquals(joins[0][2], replicateOther.get());
replicateOther.set(0);
for (int i = 1; i < joins.length; i++) {
// insert a peer
master.peerBean().peerMap().peerFound(peers.get(i).peerAddress(), null, null);
// verify replication notifications
Assert.assertEquals(joins[i][0], replicateI.get());
replicateI.set(0);
Assert.assertEquals(joins[i][1], replicateWe.get());
replicateWe.set(0);
Assert.assertEquals(joins[i][2], replicateOther.get());
replicateOther.set(0);
}
for (int i = 0; i < leaves.length; i++) {
// remove a peer
master.peerBean().peerMap().peerFailed(peers.get(i+1).peerAddress(), new PeerException(AbortCause.SHUTDOWN, "shutdown"));
// verify replication notifications
Assert.assertEquals(leaves[i][0], replicateI.get());
replicateI.set(0);
Assert.assertEquals(leaves[i][1], replicateWe.get());
replicateWe.set(0);
Assert.assertEquals(leaves[i][2], replicateOther.get());
replicateOther.set(0);
}
} finally {
if (cc != null) {
cc.shutdown().awaitListenersUninterruptibly();
}
for (PeerDHT peer: peers) {
peer.shutdown().await();
}
}