Passed
Push — master ( 8c0a82...c7049e )
by Vinicius
04:18 queued 02:48
created

TestMain.test_handle_link_up_intf_down()   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nop 2
dl 0
loc 19
rs 9.6
c 0
b 0
f 0
1
"""Module to test the main napp file."""
2
import json
3
import time
4
from unittest import TestCase
5
from unittest.mock import MagicMock, create_autospec, patch
6
# pylint: disable=import-error,no-name-in-module
7
8
from kytos.core.interface import Interface
9
from kytos.core.link import Link
10
from kytos.core.switch import Switch
11
from kytos.lib.helpers import (get_interface_mock, get_link_mock,
12
                               get_switch_mock, get_test_client)
13
from napps.kytos.topology.exceptions import RestoreError
14
from tests.unit.helpers import get_controller_mock, get_napp_urls
15
16
17
# pylint: disable=too-many-public-methods
18
class TestMain(TestCase):
19
    """Test the Main class."""
20
21
    # pylint: disable=too-many-public-methods, protected-access,C0302
22
23
    def setUp(self):
24
        """Execute steps before each tests.
25
26
        Set the server_name_url_url from kytos/topology
27
        """
28
        self.server_name_url = 'http://localhost:8181/api/kytos/topology'
29
30
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
31
        # pylint: disable=import-outside-toplevel
32
        from napps.kytos.topology.main import Main
33
        self.addCleanup(patch.stopall)
34
35
        self.napp = Main(get_controller_mock())
36
37
    def test_get_event_listeners(self):
38
        """Verify all event listeners registered."""
39
        expected_events = ['kytos/core.shutdown',
40
                           'kytos/core.shutdown.kytos/topology',
41
                           'kytos/maintenance.start_link',
42
                           'kytos/maintenance.end_link',
43
                           'kytos/maintenance.start_switch',
44
                           'kytos/maintenance.end_switch',
45
                           'kytos/storehouse.loaded',
46
                           '.*.network_status.updated',
47
                           '.*.interface.is.nni',
48
                           '.*.connection.lost',
49
                           '.*.switch.interface.created',
50
                           '.*.switch.interface.deleted',
51
                           '.*.switch.interface.link_down',
52
                           '.*.switch.interface.link_up',
53
                           '.*.switch.(new|reconnected)',
54
                           '.*.switch.port.created']
55
        actual_events = self.napp.listeners()
56
        self.assertCountEqual(expected_events, actual_events)
57
58 View Code Duplication
    def test_verify_api_urls(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
59
        """Verify all APIs registered."""
60
        expected_urls = [
61
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/interfaces'),
62
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/switches'),
63
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/links'),
64
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/'),
65
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
66
          '/api/kytos/topology/v3/interfaces/switch/<dpid>/disable'),
67
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
68
          '/api/kytos/topology/v3/interfaces/switch/<dpid>/enable'),
69
         ({'key': '[key]', 'interface_id': '[interface_id]'},
70
          {'OPTIONS', 'DELETE'},
71
          '/api/kytos/topology/v3/interfaces/<interface_id>/metadata/<key>'),
72
         ({'interface_id': '[interface_id]'}, {'POST', 'OPTIONS'},
73
          '/api/kytos/topology/v3/interfaces/<interface_id>/metadata'),
74
         ({'interface_id': '[interface_id]'}, {'GET', 'OPTIONS', 'HEAD'},
75
          '/api/kytos/topology/v3/interfaces/<interface_id>/metadata'),
76
         ({'interface_disable_id': '[interface_disable_id]'},
77
          {'POST', 'OPTIONS'},
78
          '/api/kytos/topology/v3/interfaces/<interface_disable_id>/disable'),
79
         ({'interface_enable_id': '[interface_enable_id]'},
80
          {'POST', 'OPTIONS'},
81
          '/api/kytos/topology/v3/interfaces/<interface_enable_id>/enable'),
82
         ({'dpid': '[dpid]', 'key': '[key]'}, {'OPTIONS', 'DELETE'},
83
          '/api/kytos/topology/v3/switches/<dpid>/metadata/<key>'),
84
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
85
          '/api/kytos/topology/v3/switches/<dpid>/metadata'),
86
         ({'dpid': '[dpid]'}, {'GET', 'OPTIONS', 'HEAD'},
87
          '/api/kytos/topology/v3/switches/<dpid>/metadata'),
88
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
89
          '/api/kytos/topology/v3/switches/<dpid>/disable'),
90
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
91
          '/api/kytos/topology/v3/switches/<dpid>/enable'),
92
         ({'link_id': '[link_id]', 'key': '[key]'}, {'OPTIONS', 'DELETE'},
93
          '/api/kytos/topology/v3/links/<link_id>/metadata/<key>'),
94
         ({'link_id': '[link_id]'}, {'POST', 'OPTIONS'},
95
          '/api/kytos/topology/v3/links/<link_id>/metadata'),
96
         ({'link_id': '[link_id]'}, {'GET', 'OPTIONS', 'HEAD'},
97
          '/api/kytos/topology/v3/links/<link_id>/metadata'),
98
         ({'link_id': '[link_id]'}, {'POST', 'OPTIONS'},
99
          '/api/kytos/topology/v3/links/<link_id>/disable'),
100
         ({'link_id': '[link_id]'}, {'POST', 'OPTIONS'},
101
          '/api/kytos/topology/v3/links/<link_id>/enable')]
102
103
        urls = get_napp_urls(self.napp)
104
        self.assertEqual(expected_urls, urls)
105
106
    def test_get_link_or_create(self):
107
        """Test _get_link_or_create."""
108
        dpid_a = "00:00:00:00:00:00:00:01"
109
        dpid_b = "00:00:00:00:00:00:00:02"
110
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
111
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
112
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
113
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
114
        mock_interface_a.id = dpid_a
115
        mock_interface_b.id = dpid_b
116
117
        link, created = self.napp._get_link_or_create(mock_interface_a,
118
                                                      mock_interface_b)
119
        self.assertTrue(created)
120
        self.assertEqual(link.endpoint_a.id, dpid_a)
121
        self.assertEqual(link.endpoint_b.id, dpid_b)
122
123
        link, created = self.napp._get_link_or_create(mock_interface_a,
124
                                                      mock_interface_b)
125
        self.assertFalse(created)
126
127
    def test_get_link_from_interface(self):
128
        """Test _get_link_from_interface."""
129
        mock_switch_a = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
130
        mock_switch_b = get_switch_mock("00:00:00:00:00:00:00:02", 0x04)
131
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
132
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
133
        mock_interface_c = get_interface_mock('s2-eth1', 2, mock_switch_b)
134
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
135
        self.napp.links = {'0e2b5d7bc858b9f38db11b69': mock_link}
136
        response = self.napp._get_link_from_interface(mock_interface_a)
137
        self.assertEqual(response, mock_link)
138
139
        response = self.napp._get_link_from_interface(mock_interface_c)
140
        self.assertEqual(response, None)
141
142
    def test_get_topology(self):
143
        """Test get_topology."""
144
        dpid_a = "00:00:00:00:00:00:00:01"
145
        dpid_b = "00:00:00:00:00:00:00:02"
146
        expected = {
147
                      "topology": {
148
                        "switches": {
149
                          "00:00:00:00:00:00:00:01": {
150
                            "metadata": {
151
                              "lat": "0.0",
152
                              "lng": "-30.0"
153
                            }
154
                          },
155
                          "00:00:00:00:00:00:00:02": {
156
                            "metadata": {
157
                              "lat": "0.0",
158
                              "lng": "-30.0"
159
                            }
160
                          }
161
                        },
162
                        "links": {
163
                          "cf0f4071be4": {
164
                            "id": "cf0f4071be4"
165
                          }
166
                        }
167
                      }
168
                    }
169
170
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
171
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
172
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
173
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
174
175
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
176
        mock_link.id = 'cf0f4071be4'
177
        mock_switch_a.id = dpid_a
178
        mock_switch_a.as_dict.return_value = {'metadata': {'lat': '0.0',
179
                                              'lng': '-30.0'}}
180
        mock_switch_b.id = dpid_b
181
        mock_switch_b.as_dict.return_value = {'metadata': {'lat': '0.0',
182
                                              'lng': '-30.0'}}
183
184
        self.napp.controller.switches = {dpid_a: mock_switch_a,
185
                                         dpid_b: mock_switch_b}
186
187
        self.napp.links = {"cf0f4071be4": mock_link}
188
        mock_link.as_dict.return_value = {"id": "cf0f4071be4"}
189
        api = get_test_client(self.napp.controller, self.napp)
190
191
        url = f'{self.server_name_url}/v3/'
192
        response = api.get(url)
193
        self.assertEqual(response.status_code, 200)
194
        self.assertEqual(json.loads(response.data), expected)
195
196
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
197
    def test_load_network_status(self, mock_storehouse_get_data):
198
        """Test _load_network_status."""
199
        link_id = \
200
            'cf0f4071be426b3f745027f5d22bc61f8312ae86293c9b28e7e66015607a9260'
201
        dpid_a = '00:00:00:00:00:00:00:01'
202
        dpid_b = '00:00:00:00:00:00:00:02'
203
        status = {
204
            'network_status': {
205
                'id': 'network_status',
206
                'links': {
207
                    link_id: {
208
                        'enabled': True,
209
                        'endpoint_a': {
210
                            'switch': dpid_a,
211
                            'port_number': 2
212
                        },
213
                        'endpoint_b': {
214
                            'switch': dpid_b,
215
                            'port_number': 2
216
                        }
217
                    }
218
                },
219
                'switches': {
220
                    dpid_a: {
221
                        'dpid': dpid_a,
222
                        'enabled': True,
223
                        'id': dpid_a,
224
                        'interfaces': {
225
                            f'{dpid_a}:2': {
226
                                'enabled': True,
227
                                'lldp': True,
228
                                'port_number': 2,
229
                                'name': 's1-eth2'
230
                            }
231
                        }
232
                    },
233
                    dpid_b: {
234
                        'dpid': dpid_b,
235
                        'enabled': True,
236
                        'id': dpid_b,
237
                        'interfaces': {
238
                            f'{dpid_b}:2': {
239
                                'enabled': True,
240
                                'lldp': True,
241
                                'port_number': 2,
242
                                'name': 's2-eth2'
243
                            }
244
                        }
245
                    }
246
                }
247
            }
248
        }
249
        switches_expected = [dpid_a, dpid_b]
250
        interfaces_expected = [f'{dpid_a}:2', f'{dpid_b}:2']
251
        links_expected = [link_id]
252
        mock_storehouse_get_data.return_value = status
253
        self.napp._load_network_status()
254
        self.assertListEqual(switches_expected,
255
                             list(self.napp.controller.switches.keys()))
256
        interfaces = []
257
        for switch in self.napp.controller.switches.values():
258
            for iface in switch.interfaces.values():
259
                interfaces.append(iface.id)
260
        self.assertListEqual(interfaces_expected, interfaces)
261
        self.assertListEqual(links_expected, list(self.napp.links.keys()))
262
263
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
264
    @patch('napps.kytos.topology.main.log')
265
    def test_load_network_status_fail(self, *args):
266
        """Test _load_network_status failure."""
267
        (mock_log, mock_storehouse_get_data) = args
268
        mock_log.error.return_value = True
269
        mock_storehouse_get_data.side_effect = FileNotFoundError('xpto')
270
        self.napp._load_network_status()
271
        error = 'Fail to load network status from storehouse: xpto'
272
        mock_log.error.assert_called_with(error)
273
274
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
275
    @patch('napps.kytos.topology.main.log')
276
    def test_load_network_status_does_nothing(self, *args):
277
        """Test _load_network_status doing nothing."""
278
        (mock_log, mock_storehouse_get_data) = args
279
        mock_log.info.return_value = True
280
        mock_storehouse_get_data.return_value = {}
281
        self.napp._load_network_status()
282
        error = 'There is no status saved to restore.'
283
        mock_log.info.assert_called_with(error)
284
285
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
286
    @patch('napps.kytos.topology.main.Main._load_switch')
287
    @patch('napps.kytos.topology.main.log')
288
    def test_load_network_status_fail_switch(self, *args):
289
        """Test _load_network_status failure in switch."""
290
        (mock_log, mock_load_switch, mock_get_data) = args
291
        status = {
292
            'network_status': {
293
                'id': 'network_status',
294
                'links': {},
295
                'switches': {
296
                    '1': {}
297
                }
298
            }
299
        }
300
        mock_log.error.return_value = True
301
        mock_get_data.return_value = status
302
        mock_load_switch.side_effect = Exception('xpto')
303
        self.napp._load_network_status()
304
        error = 'Error loading switch: xpto'
305
        mock_log.error.assert_called_with(error)
306
307
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
308
    @patch('napps.kytos.topology.main.Main._load_link')
309
    @patch('napps.kytos.topology.main.log')
310
    def test_load_network_status_fail_link(self, *args):
311
        """Test _load_network_status failure in link."""
312
        (mock_log, mock_load_link, mock_get_data) = args
313
        status = {
314
            'network_status': {
315
                'id': 'network_status',
316
                'switches': {},
317
                'links': {
318
                    '1': {}
319
                }
320
            }
321
        }
322
        mock_log.error.return_value = True
323
        mock_get_data.return_value = status
324
        mock_load_link.side_effect = Exception('xpto')
325
        self.napp._load_network_status()
326
        error = 'Error loading link 1: xpto'
327
        mock_log.error.assert_called_with(error)
328
329
    @patch('napps.kytos.topology.main.KytosEvent')
330
    @patch('kytos.core.buffers.KytosEventBuffer.put')
331
    def test_load_switch(self, *args):
332
        """Test _load_switch."""
333
        (mock_buffers_put, mock_event) = args
334
        dpid_a = "00:00:00:00:00:00:00:01"
335
        dpid_x = "00:00:00:00:00:00:00:XX"
336
        iface_a = f'{dpid_a}:1'
337
        switch_attrs = {
338
            'dpid': dpid_a,
339
            'enabled': True,
340
            'id': dpid_a,
341
            'interfaces': {
342
                iface_a: {
343
                    'enabled': True,
344
                    'lldp': True,
345
                    'id': iface_a,
346
                    'switch': dpid_a,
347
                    'name': 's2-eth1',
348
                    'port_number': 1
349
                }
350
            }
351
        }
352
        self.napp._load_switch(dpid_a, switch_attrs)
353
354
        self.assertEqual(len(self.napp.controller.switches), 1)
355
        self.assertIn(dpid_a, self.napp.controller.switches)
356
        self.assertNotIn(dpid_x, self.napp.controller.switches)
357
        switch = self.napp.controller.switches[dpid_a]
358
359
        self.assertEqual(switch.id, dpid_a)
360
        self.assertEqual(switch.dpid, dpid_a)
361
        self.assertTrue(switch.is_enabled())
362
        self.assertFalse(switch.is_active())
363
364
        self.assertEqual(len(switch.interfaces), 1)
365
        self.assertIn(1, switch.interfaces)
366
        self.assertNotIn(2, switch.interfaces)
367
        mock_event.assert_called()
368
        mock_buffers_put.assert_called()
369
370
        interface = switch.interfaces[1]
371
        self.assertEqual(interface.id, iface_a)
372
        self.assertEqual(interface.switch.id, dpid_a)
373
        self.assertEqual(interface.port_number, 1)
374
        self.assertTrue(interface.is_enabled())
375
        self.assertTrue(interface.lldp)
376
        self.assertTrue(interface.uni)
377
        self.assertFalse(interface.nni)
378
379
    def test_load_switch_attrs(self):
380
        """Test _load_switch."""
381
        dpid_b = "00:00:00:00:00:00:00:02"
382
        iface_b = f'{dpid_b}:1'
383
        switch_attrs = {
384
            "active": True,
385
            "connection": "127.0.0.1:43230",
386
            "data_path": "XX Human readable desc of dp",
387
            "dpid": "00:00:00:00:00:00:00:02",
388
            "enabled": False,
389
            "hardware": "Open vSwitch",
390
            "id": "00:00:00:00:00:00:00:02",
391
            "interfaces": {
392
                "00:00:00:00:00:00:00:02:1": {
393
                    "active": True,
394
                    "enabled": False,
395
                    "id": "00:00:00:00:00:00:00:02:1",
396
                    "link": "",
397
                    "lldp": False,
398
                    "mac": "de:58:c3:30:b7:b7",
399
                    "metadata": {},
400
                    "name": "s2-eth1",
401
                    "nni": False,
402
                    "port_number": 1,
403
                    "speed": 1250000000,
404
                    "switch": "00:00:00:00:00:00:00:02",
405
                    "type": "interface",
406
                    "uni": True
407
                },
408
            },
409
            "manufacturer": "Nicira, Inc.",
410
            "metadata": {},
411
            "name": "00:00:00:00:00:00:00:04",
412
            "ofp_version": "0x04",
413
            "serial": "XX serial number",
414
            "software": "2.10.7",
415
            "type": "switch"
416
        }
417
418
        self.assertEqual(len(self.napp.controller.switches), 0)
419
        self.napp._load_switch(dpid_b, switch_attrs)
420
        self.assertEqual(len(self.napp.controller.switches), 1)
421
        self.assertIn(dpid_b, self.napp.controller.switches)
422
423
        switch = self.napp.controller.switches[dpid_b]
424
        self.assertEqual(switch.id, dpid_b)
425
        self.assertEqual(switch.dpid, dpid_b)
426
        self.assertFalse(switch.is_enabled())
427
        self.assertFalse(switch.is_active())
428
        self.assertEqual(switch.description['manufacturer'], 'Nicira, Inc.')
429
        self.assertEqual(switch.description['hardware'], 'Open vSwitch')
430
        self.assertEqual(switch.description['software'], '2.10.7')
431
        self.assertEqual(switch.description['serial'], 'XX serial number')
432
        self.assertEqual(switch.description['data_path'],
433
                         'XX Human readable desc of dp')
434
435
        self.assertEqual(len(switch.interfaces), 1)
436
        self.assertIn(1, switch.interfaces)
437
        self.assertNotIn(2, switch.interfaces)
438
439
        interface = switch.interfaces[1]
440
        self.assertEqual(interface.id, iface_b)
441
        self.assertEqual(interface.switch.id, dpid_b)
442
        self.assertEqual(interface.port_number, 1)
443
        self.assertFalse(interface.is_enabled())
444
        self.assertFalse(interface.lldp)
445
        self.assertTrue(interface.uni)
446
        self.assertFalse(interface.nni)
447
448
    def test_load_link(self):
449
        """Test _load_link."""
450
        dpid_a = "00:00:00:00:00:00:00:01"
451
        dpid_b = "00:00:00:00:00:00:00:02"
452
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
453
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
454
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
455
        mock_interface_a.id = dpid_a + ':1'
456
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
457
        mock_interface_b.id = dpid_b + ':1'
458
        mock_switch_a.interfaces = {1: mock_interface_a}
459
        mock_switch_b.interfaces = {1: mock_interface_b}
460
        self.napp.controller.switches[dpid_a] = mock_switch_a
461
        self.napp.controller.switches[dpid_b] = mock_switch_b
462
        link_attrs = {
463
            'enabled': True,
464
            'endpoint_a': {
465
                'switch': dpid_a,
466
                'port_number': 1
467
            },
468
            'endpoint_b': {
469
                'switch': dpid_b,
470
                'port_number': 1
471
            }
472
        }
473
474
        self.napp._load_link(link_attrs)
475
476
        self.assertEqual(len(self.napp.links), 1)
477
        link = list(self.napp.links.values())[0]
478
479
        self.assertEqual(link.endpoint_a.id, mock_interface_a.id)
480
        self.assertEqual(link.endpoint_b.id, mock_interface_b.id)
481
        self.assertTrue(mock_interface_a.nni)
482
        self.assertTrue(mock_interface_b.nni)
483
        self.assertEqual(mock_interface_a.update_link.call_count, 1)
484
        self.assertEqual(mock_interface_b.update_link.call_count, 1)
485
486
        # test enable/disable
487
        link_id = '4d42dc08522'
488
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
489
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
490
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
491
        mock_link.id = link_id
492
        with patch('napps.kytos.topology.main.Main._get_link_or_create',
493
                   return_value=(mock_link, True)):
494
            # enable link
495
            link_attrs['enabled'] = True
496
            self.napp.links = {link_id: mock_link}
497
            self.napp._load_link(link_attrs)
498
            self.assertEqual(mock_link.enable.call_count, 1)
499
            # disable link
500
            link_attrs['enabled'] = False
501
            self.napp.links = {link_id: mock_link}
502
            self.napp._load_link(link_attrs)
503
            self.assertEqual(mock_link.disable.call_count, 1)
504
505
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
506
    def test_fail_load_link(self, get_link_or_create_mock):
507
        """Test fail load_link."""
508
        dpid_a = '00:00:00:00:00:00:00:01'
509
        dpid_b = '00:00:00:00:00:00:00:02'
510
        link_id = '4d42dc08522'
511
        mock_switch_a = get_switch_mock(dpid_a)
512
        mock_switch_b = get_switch_mock(dpid_b)
513
        mock_interface_a_1 = get_interface_mock('s1-eth1', 1, mock_switch_a)
514
        mock_interface_b_1 = get_interface_mock('s2-eth1', 1, mock_switch_b)
515
        mock_link = get_link_mock(mock_interface_a_1, mock_interface_b_1)
516
        mock_link.id = link_id
517
        self.napp.links = {link_id: mock_link}
518
        get_link_or_create_mock.return_value = mock_link
519
520
        link_attrs_fail = {
521
            'enabled': True,
522
            'endpoint_a': {
523
                'switch': dpid_a,
524
                'port_number': 999
525
            },
526
            'endpoint_b': {
527
                'switch': dpid_b,
528
                'port_number': 999
529
            }
530
        }
531
        with self.assertRaises(RestoreError):
532
            self.napp._load_link(link_attrs_fail)
533
534
        link_attrs_fail = {
535
            'enabled': True,
536
            'endpoint_a': {
537
                'switch': '00:00:00:00:00:00:00:99',
538
                'port_number': 1
539
            },
540
            'endpoint_b': {
541
                'switch': '00:00:00:00:00:00:00:77',
542
                'port_number': 1
543
            }
544
        }
545
        with self.assertRaises(RestoreError):
546
            self.napp._load_link(link_attrs_fail)
547
548 View Code Duplication
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
549
    def test_enable_switch(self, mock_save_status):
550
        """Test enable_switch."""
551
        dpid = "00:00:00:00:00:00:00:01"
552
        mock_switch = get_switch_mock(dpid)
553
        self.napp.controller.switches = {dpid: mock_switch}
554
        api = get_test_client(self.napp.controller, self.napp)
555
556
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
557
        response = api.post(url)
558
        self.assertEqual(response.status_code, 201, response.data)
559
        self.assertEqual(mock_switch.enable.call_count, 1)
560
        mock_save_status.assert_called()
561
562
        # fail case
563
        mock_switch.enable.call_count = 0
564
        dpid = "00:00:00:00:00:00:00:02"
565
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
566
        response = api.post(url)
567
        self.assertEqual(response.status_code, 404, response.data)
568
        self.assertEqual(mock_switch.enable.call_count, 0)
569
570 View Code Duplication
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
571
    def test_disable_switch(self, mock_save_status):
572
        """Test disable_switch."""
573
        dpid = "00:00:00:00:00:00:00:01"
574
        mock_switch = get_switch_mock(dpid)
575
        self.napp.controller.switches = {dpid: mock_switch}
576
        api = get_test_client(self.napp.controller, self.napp)
577
578
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
579
        response = api.post(url)
580
        self.assertEqual(response.status_code, 201, response.data)
581
        self.assertEqual(mock_switch.disable.call_count, 1)
582
        mock_save_status.assert_called()
583
584
        # fail case
585
        mock_switch.disable.call_count = 0
586
        dpid = "00:00:00:00:00:00:00:02"
587
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
588
        response = api.post(url)
589
        self.assertEqual(response.status_code, 404, response.data)
590
        self.assertEqual(mock_switch.disable.call_count, 0)
591
592
    def test_get_switch_metadata(self):
593
        """Test get_switch_metadata."""
594
        dpid = "00:00:00:00:00:00:00:01"
595
        mock_switch = get_switch_mock(dpid)
596
        mock_switch.metadata = "A"
597
        self.napp.controller.switches = {dpid: mock_switch}
598
        api = get_test_client(self.napp.controller, self.napp)
599
600
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
601
        response = api.get(url)
602
        self.assertEqual(response.status_code, 200, response.data)
603
604
        # fail case
605
        dpid = "00:00:00:00:00:00:00:02"
606
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
607
        response = api.get(url)
608
        self.assertEqual(response.status_code, 404, response.data)
609
610
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
611
    def test_add_switch_metadata(self, mock_metadata_changes):
612
        """Test add_switch_metadata."""
613
        dpid = "00:00:00:00:00:00:00:01"
614
        mock_switch = get_switch_mock(dpid)
615
        self.napp.controller.switches = {dpid: mock_switch}
616
        api = get_test_client(self.napp.controller, self.napp)
617
        payload = {"data": "A"}
618
619
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
620
        response = api.post(url, data=json.dumps(payload),
621
                            content_type='application/json')
622
        self.assertEqual(response.status_code, 201, response.data)
623
        mock_metadata_changes.assert_called()
624
625
        # fail case
626
        dpid = "00:00:00:00:00:00:00:02"
627
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
628
        response = api.post(url, data=json.dumps(payload),
629
                            content_type='application/json')
630
        self.assertEqual(response.status_code, 404, response.data)
631
632
    def test_add_switch_metadata_wrong_format(self):
633
        """Test add_switch_metadata_wrong_format."""
634
        dpid = "00:00:00:00:00:00:00:01"
635
        api = get_test_client(self.napp.controller, self.napp)
636
        payload = 'A'
637
638
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
639
        response = api.post(url, data=payload, content_type='application/json')
640
        self.assertEqual(response.status_code, 400, response.data)
641
642
        payload = None
643
        response = api.post(url, data=json.dumps(payload),
644
                            content_type='application/json')
645
        self.assertEqual(response.status_code, 415, response.data)
646
647
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
648
    def test_delete_switch_metadata(self, mock_metadata_changes):
649
        """Test delete_switch_metadata."""
650
        dpid = "00:00:00:00:00:00:00:01"
651
        mock_switch = get_switch_mock(dpid)
652
        self.napp.controller.switches = {dpid: mock_switch}
653
        api = get_test_client(self.napp.controller, self.napp)
654
655
        key = "A"
656
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
657
        response = api.delete(url)
658
        self.assertEqual(mock_metadata_changes.call_count, 1)
659
        self.assertEqual(response.status_code, 200, response.data)
660
661
        # fail case
662
        key = "A"
663
        dpid = "00:00:00:00:00:00:00:02"
664
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
665
        response = api.delete(url)
666
        self.assertEqual(mock_metadata_changes.call_count, 1)  # remains 1 call
667
        self.assertEqual(response.status_code, 404, response.data)
668
669 View Code Duplication
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
670
    def test_enable_interfaces(self, mock_save_status):
671
        """Test enable_interfaces."""
672
        dpid = '00:00:00:00:00:00:00:01'
673
        mock_switch = get_switch_mock(dpid)
674
        mock_interface_1 = get_interface_mock('s1-eth1', 1, mock_switch)
675
        mock_interface_2 = get_interface_mock('s1-eth2', 2, mock_switch)
676
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
677
        self.napp.controller.switches = {dpid: mock_switch}
678
        api = get_test_client(self.napp.controller, self.napp)
679
680
        interface_id = '00:00:00:00:00:00:00:01:1'
681
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
682
        response = api.post(url)
683
        self.assertEqual(response.status_code, 200, response.data)
684
        self.assertEqual(mock_interface_1.enable.call_count, 1)
685
        self.assertEqual(mock_interface_2.enable.call_count, 0)
686
        mock_save_status.assert_called()
687
688
        mock_interface_1.enable.call_count = 0
689
        mock_interface_2.enable.call_count = 0
690
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
691
        response = api.post(url)
692
        self.assertEqual(response.status_code, 200, response.data)
693
        self.assertEqual(mock_interface_1.enable.call_count, 1)
694
        self.assertEqual(mock_interface_2.enable.call_count, 1)
695
696
        # test interface not found
697
        interface_id = '00:00:00:00:00:00:00:01:3'
698
        mock_interface_1.enable.call_count = 0
699
        mock_interface_2.enable.call_count = 0
700
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
701
        response = api.post(url)
702
        self.assertEqual(response.status_code, 409, response.data)
703
        self.assertEqual(mock_interface_1.enable.call_count, 0)
704
        self.assertEqual(mock_interface_2.enable.call_count, 0)
705
706
        # test switch not found
707
        dpid = '00:00:00:00:00:00:00:02'
708
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
709
        response = api.post(url)
710
        self.assertEqual(response.status_code, 404, response.data)
711
        self.assertEqual(mock_interface_1.enable.call_count, 0)
712
        self.assertEqual(mock_interface_2.enable.call_count, 0)
713
714 View Code Duplication
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
715
    def test_disable_interfaces(self, mock_save_status):
716
        """Test disable_interfaces."""
717
        interface_id = '00:00:00:00:00:00:00:01:1'
718
        dpid = '00:00:00:00:00:00:00:01'
719
        mock_switch = get_switch_mock(dpid)
720
        mock_interface_1 = get_interface_mock('s1-eth1', 1, mock_switch)
721
        mock_interface_2 = get_interface_mock('s1-eth2', 2, mock_switch)
722
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
723
        self.napp.controller.switches = {dpid: mock_switch}
724
        api = get_test_client(self.napp.controller, self.napp)
725
726
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
727
        response = api.post(url)
728
        self.assertEqual(response.status_code, 200, response.data)
729
        self.assertEqual(mock_interface_1.disable.call_count, 1)
730
        self.assertEqual(mock_interface_2.disable.call_count, 0)
731
        mock_save_status.assert_called()
732
733
        mock_interface_1.disable.call_count = 0
734
        mock_interface_2.disable.call_count = 0
735
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
736
        response = api.post(url)
737
        self.assertEqual(response.status_code, 200, response.data)
738
        self.assertEqual(mock_interface_1.disable.call_count, 1)
739
        self.assertEqual(mock_interface_2.disable.call_count, 1)
740
741
        # test interface not found
742
        interface_id = '00:00:00:00:00:00:00:01:3'
743
        mock_interface_1.disable.call_count = 0
744
        mock_interface_2.disable.call_count = 0
745
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
746
        response = api.post(url)
747
        self.assertEqual(response.status_code, 409, response.data)
748
        self.assertEqual(mock_interface_1.disable.call_count, 0)
749
        self.assertEqual(mock_interface_2.disable.call_count, 0)
750
751
        # test switch not found
752
        dpid = '00:00:00:00:00:00:00:02'
753
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
754
        response = api.post(url)
755
        self.assertEqual(response.status_code, 404, response.data)
756
        self.assertEqual(mock_interface_1.disable.call_count, 0)
757
        self.assertEqual(mock_interface_2.disable.call_count, 0)
758
759
    def test_get_interface_metadata(self):
760
        """Test get_interface_metada."""
761
        interface_id = '00:00:00:00:00:00:00:01:1'
762
        dpid = '00:00:00:00:00:00:00:01'
763
        mock_switch = get_switch_mock(dpid)
764
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
765
        mock_interface.metadata = {"metada": "A"}
766
        mock_switch.interfaces = {1: mock_interface}
767
        self.napp.controller.switches = {dpid: mock_switch}
768
        api = get_test_client(self.napp.controller, self.napp)
769
770
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
771
        response = api.get(url)
772
        self.assertEqual(response.status_code, 200, response.data)
773
774
        # fail case switch not found
775
        interface_id = '00:00:00:00:00:00:00:02:1'
776
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
777
        response = api.get(url)
778
        self.assertEqual(response.status_code, 404, response.data)
779
780
        # fail case interface not found
781
        interface_id = '00:00:00:00:00:00:00:01:2'
782
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
783
        response = api.get(url)
784
        self.assertEqual(response.status_code, 404, response.data)
785
786
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
787
    def test_add_interface_metadata(self, mock_metadata_changes):
788
        """Test add_interface_metadata."""
789
        interface_id = '00:00:00:00:00:00:00:01:1'
790
        dpid = '00:00:00:00:00:00:00:01'
791
        mock_switch = get_switch_mock(dpid)
792
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
793
        mock_interface.metadata = {"metada": "A"}
794
        mock_switch.interfaces = {1: mock_interface}
795
        self.napp.controller.switches = {dpid: mock_switch}
796
        api = get_test_client(self.napp.controller, self.napp)
797
798
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
799
        payload = {"metada": "A"}
800
        response = api.post(url, data=json.dumps(payload),
801
                            content_type='application/json')
802
        self.assertEqual(response.status_code, 201, response.data)
803
        mock_metadata_changes.assert_called()
804
805
        # fail case switch not found
806
        interface_id = '00:00:00:00:00:00:00:02:1'
807
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
808
        response = api.post(url, data=json.dumps(payload),
809
                            content_type='application/json')
810
        self.assertEqual(response.status_code, 404, response.data)
811
812
        # fail case interface not found
813
        interface_id = '00:00:00:00:00:00:00:01:2'
814
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
815
        response = api.post(url, data=json.dumps(payload),
816
                            content_type='application/json')
817
        self.assertEqual(response.status_code, 404, response.data)
818
819
    def test_add_interface_metadata_wrong_format(self):
820
        """Test add_interface_metadata_wrong_format."""
821
        dpid = "00:00:00:00:00:00:00:01:1"
822
        api = get_test_client(self.napp.controller, self.napp)
823
        payload = 'A'
824
825
        url = f'{self.server_name_url}/v3/interfaces/{dpid}/metadata'
826
        response = api.post(url, data=payload, content_type='application/json')
827
        self.assertEqual(response.status_code, 400, response.data)
828
829
        payload = None
830
        response = api.post(url, data=json.dumps(payload),
831
                            content_type='application/json')
832
        self.assertEqual(response.status_code, 415, response.data)
833
834
    def test_delete_interface_metadata(self):
835
        """Test delete_interface_metadata."""
836
        interface_id = '00:00:00:00:00:00:00:01:1'
837
        dpid = '00:00:00:00:00:00:00:01'
838
        iface_url = '/v3/interfaces/'
839
        mock_switch = get_switch_mock(dpid)
840
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
841
        mock_interface.remove_metadata.side_effect = [True, False]
842
        mock_interface.metadata = {"metada": "A"}
843
        mock_switch.interfaces = {1: mock_interface}
844
        self.napp.store_items = {'interfaces': MagicMock()}
845
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
846
                                         mock_switch}
847
        api = get_test_client(self.napp.controller, self.napp)
848
849
        key = 'A'
850
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
851
        response = api.delete(url)
852
        self.assertEqual(response.status_code, 200, response.data)
853
854
        # fail case switch not found
855
        key = 'A'
856
        interface_id = '00:00:00:00:00:00:00:02:1'
857
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
858
        response = api.delete(url)
859
        self.assertEqual(response.status_code, 404, response.data)
860
861
        # fail case interface not found
862
        key = 'A'
863
        interface_id = '00:00:00:00:00:00:00:01:2'
864
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
865
        response = api.delete(url)
866
        self.assertEqual(response.status_code, 404, response.data)
867
868
        # fail case metadata not found
869
        key = 'A'
870
        interface_id = '00:00:00:00:00:00:00:01:1'
871
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
872
        response = api.delete(url)
873
        self.assertEqual(response.status_code, 404, response.data)
874
875
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
876
    def test_enable_link(self, mock_save_status):
877
        """Test enable_link."""
878
        mock_link = MagicMock(Link)
879
        self.napp.links = {'1': mock_link}
880
        api = get_test_client(self.napp.controller, self.napp)
881
        mock_save_status.return_value = True
882
883
        link_id = 1
884
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
885
        response = api.post(url)
886
        self.assertEqual(response.status_code, 201, response.data)
887
        self.assertEqual(mock_link.enable.call_count, 1)
888
889
        # fail case
890
        link_id = 2
891
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
892
        response = api.post(url)
893
        self.assertEqual(response.status_code, 404, response.data)
894
895
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
896
    def test_disable_link(self, mock_save_status):
897
        """Test disable_link."""
898
        mock_link = MagicMock(Link)
899
        self.napp.links = {'1': mock_link}
900
        api = get_test_client(self.napp.controller, self.napp)
901
        mock_save_status.return_value = True
902
903
        link_id = 1
904
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
905
        response = api.post(url)
906
        self.assertEqual(response.status_code, 201, response.data)
907
        self.assertEqual(mock_link.disable.call_count, 1)
908
909
        # fail case
910
        link_id = 2
911
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
912
        response = api.post(url)
913
        self.assertEqual(response.status_code, 404, response.data)
914
915
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
916
    def test_handle_network_status_updated(self, mock_save_status):
917
        """Test handle_link_maintenance_start."""
918
        self.napp.handle_network_status_updated()
919
        mock_save_status.assert_called_once()
920
921
    def test_get_link_metadata(self):
922
        """Test get_link_metadata."""
923
        mock_link = MagicMock(Link)
924
        mock_link.metadata = "A"
925
        self.napp.links = {'1': mock_link}
926
        msg_success = {"metadata": "A"}
927
        api = get_test_client(self.napp.controller, self.napp)
928
929
        link_id = 1
930
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
931
        response = api.get(url)
932
        self.assertEqual(response.status_code, 200, response.data)
933
        self.assertEqual(msg_success, json.loads(response.data))
934
935
        # fail case
936
        link_id = 2
937
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
938
        response = api.get(url)
939
        self.assertEqual(response.status_code, 404, response.data)
940
941
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
942
    def test_add_link_metadata(self, mock_metadata_changes):
943
        """Test add_link_metadata."""
944
        mock_link = MagicMock(Link)
945
        mock_link.metadata = "A"
946
        self.napp.links = {'1': mock_link}
947
        payload = {"metadata": "A"}
948
        api = get_test_client(self.napp.controller, self.napp)
949
950
        link_id = 1
951
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
952
        response = api.post(url, data=json.dumps(payload),
953
                            content_type='application/json')
954
        self.assertEqual(response.status_code, 201, response.data)
955
        mock_metadata_changes.assert_called()
956
957
        # fail case
958
        link_id = 2
959
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
960
        response = api.post(url, data=json.dumps(payload),
961
                            content_type='application/json')
962
        self.assertEqual(response.status_code, 404, response.data)
963
964
    def test_add_link_metadata_wrong_format(self):
965
        """Test add_link_metadata_wrong_format."""
966
        link_id = 'cf0f4071be426b3f745027f5d22'
967
        api = get_test_client(self.napp.controller, self.napp)
968
        payload = "A"
969
970
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
971
        response = api.post(url, data=payload,
972
                            content_type='application/json')
973
        self.assertEqual(response.status_code, 400, response.data)
974
975
        payload = None
976
        response = api.post(url, data=json.dumps(payload),
977
                            content_type='application/json')
978
        self.assertEqual(response.status_code, 415, response.data)
979
980
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
981
    def test_delete_link_metadata(self, mock_metadata_changes):
982
        """Test delete_link_metadata."""
983
        mock_link = MagicMock(Link)
984
        mock_link.metadata = "A"
985
        mock_link.remove_metadata.side_effect = [True, False]
986
        self.napp.links = {'1': mock_link}
987
        api = get_test_client(self.napp.controller, self.napp)
988
989
        link_id = 1
990
        key = 'A'
991
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
992
        response = api.delete(url)
993
        self.assertEqual(response.status_code, 200, response.data)
994
        mock_metadata_changes.assert_called()
995
996
        # fail case link not found
997
        link_id = 2
998
        key = 'A'
999
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
1000
        response = api.delete(url)
1001
        self.assertEqual(response.status_code, 404, response.data)
1002
1003
        # fail case metadata not found
1004
        link_id = 1
1005
        key = 'A'
1006
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
1007
        response = api.delete(url)
1008
        self.assertEqual(response.status_code, 404, response.data)
1009
1010
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1011
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
1012
    def test_handle_new_switch(self, *args):
1013
        """Test handle_new_switch."""
1014
        (mock_instance_metadata, mock_notify_topology_update) = args
1015
        mock_event = MagicMock()
1016
        mock_switch = create_autospec(Switch)
1017
        mock_event.content['switch'] = mock_switch
1018
        self.napp.handle_new_switch(mock_event)
1019
        mock_notify_topology_update.assert_called()
1020
        mock_instance_metadata.assert_called()
1021
1022
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1023
    def test_handle_connection_lost(self, mock_notify_topology_update):
1024
        """Test handle connection_lost."""
1025
        mock_event = MagicMock()
1026
        mock_switch = create_autospec(Switch)
1027
        mock_switch.return_value = True
1028
        mock_event.content['source'] = mock_switch
1029
        self.napp.handle_connection_lost(mock_event)
1030
        mock_notify_topology_update.assert_called()
1031
1032
    @patch('napps.kytos.topology.main.Main.handle_interface_link_up')
1033
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1034
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
1035
    def test_handle_interface_created(self, *args):
1036
        """Test handle_interface_created."""
1037
        (mock_metadata, mock_notify, mock_link_up) = args
1038
        mock_event = MagicMock()
1039
        mock_interface = create_autospec(Interface)
1040
        mock_event.content['interface'] = mock_interface
1041
        self.napp.handle_interface_created(mock_event)
1042
        mock_notify.assert_called()
1043
        mock_metadata.assert_called()
1044
        mock_link_up.assert_called()
1045
1046
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1047
    @patch('napps.kytos.topology.main.Main.handle_interface_link_down')
1048
    def test_handle_interface_down(self, *args):
1049
        """Test handle interface down."""
1050
        (mock_handle_interface_link_down, mock_notify_topology_update) = args
1051
        mock_event = MagicMock()
1052
        mock_interface = create_autospec(Interface)
1053
        mock_event.content['interface'] = mock_interface
1054
        self.napp.handle_interface_down(mock_event)
1055
        mock_handle_interface_link_down.assert_called()
1056
        mock_notify_topology_update.assert_called()
1057
1058
    @patch('napps.kytos.topology.main.Main.handle_interface_down')
1059
    def test_interface_deleted(self, mock_handle_interface_link_down):
1060
        """Test interface deleted."""
1061
        mock_event = MagicMock()
1062
        self.napp.handle_interface_deleted(mock_event)
1063
        mock_handle_interface_link_down.assert_called()
1064
1065
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1066
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1067
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
1068
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1069
    def test_interface_link_up(self, *args):
1070
        """Test interface link_up."""
1071
        (mock_status_change, mock_instance_metadata, mock_topology_update,
1072
         mock_link_from_interface) = args
1073
1074
        now = time.time()
1075
        mock_interface_a = create_autospec(Interface)
1076
        mock_interface_a.is_active.return_value = False
1077
        mock_interface_b = create_autospec(Interface)
1078
        mock_interface_b.is_active.return_value = True
1079
        mock_link = create_autospec(Link)
1080
        mock_link.get_metadata.return_value = now
1081
        mock_link.is_active.side_effect = [False, True]
1082
        mock_link.endpoint_a = mock_interface_a
1083
        mock_link.endpoint_b = mock_interface_b
1084
        mock_link_from_interface.return_value = mock_link
1085
        self.napp.link_up_timer = 1
1086
        self.napp.handle_interface_link_up(mock_interface_a)
1087
        mock_topology_update.assert_called()
1088
        mock_instance_metadata.assert_called()
1089
        mock_status_change.assert_called()
1090
1091
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1092
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1093
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1094
    def test_interface_link_down(self, *args):
1095
        """Test interface link down."""
1096
        (mock_status_change, mock_topology_update,
1097
         mock_link_from_interface) = args
1098
1099
        mock_event = MagicMock()
1100
        mock_interface = create_autospec(Interface)
1101
        mock_link = create_autospec(Link)
1102
        mock_link.is_active.return_value = True
1103
        mock_link_from_interface.return_value = mock_link
1104
        mock_event.content['interface'] = mock_interface
1105
        self.napp.handle_interface_link_down(mock_event)
1106
        mock_topology_update.assert_called()
1107
        mock_status_change.assert_called()
1108
1109
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1110
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1111
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1112
    def test_handle_link_down(self, *args):
1113
        """Test interface link down."""
1114
        (mock_status_change, mock_topology_update,
1115
         mock_link_from_interface) = args
1116
1117
        mock_interface = create_autospec(Interface)
1118
        mock_link = create_autospec(Link)
1119
        mock_link.is_active.return_value = True
1120
        mock_link_from_interface.return_value = mock_link
1121
        self.napp.handle_link_down(mock_interface)
1122
        mock_interface.deactivate.assert_called()
1123
        mock_link.deactivate.assert_called()
1124
        mock_topology_update.assert_called()
1125
        mock_status_change.assert_called()
1126
1127
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1128
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1129
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1130
    def test_handle_link_up(self, *args):
1131
        """Test handle link up."""
1132
        (mock_status_change, mock_topology_update,
1133
         mock_link_from_interface) = args
1134
1135
        mock_interface = create_autospec(Interface)
1136
        mock_link = MagicMock()
1137
        mock_link.is_active.return_value = True
1138
        mock_link_from_interface.return_value = mock_link
1139
        self.napp.handle_link_up(mock_interface)
1140
        mock_interface.activate.assert_called()
1141
        mock_topology_update.assert_called()
1142
        mock_status_change.assert_called()
1143
1144
    @patch('time.sleep')
1145
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
1146
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1147
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1148
    def test_handle_link_up_intf_down(self, *args):
1149
        """Test handle link up but one intf down."""
1150
        (mock_status_change, mock_topology_update,
1151
         mock_link_from_interface, _) = args
1152
1153
        mock_interface = create_autospec(Interface)
1154
        mock_link = MagicMock()
1155
        mock_link.endpoint_a.is_active.return_value = False
1156
        mock_link.is_active.return_value = False
1157
        mock_link_from_interface.return_value = mock_link
1158
        self.napp.handle_link_up(mock_interface)
1159
        mock_interface.activate.assert_called()
1160
1161
        mock_topology_update.assert_not_called()
1162
        mock_status_change.assert_not_called()
1163
1164
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
1165
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
1166
    def test_add_links(self, *args):
1167
        """Test add_links."""
1168
        (mock_notify_topology_update, mock_get_link_or_create) = args
1169
        mock_link = MagicMock()
1170
        mock_get_link_or_create.return_value = (mock_link, True)
1171
        mock_event = MagicMock()
1172
        mock_intf_a = MagicMock()
1173
        mock_intf_b = MagicMock()
1174
        mock_event.content = {"interface_a": mock_intf_a,
1175
                              "interface_b": mock_intf_b}
1176
        self.napp.add_links(mock_event)
1177
        mock_get_link_or_create.assert_called()
1178
        mock_notify_topology_update.assert_called()
1179
        mock_intf_a.update_link.assert_called()
1180
        mock_intf_b.update_link.assert_called()
1181
        mock_link.endpoint_a = mock_intf_a
1182
        mock_link.endpoint_b = mock_intf_b
1183
1184
    @patch('napps.kytos.topology.main.Main._get_switches_dict')
1185
    @patch('napps.kytos.topology.main.StoreHouse.save_status')
1186
    def test_save_status_on_store(self, *args):
1187
        """Test save_status_on_storehouse."""
1188
        (mock_save_status, mock_get_switches_dict) = args
1189
        self.napp.save_status_on_storehouse()
1190
        mock_get_switches_dict.assert_called()
1191
        mock_save_status.assert_called()
1192
1193
    @patch('napps.kytos.topology.main.KytosEvent')
1194
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1195
    def test_notify_switch_enabled(self, *args):
1196
        """Test notify switch enabled."""
1197
        dpid = "00:00:00:00:00:00:00:01"
1198
        (mock_buffers_put, mock_event) = args
1199
        self.napp.notify_switch_enabled(dpid)
1200
        mock_event.assert_called()
1201
        mock_buffers_put.assert_called()
1202
1203
    @patch('napps.kytos.topology.main.KytosEvent')
1204
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1205
    def test_notify_switch_disabled(self, *args):
1206
        """Test notify switch disabled."""
1207
        dpid = "00:00:00:00:00:00:00:01"
1208
        (mock_buffers_put, mock_event) = args
1209
        self.napp.notify_switch_disabled(dpid)
1210
        mock_event.assert_called()
1211
        mock_buffers_put.assert_called()
1212
1213
    @patch('napps.kytos.topology.main.KytosEvent')
1214
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1215
    def test_notify_topology_update(self, *args):
1216
        """Test notify_topology_update."""
1217
        (mock_buffers_put, mock_event) = args
1218
        self.napp.notify_topology_update()
1219
        mock_event.assert_called()
1220
        mock_buffers_put.assert_called()
1221
1222
    @patch('napps.kytos.topology.main.KytosEvent')
1223
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1224
    def test_notify_link_status_change(self, *args):
1225
        """Test notify link status change."""
1226
        (mock_buffers_put, mock_event) = args
1227
        mock_link = create_autospec(Link)
1228
        self.napp.notify_link_status_change(mock_link)
1229
        mock_event.assert_called()
1230
        mock_buffers_put.assert_called()
1231
1232
    @patch('napps.kytos.topology.main.KytosEvent')
1233
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1234
    @patch('napps.kytos.topology.main.Main.save_metadata_on_store')
1235
    def test_notify_metadata_changes(self, *args):
1236
        """Test notify metadata changes."""
1237
        (mock_save_metadata, mock_buffers_put, mock_event) = args
1238
        count = 0
1239
        for spec in [Switch, Interface, Link]:
1240
            mock_obj = create_autospec(spec)
1241
            mock_obj.metadata = "A"
1242
            self.napp.notify_metadata_changes(mock_obj, 'added')
1243
            self.assertEqual(mock_save_metadata.call_count, count+1)
1244
            self.assertEqual(mock_event.call_count, count+1)
1245
            self.assertEqual(mock_buffers_put.call_count, count+1)
1246
            count += 1
1247
        with self.assertRaises(ValueError):
1248
            self.napp.notify_metadata_changes(MagicMock(), 'added')
1249
1250
    @patch('napps.kytos.topology.main.KytosEvent')
1251
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1252
    def test_notify_port_created(self, *args):
1253
        """Test notify port created."""
1254
        (mock_buffers_put, mock_kytos_event) = args
1255
        mock_event = MagicMock()
1256
        self.napp.notify_port_created(mock_event)
1257
        mock_kytos_event.assert_called()
1258
        mock_buffers_put.assert_called()
1259
1260
    @patch('napps.kytos.topology.main.KytosEvent')
1261
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1262
    def test_save_metadata_on_store(self, *args):
1263
        """Test test_save_metadata_on_store."""
1264
        (mock_buffers_put, mock_kytos_event) = args
1265
        mock_store = MagicMock()
1266
        mock_switch = MagicMock(spec=Switch)
1267
        mock_switch.metadata = "A"
1268
        mock_interface = MagicMock(spec=Interface)
1269
        mock_interface.metadata = "A"
1270
        mock_link = MagicMock(spec=Link)
1271
        mock_link.metadata = "A"
1272
        self.napp.store_items = {'switches': mock_store,
1273
                                 'interfaces': mock_store,
1274
                                 'links': mock_store}
1275
        # test switches
1276
        self.napp.save_metadata_on_store(mock_switch, 'switches')
1277
        mock_kytos_event.assert_called()
1278
        mock_buffers_put.assert_called()
1279
1280
        # test interfaces
1281
        self.napp.save_metadata_on_store(mock_interface, 'interfaces')
1282
        mock_kytos_event.assert_called()
1283
        mock_buffers_put.assert_called()
1284
1285
        # test link
1286
        self.napp.save_metadata_on_store(mock_link, 'links')
1287
        mock_kytos_event.assert_called()
1288
        mock_buffers_put.assert_called()
1289
1290
    @patch('napps.kytos.topology.main.KytosEvent')
1291
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1292
    def test_verify_storehouse(self, *args):
1293
        """Test verify_storehouse."""
1294
        (mock_buffers_put, mock_kytos_event) = args
1295
        mock_entities = MagicMock()
1296
        self.napp.verify_storehouse(mock_entities)
1297
        mock_buffers_put.assert_called()
1298
        mock_kytos_event.assert_called()
1299
1300
    @patch('napps.kytos.topology.main.KytosEvent')
1301
    @patch('kytos.core.buffers.KytosEventBuffer.put')
1302
    def test_request_retrieve_entities(self, *args):
1303
        """Test retrive_entities."""
1304
        (mock_buffers_put, mock_kytos_event) = args
1305
        mock_event = MagicMock()
1306
        mock_data = MagicMock()
1307
        mock_error = MagicMock()
1308
        mock_event.content = {"namespace": "test_box"}
1309
        self.napp.request_retrieve_entities(mock_event, mock_data, mock_error)
1310
        mock_kytos_event.assert_called()
1311
        mock_buffers_put.assert_called()
1312
1313
        self.napp.request_retrieve_entities(mock_event, None, mock_error)
1314
        mock_kytos_event.assert_called()
1315
        mock_buffers_put.assert_called()
1316
1317
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1318
    def test_handle_link_maintenance_start(self, status_change_mock):
1319
        """Test handle_link_maintenance_start."""
1320
        link1 = MagicMock()
1321
        link1.id = 2
1322
        link2 = MagicMock()
1323
        link2.id = 3
1324
        link3 = MagicMock()
1325
        link3.id = 4
1326
        content = {'links': [link1, link2]}
1327
        event = MagicMock()
1328
        event.content = content
1329
        self.napp.links = {2: link1, 4: link3}
1330
        self.napp.handle_link_maintenance_start(event)
1331
        status_change_mock.assert_called_once_with(link1, reason='maintenance')
1332
1333
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
1334
    def test_handle_link_maintenance_end(self, status_change_mock):
1335
        """Test handle_link_maintenance_end."""
1336
        link1 = MagicMock()
1337
        link1.id = 2
1338
        link2 = MagicMock()
1339
        link2.id = 3
1340
        link3 = MagicMock()
1341
        link3.id = 4
1342
        content = {'links': [link1, link2]}
1343
        event = MagicMock()
1344
        event.content = content
1345
        self.napp.links = {2: link1, 4: link3}
1346
        self.napp.handle_link_maintenance_end(event)
1347
        status_change_mock.assert_called_once_with(link1, reason='maintenance')
1348
1349 View Code Duplication
    @patch('napps.kytos.topology.main.Main.handle_link_down')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1350
    def test_handle_switch_maintenance_start(self, handle_link_down_mock):
1351
        """Test handle_switch_maintenance_start."""
1352
        switch1 = MagicMock()
1353
        interface1 = MagicMock()
1354
        interface1.is_active.return_value = True
1355
        interface2 = MagicMock()
1356
        interface2.is_active.return_value = False
1357
        interface3 = MagicMock()
1358
        interface3.is_active.return_value = True
1359
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
1360
        switch2 = MagicMock()
1361
        interface4 = MagicMock()
1362
        interface4.is_active.return_value = False
1363
        interface5 = MagicMock()
1364
        interface5.is_active.return_value = True
1365
        switch2.interfaces = {1: interface4, 2: interface5}
1366
        content = {'switches': [switch1, switch2]}
1367
        event = MagicMock()
1368
        event.content = content
1369
        self.napp.handle_switch_maintenance_start(event)
1370
        self.assertEqual(handle_link_down_mock.call_count, 3)
1371
1372 View Code Duplication
    @patch('napps.kytos.topology.main.Main.handle_link_up')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1373
    def test_handle_switch_maintenance_end(self, handle_link_up_mock):
1374
        """Test handle_switch_maintenance_end."""
1375
        switch1 = MagicMock()
1376
        interface1 = MagicMock()
1377
        interface1.is_active.return_value = True
1378
        interface2 = MagicMock()
1379
        interface2.is_active.return_value = False
1380
        interface3 = MagicMock()
1381
        interface3.is_active.return_value = True
1382
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
1383
        switch2 = MagicMock()
1384
        interface4 = MagicMock()
1385
        interface4.is_active.return_value = False
1386
        interface5 = MagicMock()
1387
        interface5.is_active.return_value = True
1388
        switch2.interfaces = {1: interface4, 2: interface5}
1389
        content = {'switches': [switch1, switch2]}
1390
        event = MagicMock()
1391
        event.content = content
1392
        self.napp.handle_switch_maintenance_end(event)
1393
        self.assertEqual(handle_link_up_mock.call_count, 5)
1394