def test_peer_peer_relationships(self): graph = _make_graph_peer_peer_relationships() g1 = graph.clone() announce = Announcement.make_anycast_announcement(graph, [2]) graph.infer_paths(announce) self.assertListEqual(graph.g.nodes[9][NODE_BEST_PATHS], [(1, 2)]) self.assertEqual(graph.g.nodes[9][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertListEqual(graph.g.nodes[6][NODE_BEST_PATHS], [(5, 9, 1, 2)]) self.assertEqual(graph.g.nodes[6][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(graph.g.nodes[4][NODE_BEST_PATHS], [(3, 1, 2)]) self.assertEqual(graph.g.nodes[4][NODE_PATH_PREF], PathPref.PROVIDER) self.assertEqual(graph.g.nodes[7][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(graph.g.nodes[8][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(graph.g.nodes[10][NODE_PATH_PREF], PathPref.UNKNOWN) announce = Announcement.make_anycast_announcement(g1, [4]) g1.infer_paths(announce) self.assertListEqual(g1.g.nodes[10][NODE_BEST_PATHS], [(3, 4)]) self.assertEqual(g1.g.nodes[10][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertListEqual(g1.g.nodes[2][NODE_BEST_PATHS], [(1, 3, 4)]) self.assertEqual(g1.g.nodes[2][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[6][NODE_BEST_PATHS], [(5, 3, 4)]) self.assertEqual(g1.g.nodes[6][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[7][NODE_BEST_PATHS], [(10, 3, 4)]) self.assertEqual(g1.g.nodes[7][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[8][NODE_BEST_PATHS], [(7, 10, 3, 4)]) self.assertEqual(g1.g.nodes[8][NODE_PATH_PREF], PathPref.PROVIDER) self.assertEqual(g1.g.nodes[9][NODE_PATH_PREF], PathPref.UNKNOWN)
def test_implicit_withdrawal_multihop(self): graph = _make_graph_implicit_withdrawal_multihop() g1 = graph.clone() announce = Announcement.make_anycast_announcement(graph, [10]) graph.infer_paths(announce) self.assertListEqual(graph.g.nodes[11][NODE_BEST_PATHS], [(2, 10)]) self.assertEqual(graph.g.nodes[11][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertListEqual(graph.g.nodes[4][NODE_BEST_PATHS], [(3, 11, 2, 10)]) self.assertEqual(graph.g.nodes[4][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(graph.g.nodes[12][NODE_BEST_PATHS], [(2, 10)]) self.assertEqual(graph.g.nodes[12][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(graph.g.nodes[1][NODE_BEST_PATHS], [(10, )]) self.assertEqual(graph.g.nodes[1][NODE_PATH_PREF], PathPref.CUSTOMER) announce = Announcement.make_anycast_announcement(g1, [2]) g1.infer_paths(announce) self.assertListEqual(g1.g.nodes[11][NODE_BEST_PATHS], [(2, )]) self.assertEqual(g1.g.nodes[11][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertListEqual(g1.g.nodes[4][NODE_BEST_PATHS], [(3, 11, 2)]) self.assertEqual(g1.g.nodes[4][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[12][NODE_BEST_PATHS], [(2, )]) self.assertEqual(g1.g.nodes[12][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[1][NODE_BEST_PATHS], [(11, 2)]) self.assertEqual(g1.g.nodes[1][NODE_PATH_PREF], PathPref.PEER)
def test_implicit_withdraw(self): graph = _make_graph_implicit_withdrawal() g1 = graph.clone() announce = Announcement.make_anycast_announcement(graph, [10]) graph.infer_paths(announce) self.assertListEqual(graph.g.nodes[8][NODE_BEST_PATHS], [(6, 4, 1, 10)]) self.assertEqual(graph.g.nodes[8][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(graph.g.nodes[3][NODE_BEST_PATHS], [(2, 5, 7, 9, 10)]) self.assertEqual(graph.g.nodes[3][NODE_PATH_PREF], PathPref.PEER) self.assertListEqual(graph.g.nodes[1][NODE_BEST_PATHS], [(10, )]) self.assertEqual(graph.g.nodes[1][NODE_PATH_PREF], PathPref.CUSTOMER) announce = Announcement.make_anycast_announcement(g1, [4]) g1.infer_paths(announce) self.assertListEqual(g1.g.nodes[8][NODE_BEST_PATHS], [(6, 4)]) self.assertEqual(g1.g.nodes[8][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[3][NODE_BEST_PATHS], [(1, 4)]) self.assertEqual(g1.g.nodes[3][NODE_PATH_PREF], PathPref.PROVIDER) self.assertListEqual(g1.g.nodes[10][NODE_BEST_PATHS], [(1, 4)]) self.assertEqual(g1.g.nodes[10][NODE_PATH_PREF], PathPref.PROVIDER) self.assertEqual(g1.g.nodes[2][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(g1.g.nodes[5][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(g1.g.nodes[7][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(g1.g.nodes[9][NODE_PATH_PREF], PathPref.UNKNOWN)
def test_random_sources_on_caida_graph(self): SETS = 10 ITERATIONS = 3 for setnum in range(SETS): sources = random.sample(self.graph.g.nodes, 3) announce = Announcement.make_anycast_announcement( self.graph, sources) self.assertCountEqual(announce.source2neighbor2path.keys(), sources) g1 = self.graph.clone() g1.infer_paths(announce) for iternum in range(ITERATIONS): print( f"source set {setnum}/{SETS}, iteration {iternum}/{ITERATIONS}" ) g2 = self.graph.clone() g2.infer_paths(announce) for nodenum in g1.g.nodes: n1_paths = g1.g.nodes[nodenum][NODE_BEST_PATHS] n2_paths = g2.g.nodes[nodenum][NODE_BEST_PATHS] self.assertCountEqual(n1_paths, n2_paths) self.assertEqual( g1.g.nodes[nodenum][NODE_PATH_PREF], g2.g.nodes[nodenum][NODE_PATH_PREF], )
def test_peer_lock(self): graph = _make_graph_peer_lock() announce = Announcement.make_anycast_announcement(graph, [1, 7]) graph.infer_paths(announce) self.assertCountEqual(graph.g.nodes[2][NODE_BEST_PATHS], [(1, )]) self.assertEqual(graph.g.nodes[2][NODE_PATH_PREF], PathPref.PEER) self.assertCountEqual(graph.g.nodes[4][NODE_BEST_PATHS], [(1, )]) self.assertEqual(graph.g.nodes[4][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertCountEqual(graph.g.nodes[3][NODE_BEST_PATHS], [(7, )]) self.assertEqual(graph.g.nodes[3][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertCountEqual(graph.g.nodes[5][NODE_BEST_PATHS], [(7, ), (1, )]) self.assertEqual(graph.g.nodes[5][NODE_PATH_PREF], PathPref.CUSTOMER) self.assertCountEqual(graph.g.nodes[6][NODE_BEST_PATHS], [(2, 1), (4, 1), (3, 7), (5, 7), (5, 1)]) self.assertEqual(graph.g.nodes[6][NODE_PATH_PREF], PathPref.PROVIDER) self.assertCountEqual(graph.g.nodes[8][NODE_BEST_PATHS], [(4, 1), (3, 7), (5, 7), (5, 1)]) self.assertEqual(graph.g.nodes[8][NODE_PATH_PREF], PathPref.PEER) self.assertCountEqual(graph.g.nodes[9][NODE_BEST_PATHS], [(4, 1), (3, 7), (5, 7), (5, 1)]) self.assertEqual(graph.g.nodes[9][NODE_PATH_PREF], PathPref.CUSTOMER)
def test_diamond_exhaustive(self): def make_three_way_diamond(relationship_combination): graph = ASGraph() graph.add_peering(1, 2, relationship_combination[0]) graph.add_peering(1, 3, relationship_combination[1]) graph.add_peering(1, 4, relationship_combination[2]) graph.add_peering(2, 5, relationship_combination[3]) graph.add_peering(3, 5, relationship_combination[4]) graph.add_peering(4, 5, relationship_combination[5]) return graph for relationship_combination in itertools.product(Relationship, repeat=6): graph = make_three_way_diamond(relationship_combination) announce = Announcement.make_anycast_announcement(graph, [1]) graph.infer_paths(announce) as5_paths = list() best_pref = PathPref.UNKNOWN for transit in [2, 3, 4]: as5_pref = PathPref.from_relationship(graph, transit, 5) if as5_pref < best_pref: continue transit_pref = PathPref.from_relationship(graph, 1, transit) if transit_pref != PathPref.CUSTOMER and as5_pref != PathPref.PROVIDER: # Route will not propagate to AS5 continue if as5_pref > best_pref: as5_paths = [(transit, 1)] else: as5_paths.append((transit, 1)) best_pref = max(best_pref, as5_pref) self.assertCountEqual(graph.g.nodes[5][NODE_BEST_PATHS], as5_paths) self.assertEqual(graph.g.nodes[5][NODE_PATH_PREF], best_pref)
def test_multiple_customer_sources_prepend(self): graph = _make_graph_multiple_choices() announce = Announcement.make_anycast_announcement(graph, [8, 10]) announce.source2neighbor2path[8][5] = (8, ) graph.infer_paths(announce) as11_paths = [(8, ), (10, )] self.assertCountEqual(graph.g.nodes[11][NODE_BEST_PATHS], as11_paths) self.assertEqual(graph.g.nodes[11][NODE_PATH_PREF], PathPref.PROVIDER) as13_paths = [(12, 8), (12, 10)] self.assertCountEqual(graph.g.nodes[13][NODE_BEST_PATHS], as13_paths) self.assertEqual(graph.g.nodes[13][NODE_PATH_PREF], PathPref.PROVIDER) as9_paths = [(5, 10)] self.assertCountEqual(graph.g.nodes[9][NODE_BEST_PATHS], as9_paths) self.assertEqual(graph.g.nodes[9][NODE_PATH_PREF], PathPref.PROVIDER) as1_paths = [(2, 5, 10), (3, 5, 10), (4, 5, 10)] self.assertCountEqual(graph.g.nodes[1][NODE_BEST_PATHS], as1_paths) self.assertEqual(graph.g.nodes[1][NODE_PATH_PREF], PathPref.CUSTOMER) as7_paths = [(6, 2, 5, 10), (6, 3, 5, 10), (6, 4, 5, 10)] self.assertCountEqual(graph.g.nodes[7][NODE_BEST_PATHS], as7_paths) self.assertEqual(graph.g.nodes[7][NODE_PATH_PREF], PathPref.PROVIDER)
def test_multiple_provider_sources(self): graph = _make_graph_multiple_choices() announce = Announcement.make_anycast_announcement(graph, [2, 4]) graph.infer_paths(announce) as1_paths = [(2, ), (4, )] self.assertCountEqual(graph.g.nodes[1][NODE_BEST_PATHS], as1_paths) self.assertEqual(graph.g.nodes[1][NODE_PATH_PREF], PathPref.CUSTOMER) as3_paths = [(1, 4), (1, 2)] self.assertCountEqual(graph.g.nodes[3][NODE_BEST_PATHS], as3_paths) self.assertEqual(graph.g.nodes[3][NODE_PATH_PREF], PathPref.PROVIDER) as7_paths = [(6, 4), (6, 2)] self.assertCountEqual(graph.g.nodes[7][NODE_BEST_PATHS], as7_paths) self.assertEqual(graph.g.nodes[7][NODE_PATH_PREF], PathPref.PROVIDER) as11_paths = [ (8, 5, 4), (8, 5, 2), (9, 5, 4), (9, 5, 2), (10, 5, 4), (10, 5, 2), ] self.assertCountEqual(graph.g.nodes[11][NODE_BEST_PATHS], as11_paths) self.assertEqual(graph.g.nodes[11][NODE_PATH_PREF], PathPref.PROVIDER) self.assertEqual(graph.g.nodes[12][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(graph.g.nodes[13][NODE_PATH_PREF], PathPref.UNKNOWN)
def test_multiple_choices_from_provider(self): graph = _make_graph_multiple_choices() announce = Announcement.make_anycast_announcement(graph, [1]) graph.infer_paths(announce) self.assertEqual(graph.g.nodes[6][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(graph.g.nodes[7][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(graph.g.nodes[12][NODE_PATH_PREF], PathPref.UNKNOWN) self.assertEqual(graph.g.nodes[13][NODE_PATH_PREF], PathPref.UNKNOWN) as5_paths = [(2, 1), (3, 1), (4, 1)] self.assertCountEqual(graph.g.nodes[5][NODE_BEST_PATHS], as5_paths) self.assertEqual(graph.g.nodes[5][NODE_PATH_PREF], PathPref.PROVIDER) as8_paths = [(5, 2, 1), (5, 3, 1), (5, 4, 1)] self.assertCountEqual(graph.g.nodes[8][NODE_BEST_PATHS], as8_paths) self.assertEqual(graph.g.nodes[8][NODE_PATH_PREF], PathPref.PROVIDER) as11_paths = [ (8, 5, 2, 1), (8, 5, 3, 1), (8, 5, 4, 1), (9, 5, 2, 1), (9, 5, 3, 1), (9, 5, 4, 1), (10, 5, 2, 1), (10, 5, 3, 1), (10, 5, 4, 1), ] self.assertCountEqual(graph.g.nodes[11][NODE_BEST_PATHS], as11_paths)
def test_preferred(self): graph = _make_graph_preferred() announce = Announcement.make_anycast_announcement(graph, [4]) graph.infer_paths(announce) self.assertListEqual(graph.g.nodes[3][NODE_BEST_PATHS], [(2, 4)]) self.assertEqual(graph.g.nodes[3][NODE_PATH_PREF], PathPref.PEER) self.assertListEqual(graph.g.nodes[5][NODE_BEST_PATHS], [(1, 4)]) self.assertEqual(graph.g.nodes[5][NODE_PATH_PREF], PathPref.PEER) self.assertListEqual(graph.g.nodes[6][NODE_BEST_PATHS], [(4, )]) self.assertEqual(graph.g.nodes[6][NODE_PATH_PREF], PathPref.PROVIDER)
def test_sources(sources): announce = Announcement.make_anycast_announcement(graph, sources) self.assertEqual(set(sources), set(announce.source2neighbor2path.keys())) for source in sources: neighbor2path = announce.source2neighbor2path[source] self.assertEqual(set(graph.g[source]), set(neighbor2path.keys())) for aspath in neighbor2path.values(): self.assertEqual(aspath, ())
def test_multiple_choices_from_customer(self): graph = _make_graph_multiple_choices() announce = Announcement.make_anycast_announcement(graph, [11]) graph.infer_paths(announce) as13_paths = [(12, 10, 11), (12, 9, 11), (12, 8, 11)] self.assertCountEqual(graph.g.nodes[13][NODE_BEST_PATHS], as13_paths) self.assertEqual(graph.g.nodes[13][NODE_PATH_PREF], PathPref.PROVIDER) as7_paths = [ (6, 2, 5, 10, 11), (6, 2, 5, 9, 11), (6, 2, 5, 8, 11), (6, 3, 5, 10, 11), (6, 3, 5, 9, 11), (6, 3, 5, 8, 11), (6, 4, 5, 10, 11), (6, 4, 5, 9, 11), (6, 4, 5, 8, 11), ] self.assertCountEqual(graph.g.nodes[7][NODE_BEST_PATHS], as7_paths) self.assertEqual(graph.g.nodes[7][NODE_PATH_PREF], PathPref.PROVIDER) as1_paths = [ (2, 5, 10, 11), (2, 5, 9, 11), (2, 5, 8, 11), (3, 5, 10, 11), (3, 5, 9, 11), (3, 5, 8, 11), (4, 5, 10, 11), (4, 5, 9, 11), (4, 5, 8, 11), ] self.assertCountEqual(graph.g.nodes[1][NODE_BEST_PATHS], as1_paths) self.assertEqual(graph.g.nodes[1][NODE_PATH_PREF], PathPref.CUSTOMER)
def random_inference(graph): sources = random.sample(graph.g.nodes, 2) announce = Announcement.make_anycast_announcement(graph, sources) g1 = graph.clone() g1.infer_paths(announce)