/** * Tests that the output of snapshot can be used to construct a routing table and that the routing * is preserved. */ @Test public void testSnapshotReload() throws Exception { RandomRoutingTable rt1 = new BasicRandomRoutingTable(); // create a set of neighbors and add them to the table List<TrustGraphNodeId> neighbors = createNeighbors(1000); rt1.addNeighbors(neighbors); RandomRoutingTable.Snapshot snapshotIn = rt1.snapshot(); // create a routing table using the snapshot RandomRoutingTable rt2 = new BasicRandomRoutingTable(snapshotIn); RandomRoutingTable.Snapshot snapshotOut = rt2.snapshot(); /* verify each route that we created appears in the routing * according to getNextHop and a snapshot. */ for (Map.Entry<TrustGraphNodeId, TrustGraphNodeId> e : snapshotIn.getRoutes().entrySet()) { TrustGraphNodeId key = e.getKey(); TrustGraphNodeId value = e.getValue(); // getNextHop(key) == value assertTrue(rt2.getNextHop(key).equals(value)); // snapshot[key] == value assertTrue(snapshotOut.getRoutes().get(key).equals(value)); } }
/** * Tests that adding neighbors that are already contained in the routing via addNeighbor does not * affect the table size or any existing routes. */ @Test public void testReAddNeighbor() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); // create a set of neighbors and add them to the table List<TrustGraphNodeId> neighbors = createNeighbors(100); rt.addNeighbors(neighbors); // snapshot the state of the table for later comparison RandomRoutingTable.Snapshot snapshot1 = rt.snapshot(); Map<TrustGraphNodeId, TrustGraphNodeId> routes1 = snapshot1.getRoutes(); assertTrue(routes1.size() == neighbors.size()); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot1)); // re-add the neighbors in random order LinkedList<TrustGraphNodeId> shuffled = new LinkedList<TrustGraphNodeId>(neighbors); Collections.shuffle(shuffled); for (TrustGraphNodeId n : shuffled) { rt.addNeighbor(n); /* snapshot the table after adding and compare to * the previous state. It should be completely * unchanged since all neighbors were already in * the table. */ RandomRoutingTable.Snapshot snapshot2 = rt.snapshot(); assertTrue(snapshotsAreEquivalent(snapshot1, snapshot2)); } }
/** Tests that adding neighbors via the single add method fixes self mappings. */ @Test public void testAddNeighborFixesSelfMapping() { RandomRoutingTable rt = new BasicRandomRoutingTable(); RandomRoutingTable.Snapshot snapshot; Map<TrustGraphNodeId, TrustGraphNodeId> routes; // create a set of neighbors to add List<TrustGraphNodeId> neighbors = createNeighbors(4); // add the first neighbor, it should just contain // the first neighbor mapped to itself TrustGraphNodeId first = neighbors.get(0); rt.addNeighbor(first); assertTrue(rt.getNextHop(first).equals(first)); snapshot = rt.snapshot(); routes = snapshot.getRoutes(); assertTrue(routes.size() == 1); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); // add the other neighbors. This should immediately fix // the self routing. for (int i = 1; i < neighbors.size(); i++) { rt.addNeighbor(neighbors.get(i)); assertTrue(!rt.getNextHop(first).equals(first)); snapshot = rt.snapshot(); routes = snapshot.getRoutes(); assertTrue(routes.size() == 1 + i); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); } }
/** * Tests that using the bulk addNeighbors function does not disrupt more than one previous route. */ @Test public void testAddNeighborsPreservesRoutes() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); /* create a group of neighbors and add them to the * routing table. A snapshot of the routing is created * so that it can be compared to the routing table * after adding additional neighbors. */ Collection<TrustGraphNodeId> originalNeighbors = createNeighbors(500); rt.addNeighbors(originalNeighbors); RandomRoutingTable.Snapshot snapshot = rt.snapshot(); Map<TrustGraphNodeId, TrustGraphNodeId> routes = snapshot.getRoutes(); /* count tracks how many neighbors have been added * to the routing so far. */ int count = originalNeighbors.size(); /* for a few randomly chosen sizes, bulk add * neighbors and check the properties * of the routing. */ Random rng = new Random(); for (int i = 0; i < 10; i++) { int newCount = 100 + rng.nextInt(400); Collection<TrustGraphNodeId> newNeighbors = createNeighbors(newCount); rt.addNeighbors(newNeighbors); /* check that at most one route has changed by counting * the number of routes that are the same as the last * run. */ int sameCount = 0; for (Map.Entry<TrustGraphNodeId, TrustGraphNodeId> e : routes.entrySet()) { if (rt.getNextHop(e.getKey()).equals(e.getValue())) { sameCount += 1; } } assertTrue(routes.size() - sameCount <= 1); // check that all the new neighors are also routed for (TrustGraphNodeId n : newNeighbors) { assertTrue(rt.contains(n)); } /* take a new snapshot and ensure that it * has the correct size and is valid */ snapshot = rt.snapshot(); routes = snapshot.getRoutes(); count += newCount; assertTrue(routes.size() == count); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); } }
/** * Tests that different seqential calls to the AddNeighbor with the same inputs produce different * routings, ie "random" */ @Test public void testAddNeighborIsDynamic() { // create two routing tables RandomRoutingTable rt1 = new BasicRandomRoutingTable(); RandomRoutingTable rt2 = new BasicRandomRoutingTable(); // create a set of neighbors to add List<TrustGraphNodeId> neighbors = createNeighbors(1000); RandomRoutingTable.Snapshot snapshot1; RandomRoutingTable.Snapshot snapshot2; Map<TrustGraphNodeId, TrustGraphNodeId> routes1; Map<TrustGraphNodeId, TrustGraphNodeId> routes2; /* add the same thing to both tables in the same order, * and snapshot them */ for (TrustGraphNodeId n : neighbors) { rt1.addNeighbor(n); } for (TrustGraphNodeId n : neighbors) { rt2.addNeighbor(n); } snapshot1 = rt1.snapshot(); snapshot2 = rt2.snapshot(); routes1 = snapshot1.getRoutes(); routes2 = snapshot2.getRoutes(); // the snapshots should both be valid, and // contain the same neighbors, but different routes (whp) assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot1)); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot2)); for (TrustGraphNodeId n : neighbors) { assertTrue(routes1.containsKey(n)); assertTrue(routes2.containsKey(n)); } /* test for at least one differing route * (should succeed with very high probability) */ boolean mappingIsDifferent = false; for (TrustGraphNodeId n : neighbors) { // if the routing for this neighbor in // snapshot1 is different than snapshot2, the // test is a success. if (!routes1.get(n).equals(routes2.get(n))) { mappingIsDifferent = true; break; } } assertTrue(mappingIsDifferent); }
/** Tests that routes are created correctly when snapshots are loaded. */ @Test public void testSnapshotLoad() throws Exception { // create a set of neighbors and add them to the table List<TrustGraphNodeId> neighbors = createNeighbors(1000); Map<TrustGraphNodeId, TrustGraphNodeId> routesIn = new HashMap<TrustGraphNodeId, TrustGraphNodeId>(); for (int i = 0; i < neighbors.size(); i++) { // map each neigbor to the next, circularly routesIn.put(neighbors.get(i), neighbors.get((i + 1) % neighbors.size())); } // create a routing table using the constructed snapshot RandomRoutingTable.Snapshot snapshotIn = new BasicRandomRoutingTable.Snapshot(routesIn, new ArrayList(routesIn.keySet())); RandomRoutingTable rt = new BasicRandomRoutingTable(snapshotIn); Map<TrustGraphNodeId, TrustGraphNodeId> snapshotOut = rt.snapshot().getRoutes(); /* verify each route that we created appears in the routing * according to getNextHop and a snapshot. */ for (Map.Entry<TrustGraphNodeId, TrustGraphNodeId> e : routesIn.entrySet()) { TrustGraphNodeId key = e.getKey(); TrustGraphNodeId value = e.getValue(); // getNextHop(key) == value assertTrue(rt.getNextHop(key).equals(value)); // snapshot[key] == value assertTrue(snapshotOut.get(key).equals(value)); } }
/** Tests that getNextHop and snapshot agree. */ @Test public void testSnapshotVsGetNextHop() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); // add a group of neighbors to the routing table List<TrustGraphNodeId> neighbors = createNeighbors(1000); rt.addNeighbors(neighbors); // capture a snapshot of the routing RandomRoutingTable.Snapshot snapshot = rt.snapshot(); Map<TrustGraphNodeId, TrustGraphNodeId> routes = snapshot.getRoutes(); assertTrue(routes.size() == neighbors.size()); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); /* make sure that each mapping in the snapshot matches up with * the result of getNextHop and vice versa. */ for (Map.Entry<TrustGraphNodeId, TrustGraphNodeId> e : routes.entrySet()) { assertTrue(rt.getNextHop(e.getKey()).equals(e.getValue())); } for (TrustGraphNodeId n : neighbors) { assertTrue(rt.getNextHop(n).equals(routes.get(n))); } }
/** Tests that the single add neighbor method addNeighbor creates a valid set of routes. */ @Test public void testAddNeighborBasic() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); /* create a large group of neigbors and add them * individually. */ Collection<TrustGraphNodeId> neighbors = createNeighbors(1000); for (TrustGraphNodeId n : neighbors) { rt.addNeighbor(n); } // there should be a route for every neighbor added for (TrustGraphNodeId n : neighbors) { assertTrue(rt.contains(n)); } // every neighbor should be routed to someone else for (TrustGraphNodeId n : neighbors) { TrustGraphNodeId next = rt.getNextHop(n); assertTrue(next != null && !next.equals(n)); } // A snapshot of the resulting routing table should validate RandomRoutingTable.Snapshot snapshot = rt.snapshot(); Map<TrustGraphNodeId, TrustGraphNodeId> routes = snapshot.getRoutes(); assertTrue(routes.size() == neighbors.size()); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); // every neighbor should be in the snapshot for (TrustGraphNodeId n : neighbors) { assertTrue(routes.containsKey(n)); assertTrue(routes.containsValue(n)); } }
/** Tests adding and removing neighbors in random order repeatedly emptying out the table. */ @Test public void testAddRemoveEmpty() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); for (int i = 0; i < 10; i++) { // create i neighbors LinkedList<TrustGraphNodeId> neighbors = new LinkedList<TrustGraphNodeId>(createNeighbors(i)); // add them, then remove in order for (TrustGraphNodeId n : neighbors) { rt.addNeighbor(n); } for (TrustGraphNodeId n : neighbors) { rt.removeNeighbor(n); assertTrue(BasicRandomRoutingTable.isValidSnapshot(rt.snapshot())); } assertTrue(rt.isEmpty()); // add them and remove them in reverse order for (TrustGraphNodeId n : neighbors) { rt.addNeighbor(n); } Collections.reverse(neighbors); for (TrustGraphNodeId n : neighbors) { rt.removeNeighbor(n); assertTrue(BasicRandomRoutingTable.isValidSnapshot(rt.snapshot())); } assertTrue(rt.isEmpty()); // add them and remove them in random order for (TrustGraphNodeId n : neighbors) { rt.addNeighbor(n); } Collections.shuffle(neighbors); for (TrustGraphNodeId n : neighbors) { rt.removeNeighbor(n); assertTrue(BasicRandomRoutingTable.isValidSnapshot(rt.snapshot())); } assertTrue(rt.isEmpty()); } }
/** Tests that a call to addNeighbors fixes any self-mapped neighbors. */ @Test public void testAddNeighborsFixesSelfMapping() throws Exception { /* this tests runs with a few different low size lists being passed * to the addNeighbors method to make sure that degenerate cases * like a list of size 1 are handled correctly. */ for (int neighborCount = 1; neighborCount < 5; neighborCount++) { // create a new routing table RandomRoutingTable rt = new BasicRandomRoutingTable(); RandomRoutingTable.Snapshot snapshot; Map<TrustGraphNodeId, TrustGraphNodeId> routes; // create a lone neighbor and a list of other neighbors TrustGraphNodeId loner = createNeighbors(1).get(0); Collection<TrustGraphNodeId> neighbors = createNeighbors(neighborCount); // add the single neighbor and make sure it is mapped to itself rt.addNeighbor(loner); snapshot = rt.snapshot(); routes = snapshot.getRoutes(); assertTrue(routes.size() == 1); assertTrue(routes.get(loner).equals(loner)); /* add the rest of the neighbors and make sure that the loner * is no longer mapped to iself and that otherwise the * routing is valid. */ rt.addNeighbors(neighbors); snapshot = rt.snapshot(); routes = snapshot.getRoutes(); assertTrue(routes.size() == 1 + neighbors.size()); assertTrue(!routes.get(loner).equals(loner)); assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); } }
/** Tests the size() method of BasicRandomRoutingTable */ @Test public void testSize() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); // add a random number of nodes between 100 and 400 int number = 100 + new Random().nextInt(400); List<TrustGraphNodeId> neighbors = createNeighbors(number); assertTrue(number == neighbors.size()); /* check that the routing table size is the same as the * number of neighbors added */ rt.addNeighbors(neighbors); assertTrue(number == rt.size()); assertTrue(rt.size() == rt.snapshot().getRoutes().size()); }
/** * tests that calling RemoveNeighbors removes only the intended neighbors and preserves valid * routing. */ @Test public void testRemoveNeighbors() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); // create a set of neighbors to test with List<TrustGraphNodeId> neighbors = createNeighbors(120); rt.addNeighbors(neighbors); // make sure everyone is in the table to start with for (TrustGraphNodeId n : neighbors) { assertTrue(rt.contains(n)); } /* remove the 120 neighbors in random order, in increasingly large * chunks from 1 to 15 */ LinkedList<TrustGraphNodeId> shuffled = new LinkedList(neighbors); Collections.shuffle(shuffled); for (int i = 1; i <= 15; i++) { /* pop i things from the shuffled list into the list remove, * then remove them in a bulk operation. */ LinkedList<TrustGraphNodeId> remove = new LinkedList(); for (int j = 0; j < i; j++) { remove.push(shuffled.pop()); } rt.removeNeighbors(remove); // make sure they're gone. for (TrustGraphNodeId n : remove) { assertFalse(rt.contains(n)); } // make sure everything else is still there. for (TrustGraphNodeId n : shuffled) { assertTrue(rt.contains(n)); } // make sure the routing is still valid in total. assertTrue(BasicRandomRoutingTable.isValidSnapshot(rt.snapshot())); } // make sure everything was eventually removed assertTrue(rt.isEmpty()); }
/** * Tests that removeNeighbor only removes the intended neighbor from the routing and preserves a * valid routing. */ @Test public void testRemoveNeighbor() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); // create a set of neighbors to test with List<TrustGraphNodeId> neighbors = createNeighbors(100); rt.addNeighbors(neighbors); // make sure everyone is in the table to start with for (TrustGraphNodeId n : neighbors) { assertTrue(rt.contains(n)); } /* remove the neighbors in random order. Check that the * routing remains valid, the expected item has been removed * and that all other items are still present. */ LinkedList<TrustGraphNodeId> shuffled = new LinkedList(neighbors); Collections.shuffle(shuffled); for (int i = 0; i < neighbors.size(); i++) { // select a neighbor to remove and remove it TrustGraphNodeId remove = shuffled.pop(); rt.removeNeighbor(remove); // make sure it's gone assertFalse(rt.contains(remove)); // make sure everything else is still there. for (TrustGraphNodeId n : shuffled) { assertTrue(rt.contains(n)); } // make sure the routing is still valid in total. assertTrue(BasicRandomRoutingTable.isValidSnapshot(rt.snapshot())); } // make sure everything was eventually removed assertTrue(rt.isEmpty()); }
/** simple test of the validity of the snapshot method. */ @Test public void testSnapshot() throws Exception { RandomRoutingTable rt = new BasicRandomRoutingTable(); // create a set of neighbors and add them to the table List<TrustGraphNodeId> neighbors = createNeighbors(1000); rt.addNeighbors(neighbors); RandomRoutingTable.Snapshot snapshot = rt.snapshot(); Map<TrustGraphNodeId, TrustGraphNodeId> routes = snapshot.getRoutes(); // make sure it meets the table's own validity criteria assertTrue(BasicRandomRoutingTable.isValidSnapshot(snapshot)); /* make sure everything we added is in the snapshot * and only those things are present */ assertTrue(routes.size() == neighbors.size()); for (TrustGraphNodeId n : neighbors) { assertTrue(routes.containsKey(n)); assertTrue(routes.containsValue(n)); } }