Completed
Pull Request — master (#108)
by
unknown
02:07
created

TestMain.test_handle_switch_maintenance_start()   A

Complexity

Conditions 1

Size

Total Lines 22
Code Lines 21

Duplication

Lines 22
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 21
nop 2
dl 22
loc 22
rs 9.376
c 0
b 0
f 0
1
"""Module to test the main napp file."""
2
import time
3
import json
4
5
from unittest import TestCase
6
from unittest.mock import MagicMock, create_autospec, patch
7
8
from kytos.core.switch import Switch
9
from kytos.core.interface import Interface
10
from kytos.core.link import Link
11
from kytos.lib.helpers import get_switch_mock, get_test_client
12
13
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
    # pylint: disable=too-many-public-methods
21
22
    def setUp(self):
23
        """Execute steps before each tests.
24
25
        Set the server_name_url_url from kytos/topology
26
        """
27
        self.server_name_url = 'http://localhost:8181/api/kytos/topology'
28
29
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
30
        from napps.kytos.topology.main import Main
31
        self.addCleanup(patch.stopall)
32
33
        self.napp = Main(get_controller_mock())
34
35
    def test_get_event_listeners(self):
36
        """Verify all event listeners registered."""
37
        expected_events = ['kytos/core.shutdown',
38
                           'kytos/core.shutdown.kytos/topology',
39
                           'kytos/maintenance.start_link',
40
                           'kytos/maintenance.end_link',
41
                           'kytos/maintenance.start_switch',
42
                           'kytos/maintenance.end_switch',
43
                           '.*.interface.is.nni',
44
                           '.*.connection.lost',
45
                           '.*.switch.interface.created',
46
                           '.*.switch.interface.deleted',
47
                           '.*.switch.interface.link_down',
48
                           '.*.switch.interface.link_up',
49
                           '.*.switch.(new|reconnected)',
50
                           '.*.switch.port.created',
51
                           'kytos/topology.*.metadata.*']
52
        actual_events = self.napp.listeners()
53
        self.assertCountEqual(expected_events, actual_events)
54
55 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...
56
        """Verify all APIs registered."""
57
        expected_urls = [
58
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/interfaces'),
59
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/switches'),
60
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/restore'),
61
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/links'),
62
         ({}, {'GET', 'OPTIONS', 'HEAD'}, '/api/kytos/topology/v3/'),
63
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
64
          '/api/kytos/topology/v3/interfaces/switch/<dpid>/disable'),
65
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
66
          '/api/kytos/topology/v3/interfaces/switch/<dpid>/enable'),
67
         ({'key': '[key]', 'interface_id': '[interface_id]'},
68
          {'OPTIONS', 'DELETE'},
69
          '/api/kytos/topology/v3/interfaces/<interface_id>/metadata/<key>'),
70
         ({'interface_id': '[interface_id]'}, {'POST', 'OPTIONS'},
71
          '/api/kytos/topology/v3/interfaces/<interface_id>/metadata'),
72
         ({'interface_id': '[interface_id]'}, {'GET', 'OPTIONS', 'HEAD'},
73
          '/api/kytos/topology/v3/interfaces/<interface_id>/metadata'),
74
         ({'interface_disable_id': '[interface_disable_id]'},
75
          {'POST', 'OPTIONS'},
76
          '/api/kytos/topology/v3/interfaces/<interface_disable_id>/disable'),
77
         ({'interface_enable_id': '[interface_enable_id]'},
78
          {'POST', 'OPTIONS'},
79
          '/api/kytos/topology/v3/interfaces/<interface_enable_id>/enable'),
80
         ({'dpid': '[dpid]', 'key': '[key]'}, {'OPTIONS', 'DELETE'},
81
          '/api/kytos/topology/v3/switches/<dpid>/metadata/<key>'),
82
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
83
          '/api/kytos/topology/v3/switches/<dpid>/metadata'),
84
         ({'dpid': '[dpid]'}, {'GET', 'OPTIONS', 'HEAD'},
85
          '/api/kytos/topology/v3/switches/<dpid>/metadata'),
86
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
87
          '/api/kytos/topology/v3/switches/<dpid>/disable'),
88
         ({'dpid': '[dpid]'}, {'POST', 'OPTIONS'},
89
          '/api/kytos/topology/v3/switches/<dpid>/enable'),
90
         ({'link_id': '[link_id]', 'key': '[key]'}, {'OPTIONS', 'DELETE'},
91
          '/api/kytos/topology/v3/links/<link_id>/metadata/<key>'),
92
         ({'link_id': '[link_id]'}, {'POST', 'OPTIONS'},
93
          '/api/kytos/topology/v3/links/<link_id>/metadata'),
94
         ({'link_id': '[link_id]'}, {'GET', 'OPTIONS', 'HEAD'},
95
          '/api/kytos/topology/v3/links/<link_id>/metadata'),
96
         ({'link_id': '[link_id]'}, {'POST', 'OPTIONS'},
97
          '/api/kytos/topology/v3/links/<link_id>/disable'),
98
         ({'link_id': '[link_id]'}, {'POST', 'OPTIONS'},
99
          '/api/kytos/topology/v3/links/<link_id>/enable')]
100
101
        urls = get_napp_urls(self.napp)
102
        self.assertEqual(expected_urls, urls)
103
104
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
105
    def test_restore_network_status(self, mock_storehouse):
106
        """Test restore_network_status."""
107
        mock_switch = get_switch_mock('00:00:00:00:00:00:00:01')
108
        mock_interface = create_autospec(Interface)
109
        mock_switch.interfaces = {1: mock_interface}
110
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
111
                                         mock_switch}
112
        msg_expected = 'There is no status saved to restore.'
113
        msg_success = 'Administrative status restored.'
114
        status = {
115
            0: {
116
                'id': 'network.status',
117
                'switches': {
118
                    '00:00:00:00:00:00:00:01': {
119
                        'dpid': '00:00:00:00:00:00:00:01',
120
                        'enabled': True,
121
                        'id': '00:00:00:00:00:00:00:01',
122
                        'interfaces': {
123
                            '00:00:00:00:00:00:00:01:1': {
124
                                'enabled': True,
125
                                'id': '00:00:00:00:00:00:00:01:1',
126
                            }
127
                        }
128
                    }
129
                }
130
            }
131
        }
132
        status_disable = {
133
            0: {
134
                'id': 'network.status',
135
                'switches': {
136
                    '00:00:00:00:00:00:00:01': {
137
                        'dpid': '00:00:00:00:00:00:00:01',
138
                        'enabled': False,
139
                        'id': '00:00:00:00:00:00:00:01',
140
                        'interfaces': {
141
                            '00:00:00:00:00:00:00:01:1': {
142
                                'enabled': False,
143
                                'id': '00:00:00:00:00:00:00:01:1',
144
                            }
145
                        }
146
                    }
147
                }
148
            }
149
        }
150
151
        api = get_test_client(self.napp.controller, self.napp)
152
        mock_storehouse.side_effect = [None, status, status_disable]
153
154
        # fail case
155
        url = f'{self.server_name_url}/v3/restore'
156
        response = api.get(url)
157
        self.assertEqual(response.status_code, 404, response.data)
158
        self.assertEqual(msg_expected, json.loads(response.data))
159
160
        # enable
161
        url = f'{self.server_name_url}/v3/restore'
162
        response = api.get(url)
163
        self.assertEqual(response.status_code, 200, response.data)
164
        self.assertEqual(msg_success, json.loads(response.data))
165
        self.assertEqual(mock_switch.enable.call_count, 1)
166
        self.assertEqual(mock_interface.enable.call_count, 1)
167
168
        # disable
169
        url = f'{self.server_name_url}/v3/restore'
170
        response = api.get(url)
171
        self.assertEqual(response.status_code, 200, response.data)
172
        self.assertEqual(msg_success, json.loads(response.data))
173
        self.assertEqual(mock_switch.disable.call_count, 1)
174
        self.assertEqual(mock_interface.disable.call_count, 1)
175
176 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...
177
    def test_enable_switch(self, mock_save_status):
178
        """Test enable_swicth."""
179
        dpid = "00:00:00:00:00:00:00:01"
180
        mock_switch = get_switch_mock(dpid)
181
        msg_success = "Operation successful"
182
        msg_fail = "Switch not found"
183
        self.napp.controller.switches = {"00:00:00:00:00:00:00:01":
184
                                         mock_switch}
185
        api = get_test_client(self.napp.controller, self.napp)
186
187
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
188
        response = api.post(url)
189
        self.assertEqual(response.status_code, 201, response.data)
190
        self.assertEqual(msg_success, json.loads(response.data))
191
        self.assertEqual(mock_switch.enable.call_count, 1)
192
        mock_save_status.assert_called()
193
194
        # fail case
195
        mock_switch.enable.call_count = 0
196
        dpid = "00:00:00:00:00:00:00:02"
197
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
198
        response = api.post(url)
199
        self.assertEqual(response.status_code, 404, response.data)
200
        self.assertEqual(msg_fail, json.loads(response.data))
201
        self.assertEqual(mock_switch.enable.call_count, 0)
202
203 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...
204
    def test_disable_switch(self, mock_save_status):
205
        """Test disable_swicth."""
206
        dpid = "00:00:00:00:00:00:00:01"
207
        mock_switch = get_switch_mock(dpid)
208
        msg_success = "Operation successful"
209
        msg_fail = "Switch not found"
210
        self.napp.controller.switches = {dpid: mock_switch}
211
        api = get_test_client(self.napp.controller, self.napp)
212
213
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
214
        response = api.post(url)
215
        self.assertEqual(response.status_code, 201, response.data)
216
        self.assertEqual(msg_success, json.loads(response.data))
217
        self.assertEqual(mock_switch.disable.call_count, 1)
218
        mock_save_status.assert_called()
219
220
        # fail case
221
        mock_switch.disable.call_count = 0
222
        dpid = "00:00:00:00:00:00:00:02"
223
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
224
        response = api.post(url)
225
        self.assertEqual(response.status_code, 404, response.data)
226
        self.assertEqual(msg_fail, json.loads(response.data))
227
        self.assertEqual(mock_switch.disable.call_count, 0)
228
229
    def test_get_switch_metadata(self):
230
        """Test get_switch_metadata."""
231
        dpid = "00:00:00:00:00:00:00:01"
232
        mock_switch = get_switch_mock(dpid)
233
        mock_switch.metadata = "A"
234
        self.napp.controller.switches = {dpid: mock_switch}
235
        api = get_test_client(self.napp.controller, self.napp)
236
237
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
238
        response = api.get(url)
239
        self.assertEqual(response.status_code, 200, response.data)
240
241
        # fail case
242
        dpid = "00:00:00:00:00:00:00:02"
243
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
244
        response = api.get(url)
245
        self.assertEqual(response.status_code, 404, response.data)
246
247
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
248
    def test_add_switch_metadata(self, mock_metadata_changes):
249
        """Test add_switch_metadata."""
250
        dpid = "00:00:00:00:00:00:00:01"
251
        mock_switch = get_switch_mock(dpid)
252
        self.napp.controller.switches = {dpid: mock_switch}
253
        api = get_test_client(self.napp.controller, self.napp)
254
        payload = {"data": "A"}
255
256
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
257
        response = api.post(url, data=json.dumps(payload),
258
                            content_type='application/json')
259
        self.assertEqual(response.status_code, 201, response.data)
260
        mock_metadata_changes.assert_called()
261
262
        # fail case
263
        dpid = "00:00:00:00:00:00:00:02"
264
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
265
        response = api.post(url, data=json.dumps(payload),
266
                            content_type='application/json')
267
        self.assertEqual(response.status_code, 404, response.data)
268
269
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
270
    def test_delete_switch_metadata(self, mock_metadata_changes):
271
        """Test delete_switch_metadata."""
272
        dpid = "00:00:00:00:00:00:00:01"
273
        mock_switch = get_switch_mock(dpid)
274
        self.napp.controller.switches = {dpid: mock_switch}
275
        api = get_test_client(self.napp.controller, self.napp)
276
277
        key = "A"
278
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
279
        response = api.delete(url)
280
        mock_metadata_changes.assert_called()
281
        self.assertEqual(response.status_code, 200, response.data)
282
283
        # fail case
284
        key = "A"
285
        dpid = "00:00:00:00:00:00:00:02"
286
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
287
        response = api.delete(url)
288
        mock_metadata_changes.assert_called()
289
        self.assertEqual(response.status_code, 404, response.data)
290
291 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...
292
    def test_enable_interfaces(self, mock_save_status):
293
        """Test enable_interfaces."""
294
        mock_switch = create_autospec(Switch)
295
        mock_interface_1 = create_autospec(Interface)
296
        mock_interface_2 = create_autospec(Interface)
297
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
298
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
299
                                         mock_switch}
300
        api = get_test_client(self.napp.controller, self.napp)
301
        expected_success = 'Operation successful'
302
303
        interface_id = '00:00:00:00:00:00:00:01:1'
304
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
305
        response = api.post(url)
306
        self.assertEqual(response.status_code, 200, response.data)
307
        self.assertEqual(expected_success, json.loads(response.data))
308
        self.assertEqual(mock_interface_1.enable.call_count, 1)
309
        self.assertEqual(mock_interface_2.enable.call_count, 0)
310
        mock_save_status.assert_called()
311
312
        dpid = '00:00:00:00:00:00:00:01'
313
        mock_interface_1.enable.call_count = 0
314
        mock_interface_2.enable.call_count = 0
315
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
316
        response = api.post(url)
317
        self.assertEqual(response.status_code, 200, response.data)
318
        self.assertEqual(expected_success, json.loads(response.data))
319
        self.assertEqual(mock_interface_1.enable.call_count, 1)
320
        self.assertEqual(mock_interface_2.enable.call_count, 1)
321
322
        # test interface not found
323
        interface_id = '00:00:00:00:00:00:00:01:3'
324
        mock_interface_1.enable.call_count = 0
325
        mock_interface_2.enable.call_count = 0
326
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
327
        response = api.post(url)
328
        self.assertEqual(response.status_code, 409, response.data)
329
        self.assertEqual(mock_interface_1.enable.call_count, 0)
330
        self.assertEqual(mock_interface_2.enable.call_count, 0)
331
332
        # test switch not found
333
        dpid = '00:00:00:00:00:00:00:02'
334
        expected_fail = f"Switch not found: '{dpid}'"
335
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
336
        response = api.post(url)
337
        self.assertEqual(response.status_code, 404, response.data)
338
        self.assertEqual(expected_fail, json.loads(response.data))
339
        self.assertEqual(mock_interface_1.enable.call_count, 0)
340
        self.assertEqual(mock_interface_2.enable.call_count, 0)
341
342 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...
343
    def test_disable_interfaces(self, mock_save_status):
344
        """Test disable_interfaces."""
345
        interface_id = '00:00:00:00:00:00:00:01:1'
346
        dpid = '00:00:00:00:00:00:00:01'
347
        expected = 'Operation successful'
348
        mock_switch = create_autospec(Switch)
349
        mock_interface_1 = create_autospec(Interface)
350
        mock_interface_2 = create_autospec(Interface)
351
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
352
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
353
                                         mock_switch}
354
        api = get_test_client(self.napp.controller, self.napp)
355
356
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
357
        response = api.post(url)
358
        self.assertEqual(response.status_code, 200, response.data)
359
        self.assertEqual(expected, json.loads(response.data))
360
        self.assertEqual(mock_interface_1.disable.call_count, 1)
361
        self.assertEqual(mock_interface_2.disable.call_count, 0)
362
        mock_save_status.assert_called()
363
364
        mock_interface_1.disable.call_count = 0
365
        mock_interface_2.disable.call_count = 0
366
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
367
        response = api.post(url)
368
        self.assertEqual(response.status_code, 200, response.data)
369
        self.assertEqual(expected, json.loads(response.data))
370
        self.assertEqual(mock_interface_1.disable.call_count, 1)
371
        self.assertEqual(mock_interface_2.disable.call_count, 1)
372
373
        # test interface not found
374
        interface_id = '00:00:00:00:00:00:00:01:3'
375
        mock_interface_1.disable.call_count = 0
376
        mock_interface_2.disable.call_count = 0
377
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
378
        response = api.post(url)
379
        self.assertEqual(response.status_code, 409, response.data)
380
        self.assertEqual(mock_interface_1.disable.call_count, 0)
381
        self.assertEqual(mock_interface_2.disable.call_count, 0)
382
383
        # test switch not found
384
        dpid = '00:00:00:00:00:00:00:02'
385
        expected_fail = f"Switch not found: '{dpid}'"
386
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
387
        response = api.post(url)
388
        self.assertEqual(response.status_code, 404, response.data)
389
        self.assertEqual(expected_fail, json.loads(response.data))
390
        self.assertEqual(mock_interface_1.disable.call_count, 0)
391
        self.assertEqual(mock_interface_2.disable.call_count, 0)
392
393
    def test_get_interface_metadata(self):
394
        """Test get_interface_metada."""
395
        interface_id = '00:00:00:00:00:00:00:01:1'
396
        msg_error_switch = "Switch not found"
397
        msg_error_interface = "Interface not found"
398
        mock_switch = create_autospec(Switch)
399
        mock_interface = create_autospec(Interface)
400
        mock_interface.metadata = {"metada": "A"}
401
        mock_switch.interfaces = {1: mock_interface}
402
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
403
                                         mock_switch}
404
        api = get_test_client(self.napp.controller, self.napp)
405
406
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
407
        response = api.get(url)
408
        self.assertEqual(response.status_code, 200, response.data)
409
410
        # fail case switch not found
411
        interface_id = '00:00:00:00:00:00:00:02:1'
412
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
413
        response = api.get(url)
414
        self.assertEqual(response.status_code, 404, response.data)
415
        self.assertEqual(msg_error_switch, json.loads(response.data))
416
417
        # fail case interface not found
418
        interface_id = '00:00:00:00:00:00:00:01:2'
419
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
420
        response = api.get(url)
421
        self.assertEqual(response.status_code, 404, response.data)
422
        self.assertEqual(msg_error_interface, json.loads(response.data))
423
424
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
425
    def test_add_interface_metadata(self, mock_metadata_changes):
426
        """Test add_interface_metadata."""
427
        interface_id = '00:00:00:00:00:00:00:01:1'
428
        msg_error_switch = "Switch not found"
429
        msg_error_interface = "Interface not found"
430
        mock_switch = create_autospec(Switch)
431
        mock_interface = create_autospec(Interface)
432
        mock_interface.metadata = {"metada": "A"}
433
        mock_switch.interfaces = {1: mock_interface}
434
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
435
                                         mock_switch}
436
        api = get_test_client(self.napp.controller, self.napp)
437
438
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
439
        payload = {"metada": "A"}
440
        response = api.post(url, data=json.dumps(payload),
441
                            content_type='application/json')
442
        self.assertEqual(response.status_code, 201, response.data)
443
        mock_metadata_changes.assert_called()
444
445
        # fail case switch not found
446
        interface_id = '00:00:00:00:00:00:00:02:1'
447
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
448
        response = api.post(url, data=json.dumps(payload),
449
                            content_type='application/json')
450
        self.assertEqual(response.status_code, 404, response.data)
451
        self.assertEqual(msg_error_switch, json.loads(response.data))
452
453
        # fail case interface not found
454
        interface_id = '00:00:00:00:00:00:00:01:2'
455
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
456
        response = api.post(url, data=json.dumps(payload),
457
                            content_type='application/json')
458
        self.assertEqual(response.status_code, 404, response.data)
459
        self.assertEqual(msg_error_interface, json.loads(response.data))
460
461
    def test_delete_interface_metadata(self):
462
        """Test delete_interface_metadata."""
463
        interface_id = '00:00:00:00:00:00:00:01:1'
464
        iface_url = '/v3/interfaces/'
465
        msg_error_switch = "Switch not found"
466
        msg_error_interface = "Interface not found"
467
        msg_error_metadata = "Metadata not found"
468
        mock_switch = create_autospec(Switch)
469
        mock_interface = create_autospec(Interface)
470
        mock_interface.remove_metadata.side_effect = [True, False]
471
        mock_interface.metadata = {"metada": "A"}
472
        mock_switch.interfaces = {1: mock_interface}
473
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
474
                                         mock_switch}
475
        api = get_test_client(self.napp.controller, self.napp)
476
477
        key = 'A'
478
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
479
        response = api.delete(url)
480
        self.assertEqual(response.status_code, 200, response.data)
481
482
        # fail case switch not found
483
        key = 'A'
484
        interface_id = '00:00:00:00:00:00:00:02:1'
485
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
486
        response = api.delete(url)
487
        self.assertEqual(response.status_code, 404, response.data)
488
        self.assertEqual(msg_error_switch, json.loads(response.data))
489
490
        # fail case interface not found
491
        key = 'A'
492
        interface_id = '00:00:00:00:00:00:00:01:2'
493
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
494
        response = api.delete(url)
495
        self.assertEqual(response.status_code, 404, response.data)
496
        self.assertEqual(msg_error_interface, json.loads(response.data))
497
498
        # fail case metadata not found
499
        key = 'A'
500
        interface_id = '00:00:00:00:00:00:00:01:1'
501
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
502
        response = api.delete(url)
503
        self.assertEqual(response.status_code, 404, response.data)
504
        self.assertEqual(msg_error_metadata, json.loads(response.data))
505
506 View Code Duplication
    def test_enable_link(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
507
        """Test enable_link."""
508
        mock_link = MagicMock(Link)
509
        self.napp.links = {'1': mock_link}
510
        msg_success = 'Operation successful'
511
        msg_fail = 'Link not found'
512
        api = get_test_client(self.napp.controller, self.napp)
513
514
        link_id = 1
515
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
516
        response = api.post(url)
517
        self.assertEqual(response.status_code, 201, response.data)
518
        self.assertEqual(msg_success, json.loads(response.data))
519
        self.assertEqual(mock_link.enable.call_count, 1)
520
521
        # fail case
522
        link_id = 2
523
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
524
        response = api.post(url)
525
        self.assertEqual(response.status_code, 404, response.data)
526
        self.assertEqual(msg_fail, json.loads(response.data))
527
528 View Code Duplication
    def test_disable_link(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
529
        """Test disable_link."""
530
        mock_link = MagicMock(Link)
531
        self.napp.links = {'1': mock_link}
532
        msg_success = 'Operation successful'
533
        msg_fail = 'Link not found'
534
        api = get_test_client(self.napp.controller, self.napp)
535
536
        link_id = 1
537
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
538
        response = api.post(url)
539
        self.assertEqual(response.status_code, 201, response.data)
540
        self.assertEqual(msg_success, json.loads(response.data))
541
        self.assertEqual(mock_link.disable.call_count, 1)
542
543
        # fail case
544
        link_id = 2
545
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
546
        response = api.post(url)
547
        self.assertEqual(response.status_code, 404, response.data)
548
        self.assertEqual(msg_fail, json.loads(response.data))
549
550 View Code Duplication
    def test_get_link_metadata(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
551
        """Test get_link_metadata."""
552
        mock_link = MagicMock(Link)
553
        mock_link.metadata = "A"
554
        self.napp.links = {'1': mock_link}
555
        msg_fail = 'Link not found'
556
        msg_success = {"metadata": "A"}
557
        api = get_test_client(self.napp.controller, self.napp)
558
559
        link_id = 1
560
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
561
        response = api.get(url)
562
        self.assertEqual(response.status_code, 200, response.data)
563
        self.assertEqual(msg_success, json.loads(response.data))
564
565
        # fail case
566
        link_id = 2
567
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
568
        response = api.get(url)
569
        self.assertEqual(response.status_code, 404, response.data)
570
        self.assertEqual(msg_fail, json.loads(response.data))
571
572
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
573
    def test_add_link_metadata(self, mock_metadata_changes):
574
        """Test add_link_metadata."""
575
        mock_link = MagicMock(Link)
576
        mock_link.metadata = "A"
577
        self.napp.links = {'1': mock_link}
578
        msg_fail = 'Link not found'
579
        msg_success = 'Operation successful'
580
        payload = {"metadata": "A"}
581
        api = get_test_client(self.napp.controller, self.napp)
582
583
        link_id = 1
584
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
585
        response = api.post(url, data=json.dumps(payload),
586
                            content_type='application/json')
587
        self.assertEqual(response.status_code, 201, response.data)
588
        self.assertEqual(msg_success, json.loads(response.data))
589
        mock_metadata_changes.assert_called()
590
591
        # fail case
592
        link_id = 2
593
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
594
        response = api.post(url, data=json.dumps(payload),
595
                            content_type='application/json')
596
        self.assertEqual(response.status_code, 404, response.data)
597
        self.assertEqual(msg_fail, json.loads(response.data))
598
599
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
600
    def test_delete_link_metadata(self, mock_metadata_changes):
601
        """Test delete_link_metadata."""
602
        mock_link = MagicMock(Link)
603
        mock_link.metadata = "A"
604
        mock_link.remove_metadata.side_effect = [True, False]
605
        self.napp.links = {'1': mock_link}
606
        msg_fail = 'Link not found'
607
        msg_error_metadata = 'Metadata not found'
608
        msg_success = 'Operation successful'
609
        api = get_test_client(self.napp.controller, self.napp)
610
611
        link_id = 1
612
        key = 'A'
613
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
614
        response = api.delete(url)
615
        self.assertEqual(response.status_code, 200, response.data)
616
        self.assertEqual(msg_success, json.loads(response.data))
617
        mock_metadata_changes.assert_called()
618
619
        # fail case link not found
620
        link_id = 2
621
        key = 'A'
622
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
623
        response = api.delete(url)
624
        self.assertEqual(response.status_code, 404, response.data)
625
        self.assertEqual(msg_fail, json.loads(response.data))
626
627
        # fail case metadata not found
628
        link_id = 1
629
        key = 'A'
630
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
631
        response = api.delete(url)
632
        self.assertEqual(response.status_code, 404, response.data)
633
        self.assertEqual(msg_error_metadata, json.loads(response.data))
634
635
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
636
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
637
    def test_handle_new_switch(self, *args):
638
        """Test handle_new_switch."""
639
        (mock_instance_metadata, mock_notify_topology_update) = args
640
        mock_event = MagicMock()
641
        mock_switch = create_autospec(Switch)
642
        mock_event.content['switch'] = mock_switch
643
        self.napp.handle_new_switch(mock_event)
644
        mock_notify_topology_update.assert_called()
645
        mock_instance_metadata.assert_called()
646
647
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
648
    def test_handle_connection_lost(self, mock_notify_topology_update):
649
        """Test handle connection_lost."""
650
        mock_event = MagicMock()
651
        mock_switch = create_autospec(Switch)
652
        mock_switch.return_value = True
653
        mock_event.content['source'] = mock_switch
654
        self.napp.handle_connection_lost(mock_event)
655
        mock_notify_topology_update.assert_called()
656
657
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
658
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
659
    def test_handle_interface_up(self, *args):
660
        """Test handle_interface_up."""
661
        (mock_instance_metadata, mock_notify_topology_update) = args
662
        mock_event = MagicMock()
663
        mock_interface = create_autospec(Interface)
664
        mock_event.content['interface'] = mock_interface
665
        self.napp.handle_interface_up(mock_event)
666
        mock_notify_topology_update.assert_called()
667
        mock_instance_metadata.assert_called()
668
669
    @patch('napps.kytos.topology.main.Main.handle_interface_up')
670
    def test_handle_interface_created(self, mock_handle_interface_up):
671
        """Test handle interface created."""
672
        mock_event = MagicMock()
673
        self.napp.handle_interface_created(mock_event)
674
        mock_handle_interface_up.assert_called()
675
676
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
677
    @patch('napps.kytos.topology.main.Main.handle_interface_link_down')
678
    def test_handle_interface_down(self, *args):
679
        """Test handle interface down."""
680
        (mock_handle_interface_link_down, mock_notify_topology_update) = args
681
        mock_event = MagicMock()
682
        mock_interface = create_autospec(Interface)
683
        mock_event.content['interface'] = mock_interface
684
        self.napp.handle_interface_down(mock_event)
685
        mock_handle_interface_link_down.assert_called()
686
        mock_notify_topology_update.assert_called()
687
688
    @patch('napps.kytos.topology.main.Main.handle_interface_down')
689
    def test_interface_deleted(self, mock_handle_interface_link_down):
690
        """Test interface deleted."""
691
        mock_event = MagicMock()
692
        self.napp.handle_interface_deleted(mock_event)
693
        mock_handle_interface_link_down.assert_called()
694
695
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
696
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
697
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
698
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
699
    def test_interface_link_up(self, *args):
700
        """Test interface link_up."""
701
        (mock_status_change, mock_instance_metadata, mock_topology_update,
702
         mock_link_from_interface) = args
703
704
        now = time.time()
705
        mock_event = MagicMock()
706
        mock_interface_a = create_autospec(Interface)
707
        mock_interface_a.is_active.return_value = False
708
        mock_interface_b = create_autospec(Interface)
709
        mock_interface_b.is_active.return_value = True
710
        mock_link = create_autospec(Link)
711
        mock_link.get_metadata.return_value = now
712
        mock_link.is_active.side_effect = [False, True]
713
        mock_link.endpoint_a = mock_interface_a
714
        mock_link.endpoint_b = mock_interface_b
715
        mock_link_from_interface.return_value = mock_link
716
        content = {'interface': mock_interface_a}
717
        mock_event.content = content
718
        self.napp.link_up_timer = 1
719
        self.napp.handle_interface_link_up(mock_event)
720
        mock_topology_update.assert_called()
721
        mock_instance_metadata.assert_called()
722
        mock_status_change.assert_called()
723
724
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
725
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
726
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
727
    def test_interface_link_down(self, *args):
728
        """Test interface link down."""
729
        (mock_status_change, mock_topology_update,
730
         mock_link_from_interface) = args
731
732
        mock_event = MagicMock()
733
        mock_interface = create_autospec(Interface)
734
        mock_link = create_autospec(Link)
735
        mock_link.is_active.return_value = True
736
        mock_link_from_interface.return_value = mock_link
737
        mock_event.content['interface'] = mock_interface
738
        self.napp.handle_interface_link_down(mock_event)
739
        mock_topology_update.assert_called()
740
        mock_status_change.assert_called()
741
742
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
743
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
744
    def test_add_links(self, *args):
745
        """Test add_links."""
746
        (mock_notify_topology_update, mock_get_link_or_create) = args
747
        mock_event = MagicMock()
748
        self.napp.add_links(mock_event)
749
        mock_get_link_or_create.assert_called()
750
        mock_notify_topology_update.assert_called()
751
752
    @patch('napps.kytos.topology.main.KytosEvent')
753
    @patch('kytos.core.buffers.KytosEventBuffer.put')
754
    def test_notify_topology_update(self, *args):
755
        """Test notify_topology_update."""
756
        (mock_buffers_put, mock_event) = args
757
        self.napp.notify_topology_update()
758
        mock_event.assert_called()
759
        mock_buffers_put.assert_called()
760
761
    @patch('napps.kytos.topology.main.KytosEvent')
762
    @patch('kytos.core.buffers.KytosEventBuffer.put')
763
    def test_notify_link_status_change(self, *args):
764
        """Test notify link status change."""
765
        (mock_buffers_put, mock_event) = args
766
        mock_link = create_autospec(Link)
767
        self.napp.notify_link_status_change(mock_link)
768
        mock_event.assert_called()
769
        mock_buffers_put.assert_called()
770
771
    @patch('napps.kytos.topology.main.KytosEvent')
772
    @patch('kytos.core.buffers.KytosEventBuffer.put')
773
    @patch('napps.kytos.topology.main.isinstance')
774
    def test_notify_metadata_changes(self, *args):
775
        """Test notify metadata changes."""
776
        (mock_isinstance, mock_buffers_put, mock_event) = args
777
        mock_isinstance.return_value = True
778
        mock_obj = MagicMock()
779
        mock_action = create_autospec(Switch)
780
        self.napp.notify_metadata_changes(mock_obj, mock_action)
781
        mock_event.assert_called()
782
        mock_isinstance.assert_called()
783
        mock_buffers_put.assert_called()
784
785
    @patch('napps.kytos.topology.main.KytosEvent')
786
    @patch('kytos.core.buffers.KytosEventBuffer.put')
787
    def test_notify_port_created(self, *args):
788
        """Test notify port created."""
789
        (mock_buffers_put, mock_kytos_event) = args
790
        mock_event = MagicMock()
791
        self.napp.notify_port_created(mock_event)
792
        mock_kytos_event.assert_called()
793
        mock_buffers_put.assert_called()
794
795
    @patch('napps.kytos.topology.main.KytosEvent')
796
    @patch('kytos.core.buffers.KytosEventBuffer.put')
797
    def test_verify_storehouse(self, *args):
798
        """Test verify_storehouse."""
799
        (mock_buffers_put, mock_kytos_event) = args
800
        mock_entities = MagicMock()
801
        self.napp.verify_storehouse(mock_entities)
802
        mock_buffers_put.assert_called()
803
        mock_kytos_event.assert_called()
804
805
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
806
    def test_handle_link_maintenance_start(self, status_change_mock):
807
        """Test handle_link_maintenance_start."""
808
        link1 = MagicMock()
809
        link1.id = 2
810
        link2 = MagicMock()
811
        link2.id = 3
812
        link3 = MagicMock()
813
        link3.id = 4
814
        content = {'links': [link1, link2]}
815
        event = MagicMock()
816
        event.content = content
817
        self.napp.links = {2: link1, 4: link3}
818
        self.napp.handle_link_maintenance_start(event)
819
        status_change_mock.assert_called_once_with(link1)
820
821
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
822
    def test_handle_link_maintenance_end(self, status_change_mock):
823
        """Test handle_link_maintenance_end."""
824
        link1 = MagicMock()
825
        link1.id = 2
826
        link2 = MagicMock()
827
        link2.id = 3
828
        link3 = MagicMock()
829
        link3.id = 4
830
        content = {'links': [link1, link2]}
831
        event = MagicMock()
832
        event.content = content
833
        self.napp.links = {2: link1, 4: link3}
834
        self.napp.handle_link_maintenance_end(event)
835
        status_change_mock.assert_called_once_with(link1)
836
837 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...
838
    def test_handle_switch_maintenance_start(self, handle_link_down_mock):
839
        """Test handle_switch_maintenance_start."""
840
        switch1 = MagicMock()
841
        interface1 = MagicMock()
842
        interface1.is_active.return_value = True
843
        interface2 = MagicMock()
844
        interface2.is_active.return_value = False
845
        interface3 = MagicMock()
846
        interface3.is_active.return_value = True
847
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
848
        switch2 = MagicMock()
849
        interface4 = MagicMock()
850
        interface4.is_active.return_value = False
851
        interface5 = MagicMock()
852
        interface5.is_active.return_value = True
853
        switch2.interfaces = {1: interface4, 2: interface5}
854
        content = {'switches': [switch1, switch2]}
855
        event = MagicMock()
856
        event.content = content
857
        self.napp.handle_switch_maintenance_start(event)
858
        self.assertEqual(handle_link_down_mock.call_count, 3)
859
860 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...
861
    def test_handle_switch_maintenance_end(self, handle_link_up_mock):
862
        """Test handle_switch_maintenance_end."""
863
        switch1 = MagicMock()
864
        interface1 = MagicMock()
865
        interface1.is_active.return_value = True
866
        interface2 = MagicMock()
867
        interface2.is_active.return_value = False
868
        interface3 = MagicMock()
869
        interface3.is_active.return_value = True
870
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
871
        switch2 = MagicMock()
872
        interface4 = MagicMock()
873
        interface4.is_active.return_value = False
874
        interface5 = MagicMock()
875
        interface5.is_active.return_value = True
876
        switch2.interfaces = {1: interface4, 2: interface5}
877
        content = {'switches': [switch1, switch2]}
878
        event = MagicMock()
879
        event.content = content
880
        self.napp.handle_switch_maintenance_end(event)
881
        self.assertEqual(handle_link_up_mock.call_count, 5)
882