Passed
Pull Request — master (#65)
by
unknown
03:19
created

TestGraph.test_update_link_unsupported_metadata()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 11
nop 1
dl 0
loc 12
ccs 11
cts 11
cp 1
crap 1
rs 9.85
c 0
b 0
f 0
1
"""Test Graph methods."""
2 1
from unittest import TestCase
3 1
from unittest.mock import MagicMock, call, patch
4
5 1
from kytos.core.common import EntityStatus
6 1
from napps.kytos.pathfinder.graph import KytosGraph
7
8
# pylint: disable=import-error
9 1
from tests.helpers import (
10
    get_filter_links_fake,
11
    get_topology_mock,
12
    get_topology_with_metadata_mock,
13
)
14
15
# pylint: disable=arguments-differ, protected-access, no-member
16
17
18 1
class TestGraph(TestCase):
19
    """Tests for the Main class."""
20
21 1
    @patch("networkx.Graph")
22 1
    def setUp(self, mock_graph):
23
        """Execute steps before each tests."""
24 1
        self.mock_graph = mock_graph.return_value
25 1
        self.kytos_graph = KytosGraph()
26
27 1
    def test_clear(self):
28
        """Test clear."""
29 1
        self.kytos_graph.clear()
30
31 1
        self.mock_graph.clear.assert_called()
32
33 1
    def setting_update_topology(self, *args):
34
        """Set the primary elements needed to
35
        test the topology update process."""
36 1
        (mock_update_nodes, mock_update_links) = args
37 1
        topology = get_topology_mock()
38 1
        self.kytos_graph.update_topology(topology)
39
40 1
        self.mock_graph.clear.assert_called()
41
42 1
        return mock_update_nodes, mock_update_links, topology
43
44 1
    @patch("napps.kytos.pathfinder.graph.KytosGraph.update_links")
45 1
    @patch("napps.kytos.pathfinder.graph.KytosGraph.update_nodes")
46 1
    def test_update_topology_switches(self, *args):
47
        """Test update topology."""
48 1
        mock_update_nodes, _, topology = self.setting_update_topology(*args)
49 1
        mock_update_nodes.assert_called_with(topology.switches)
50
51 1
    @patch("napps.kytos.pathfinder.graph.KytosGraph.update_links")
52 1
    @patch("napps.kytos.pathfinder.graph.KytosGraph.update_nodes")
53 1
    def test_update_topology_links(self, *args):
54
        """Test update topology."""
55 1
        _, mock_update_links, topology = self.setting_update_topology(*args)
56 1
        mock_update_links.assert_called_with(topology.links)
57
58 1
    def test_update_links(self):
59
        """Test update_links."""
60 1
        topology = get_topology_mock()
61 1
        self.kytos_graph.update_links(topology.links)
62 1
        assert self.mock_graph.add_edge.call_count == len(topology.links)
63
64 1
    def test_update_links_not_up(self):
65
        """Test update_links entity not up."""
66 1
        topology = get_topology_mock()
67 1
        keys_num = 2
68 1
        for key in list(topology.links.keys())[:keys_num]:
69 1
            topology.links[key].status = EntityStatus.DOWN
70
71 1
        self.kytos_graph.update_links(topology.links)
72 1
        assert self.mock_graph.add_edge.call_count == len(topology.links) - keys_num
73
74
    # pylint: disable=consider-using-dict-items
75 1
    def test_update_nodes_not_up(self):
76
        """Test update_nodes entity not up."""
77 1
        topology = get_topology_mock()
78 1
        keys_num = 2
79 1
        for key in list(topology.switches)[:keys_num]:
80 1
            topology.switches[key].status = EntityStatus.DISABLED
81 1
        for key in topology.switches:
82 1
            topology.switches[key].interfaces = {}
83
84 1
        self.kytos_graph.update_nodes(topology.switches)
85 1
        assert self.mock_graph.add_node.call_count == len(topology.switches) - keys_num
86
87 1
    def test_update_nodes(self):
88
        """Test update nodes."""
89 1
        topology = get_topology_mock()
90 1
        self.kytos_graph.update_nodes(topology.switches)
91
92 1
        edge_count = sum(
93
            (len(sw.interfaces.values()) for sw in topology.switches.values())
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable sw does not seem to be defined.
Loading history...
94
        )
95 1
        node_count = len(topology.switches) + edge_count
96 1
        assert self.mock_graph.add_edge.call_count == edge_count
97 1
        assert self.mock_graph.add_node.call_count == node_count
98
99 1
    def test_update_nodes_2(self):
100
        """Test update nodes."""
101
102 1
        effect = MagicMock(side_effect=AttributeError)
103
104 1
        topology = get_topology_mock()
105 1
        with self.assertRaises(Exception):
106 1
            with patch.object(self.mock_graph, "add_node", effect):
107 1
                self.kytos_graph.update_nodes(topology.switches)
108
109 1
        self.assertRaises(AttributeError)
110
111 1
    def test_remove_switch_hops(self):
112
        """Test remove switch hops."""
113 1
        circuit = {
114
            "hops": [
115
                "00:00:00:00:00:00:00:01:1",
116
                "00:00:00:00:00:00:00:01",
117
                "00:00:00:00:00:00:00:01:2",
118
            ]
119
        }
120
121 1
        self.kytos_graph._remove_switch_hops(circuit)
122
123 1
        expected_circuit = {
124
            "hops": ["00:00:00:00:00:00:00:01:1", "00:00:00:00:00:00:00:01:2"]
125
        }
126 1
        self.assertEqual(circuit, expected_circuit)
127
128 1
    @patch("networkx.shortest_simple_paths", return_value=["any"])
129 1
    def test_shortest_paths(self, mock_shortest_simple_paths):
130
        """Test shortest paths."""
131 1
        source, dest = "00:00:00:00:00:00:00:01:1", "00:00:00:00:00:00:00:02:2"
132 1
        k_shortest_paths = self.kytos_graph.k_shortest_paths(source, dest)
133
134 1
        mock_shortest_simple_paths.assert_called_with(
135
            self.kytos_graph.graph, source, dest, weight=None
136
        )
137 1
        self.assertEqual(k_shortest_paths, ["any"])
138
139 1
    @patch("napps.kytos.pathfinder.graph.graph.combinations", autospec=True)
140 1
    def test_constrained_k_shortest_paths(self, mock_combinations):
141
        """Test shortest constrained paths."""
142 1
        source, dest = "00:00:00:00:00:00:00:01:1", "00:00:00:00:00:00:00:02:2"
143 1
        minimum_hits = 1
144 1
        mandatory_metrics = {"bandwidth": 100}
145 1
        flexible_metrics = {"utilization": 2}
146 1
        mock_combinations.return_value = [(("utilization", 2),)]
147 1
        constrained_k_shortest_paths = [["path1"], ["path2"]]
148
149 1
        self.kytos_graph.graph.edge_subgraph = MagicMock(return_value=None)
150 1
        self.kytos_graph.k_shortest_paths = MagicMock(
151
            return_value=constrained_k_shortest_paths
152
        )
153 1
        self.kytos_graph._filter_links = MagicMock(side_effect=get_filter_links_fake)
154 1
        k_shortest_paths = self.kytos_graph.constrained_k_shortest_paths(
155
            source,
156
            dest,
157
            minimum_hits=minimum_hits,
158
            mandatory_metrics=mandatory_metrics,
159
            flexible_metrics=flexible_metrics,
160
        )
161
162 1
        self.kytos_graph.k_shortest_paths.assert_has_calls(
163
            [
164
                call(
165
                    source,
166
                    dest,
167
                    weight=None,
168
                    k=1,
169
                    graph=None,
170
                )
171
            ]
172
        )
173 1
        self.kytos_graph._filter_links.assert_called()
174 1
        for constrained_path in k_shortest_paths:
175 1
            assert constrained_path["hops"] in constrained_k_shortest_paths
176 1
            assert constrained_path["metrics"] == {
177
                "bandwidth": 100,
178
                "utilization": 2,
179
            }
180
181 1
    def test_get_link_metadata(self):
182
        """Test metadata retrieval."""
183 1
        topology = get_topology_with_metadata_mock()
184 1
        self.kytos_graph.update_nodes(topology.switches)
185 1
        self.kytos_graph.update_links(topology.links)
186 1
        endpoint_a = "S1:1"
187 1
        endpoint_b = "S2:1"
188 1
        metadata = {"reliability": 5, "bandwidth": 100, "delay": 105}
189 1
        self.kytos_graph.get_link_metadata = MagicMock(return_value=metadata)
190
191 1
        result = self.kytos_graph.get_link_metadata(endpoint_a, endpoint_b)
192
193 1
        assert result == metadata
194
195 1
    def test_update_link_metadata(self):
196
        """Test update link metadata."""
197 1
        graph = MagicMock()
198 1
        link = MagicMock()
199 1
        endpoint_a_id = 1
200 1
        endpoint_b_id = 2
201 1
        link.endpoint_a.id = endpoint_a_id
202 1
        link.endpoint_b.id = endpoint_b_id
203 1
        link.metadata.items.return_value = [("reliability", 50)]
204 1
        self.kytos_graph.graph = graph
205 1
        self.kytos_graph.update_link_metadata(link)
206 1
        call_res = str(self.kytos_graph.graph._mock_mock_calls)
207 1
        assert "__getitem__(1)" in call_res
208 1
        assert "__getitem__(2)" in call_res
209 1
        assert "__setitem__('reliability', 50)" in call_res
210
211 1
    def test_update_link_unsupported_metadata(self):
212
        """Test update link metadata with an unsupported key."""
213 1
        graph = MagicMock()
214 1
        link = MagicMock()
215 1
        endpoint_a_id = 1
216 1
        endpoint_b_id = 2
217 1
        link.endpoint_a.id = endpoint_a_id
218 1
        link.endpoint_b.id = endpoint_b_id
219 1
        link.metadata.items.return_value = [("random_metric", 50)]
220 1
        self.kytos_graph.graph = graph
221 1
        self.kytos_graph.update_link_metadata(link)
222
        assert self.kytos_graph.graph._mock_mock_calls == []
223