Passed
Push — master ( 98d456...fe0679 )
by Vinicius
02:00 queued 13s
created

TestMain.test_load_switch_attrs()   B

Complexity

Conditions 1

Size

Total Lines 68
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 60
nop 1
dl 0
loc 68
ccs 30
cts 30
cp 1
crap 1
rs 8.309
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""Module to test the main napp file."""
2
# pylint: disable=import-error,no-name-in-module,wrong-import-order
3
# pylint: disable=import-outside-toplevel,attribute-defined-outside-init
4 1
import pytest
5 1
import time
6 1
from datetime import timedelta
7 1
from unittest.mock import MagicMock, create_autospec, patch, call
8
9 1
from kytos.core.common import EntityStatus
10 1
from kytos.core.helpers import now
11 1
from kytos.core.events import KytosEvent
12 1
from kytos.core.interface import Interface
13 1
from kytos.core.link import Link
14 1
from kytos.core.switch import Switch
15 1
from kytos.lib.helpers import (get_interface_mock, get_link_mock,
16
                               get_controller_mock, get_switch_mock,
17
                               get_test_client)
18 1
from napps.kytos.topology.exceptions import RestoreError
19
20
21 1
@pytest.mark.parametrize("liveness_status, status",
22
                         [("up", EntityStatus.UP),
23
                          ("down", EntityStatus.DOWN)])
24 1
def test_handle_link_liveness_status(liveness_status, status) -> None:
25
    """Test handle link liveness."""
26 1
    from napps.kytos.topology.main import Main
27 1
    Main.get_topo_controller = MagicMock()
28 1
    napp = Main(get_controller_mock())
29 1
    napp.notify_topology_update = MagicMock()
30 1
    napp.notify_link_status_change = MagicMock()
31
32 1
    link = MagicMock(id="some_id", status=status)
33 1
    napp.handle_link_liveness_status(link, liveness_status)
34
35 1
    add_link_meta = napp.topo_controller.add_link_metadata
36 1
    add_link_meta.assert_called_with(link.id, {"liveness_status":
37
                                               liveness_status})
38 1
    link.extend_metadata.assert_called_with({"liveness_status":
39
                                             liveness_status})
40 1
    assert napp.notify_topology_update.call_count == 1
41 1
    assert napp.notify_link_status_change.call_count == 1
42 1
    reason = f"liveness_{liveness_status}"
43 1
    napp.notify_link_status_change.assert_called_with(link, reason=reason)
44
45
46
# pylint: disable=too-many-public-methods
47 1
class TestMain:
48
    """Test the Main class."""
49
50
    # pylint: disable=too-many-public-methods, protected-access,C0302
51
52 1
    def setup_method(self):
53
        """Execute steps before each tests."""
54 1
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
55
        # pylint: disable=import-outside-toplevel
56 1
        from napps.kytos.topology.main import Main
57 1
        Main.get_topo_controller = MagicMock()
58 1
        controller = get_controller_mock()
59 1
        self.napp = Main(controller)
60 1
        self.api_client = get_test_client(controller, self.napp)
61 1
        self.base_endpoint = 'kytos/topology/v3'
62
63 1
    def test_get_event_listeners(self):
64
        """Verify all event listeners registered."""
65 1
        expected_events = [
66
            'kytos/core.shutdown',
67
            'kytos/core.shutdown.kytos/topology',
68
            'kytos/.*.link_available_tags',
69
            '.*.topo_controller.upsert_switch',
70
            '.*.of_lldp.network_status.updated',
71
            '.*.interface.is.nni',
72
            '.*.connection.lost',
73
            '.*.switch.interfaces.created',
74
            '.*.topology.switch.interface.created',
75
            '.*.switch.interface.deleted',
76
            '.*.switch.interface.link_down',
77
            '.*.switch.interface.link_up',
78
            '.*.switch.(new|reconnected)',
79
            'kytos/.*.liveness.(up|down)',
80
            'kytos/.*.liveness.disabled',
81
            '.*.switch.port.created',
82
            'kytos/topology.notify_link_up_if_status',
83
            'topology.interruption.start',
84
            'topology.interruption.end',
85
        ]
86 1
        actual_events = self.napp.listeners()
87 1
        assert sorted(expected_events) == sorted(actual_events)
88
89 1
    def test_get_link_or_create(self):
90
        """Test _get_link_or_create."""
91 1
        dpid_a = "00:00:00:00:00:00:00:01"
92 1
        dpid_b = "00:00:00:00:00:00:00:02"
93 1
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
94 1
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
95 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
96 1
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
97 1
        mock_interface_a.id = dpid_a
98 1
        mock_interface_b.id = dpid_b
99
100 1
        link, created = self.napp._get_link_or_create(mock_interface_a,
101
                                                      mock_interface_b)
102 1
        assert created
103 1
        assert link.endpoint_a.id == dpid_a
104 1
        assert link.endpoint_b.id == dpid_b
105
106 1
        link, created = self.napp._get_link_or_create(mock_interface_a,
107
                                                      mock_interface_b)
108 1
        assert not created
109
110 1
    def test_get_link_from_interface(self):
111
        """Test _get_link_from_interface."""
112 1
        mock_switch_a = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
113 1
        mock_switch_b = get_switch_mock("00:00:00:00:00:00:00:02", 0x04)
114 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
115 1
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
116 1
        mock_interface_c = get_interface_mock('s2-eth1', 2, mock_switch_b)
117 1
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
118 1
        self.napp.links = {'0e2b5d7bc858b9f38db11b69': mock_link}
119 1
        response = self.napp._get_link_from_interface(mock_interface_a)
120 1
        assert response == mock_link
121
122 1
        response = self.napp._get_link_from_interface(mock_interface_c)
123 1
        assert not response
124
125 1
    async def test_get_topology(self):
126
        """Test get_topology."""
127 1
        dpid_a = "00:00:00:00:00:00:00:01"
128 1
        dpid_b = "00:00:00:00:00:00:00:02"
129 1
        expected = {
130
                      "topology": {
131
                        "switches": {
132
                          "00:00:00:00:00:00:00:01": {
133
                            "metadata": {
134
                              "lat": "0.0",
135
                              "lng": "-30.0"
136
                            }
137
                          },
138
                          "00:00:00:00:00:00:00:02": {
139
                            "metadata": {
140
                              "lat": "0.0",
141
                              "lng": "-30.0"
142
                            }
143
                          }
144
                        },
145
                        "links": {
146
                          "cf0f4071be4": {
147
                            "id": "cf0f4071be4"
148
                          }
149
                        }
150
                      }
151
                    }
152
153 1
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
154 1
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
155 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
156 1
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
157
158 1
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
159 1
        mock_link.id = 'cf0f4071be4'
160 1
        mock_switch_a.id = dpid_a
161 1
        mock_switch_a.as_dict.return_value = {'metadata': {'lat': '0.0',
162
                                              'lng': '-30.0'}}
163 1
        mock_switch_b.id = dpid_b
164 1
        mock_switch_b.as_dict.return_value = {'metadata': {'lat': '0.0',
165
                                              'lng': '-30.0'}}
166
167 1
        self.napp.controller.switches = {dpid_a: mock_switch_a,
168
                                         dpid_b: mock_switch_b}
169
170 1
        self.napp.links = {"cf0f4071be4": mock_link}
171 1
        mock_link.as_dict.return_value = {"id": "cf0f4071be4"}
172 1
        endpoint = f"{self.base_endpoint}/"
173 1
        response = await self.api_client.get(endpoint)
174 1
        assert response.status_code == 200
175 1
        assert response.json() == expected
176
177 1
    def test_load_topology(self):
178
        """Test load_topology."""
179 1
        link_id = \
180
            'cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260'
181 1
        dpid_a = '00:00:00:00:00:00:00:01'
182 1
        dpid_b = '00:00:00:00:00:00:00:02'
183 1
        topology = {
184
            "topology": {
185
                "links": {
186
                    link_id: {
187
                        "enabled": True,
188
                        "id": link_id,
189
                        "endpoint_a": {"id": f"{dpid_a}:2"},
190
                        "endpoint_b": {"id": f"{dpid_b}:2"},
191
                    }
192
                },
193
                "switches": {
194
                    dpid_a: {
195
                        "dpid": dpid_a,
196
                        "enabled": True,
197
                        "metadata": {},
198
                        "id": dpid_a,
199
                        "interfaces": {
200
                            f"{dpid_a}:2": {
201
                                "enabled": True,
202
                                "metadata": {},
203
                                "lldp": True,
204
                                "port_number": 2,
205
                                "name": "s1-eth2",
206
                            }
207
                        },
208
                    },
209
                    dpid_b: {
210
                        "dpid": dpid_b,
211
                        "enabled": True,
212
                        "metadata": {},
213
                        "id": dpid_b,
214
                        "interfaces": {
215
                            f"{dpid_b}:2": {
216
                                "enabled": True,
217
                                "metadata": {},
218
                                "lldp": True,
219
                                "port_number": 2,
220
                                "name": "s2-eth2",
221
                            }
222
                        },
223
                    },
224
                },
225
            }
226
        }
227 1
        switches_expected = [dpid_a, dpid_b]
228 1
        interfaces_expected = [f'{dpid_a}:2', f'{dpid_b}:2']
229 1
        links_expected = [link_id]
230 1
        self.napp.topo_controller.get_topology.return_value = topology
231 1
        self.napp.load_topology()
232 1
        assert switches_expected == list(self.napp.controller.switches.keys())
233 1
        interfaces = []
234 1
        for switch in self.napp.controller.switches.values():
235 1
            for iface in switch.interfaces.values():
236 1
                interfaces.append(iface.id)
237 1
        assert interfaces_expected == interfaces
238 1
        assert links_expected == list(self.napp.links.keys())
239
240 1
    @patch('napps.kytos.topology.main.Main._load_switch')
241 1
    @patch('napps.kytos.topology.main.Main._load_link')
242 1
    def test_load_topology_does_nothing(self, *args):
243
        """Test _load_network_status doing nothing."""
244 1
        (mock_load_link, mock_load_switch) = args
245 1
        self.napp.topo_controller.get_topology.return_value = {
246
            "topology": {"switches": {}, "links": {}}
247
        }
248 1
        self.napp.topo_controller.load_topology()
249 1
        assert mock_load_link.call_count == 0
250 1
        assert mock_load_switch.call_count == 0
251
252 1
    @patch('napps.kytos.topology.main.Main._load_switch')
253 1
    @patch('napps.kytos.topology.main.log')
254 1
    def test_load_topology_fail_switch(self, *args):
255
        """Test load_topology failure in switch."""
256 1
        (mock_log, mock_load_switch) = args
257 1
        topology = {
258
            'topology': {
259
                'links': {},
260
                'switches': {
261
                    '1': {}
262
                }
263
            }
264
        }
265 1
        mock_log.error.return_value = True
266 1
        self.napp.topo_controller.get_topology.return_value = topology
267 1
        mock_load_switch.side_effect = Exception('xpto')
268 1
        self.napp.load_topology()
269 1
        error = 'Error loading switch: xpto'
270 1
        mock_log.error.assert_called_with(error)
271
272 1
    @patch('napps.kytos.topology.main.Main._load_link')
273 1
    @patch('napps.kytos.topology.main.log')
274 1
    def test_load_topology_fail_link(self, *args):
275
        """Test load_topology failure in link."""
276 1
        (mock_log, mock_load_link) = args
277 1
        topology = {
278
            'topology': {
279
                'switches': {},
280
                'links': {
281
                    '1': {}
282
                }
283
            }
284
        }
285 1
        mock_log.error.return_value = True
286 1
        self.napp.topo_controller.get_topology.return_value = topology
287 1
        mock_load_link.side_effect = Exception('xpto')
288 1
        self.napp.load_topology()
289 1
        error = 'Error loading link 1: xpto'
290 1
        mock_log.error.assert_called_with(error)
291
292 1
    @patch('napps.kytos.topology.main.Main.load_interfaces_available_tags')
293 1
    @patch('napps.kytos.topology.main.KytosEvent')
294 1
    def test_load_switch(self, *args):
295
        """Test _load_switch."""
296 1
        (mock_event, mock_load_tags) = args
297 1
        mock_buffers_put = MagicMock()
298 1
        self.napp.controller.buffers.app.put = mock_buffers_put
299 1
        dpid_a = "00:00:00:00:00:00:00:01"
300 1
        dpid_x = "00:00:00:00:00:00:00:XX"
301 1
        iface_a = f'{dpid_a}:1'
302 1
        switch_attrs = {
303
            'dpid': dpid_a,
304
            'enabled': True,
305
            'id': dpid_a,
306
            'metadata': {},
307
            'interfaces': {
308
                iface_a: {
309
                    'enabled': True,
310
                    'active': True,
311
                    'lldp': True,
312
                    'id': iface_a,
313
                    'switch': dpid_a,
314
                    'metadata': {},
315
                    'name': 's2-eth1',
316
                    'port_number': 1
317
                }
318
            }
319
        }
320 1
        self.napp._load_switch(dpid_a, switch_attrs)
321
322 1
        assert len(self.napp.controller.switches) == 1
323 1
        assert dpid_a in self.napp.controller.switches
324 1
        assert dpid_x not in self.napp.controller.switches
325 1
        switch = self.napp.controller.switches[dpid_a]
326 1
        interface_details = self.napp.topo_controller.get_interfaces_details
327 1
        interface_details.assert_called_once_with([iface_a])
328 1
        mock_load_tags.assert_called()
329
330 1
        assert switch.id == dpid_a
331 1
        assert switch.dpid == dpid_a
332 1
        assert switch.is_enabled()
333 1
        assert not switch.is_active()
334
335 1
        assert len(switch.interfaces) == 1
336 1
        assert 1 in switch.interfaces
337 1
        assert 2 not in switch.interfaces
338 1
        mock_event.assert_called()
339 1
        mock_buffers_put.assert_called()
340
341 1
        interface = switch.interfaces[1]
342 1
        assert interface.id == iface_a
343 1
        assert interface.switch.id == dpid_a
344 1
        assert interface.port_number == 1
345 1
        assert interface.is_enabled()
346 1
        assert not interface.is_active()
347 1
        assert interface.lldp
348 1
        assert interface.uni
349 1
        assert not interface.nni
350
351 1
    def test_load_switch_attrs(self):
352
        """Test _load_switch."""
353 1
        dpid_b = "00:00:00:00:00:00:00:02"
354 1
        iface_b = f'{dpid_b}:1'
355 1
        switch_attrs = {
356
            "active": True,
357
            "connection": "127.0.0.1:43230",
358
            "data_path": "XX Human readable desc of dp",
359
            "dpid": "00:00:00:00:00:00:00:02",
360
            "enabled": False,
361
            "hardware": "Open vSwitch",
362
            "id": "00:00:00:00:00:00:00:02",
363
            "interfaces": {
364
                "00:00:00:00:00:00:00:02:1": {
365
                    "active": True,
366
                    "enabled": False,
367
                    "id": "00:00:00:00:00:00:00:02:1",
368
                    "link": "",
369
                    "lldp": False,
370
                    "mac": "de:58:c3:30:b7:b7",
371
                    "metadata": {},
372
                    "name": "s2-eth1",
373
                    "nni": False,
374
                    "port_number": 1,
375
                    "speed": 1250000000,
376
                    "switch": "00:00:00:00:00:00:00:02",
377
                    "type": "interface",
378
                    "uni": True
379
                },
380
            },
381
            "manufacturer": "Nicira, Inc.",
382
            "metadata": {},
383
            "name": "00:00:00:00:00:00:00:04",
384
            "ofp_version": "0x04",
385
            "serial": "XX serial number",
386
            "software": "2.10.7",
387
            "type": "switch"
388
        }
389
390 1
        assert len(self.napp.controller.switches) == 0
391 1
        self.napp._load_switch(dpid_b, switch_attrs)
392 1
        assert len(self.napp.controller.switches) == 1
393 1
        assert dpid_b in self.napp.controller.switches
394
395 1
        switch = self.napp.controller.switches[dpid_b]
396 1
        assert switch.id == dpid_b
397 1
        assert switch.dpid == dpid_b
398 1
        assert not switch.is_enabled()
399 1
        assert not switch.is_active()
400 1
        assert switch.description['manufacturer'] == 'Nicira, Inc.'
401 1
        assert switch.description['hardware'] == 'Open vSwitch'
402 1
        assert switch.description['software'] == '2.10.7'
403 1
        assert switch.description['serial'] == 'XX serial number'
404 1
        exp_data_path = 'XX Human readable desc of dp'
405 1
        assert switch.description['data_path'] == exp_data_path
406
407 1
        assert len(switch.interfaces) == 1
408 1
        assert 1 in switch.interfaces
409 1
        assert 2 not in switch.interfaces
410
411 1
        interface = switch.interfaces[1]
412 1
        assert interface.id == iface_b
413 1
        assert interface.switch.id == dpid_b
414 1
        assert interface.port_number == 1
415 1
        assert not interface.is_enabled()
416 1
        assert not interface.lldp
417 1
        assert interface.uni
418 1
        assert not interface.nni
419
420 1
    def test_interfaces_available_tags(self):
421
        """Test load_interfaces_available_tags."""
422 1
        dpid_a = "00:00:00:00:00:00:00:01"
423 1
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
424 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
425 1
        mock_interface_a.id = dpid_a + ':1'
426 1
        mock_switch_a.interfaces = {1: mock_interface_a}
427 1
        tags = [1, 2, 3]
428 1
        interface_details = [{"id": mock_interface_a.id,
429
                             "available_vlans": tags}]
430 1
        self.napp.load_interfaces_available_tags(mock_switch_a,
431
                                                 interface_details)
432 1
        mock_interface_a.set_available_tags.assert_called_once_with(tags)
433
434 1
    def test_handle_on_link_available_tags(self):
435
        """test_handle_on_link_available_tags."""
436 1
        dpid_a = "00:00:00:00:00:00:00:01"
437 1
        dpid_b = "00:00:00:00:00:00:00:02"
438 1
        tag = MagicMock()
439 1
        tag.value = 1
440 1
        tags = [tag]
441 1
        link_mock = MagicMock()
442 1
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
443 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
444 1
        mock_interface_a.available_tags = tags
445 1
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
446 1
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
447 1
        mock_interface_b.available_tags = tags
448 1
        link_id = '4d42dc08522'
449 1
        link_mock.id = link_id
450 1
        link_mock.endpoint_a = mock_interface_a
451 1
        link_mock.endpoint_b = mock_interface_b
452
453 1
        self.napp.links[link_id] = link_mock
454 1
        self.napp.handle_on_link_available_tags(link_mock)
455 1
        bulk_upsert = self.napp.topo_controller.bulk_upsert_interface_details
456 1
        bulk_upsert.assert_called_once_with(
457
            [
458
                (
459
                    "00:00:00:00:00:00:00:01:1",
460
                    {"_id": "00:00:00:00:00:00:00:01:1",
461
                     "available_vlans": [1]},
462
                ),
463
                (
464
                    "00:00:00:00:00:00:00:02:1",
465
                    {"_id": "00:00:00:00:00:00:00:02:1",
466
                     "available_vlans": [1]},
467
                ),
468
            ]
469
        )
470
471 1
    def test_load_link(self):
472
        """Test _load_link."""
473 1
        dpid_a = "00:00:00:00:00:00:00:01"
474 1
        dpid_b = "00:00:00:00:00:00:00:02"
475 1
        link_id = '4d42dc08522'
476 1
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
477 1
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
478 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
479 1
        mock_interface_a.id = dpid_a + ':1'
480 1
        mock_interface_a.available_tags = [1, 2, 3]
481 1
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
482 1
        mock_interface_b.id = dpid_b + ':1'
483 1
        mock_interface_b.available_tags = [1, 2, 3]
484 1
        mock_switch_a.interfaces = {1: mock_interface_a}
485 1
        mock_switch_b.interfaces = {1: mock_interface_b}
486 1
        self.napp.controller.switches[dpid_a] = mock_switch_a
487 1
        self.napp.controller.switches[dpid_b] = mock_switch_b
488 1
        link_attrs = {
489
            'enabled': True,
490
            'id': link_id,
491
            'metadata': {},
492
            'endpoint_a': {
493
                'id': mock_interface_a.id
494
            },
495
            'endpoint_b': {
496
                'id': mock_interface_b.id
497
            }
498
        }
499
500 1
        self.napp._load_link(link_attrs)
501
502 1
        assert len(self.napp.links) == 1
503 1
        link = list(self.napp.links.values())[0]
504
505 1
        assert link.endpoint_a.id == mock_interface_a.id
506 1
        assert link.endpoint_b.id == mock_interface_b.id
507 1
        assert mock_interface_a.nni
508 1
        assert mock_interface_b.nni
509 1
        assert mock_interface_a.update_link.call_count == 1
510 1
        assert mock_interface_b.update_link.call_count == 1
511
512
        # test enable/disable
513 1
        link_id = '4d42dc08522'
514 1
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
515 1
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
516 1
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
517 1
        mock_link.id = link_id
518 1
        with patch('napps.kytos.topology.main.Main._get_link_or_create',
519
                   return_value=(mock_link, True)):
520
            # enable link
521 1
            link_attrs['enabled'] = True
522 1
            self.napp.links = {link_id: mock_link}
523 1
            self.napp._load_link(link_attrs)
524 1
            assert mock_link.enable.call_count == 1
525
            # disable link
526 1
            link_attrs['enabled'] = False
527 1
            self.napp.links = {link_id: mock_link}
528 1
            self.napp._load_link(link_attrs)
529 1
            assert mock_link.disable.call_count == 1
530
531 1
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
532 1
    def test_fail_load_link(self, get_link_or_create_mock):
533
        """Test fail load_link."""
534 1
        dpid_a = '00:00:00:00:00:00:00:01'
535 1
        dpid_b = '00:00:00:00:00:00:00:02'
536 1
        link_id = '4d42dc08522'
537 1
        mock_switch_a = get_switch_mock(dpid_a)
538 1
        mock_switch_b = get_switch_mock(dpid_b)
539 1
        mock_interface_a_1 = get_interface_mock('s1-eth1', 1, mock_switch_a)
540 1
        mock_interface_b_1 = get_interface_mock('s2-eth1', 1, mock_switch_b)
541 1
        mock_link = get_link_mock(mock_interface_a_1, mock_interface_b_1)
542 1
        mock_link.id = link_id
543 1
        self.napp.links = {link_id: mock_link}
544 1
        get_link_or_create_mock.return_value = mock_link
545
546 1
        link_attrs_fail = {
547
            'enabled': True,
548
            'id': link_id,
549
            'metadata': {},
550
            'endpoint_a': {
551
                'id': f"{dpid_a}:999",
552
            },
553
            'endpoint_b': {
554
                'id': f"{dpid_b}:999",
555
            }
556
        }
557 1
        with pytest.raises(RestoreError):
558 1
            self.napp._load_link(link_attrs_fail)
559
560 1
        link_attrs_fail = {
561
            'enabled': True,
562
            'id': link_id,
563
            'endpoint_a': {
564
                'id': f"{dpid_a}:1",
565
            },
566
            'endpoint_b': {
567
                'id': f"{dpid_b}:1",
568
            }
569
        }
570 1
        with pytest.raises(RestoreError):
571 1
            self.napp._load_link(link_attrs_fail)
572
573 1 View Code Duplication
    @patch('napps.kytos.topology.main.Main.notify_switch_links_status')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
574 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
575 1
    async def test_enable_switch(self, mock_notify_topo, mock_sw_l_status):
576
        """Test enable_switch."""
577 1
        dpid = "00:00:00:00:00:00:00:01"
578 1
        mock_switch = get_switch_mock(dpid)
579 1
        self.napp.controller.switches = {dpid: mock_switch}
580
581 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/enable"
582 1
        response = await self.api_client.post(endpoint)
583 1
        assert response.status_code == 201
584 1
        assert mock_switch.enable.call_count == 1
585 1
        self.napp.topo_controller.enable_switch.assert_called_once_with(dpid)
586 1
        mock_notify_topo.assert_called()
587 1
        mock_sw_l_status.assert_called()
588
589
        # fail case
590 1
        mock_switch.enable.call_count = 0
591 1
        dpid = "00:00:00:00:00:00:00:02"
592 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/enable"
593 1
        response = await self.api_client.post(endpoint)
594 1
        assert response.status_code == 404
595 1
        assert mock_switch.enable.call_count == 0
596
597 1 View Code Duplication
    @patch('napps.kytos.topology.main.Main.notify_switch_links_status')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
598 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
599 1
    async def test_disable_switch(self, mock_notify_topo, mock_sw_l_status):
600
        """Test disable_switch."""
601 1
        dpid = "00:00:00:00:00:00:00:01"
602 1
        mock_switch = get_switch_mock(dpid)
603 1
        self.napp.controller.switches = {dpid: mock_switch}
604
605 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/disable"
606 1
        response = await self.api_client.post(endpoint)
607 1
        assert response.status_code == 201
608 1
        assert mock_switch.disable.call_count == 1
609 1
        self.napp.topo_controller.disable_switch.assert_called_once_with(dpid)
610 1
        mock_notify_topo.assert_called()
611 1
        mock_sw_l_status.assert_called()
612
613
        # fail case
614 1
        mock_switch.disable.call_count = 0
615 1
        dpid = "00:00:00:00:00:00:00:02"
616 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/disable"
617 1
        response = await self.api_client.post(endpoint)
618 1
        assert response.status_code == 404
619 1
        assert mock_switch.disable.call_count == 0
620
621 1
    async def test_get_switch_metadata(self):
622
        """Test get_switch_metadata."""
623 1
        dpid = "00:00:00:00:00:00:00:01"
624 1
        mock_switch = get_switch_mock(dpid)
625 1
        mock_switch.metadata = "A"
626 1
        self.napp.controller.switches = {dpid: mock_switch}
627
628 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata"
629 1
        response = await self.api_client.get(endpoint)
630 1
        assert response.status_code == 200
631 1
        assert response.json() == {"metadata": mock_switch.metadata}
632
633
        # fail case
634 1
        dpid = "00:00:00:00:00:00:00:02"
635 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata"
636 1
        response = await self.api_client.get(endpoint)
637 1
        assert response.status_code == 404
638
639 1
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
640 1
    async def test_add_switch_metadata(
641
        self, mock_metadata_changes, event_loop
642
    ):
643
        """Test add_switch_metadata."""
644 1
        self.napp.controller.loop = event_loop
645 1
        dpid = "00:00:00:00:00:00:00:01"
646 1
        mock_switch = get_switch_mock(dpid)
647 1
        self.napp.controller.switches = {dpid: mock_switch}
648 1
        payload = {"data": "A"}
649
650 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata"
651 1
        response = await self.api_client.post(endpoint, json=payload)
652 1
        assert response.status_code == 201
653
654 1
        mock_metadata_changes.assert_called()
655 1
        self.napp.topo_controller.add_switch_metadata.assert_called_once_with(
656
            dpid, payload
657
        )
658
659
        # fail case
660 1
        dpid = "00:00:00:00:00:00:00:02"
661 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata"
662 1
        response = await self.api_client.post(endpoint, json=payload)
663 1
        assert response.status_code == 404
664
665 1
    async def test_add_switch_metadata_wrong_format(self, event_loop):
666
        """Test add_switch_metadata_wrong_format."""
667 1
        self.napp.controller.loop = event_loop
668 1
        dpid = "00:00:00:00:00:00:00:01"
669 1
        payload = 'A'
670
671 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata"
672 1
        response = await self.api_client.post(endpoint, json=payload)
673 1
        assert response.status_code == 400
674
675 1
        payload = None
676 1
        response = await self.api_client.post(endpoint, json=payload)
677 1
        assert response.status_code == 415
678
679 1
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
680 1
    async def test_delete_switch_metadata(
681
        self, mock_metadata_changes, event_loop
682
    ):
683
        """Test delete_switch_metadata."""
684 1
        self.napp.controller.loop = event_loop
685 1
        dpid = "00:00:00:00:00:00:00:01"
686 1
        mock_switch = get_switch_mock(dpid)
687 1
        mock_switch.metadata = {"A": "A"}
688 1
        self.napp.controller.switches = {dpid: mock_switch}
689
690 1
        key = "A"
691 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata/{key}"
692 1
        response = await self.api_client.delete(endpoint)
693
694 1
        assert response.status_code == 200
695 1
        assert mock_metadata_changes.call_count == 1
696 1
        del_key_mock = self.napp.topo_controller.delete_switch_metadata_key
697 1
        del_key_mock.assert_called_with(
698
            dpid, key
699
        )
700
701
        # fail case
702 1
        key = "A"
703 1
        dpid = "00:00:00:00:00:00:00:02"
704 1
        endpoint = f"{self.base_endpoint}/switches/{dpid}/metadata/{key}"
705 1
        response = await self.api_client.delete(endpoint)
706 1
        assert mock_metadata_changes.call_count == 1
707 1
        assert response.status_code == 404
708
709 1 View Code Duplication
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
710 1
    async def test_enable_interfaces(self, mock_notify_topo):
711
        """Test enable_interfaces."""
712 1
        dpid = '00:00:00:00:00:00:00:01'
713 1
        mock_switch = get_switch_mock(dpid)
714 1
        mock_interface_1 = get_interface_mock('s1-eth1', 1, mock_switch)
715 1
        mock_interface_2 = get_interface_mock('s1-eth2', 2, mock_switch)
716 1
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
717 1
        self.napp.controller.switches = {dpid: mock_switch}
718
719 1
        interface_id = '00:00:00:00:00:00:00:01:1'
720
721 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/enable"
722 1
        response = await self.api_client.post(endpoint)
723 1
        assert response.status_code == 200
724 1
        assert mock_interface_1.enable.call_count == 1
725 1
        assert mock_interface_2.enable.call_count == 0
726 1
        self.napp.topo_controller.enable_interface.assert_called_with(
727
            interface_id
728
        )
729 1
        mock_notify_topo.assert_called()
730
731 1
        mock_interface_1.enable.call_count = 0
732 1
        mock_interface_2.enable.call_count = 0
733 1
        endpoint = f"{self.base_endpoint}/interfaces/switch/{dpid}/enable"
734 1
        response = await self.api_client.post(endpoint)
735 1
        assert response.status_code == 200
736 1
        self.napp.topo_controller.upsert_switch.assert_called_with(
737
            mock_switch.id, mock_switch.as_dict()
738
        )
739 1
        assert mock_interface_1.enable.call_count == 1
740 1
        assert mock_interface_2.enable.call_count == 1
741
742
        # test interface not found
743 1
        interface_id = '00:00:00:00:00:00:00:01:3'
744 1
        mock_interface_1.enable.call_count = 0
745 1
        mock_interface_2.enable.call_count = 0
746 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/enable"
747 1
        response = await self.api_client.post(endpoint)
748 1
        assert response.status_code == 404
749 1
        assert mock_interface_1.enable.call_count == 0
750 1
        assert mock_interface_2.enable.call_count == 0
751
752
        # test switch not found
753 1
        dpid = '00:00:00:00:00:00:00:02'
754 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/enable"
755 1
        response = await self.api_client.post(endpoint)
756 1
        assert response.status_code == 404
757 1
        assert mock_interface_1.enable.call_count == 0
758 1
        assert mock_interface_2.enable.call_count == 0
759
760 1 View Code Duplication
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
761 1
    async def test_disable_interfaces(self, mock_notify_topo):
762
        """Test disable_interfaces."""
763 1
        interface_id = '00:00:00:00:00:00:00:01:1'
764 1
        dpid = '00:00:00:00:00:00:00:01'
765 1
        mock_switch = get_switch_mock(dpid)
766 1
        mock_interface_1 = get_interface_mock('s1-eth1', 1, mock_switch)
767 1
        mock_interface_2 = get_interface_mock('s1-eth2', 2, mock_switch)
768 1
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
769 1
        self.napp.controller.switches = {dpid: mock_switch}
770
771 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/disable"
772 1
        response = await self.api_client.post(endpoint)
773 1
        assert response.status_code == 200
774
775 1
        self.napp.topo_controller.disable_interface.assert_called_with(
776
            interface_id
777
        )
778 1
        assert mock_interface_1.disable.call_count == 1
779 1
        assert mock_interface_2.disable.call_count == 0
780 1
        mock_notify_topo.assert_called()
781
782 1
        mock_interface_1.disable.call_count = 0
783 1
        mock_interface_2.disable.call_count = 0
784
785 1
        endpoint = f"{self.base_endpoint}/interfaces/switch/{dpid}/disable"
786 1
        response = await self.api_client.post(endpoint)
787 1
        assert response.status_code == 200
788
789 1
        self.napp.topo_controller.upsert_switch.assert_called_with(
790
            mock_switch.id, mock_switch.as_dict()
791
        )
792 1
        assert mock_interface_1.disable.call_count == 1
793 1
        assert mock_interface_2.disable.call_count == 1
794
795
        # test interface not found
796 1
        interface_id = '00:00:00:00:00:00:00:01:3'
797 1
        mock_interface_1.disable.call_count = 0
798 1
        mock_interface_2.disable.call_count = 0
799 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/disable"
800 1
        response = await self.api_client.post(endpoint)
801
802 1
        assert response.status_code == 404
803 1
        assert mock_interface_1.disable.call_count == 0
804 1
        assert mock_interface_2.disable.call_count == 0
805
806
        # test switch not found
807 1
        dpid = '00:00:00:00:00:00:00:02'
808 1
        endpoint = f"{self.base_endpoint}/interfaces/switch/{dpid}/disable"
809 1
        response = await self.api_client.post(endpoint)
810 1
        assert response.status_code == 404
811 1
        assert mock_interface_1.disable.call_count == 0
812 1
        assert mock_interface_2.disable.call_count == 0
813
814 1
    async def test_get_interface_metadata(self):
815
        """Test get_interface_metada."""
816 1
        interface_id = '00:00:00:00:00:00:00:01:1'
817 1
        dpid = '00:00:00:00:00:00:00:01'
818 1
        mock_switch = get_switch_mock(dpid)
819 1
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
820 1
        mock_interface.metadata = {"A": "B"}
821 1
        mock_switch.interfaces = {1: mock_interface}
822 1
        self.napp.controller.switches = {dpid: mock_switch}
823
824 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
825 1
        response = await self.api_client.get(endpoint)
826 1
        assert response.status_code == 200
827 1
        assert response.json() == {"metadata": mock_interface.metadata}
828
829
        # fail case switch not found
830 1
        interface_id = '00:00:00:00:00:00:00:02:1'
831 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
832 1
        response = await self.api_client.get(endpoint)
833 1
        assert response.status_code == 404
834
835
        # fail case interface not found
836 1
        interface_id = '00:00:00:00:00:00:00:01:2'
837 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
838 1
        response = await self.api_client.get(endpoint)
839 1
        assert response.status_code == 404
840
841 1
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
842 1
    async def test_add_interface_metadata(
843
        self, mock_metadata_changes, event_loop
844
    ):
845
        """Test add_interface_metadata."""
846 1
        self.napp.controller.loop = event_loop
847 1
        interface_id = '00:00:00:00:00:00:00:01:1'
848 1
        dpid = '00:00:00:00:00:00:00:01'
849 1
        mock_switch = get_switch_mock(dpid)
850 1
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
851 1
        mock_interface.metadata = {"metada": "A"}
852 1
        mock_switch.interfaces = {1: mock_interface}
853 1
        self.napp.controller.switches = {dpid: mock_switch}
854 1
        payload = {"metada": "A"}
855 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
856 1
        response = await self.api_client.post(endpoint, json=payload)
857 1
        assert response.status_code == 201
858 1
        mock_metadata_changes.assert_called()
859
860
        # fail case switch not found
861 1
        interface_id = '00:00:00:00:00:00:00:02:1'
862 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
863 1
        response = await self.api_client.post(endpoint, json=payload)
864 1
        assert response.status_code == 404
865
866
        # fail case interface not found
867 1
        interface_id = '00:00:00:00:00:00:00:01:2'
868 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
869 1
        response = await self.api_client.post(endpoint, json=payload)
870 1
        assert response.status_code == 404
871
872 1
    async def test_add_interface_metadata_wrong_format(self, event_loop):
873
        """Test add_interface_metadata_wrong_format."""
874 1
        self.napp.controller.loop = event_loop
875 1
        interface_id = "00:00:00:00:00:00:00:01:1"
876 1
        endpoint = f"{self.base_endpoint}/interfaces/{interface_id}/metadata"
877 1
        response = await self.api_client.post(endpoint, json='A')
878 1
        assert response.status_code == 400
879 1
        response = await self.api_client.post(endpoint, json=None)
880 1
        assert response.status_code == 415
881
882 1
    async def test_delete_interface_metadata(self, event_loop):
883
        """Test delete_interface_metadata."""
884 1
        self.napp.controller.loop = event_loop
885 1
        interface_id = '00:00:00:00:00:00:00:01:1'
886 1
        dpid = '00:00:00:00:00:00:00:01'
887 1
        mock_switch = get_switch_mock(dpid)
888 1
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
889 1
        mock_interface.remove_metadata.side_effect = [True, False]
890 1
        mock_interface.metadata = {"A": "A"}
891 1
        mock_switch.interfaces = {1: mock_interface}
892 1
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
893
                                         mock_switch}
894
895 1
        key = 'A'
896 1
        url = f"{self.base_endpoint}/interfaces/{interface_id}/metadata/{key}"
897 1
        response = await self.api_client.delete(url)
898 1
        assert response.status_code == 200
899
900 1
        del_key_mock = self.napp.topo_controller.delete_interface_metadata_key
901 1
        del_key_mock.assert_called_once_with(interface_id, key)
902
903
        # fail case switch not found
904 1
        key = 'A'
905 1
        interface_id = '00:00:00:00:00:00:00:02:1'
906 1
        url = f"{self.base_endpoint}/interfaces/{interface_id}/metadata/{key}"
907 1
        response = await self.api_client.delete(url)
908 1
        assert response.status_code == 404
909
910
        # fail case interface not found
911 1
        key = 'A'
912 1
        interface_id = '00:00:00:00:00:00:00:01:2'
913 1
        url = f"{self.base_endpoint}/interfaces/{interface_id}/metadata/{key}"
914 1
        response = await self.api_client.delete(url)
915 1
        assert response.status_code == 404
916
917
        # fail case metadata not found
918 1
        key = 'B'
919 1
        interface_id = '00:00:00:00:00:00:00:01:1'
920 1
        url = f"{self.base_endpoint}/interfaces/{interface_id}/metadata/{key}"
921 1
        response = await self.api_client.delete(url)
922 1
        assert response.status_code == 404
923
924 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
925 1
    async def test_enable_link(self, mock_notify_topo):
926
        """Test enable_link."""
927 1
        mock_link = MagicMock(Link)
928 1
        self.napp.links = {'1': mock_link}
929
930 1
        link_id = "1"
931 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/enable"
932 1
        response = await self.api_client.post(endpoint)
933 1
        assert response.status_code == 201
934 1
        assert mock_link.enable.call_count == 1
935 1
        self.napp.topo_controller.enable_link.assert_called_with(link_id)
936 1
        mock_notify_topo.assert_called()
937
938
        # fail case
939 1
        link_id = "2"
940 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/enable"
941 1
        response = await self.api_client.post(endpoint)
942 1
        assert response.status_code == 404
943
944 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
945 1
    async def test_disable_link(self, mock_notify_topo):
946
        """Test disable_link."""
947 1
        mock_link = MagicMock(Link)
948 1
        self.napp.links = {'1': mock_link}
949
950 1
        link_id = "1"
951 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/disable"
952 1
        response = await self.api_client.post(endpoint)
953 1
        assert response.status_code == 201
954 1
        assert mock_link.disable.call_count == 1
955 1
        assert mock_notify_topo.call_count == 1
956 1
        self.napp.topo_controller.disable_link.assert_called_with(link_id)
957
958
        # fail case
959 1
        link_id = "2"
960 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/disable"
961 1
        response = await self.api_client.post(endpoint)
962 1
        assert response.status_code == 404
963
964 1
    def test_handle_lldp_status_updated(self):
965
        """Test handle_lldp_status_updated."""
966 1
        event = MagicMock()
967 1
        self.napp.controller.buffers.app.put = MagicMock()
968
969 1
        dpid_a = "00:00:00:00:00:00:00:01"
970 1
        dpid_b = "00:00:00:00:00:00:00:02"
971 1
        dpids = [dpid_a, dpid_b]
972 1
        interface_ids = [f"{dpid}:1" for dpid in dpids]
973
974 1
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
975 1
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
976 1
        self.napp.controller.switches = {dpid_a: mock_switch_a,
977
                                         dpid_b: mock_switch_b}
978
979 1
        event.content = {"interface_ids": interface_ids, "state": "disabled"}
980 1
        self.napp.handle_lldp_status_updated(event)
981
982 1
        mock_put = self.napp.controller.buffers.app.put
983 1
        assert mock_put.call_count == len(interface_ids)
984
985 1
    def test_handle_topo_controller_upsert_switch(self):
986
        """Test handle_topo_controller_upsert_switch."""
987 1
        event = MagicMock()
988 1
        self.napp.handle_topo_controller_upsert_switch(event)
989 1
        mock = self.napp.topo_controller.upsert_switch
990 1
        mock.assert_called_with(event.id, event.as_dict())
991
992 1
    async def test_get_link_metadata(self):
993
        """Test get_link_metadata."""
994 1
        mock_link = MagicMock(Link)
995 1
        mock_link.metadata = "A"
996 1
        self.napp.links = {'1': mock_link}
997 1
        msg_success = {"metadata": "A"}
998
999 1
        link_id = "1"
1000 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata"
1001 1
        response = await self.api_client.get(endpoint)
1002 1
        assert response.status_code == 200
1003 1
        assert msg_success == response.json()
1004
1005
        # fail case
1006 1
        link_id = "2"
1007 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata"
1008 1
        response = await self.api_client.get(endpoint)
1009 1
        assert response.status_code == 404
1010
1011 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1012 1
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
1013 1
    async def test_add_link_metadata(
1014
        self,
1015
        mock_metadata_changes,
1016
        mock_topology_update,
1017
        event_loop
1018
    ):
1019
        """Test add_link_metadata."""
1020 1
        self.napp.controller.loop = event_loop
1021 1
        mock_link = MagicMock(Link)
1022 1
        mock_link.metadata = "A"
1023 1
        self.napp.links = {'1': mock_link}
1024 1
        payload = {"metadata": "A"}
1025 1
        link_id = 1
1026
1027 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata"
1028 1
        response = await self.api_client.post(endpoint, json=payload)
1029 1
        assert response.status_code == 201
1030 1
        mock_metadata_changes.assert_called()
1031 1
        mock_topology_update.assert_called()
1032
1033
        # fail case
1034 1
        link_id = 2
1035 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata"
1036 1
        response = await self.api_client.post(endpoint, json=payload)
1037 1
        assert response.status_code == 404
1038
1039 1
    async def test_add_link_metadata_wrong_format(self, event_loop):
1040
        """Test add_link_metadata_wrong_format."""
1041 1
        self.napp.controller.loop = event_loop
1042 1
        link_id = 'cf0f4071be426b3f745027f5d22'
1043 1
        payload = "A"
1044 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata"
1045 1
        response = await self.api_client.post(endpoint, json=payload)
1046 1
        assert response.status_code == 400
1047
1048 1
        payload = None
1049 1
        response = await self.api_client.post(endpoint, json=payload)
1050 1
        assert response.status_code == 415
1051
1052 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1053 1
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
1054 1
    async def test_delete_link_metadata(
1055
        self,
1056
        mock_metadata_changes,
1057
        mock_topology_update
1058
    ):
1059
        """Test delete_link_metadata."""
1060 1
        mock_link = MagicMock(Link)
1061 1
        mock_link.metadata = {"A": "A"}
1062 1
        mock_link.remove_metadata.side_effect = [True, False]
1063 1
        self.napp.links = {'1': mock_link}
1064
1065 1
        link_id = 1
1066 1
        key = 'A'
1067 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata/{key}"
1068 1
        response = await self.api_client.delete(endpoint)
1069 1
        assert response.status_code == 200
1070 1
        del_mock = self.napp.topo_controller.delete_link_metadata_key
1071 1
        del_mock.assert_called_once_with(mock_link.id, key)
1072 1
        mock_metadata_changes.assert_called()
1073 1
        mock_topology_update.assert_called()
1074
1075
        # fail case link not found
1076 1
        link_id = 2
1077 1
        key = 'A'
1078 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata/{key}"
1079 1
        response = await self.api_client.delete(endpoint)
1080 1
        assert response.status_code == 404
1081
1082
        # fail case metadata not found
1083 1
        link_id = 1
1084 1
        key = 'B'
1085 1
        endpoint = f"{self.base_endpoint}/links/{link_id}/metadata/{key}"
1086 1
        response = await self.api_client.delete(endpoint)
1087 1
        assert response.status_code == 404
1088
1089 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1090 1
    def test_handle_new_switch(self, mock_notify_topology_update):
1091
        """Test handle_new_switch."""
1092 1
        mock_event = MagicMock()
1093 1
        mock_switch = create_autospec(Switch)
1094 1
        mock_event.content['switch'] = mock_switch
1095 1
        self.napp.handle_new_switch(mock_event)
1096 1
        mock = self.napp.topo_controller.upsert_switch
1097 1
        mock.assert_called_once_with(mock_event.content['switch'].id,
1098
                                     mock_event.content['switch'].as_dict())
1099 1
        mock_notify_topology_update.assert_called()
1100
1101 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1102 1
    def test_handle_connection_lost(self, mock_notify_topology_update):
1103
        """Test handle connection_lost."""
1104 1
        mock_event = MagicMock()
1105 1
        mock_switch = create_autospec(Switch)
1106 1
        mock_switch.return_value = True
1107 1
        mock_event.content['source'] = mock_switch
1108 1
        self.napp.handle_connection_lost(mock_event)
1109 1
        mock_notify_topology_update.assert_called()
1110
1111 1
    @patch('napps.kytos.topology.main.Main.handle_interface_link_up')
1112 1
    def test_handle_interface_created(self, mock_link_up):
1113
        """Test handle_interface_created."""
1114 1
        mock_event = MagicMock()
1115 1
        mock_interface = create_autospec(Interface)
1116 1
        mock_interface.id = "1"
1117 1
        mock_event.content = {'interface': mock_interface}
1118 1
        self.napp.handle_interface_created(mock_event)
1119 1
        mock_link_up.assert_called()
1120
1121 1
    @patch('napps.kytos.topology.main.Main.handle_interface_link_up')
1122 1
    def test_handle_interface_created_inactive(self, mock_link_up):
1123
        """Test handle_interface_created inactive."""
1124 1
        mock_event = MagicMock()
1125 1
        mock_interface = create_autospec(Interface)
1126 1
        mock_interface.id = "1"
1127 1
        mock_event.content = {'interface': mock_interface}
1128 1
        mock_interface.is_active.return_value = False
1129 1
        self.napp.handle_interface_created(mock_event)
1130 1
        mock_link_up.assert_not_called()
1131
1132 1
    def test_handle_interfaces_created(self):
1133
        """Test handle_interfaces_created."""
1134 1
        buffers_app_mock = MagicMock()
1135 1
        self.napp.controller.buffers.app = buffers_app_mock
1136 1
        mock_switch = create_autospec(Switch)
1137 1
        mock_event = MagicMock()
1138 1
        mock_interface = create_autospec(Interface)
1139 1
        mock_interface.id = "1"
1140 1
        mock_interface.switch = mock_switch
1141 1
        mock_interface_two = create_autospec(Interface)
1142 1
        mock_interface_two.id = "2"
1143 1
        mock_event.content = {'interfaces': [mock_interface,
1144
                              mock_interface_two]}
1145 1
        self.napp.handle_interfaces_created(mock_event)
1146 1
        upsert_mock = self.napp.topo_controller.upsert_switch
1147 1
        upsert_mock.assert_called_with(mock_switch.id, mock_switch.as_dict())
1148 1
        assert self.napp.controller.buffers.app.put.call_count == 2
1149
1150 1
    @patch('napps.kytos.topology.main.Main.handle_interface_link_down')
1151 1
    def test_handle_interface_down(self, mock_handle_interface_link_down):
1152
        """Test handle interface down."""
1153 1
        mock_event = MagicMock()
1154 1
        mock_interface = create_autospec(Interface)
1155 1
        mock_event.content['interface'] = mock_interface
1156 1
        self.napp.handle_interface_down(mock_event)
1157 1
        mock_handle_interface_link_down.assert_called()
1158
1159 1
    @patch('napps.kytos.topology.main.Main.handle_interface_down')
1160 1
    def test_interface_deleted(self, mock_handle_interface_link_down):
1161
        """Test interface deleted."""
1162 1
        mock_event = MagicMock()
1163 1
        self.napp.handle_interface_deleted(mock_event)
1164 1
        mock_handle_interface_link_down.assert_called()
1165
1166 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1167 1
    @patch('napps.kytos.topology.main.Main.notify_link_up_if_status')
1168 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1169 1
    def test_interface_link_up(self, *args):
1170
        """Test interface link_up."""
1171 1
        (mock_notify_topology_update,
1172
         mock_notify_link_up_if_status,
1173
         mock_link_from_interface) = args
1174
1175 1
        tnow = time.time()
1176 1
        mock_interface_a = create_autospec(Interface)
1177 1
        mock_interface_a.is_active.return_value = False
1178 1
        mock_interface_b = create_autospec(Interface)
1179 1
        mock_interface_b.is_active.return_value = True
1180 1
        mock_link = create_autospec(Link)
1181 1
        mock_link.get_metadata.return_value = tnow
1182 1
        mock_link.is_active.side_effect = [False, True]
1183 1
        mock_link.endpoint_a = mock_interface_a
1184 1
        mock_link.endpoint_b = mock_interface_b
1185 1
        mock_link_from_interface.return_value = mock_link
1186 1
        mock_link.status = EntityStatus.UP
1187 1
        event = KytosEvent("kytos.of_core.switch.interface.down")
1188 1
        self.napp.handle_interface_link_up(mock_interface_a, event)
1189 1
        mock_notify_topology_update.assert_called()
1190 1
        mock_link.extend_metadata.assert_called()
1191 1
        mock_link.activate.assert_called()
1192 1
        mock_notify_link_up_if_status.assert_called()
1193
1194 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1195 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1196 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1197 1
    def test_interface_link_down(self, *args):
1198
        """Test interface link down."""
1199 1
        (mock_status_change, mock_topology_update,
1200
         mock_link_from_interface) = args
1201
1202 1
        mock_interface = create_autospec(Interface)
1203 1
        mock_link = create_autospec(Link)
1204 1
        mock_link.is_active.return_value = True
1205 1
        mock_link_from_interface.return_value = mock_link
1206 1
        event = KytosEvent("kytos.of_core.switch.interface.link_up")
1207 1
        self.napp.handle_interface_link_down(mock_interface, event)
1208 1
        mock_topology_update.assert_called()
1209 1
        mock_status_change.assert_called()
1210
1211 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1212 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1213 1
    def test_interface_link_down_unordered_event(self, *args):
1214
        """Test interface link down unordered event."""
1215 1
        (mock_status_change, mock_topology_update) = args
1216
1217 1
        mock_interface = create_autospec(Interface)
1218 1
        mock_interface.id = "1"
1219 1
        event_2 = KytosEvent("kytos.of_core.switch.interface.down")
1220 1
        event_1 = KytosEvent("kytos.of_core.switch.interface.up")
1221 1
        assert event_1.timestamp > event_2.timestamp
1222 1
        self.napp._intfs_updated_at[mock_interface.id] = event_1.timestamp
1223 1
        self.napp.handle_interface_link_down(mock_interface, event_2)
1224 1
        mock_topology_update.assert_not_called()
1225 1
        mock_status_change.assert_not_called()
1226
1227 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1228 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1229 1
    def test_interface_link_up_unordered_event(self, *args):
1230
        """Test interface link up unordered event."""
1231 1
        (mock_status_change, mock_topology_update) = args
1232
1233 1
        mock_interface = create_autospec(Interface)
1234 1
        mock_interface.id = "1"
1235 1
        event_2 = KytosEvent("kytos.of_core.switch.interface.up")
1236 1
        event_1 = KytosEvent("kytos.of_core.switch.interface.down")
1237 1
        assert event_1.timestamp > event_2.timestamp
1238 1
        self.napp._intfs_updated_at[mock_interface.id] = event_1.timestamp
1239 1
        self.napp.handle_interface_link_up(mock_interface, event_2)
1240 1
        mock_topology_update.assert_not_called()
1241 1
        mock_status_change.assert_not_called()
1242
1243 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1244 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1245 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1246 1
    def test_handle_link_down(self, *args):
1247
        """Test interface link down."""
1248 1
        (mock_status_change, mock_topology_update,
1249
         mock_link_from_interface) = args
1250
1251 1
        mock_interface = create_autospec(Interface)
1252 1
        mock_link = create_autospec(Link)
1253 1
        mock_link.is_active.return_value = True
1254 1
        mock_link_from_interface.return_value = mock_link
1255 1
        self.napp.handle_link_down(mock_interface)
1256 1
        mock_interface.deactivate.assert_not_called()
1257 1
        mock_link.deactivate.assert_called()
1258 1
        mock_link.extend_metadata.assert_called()
1259 1
        assert mock_topology_update.call_count == 1
1260 1
        mock_status_change.assert_called()
1261
1262 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1263 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1264 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1265 1
    def test_handle_link_down_not_active(self, *args):
1266
        """Test interface link down with link not active."""
1267 1
        (mock_status_change, mock_topology_update,
1268
         mock_link_from_interface) = args
1269
1270 1
        mock_interface = create_autospec(Interface)
1271 1
        mock_link = create_autospec(Link)
1272 1
        mock_link.is_active.return_value = False
1273 1
        mock_link_from_interface.return_value = mock_link
1274 1
        mock_link.get_metadata.return_value = False
1275 1
        self.napp.handle_link_down(mock_interface)
1276 1
        mock_topology_update.assert_called()
1277 1
        mock_status_change.assert_not_called()
1278
1279 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1280 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1281 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1282 1
    def test_handle_link_down_not_active_last_status(self, *args):
1283
        """Test interface link down with link not active."""
1284 1
        (mock_status_change, mock_topology_update,
1285
         mock_link_from_interface) = args
1286
1287 1
        mock_interface = create_autospec(Interface)
1288 1
        mock_link = create_autospec(Link)
1289 1
        mock_link.is_active.return_value = False
1290 1
        mock_link_from_interface.return_value = mock_link
1291 1
        mock_link.get_metadata.return_value = True
1292 1
        self.napp.handle_link_down(mock_interface)
1293 1
        mock_topology_update.assert_called()
1294 1
        mock_status_change.assert_called()
1295
1296 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1297 1
    @patch('napps.kytos.topology.main.Main.notify_link_up_if_status')
1298 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1299 1
    def test_handle_link_up(self, *args):
1300
        """Test handle link up."""
1301 1
        (mock_notify_topology_update,
1302
         mock_notify_link_up_if_status,
1303
         mock_link_from_interface) = args
1304
1305 1
        mock_interface = create_autospec(Interface)
1306 1
        mock_link = MagicMock(status=EntityStatus.UP)
1307 1
        mock_link.is_active.return_value = True
1308 1
        mock_link_from_interface.return_value = mock_link
1309 1
        self.napp.handle_link_up(mock_interface)
1310 1
        mock_interface.activate.assert_not_called()
1311 1
        assert mock_notify_link_up_if_status.call_count == 1
1312 1
        mock_notify_topology_update.assert_called()
1313
1314 1
    @patch('time.sleep')
1315 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1316 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1317 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1318 1
    def test_handle_link_up_intf_down(self, *args):
1319
        """Test handle link up but one intf down."""
1320 1
        (mock_status_change, mock_topology_update,
1321
         mock_link_from_interface, _) = args
1322
1323 1
        mock_interface = create_autospec(Interface)
1324 1
        mock_link = MagicMock()
1325 1
        mock_link.endpoint_a.is_active.return_value = False
1326 1
        mock_link.is_active.return_value = False
1327 1
        mock_link_from_interface.return_value = mock_link
1328 1
        self.napp.handle_link_up(mock_interface)
1329 1
        mock_interface.activate.assert_not_called()
1330 1
        assert mock_topology_update.call_count == 1
1331 1
        mock_status_change.assert_not_called()
1332
1333 1
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
1334 1
    @patch('napps.kytos.topology.main.Main.notify_link_up_if_status')
1335 1
    def test_add_links(self, *args):
1336
        """Test add_links."""
1337 1
        (mock_notify_link_up_if_status,
1338
         mock_get_link_or_create) = args
1339
1340 1
        mock_link = MagicMock()
1341 1
        mock_get_link_or_create.return_value = (mock_link, True)
1342 1
        mock_event = MagicMock()
1343 1
        mock_intf_a = MagicMock()
1344 1
        mock_intf_b = MagicMock()
1345 1
        mock_event.content = {
1346
            "interface_a": mock_intf_a,
1347
            "interface_b": mock_intf_b
1348
        }
1349 1
        self.napp.add_links(mock_event)
1350 1
        mock_link.extend_metadata.assert_called()
1351 1
        mock_get_link_or_create.assert_called()
1352 1
        mock_notify_link_up_if_status.assert_called()
1353 1
        mock_intf_a.update_link.assert_called()
1354 1
        mock_intf_b.update_link.assert_called()
1355 1
        mock_link.endpoint_a = mock_intf_a
1356 1
        mock_link.endpoint_b = mock_intf_b
1357
1358 1
    def test_notify_switch_enabled(self):
1359
        """Test notify switch enabled."""
1360 1
        dpid = "00:00:00:00:00:00:00:01"
1361 1
        mock_buffers_put = MagicMock()
1362 1
        self.napp.controller.buffers.app.put = mock_buffers_put
1363 1
        self.napp.notify_switch_enabled(dpid)
1364 1
        mock_buffers_put.assert_called()
1365
1366 1
    def test_notify_switch_disabled(self):
1367
        """Test notify switch disabled."""
1368 1
        dpid = "00:00:00:00:00:00:00:01"
1369 1
        mock_buffers_put = MagicMock()
1370 1
        self.napp.controller.buffers.app.put = mock_buffers_put
1371 1
        self.napp.notify_switch_disabled(dpid)
1372 1
        mock_buffers_put.assert_called()
1373
1374 1
    def test_notify_topology_update(self):
1375
        """Test notify_topology_update."""
1376 1
        mock_buffers_put = MagicMock()
1377 1
        self.napp.controller.buffers.app.put = mock_buffers_put
1378 1
        self.napp.notify_topology_update()
1379 1
        mock_buffers_put.assert_called()
1380
1381 1
    def test_notify_link_status_change(self):
1382
        """Test notify link status change."""
1383 1
        mock_buffers_put = MagicMock()
1384 1
        self.napp.controller.buffers.app.put = mock_buffers_put
1385 1
        mock_link = create_autospec(Link)
1386 1
        mock_link.id = 'test_link'
1387 1
        mock_link.status_reason = frozenset()
1388 1
        mock_link.status = EntityStatus.UP
1389
1390
        # Check when switching to up
1391 1
        self.napp.notify_link_status_change(mock_link, 'test')
1392 1
        assert mock_buffers_put.call_count == 1
1393 1
        args, _ = mock_buffers_put.call_args
1394 1
        event = args[0]
1395 1
        assert event.content['link'] is mock_link
1396 1
        assert event.content['reason'] == 'test'
1397 1
        assert event.name == 'kytos/topology.link_up'
1398
1399
        # Check result when no change
1400 1
        self.napp.notify_link_status_change(mock_link, 'test2')
1401 1
        assert mock_buffers_put.call_count == 1
1402
1403
        # Check when switching to down
1404 1
        mock_link.status_reason = frozenset({'disabled'})
1405 1
        mock_link.status = EntityStatus.DOWN
1406 1
        self.napp.notify_link_status_change(mock_link, 'test3')
1407 1
        assert mock_buffers_put.call_count == 2
1408 1
        args, _ = mock_buffers_put.call_args
1409 1
        event = args[0]
1410 1
        assert event.content['link'] is mock_link
1411 1
        assert event.content['reason'] == 'test3'
1412 1
        assert event.name == 'kytos/topology.link_down'
1413
1414 1
    def test_notify_metadata_changes(self):
1415
        """Test notify metadata changes."""
1416 1
        mock_buffers_put = MagicMock()
1417 1
        self.napp.controller.buffers.app.put = mock_buffers_put
1418 1
        count = 0
1419 1
        for spec in [Switch, Interface, Link]:
1420 1
            mock_obj = create_autospec(spec)
1421 1
            mock_obj.metadata = {"some_key": "some_value"}
1422 1
            self.napp.notify_metadata_changes(mock_obj, 'added')
1423 1
            assert mock_buffers_put.call_count == count+1
1424 1
            count += 1
1425 1
        with pytest.raises(ValueError):
1426 1
            self.napp.notify_metadata_changes(MagicMock(), 'added')
1427
1428 1
    def test_notify_port_created(self):
1429
        """Test notify port created."""
1430 1
        mock_buffers_put = MagicMock()
1431 1
        self.napp.controller.buffers.app.put = mock_buffers_put
1432 1
        event = KytosEvent("some_event")
1433 1
        expected_name = "kytos/topology.port.created"
1434 1
        self.napp.notify_port_created(event)
1435 1
        assert mock_buffers_put.call_count == 1
1436 1
        assert mock_buffers_put.call_args_list[0][0][0].name == expected_name
1437
1438 1
    def test_get_links_from_interfaces(self) -> None:
1439
        """Test get_links_from_interfaces."""
1440 1
        interfaces = [MagicMock(id=f"intf{n}") for n in range(4)]
1441 1
        links = {
1442
            "link1": MagicMock(id="link1",
1443
                               endpoint_a=interfaces[0],
1444
                               endpoint_b=interfaces[1]),
1445
            "link2": MagicMock(id="link2",
1446
                               endpoint_a=interfaces[2],
1447
                               endpoint_b=interfaces[3]),
1448
        }
1449 1
        self.napp.links = links
1450 1
        response = self.napp.get_links_from_interfaces(interfaces)
1451 1
        assert links == response
1452 1
        response = self.napp.get_links_from_interfaces(interfaces[:2])
1453 1
        assert response == {"link1": links["link1"]}
1454
1455 1
    def test_handle_link_liveness_disabled(self) -> None:
1456
        """Test handle_link_liveness_disabled."""
1457 1
        interfaces = [MagicMock(id=f"intf{n}") for n in range(4)]
1458 1
        links = {
1459
            "link1": MagicMock(id="link1",
1460
                               endpoint_a=interfaces[0],
1461
                               endpoint_b=interfaces[1]),
1462
            "link2": MagicMock(id="link2",
1463
                               endpoint_a=interfaces[2],
1464
                               endpoint_b=interfaces[3]),
1465
        }
1466 1
        self.napp.links = links
1467 1
        self.napp.notify_topology_update = MagicMock()
1468 1
        self.napp.notify_link_status_change = MagicMock()
1469
1470 1
        self.napp.handle_link_liveness_disabled(interfaces)
1471
1472 1
        bulk_delete = self.napp.topo_controller.bulk_delete_link_metadata_key
1473 1
        assert bulk_delete.call_count == 1
1474 1
        assert self.napp.notify_topology_update.call_count == 1
1475 1
        assert self.napp.notify_link_status_change.call_count == len(links)
1476
1477 1
    def test_link_status_hook_link_up_timer(self) -> None:
1478
        """Test status hook link up timer."""
1479 1
        last_change = time.time() - self.napp.link_up_timer + 5
1480 1
        link = MagicMock(metadata={"last_status_change": last_change})
1481 1
        link.is_active.return_value = True
1482 1
        link.is_enabled.return_value = True
1483 1
        res = self.napp.link_status_hook_link_up_timer(link)
1484 1
        assert res == EntityStatus.DOWN
1485
1486 1
        last_change = time.time() - self.napp.link_up_timer
1487 1
        link.metadata["last_status_change"] = last_change
1488 1
        res = self.napp.link_status_hook_link_up_timer(link)
1489 1
        assert res is None
1490
1491 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1492 1
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1493 1
    @patch('time.sleep')
1494 1
    def test_notify_link_up_if_status(
1495
        self,
1496
        mock_sleep,
1497
        mock_notify_topo,
1498
        mock_notify_link,
1499
    ) -> None:
1500
        """Test notify link up if status."""
1501
1502 1
        link = MagicMock(status=EntityStatus.UP)
1503 1
        link.get_metadata.return_value = now()
1504 1
        assert not self.napp.notify_link_up_if_status(link, "link up")
1505 1
        link.update_metadata.assert_not_called()
1506 1
        mock_notify_topo.assert_not_called()
1507 1
        mock_notify_link.assert_not_called()
1508
1509 1
        link = MagicMock(status=EntityStatus.UP)
1510 1
        link.get_metadata.return_value = now() - timedelta(seconds=60)
1511 1
        assert not self.napp.notify_link_up_if_status(link, "link up")
1512 1
        link.update_metadata.assert_called()
1513 1
        mock_notify_topo.assert_called()
1514 1
        mock_notify_link.assert_called()
1515
1516 1
        assert mock_sleep.call_count == 2
1517
1518 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1519 1
    def test_notify_switch_links_status(self, mock_notify_link_status_change):
1520
        """Test switch links notification when switch status change"""
1521 1
        buffers_app_mock = MagicMock()
1522 1
        self.napp.controller.buffers.app = buffers_app_mock
1523 1
        dpid = "00:00:00:00:00:00:00:01"
1524 1
        mock_switch = get_switch_mock(dpid)
1525 1
        link1 = MagicMock()
1526 1
        link1.endpoint_a.switch = mock_switch
1527 1
        self.napp.links = {1: link1}
1528
1529 1
        self.napp.notify_switch_links_status(mock_switch, "link enabled")
1530 1
        assert self.napp.controller.buffers.app.put.call_count == 1
1531
1532 1
        self.napp.notify_switch_links_status(mock_switch, "link disabled")
1533 1
        assert self.napp.controller.buffers.app.put.call_count == 1
1534 1
        assert mock_notify_link_status_change.call_count == 1
1535
1536
        # Without notification
1537 1
        link1.endpoint_a.switch = None
1538 1
        self.napp.notify_switch_links_status(mock_switch, "link enabled")
1539 1
        assert self.napp.controller.buffers.app.put.call_count == 1
1540
1541 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1542 1
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1543 1
    def test_notify_interface_link_status(self, *args):
1544
        """Test interface links notification when enable"""
1545 1
        (mock_get_link_from_interface,
1546
         mock_notify_link_status_change) = args
1547 1
        buffers_app_mock = MagicMock()
1548 1
        self.napp.controller.buffers.app = buffers_app_mock
1549 1
        mock_link = MagicMock()
1550 1
        mock_get_link_from_interface.return_value = mock_link
1551 1
        self.napp.notify_interface_link_status(MagicMock(), "link enabled")
1552 1
        assert mock_get_link_from_interface.call_count == 1
1553 1
        assert self.napp.controller.buffers.app.put.call_count == 1
1554
1555 1
        self.napp.notify_interface_link_status(MagicMock(), "link disabled")
1556 1
        assert mock_get_link_from_interface.call_count == 2
1557 1
        assert mock_notify_link_status_change.call_count == 1
1558 1
        assert self.napp.controller.buffers.app.put.call_count == 1
1559
1560
        # Without notification
1561 1
        mock_get_link_from_interface.return_value = None
1562 1
        self.napp.notify_interface_link_status(MagicMock(), "link enabled")
1563 1
        assert mock_get_link_from_interface.call_count == 3
1564 1
        assert self.napp.controller.buffers.app.put.call_count == 1
1565
1566 1 View Code Duplication
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1567 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1568 1
    def test_interruption_start(
1569
        self,
1570
        mock_notify_link_status_change,
1571
        mock_notify_topology_update
1572
    ):
1573
        """Tests processing of received interruption start events."""
1574 1
        link_a = MagicMock()
1575 1
        link_b = MagicMock()
1576 1
        link_c = MagicMock()
1577 1
        self.napp.links = {
1578
            'link_a': link_a,
1579
            'link_b': link_b,
1580
            'link_c': link_c,
1581
        }
1582 1
        event = KytosEvent(
1583
            "topology.interruption.start",
1584
            {
1585
                'type': 'test_interruption',
1586
                'switches': [
1587
                ],
1588
                'interfaces': [
1589
                ],
1590
                'links': [
1591
                    'link_a',
1592
                    'link_c',
1593
                ],
1594
            }
1595
        )
1596 1
        self.napp.handle_interruption_start(event)
1597 1
        mock_notify_link_status_change.assert_has_calls(
1598
            [
1599
                call(link_a, 'test_interruption'),
1600
                call(link_c, 'test_interruption'),
1601
            ]
1602
        )
1603 1
        assert mock_notify_link_status_change.call_count == 2
1604 1
        mock_notify_topology_update.assert_called_once()
1605
1606 1 View Code Duplication
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1607 1
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1608 1
    def test_interruption_end(
1609
        self,
1610
        mock_notify_link_status_change,
1611
        mock_notify_topology_update
1612
    ):
1613
        """Tests processing of received interruption end events."""
1614 1
        link_a = MagicMock()
1615 1
        link_b = MagicMock()
1616 1
        link_c = MagicMock()
1617 1
        self.napp.links = {
1618
            'link_a': link_a,
1619
            'link_b': link_b,
1620
            'link_c': link_c,
1621
        }
1622 1
        event = KytosEvent(
1623
            "topology.interruption.start",
1624
            {
1625
                'type': 'test_interruption',
1626
                'switches': [
1627
                ],
1628
                'interfaces': [
1629
                ],
1630
                'links': [
1631
                    'link_a',
1632
                    'link_c',
1633
                ],
1634
            }
1635
        )
1636 1
        self.napp.handle_interruption_end(event)
1637 1
        mock_notify_link_status_change.assert_has_calls(
1638
            [
1639
                call(link_a, 'test_interruption'),
1640
                call(link_c, 'test_interruption'),
1641
            ]
1642
        )
1643 1
        assert mock_notify_link_status_change.call_count == 2
1644
        mock_notify_topology_update.assert_called_once()
1645