diff env/lib/python3.9/site-packages/networkx/generators/tests/test_internet_as_graphs.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/networkx/generators/tests/test_internet_as_graphs.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,189 @@
+from networkx import is_connected, neighbors
+from networkx.generators.internet_as_graphs import random_internet_as_graph
+from networkx.testing import almost_equal
+
+
+class TestInternetASTopology:
+    @classmethod
+    def setup_class(cls):
+        cls.n = 1000
+        cls.seed = 42
+        cls.G = random_internet_as_graph(cls.n, cls.seed)
+        cls.T = []
+        cls.M = []
+        cls.C = []
+        cls.CP = []
+        cls.customers = {}
+        cls.providers = {}
+
+        for i in cls.G.nodes():
+            if cls.G.nodes[i]["type"] == "T":
+                cls.T.append(i)
+            elif cls.G.nodes[i]["type"] == "M":
+                cls.M.append(i)
+            elif cls.G.nodes[i]["type"] == "C":
+                cls.C.append(i)
+            elif cls.G.nodes[i]["type"] == "CP":
+                cls.CP.append(i)
+            else:
+                raise ValueError(
+                    "Inconsistent data in the graph\
+                        node attributes"
+                )
+            cls.set_customers(i)
+            cls.set_providers(i)
+
+    @classmethod
+    def set_customers(cls, i):
+        if i not in cls.customers:
+            cls.customers[i] = set()
+            for j in neighbors(cls.G, i):
+                e = cls.G.edges[(i, j)]
+                if e["type"] == "transit":
+                    customer = int(e["customer"])
+                    if j == customer:
+                        cls.set_customers(j)
+                        cls.customers[i] = cls.customers[i].union(cls.customers[j])
+                        cls.customers[i].add(j)
+                    elif i != customer:
+                        raise ValueError(
+                            "Inconsistent data in the graph\
+                                edge attributes"
+                        )
+
+    @classmethod
+    def set_providers(cls, i):
+        if i not in cls.providers:
+            cls.providers[i] = set()
+            for j in neighbors(cls.G, i):
+                e = cls.G.edges[(i, j)]
+                if e["type"] == "transit":
+                    customer = int(e["customer"])
+                    if i == customer:
+                        cls.set_providers(j)
+                        cls.providers[i] = cls.providers[i].union(cls.providers[j])
+                        cls.providers[i].add(j)
+                    elif j != customer:
+                        raise ValueError(
+                            "Inconsistent data in the graph\
+                                edge attributes"
+                        )
+
+    def test_wrong_input(self):
+        G = random_internet_as_graph(0)
+        assert len(G.nodes()) == 0
+
+        G = random_internet_as_graph(-1)
+        assert len(G.nodes()) == 0
+
+        G = random_internet_as_graph(1)
+        assert len(G.nodes()) == 1
+
+    def test_node_numbers(self):
+        assert len(self.G.nodes()) == self.n
+        assert len(self.T) < 7
+        assert len(self.M) == int(round(self.n * 0.15))
+        assert len(self.CP) == int(round(self.n * 0.05))
+        numb = self.n - len(self.T) - len(self.M) - len(self.CP)
+        assert len(self.C) == numb
+
+    def test_connectivity(self):
+        assert is_connected(self.G)
+
+    def test_relationships(self):
+        # T nodes are not customers of anyone
+        for i in self.T:
+            assert len(self.providers[i]) == 0
+
+        # C nodes are not providers of anyone
+        for i in self.C:
+            assert len(self.customers[i]) == 0
+
+        # CP nodes are not providers of anyone
+        for i in self.CP:
+            assert len(self.customers[i]) == 0
+
+        # test whether there is a customer-provider loop
+        for i in self.G.nodes():
+            assert len(self.customers[i].intersection(self.providers[i])) == 0
+
+        # test whether there is a peering with a customer or provider
+        for i, j in self.G.edges():
+            if self.G.edges[(i, j)]["type"] == "peer":
+                assert j not in self.customers[i]
+                assert i not in self.customers[j]
+                assert j not in self.providers[i]
+                assert i not in self.providers[j]
+
+    def test_degree_values(self):
+        d_m = 0  # multihoming degree for M nodes
+        d_cp = 0  # multihoming degree for CP nodes
+        d_c = 0  # multihoming degree for C nodes
+        p_m_m = 0  # avg number of peering edges between M and M
+        p_cp_m = 0  # avg number of peering edges between CP and M
+        p_cp_cp = 0  # avg number of peering edges between CP and CP
+        t_m = 0  # probability M's provider is T
+        t_cp = 0  # probability CP's provider is T
+        t_c = 0  # probability C's provider is T
+
+        for i, j in self.G.edges():
+            e = self.G.edges[(i, j)]
+            if e["type"] == "transit":
+                cust = int(e["customer"])
+                if i == cust:
+                    prov = j
+                elif j == cust:
+                    prov = i
+                else:
+                    raise ValueError(
+                        "Inconsistent data in the graph edge\
+                            attributes"
+                    )
+                if cust in self.M:
+                    d_m += 1
+                    if self.G.nodes[prov]["type"] == "T":
+                        t_m += 1
+                elif cust in self.C:
+                    d_c += 1
+                    if self.G.nodes[prov]["type"] == "T":
+                        t_c += 1
+                elif cust in self.CP:
+                    d_cp += 1
+                    if self.G.nodes[prov]["type"] == "T":
+                        t_cp += 1
+                else:
+                    raise ValueError(
+                        "Inconsistent data in the graph edge\
+                            attributes"
+                    )
+            elif e["type"] == "peer":
+                if self.G.nodes[i]["type"] == "M" and self.G.nodes[j]["type"] == "M":
+                    p_m_m += 1
+                if self.G.nodes[i]["type"] == "CP" and self.G.nodes[j]["type"] == "CP":
+                    p_cp_cp += 1
+                if (
+                    self.G.nodes[i]["type"] == "M"
+                    and self.G.nodes[j]["type"] == "CP"
+                    or self.G.nodes[i]["type"] == "CP"
+                    and self.G.nodes[j]["type"] == "M"
+                ):
+                    p_cp_m += 1
+            else:
+                raise ValueError(
+                    "Unexpected data in the graph edge\
+                        attributes"
+                )
+
+        assert almost_equal(d_m / len(self.M), 2 + (2.5 * self.n) / 10000, places=0)
+        assert almost_equal(d_cp / len(self.CP), 2 + (1.5 * self.n) / 10000, places=0)
+        assert almost_equal(d_c / len(self.C), 1 + (5 * self.n) / 100000, places=0)
+
+        assert almost_equal(p_m_m / len(self.M), 1 + (2 * self.n) / 10000, places=0)
+        assert almost_equal(p_cp_m / len(self.CP), 0.2 + (2 * self.n) / 10000, places=0)
+        assert almost_equal(
+            p_cp_cp / len(self.CP), 0.05 + (2 * self.n) / 100000, places=0
+        )
+
+        assert almost_equal(t_m / d_m, 0.375, places=1)
+        assert almost_equal(t_cp / d_cp, 0.375, places=1)
+        assert almost_equal(t_c / d_c, 0.125, places=1)