Completed
Pull Request — master (#108)
by
unknown
02:43
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
        dpid = '00:00:00:00:00:00:00:01'
108
        mock_switch = get_switch_mock(dpid)
109
        mock_interface = create_autospec(Interface)
110
        mock_switch.interfaces = {1: mock_interface}
111
        self.napp.controller.switches = {dpid: mock_switch}
112
        msg_expected = 'There is no status saved to restore.'
113
        msg_success = 'Administrative status restored.'
114
        status = {
115
            'network_status': {
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
            'network_status': {
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 = [{}, 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 = {dpid: mock_switch}
184
        api = get_test_client(self.napp.controller, self.napp)
185
186
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
187
        response = api.post(url)
188
        self.assertEqual(response.status_code, 201, response.data)
189
        self.assertEqual(msg_success, json.loads(response.data))
190
        self.assertEqual(mock_switch.enable.call_count, 1)
191
        mock_save_status.assert_called()
192
193
        # fail case
194
        mock_switch.enable.call_count = 0
195
        dpid = "00:00:00:00:00:00:00:02"
196
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
197
        response = api.post(url)
198
        self.assertEqual(response.status_code, 404, response.data)
199
        self.assertEqual(msg_fail, json.loads(response.data))
200
        self.assertEqual(mock_switch.enable.call_count, 0)
201
202 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...
203
    def test_disable_switch(self, mock_save_status):
204
        """Test disable_swicth."""
205
        dpid = "00:00:00:00:00:00:00:01"
206
        mock_switch = get_switch_mock(dpid)
207
        msg_success = "Operation successful"
208
        msg_fail = "Switch not found"
209
        self.napp.controller.switches = {dpid: mock_switch}
210
        api = get_test_client(self.napp.controller, self.napp)
211
212
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
213
        response = api.post(url)
214
        self.assertEqual(response.status_code, 201, response.data)
215
        self.assertEqual(msg_success, json.loads(response.data))
216
        self.assertEqual(mock_switch.disable.call_count, 1)
217
        mock_save_status.assert_called()
218
219
        # fail case
220
        mock_switch.disable.call_count = 0
221
        dpid = "00:00:00:00:00:00:00:02"
222
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
223
        response = api.post(url)
224
        self.assertEqual(response.status_code, 404, response.data)
225
        self.assertEqual(msg_fail, json.loads(response.data))
226
        self.assertEqual(mock_switch.disable.call_count, 0)
227
228
    def test_get_switch_metadata(self):
229
        """Test get_switch_metadata."""
230
        dpid = "00:00:00:00:00:00:00:01"
231
        mock_switch = get_switch_mock(dpid)
232
        mock_switch.metadata = "A"
233
        self.napp.controller.switches = {dpid: mock_switch}
234
        api = get_test_client(self.napp.controller, self.napp)
235
236
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
237
        response = api.get(url)
238
        self.assertEqual(response.status_code, 200, response.data)
239
240
        # fail case
241
        dpid = "00:00:00:00:00:00:00:02"
242
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
243
        response = api.get(url)
244
        self.assertEqual(response.status_code, 404, response.data)
245
246
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
247
    def test_add_switch_metadata(self, mock_metadata_changes):
248
        """Test add_switch_metadata."""
249
        dpid = "00:00:00:00:00:00:00:01"
250
        mock_switch = get_switch_mock(dpid)
251
        self.napp.controller.switches = {dpid: mock_switch}
252
        api = get_test_client(self.napp.controller, self.napp)
253
        payload = {"data": "A"}
254
255
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
256
        response = api.post(url, data=json.dumps(payload),
257
                            content_type='application/json')
258
        self.assertEqual(response.status_code, 201, response.data)
259
        mock_metadata_changes.assert_called()
260
261
        # fail case
262
        dpid = "00:00:00:00:00:00:00:02"
263
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
264
        response = api.post(url, data=json.dumps(payload),
265
                            content_type='application/json')
266
        self.assertEqual(response.status_code, 404, response.data)
267
268
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
269
    def test_delete_switch_metadata(self, mock_metadata_changes):
270
        """Test delete_switch_metadata."""
271
        dpid = "00:00:00:00:00:00:00:01"
272
        mock_switch = get_switch_mock(dpid)
273
        self.napp.controller.switches = {dpid: mock_switch}
274
        api = get_test_client(self.napp.controller, self.napp)
275
276
        key = "A"
277
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
278
        response = api.delete(url)
279
        mock_metadata_changes.assert_called()
280
        self.assertEqual(response.status_code, 200, response.data)
281
282
        # fail case
283
        key = "A"
284
        dpid = "00:00:00:00:00:00:00:02"
285
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
286
        response = api.delete(url)
287
        mock_metadata_changes.assert_called()
288
        self.assertEqual(response.status_code, 404, response.data)
289
290 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...
291
    def test_enable_interfaces(self, mock_save_status):
292
        """Test enable_interfaces."""
293
        dpid = '00:00:00:00:00:00:00:01'
294
        mock_switch = get_switch_mock(dpid)
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 = {dpid: mock_switch}
299
        api = get_test_client(self.napp.controller, self.napp)
300
        expected_success = 'Operation successful'
301
302
        interface_id = '00:00:00:00:00:00:00:01:1'
303
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
304
        response = api.post(url)
305
        self.assertEqual(response.status_code, 200, response.data)
306
        self.assertEqual(expected_success, json.loads(response.data))
307
        self.assertEqual(mock_interface_1.enable.call_count, 1)
308
        self.assertEqual(mock_interface_2.enable.call_count, 0)
309
        mock_save_status.assert_called()
310
311
        mock_interface_1.enable.call_count = 0
312
        mock_interface_2.enable.call_count = 0
313
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
314
        response = api.post(url)
315
        self.assertEqual(response.status_code, 200, response.data)
316
        self.assertEqual(expected_success, json.loads(response.data))
317
        self.assertEqual(mock_interface_1.enable.call_count, 1)
318
        self.assertEqual(mock_interface_2.enable.call_count, 1)
319
320
        # test interface not found
321
        interface_id = '00:00:00:00:00:00:00:01:3'
322
        mock_interface_1.enable.call_count = 0
323
        mock_interface_2.enable.call_count = 0
324
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
325
        response = api.post(url)
326
        self.assertEqual(response.status_code, 409, response.data)
327
        self.assertEqual(mock_interface_1.enable.call_count, 0)
328
        self.assertEqual(mock_interface_2.enable.call_count, 0)
329
330
        # test switch not found
331
        dpid = '00:00:00:00:00:00:00:02'
332
        expected_fail = f"Switch not found: '{dpid}'"
333
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
334
        response = api.post(url)
335
        self.assertEqual(response.status_code, 404, response.data)
336
        self.assertEqual(expected_fail, json.loads(response.data))
337
        self.assertEqual(mock_interface_1.enable.call_count, 0)
338
        self.assertEqual(mock_interface_2.enable.call_count, 0)
339
340 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...
341
    def test_disable_interfaces(self, mock_save_status):
342
        """Test disable_interfaces."""
343
        interface_id = '00:00:00:00:00:00:00:01:1'
344
        dpid = '00:00:00:00:00:00:00:01'
345
        expected = 'Operation successful'
346
        mock_switch = get_switch_mock(dpid)
347
        mock_interface_1 = create_autospec(Interface)
348
        mock_interface_2 = create_autospec(Interface)
349
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
350
        self.napp.controller.switches = {dpid: mock_switch}
351
        api = get_test_client(self.napp.controller, self.napp)
352
353
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
354
        response = api.post(url)
355
        self.assertEqual(response.status_code, 200, response.data)
356
        self.assertEqual(expected, json.loads(response.data))
357
        self.assertEqual(mock_interface_1.disable.call_count, 1)
358
        self.assertEqual(mock_interface_2.disable.call_count, 0)
359
        mock_save_status.assert_called()
360
361
        mock_interface_1.disable.call_count = 0
362
        mock_interface_2.disable.call_count = 0
363
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
364
        response = api.post(url)
365
        self.assertEqual(response.status_code, 200, response.data)
366
        self.assertEqual(expected, json.loads(response.data))
367
        self.assertEqual(mock_interface_1.disable.call_count, 1)
368
        self.assertEqual(mock_interface_2.disable.call_count, 1)
369
370
        # test interface not found
371
        interface_id = '00:00:00:00:00:00:00:01:3'
372
        mock_interface_1.disable.call_count = 0
373
        mock_interface_2.disable.call_count = 0
374
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
375
        response = api.post(url)
376
        self.assertEqual(response.status_code, 409, response.data)
377
        self.assertEqual(mock_interface_1.disable.call_count, 0)
378
        self.assertEqual(mock_interface_2.disable.call_count, 0)
379
380
        # test switch not found
381
        dpid = '00:00:00:00:00:00:00:02'
382
        expected_fail = f"Switch not found: '{dpid}'"
383
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
384
        response = api.post(url)
385
        self.assertEqual(response.status_code, 404, response.data)
386
        self.assertEqual(expected_fail, json.loads(response.data))
387
        self.assertEqual(mock_interface_1.disable.call_count, 0)
388
        self.assertEqual(mock_interface_2.disable.call_count, 0)
389
390
    def test_get_interface_metadata(self):
391
        """Test get_interface_metada."""
392
        interface_id = '00:00:00:00:00:00:00:01:1'
393
        dpid = '00:00:00:00:00:00:00:01'
394
        msg_error_switch = "Switch not found"
395
        msg_error_interface = "Interface not found"
396
        mock_switch = get_switch_mock(dpid)
397
        mock_interface = create_autospec(Interface)
398
        mock_interface.metadata = {"metada": "A"}
399
        mock_switch.interfaces = {1: mock_interface}
400
        self.napp.controller.switches = {dpid: mock_switch}
401
        api = get_test_client(self.napp.controller, self.napp)
402
403
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
404
        response = api.get(url)
405
        self.assertEqual(response.status_code, 200, response.data)
406
407
        # fail case switch not found
408
        interface_id = '00:00:00:00:00:00:00:02:1'
409
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
410
        response = api.get(url)
411
        self.assertEqual(response.status_code, 404, response.data)
412
        self.assertEqual(msg_error_switch, json.loads(response.data))
413
414
        # fail case interface not found
415
        interface_id = '00:00:00:00:00:00:00:01:2'
416
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
417
        response = api.get(url)
418
        self.assertEqual(response.status_code, 404, response.data)
419
        self.assertEqual(msg_error_interface, json.loads(response.data))
420
421
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
422
    def test_add_interface_metadata(self, mock_metadata_changes):
423
        """Test add_interface_metadata."""
424
        interface_id = '00:00:00:00:00:00:00:01:1'
425
        dpid = '00:00:00:00:00:00:00:01'
426
        msg_error_switch = "Switch not found"
427
        msg_error_interface = "Interface not found"
428
        mock_switch = get_switch_mock(dpid)
429
        mock_interface = create_autospec(Interface)
430
        mock_interface.metadata = {"metada": "A"}
431
        mock_switch.interfaces = {1: mock_interface}
432
        self.napp.controller.switches = {dpid: mock_switch}
433
        api = get_test_client(self.napp.controller, self.napp)
434
435
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
436
        payload = {"metada": "A"}
437
        response = api.post(url, data=json.dumps(payload),
438
                            content_type='application/json')
439
        self.assertEqual(response.status_code, 201, response.data)
440
        mock_metadata_changes.assert_called()
441
442
        # fail case switch not found
443
        interface_id = '00:00:00:00:00:00:00:02:1'
444
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
445
        response = api.post(url, data=json.dumps(payload),
446
                            content_type='application/json')
447
        self.assertEqual(response.status_code, 404, response.data)
448
        self.assertEqual(msg_error_switch, json.loads(response.data))
449
450
        # fail case interface not found
451
        interface_id = '00:00:00:00:00:00:00:01:2'
452
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
453
        response = api.post(url, data=json.dumps(payload),
454
                            content_type='application/json')
455
        self.assertEqual(response.status_code, 404, response.data)
456
        self.assertEqual(msg_error_interface, json.loads(response.data))
457
458
    def test_delete_interface_metadata(self):
459
        """Test delete_interface_metadata."""
460
        interface_id = '00:00:00:00:00:00:00:01:1'
461
        dpid = '00:00:00:00:00:00:00:01'
462
        iface_url = '/v3/interfaces/'
463
        msg_error_switch = "Switch not found"
464
        msg_error_interface = "Interface not found"
465
        msg_error_metadata = "Metadata not found"
466
        mock_switch = get_switch_mock(dpid)
467
        mock_interface = create_autospec(Interface)
468
        mock_interface.remove_metadata.side_effect = [True, False]
469
        mock_interface.metadata = {"metada": "A"}
470
        mock_switch.interfaces = {1: mock_interface}
471
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
472
                                         mock_switch}
473
        api = get_test_client(self.napp.controller, self.napp)
474
475
        key = 'A'
476
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
477
        response = api.delete(url)
478
        self.assertEqual(response.status_code, 200, response.data)
479
480
        # fail case switch not found
481
        key = 'A'
482
        interface_id = '00:00:00:00:00:00:00:02:1'
483
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
484
        response = api.delete(url)
485
        self.assertEqual(response.status_code, 404, response.data)
486
        self.assertEqual(msg_error_switch, json.loads(response.data))
487
488
        # fail case interface not found
489
        key = 'A'
490
        interface_id = '00:00:00:00:00:00:00:01:2'
491
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
492
        response = api.delete(url)
493
        self.assertEqual(response.status_code, 404, response.data)
494
        self.assertEqual(msg_error_interface, json.loads(response.data))
495
496
        # fail case metadata not found
497
        key = 'A'
498
        interface_id = '00:00:00:00:00:00:00:01:1'
499
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
500
        response = api.delete(url)
501
        self.assertEqual(response.status_code, 404, response.data)
502
        self.assertEqual(msg_error_metadata, json.loads(response.data))
503
504 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...
505
        """Test enable_link."""
506
        mock_link = MagicMock(Link)
507
        self.napp.links = {'1': mock_link}
508
        msg_success = 'Operation successful'
509
        msg_fail = 'Link not found'
510
        api = get_test_client(self.napp.controller, self.napp)
511
512
        link_id = 1
513
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
514
        response = api.post(url)
515
        self.assertEqual(response.status_code, 201, response.data)
516
        self.assertEqual(msg_success, json.loads(response.data))
517
        self.assertEqual(mock_link.enable.call_count, 1)
518
519
        # fail case
520
        link_id = 2
521
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
522
        response = api.post(url)
523
        self.assertEqual(response.status_code, 404, response.data)
524
        self.assertEqual(msg_fail, json.loads(response.data))
525
526 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...
527
        """Test disable_link."""
528
        mock_link = MagicMock(Link)
529
        self.napp.links = {'1': mock_link}
530
        msg_success = 'Operation successful'
531
        msg_fail = 'Link not found'
532
        api = get_test_client(self.napp.controller, self.napp)
533
534
        link_id = 1
535
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
536
        response = api.post(url)
537
        self.assertEqual(response.status_code, 201, response.data)
538
        self.assertEqual(msg_success, json.loads(response.data))
539
        self.assertEqual(mock_link.disable.call_count, 1)
540
541
        # fail case
542
        link_id = 2
543
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
544
        response = api.post(url)
545
        self.assertEqual(response.status_code, 404, response.data)
546
        self.assertEqual(msg_fail, json.loads(response.data))
547
548 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...
549
        """Test get_link_metadata."""
550
        mock_link = MagicMock(Link)
551
        mock_link.metadata = "A"
552
        self.napp.links = {'1': mock_link}
553
        msg_fail = 'Link not found'
554
        msg_success = {"metadata": "A"}
555
        api = get_test_client(self.napp.controller, self.napp)
556
557
        link_id = 1
558
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
559
        response = api.get(url)
560
        self.assertEqual(response.status_code, 200, response.data)
561
        self.assertEqual(msg_success, json.loads(response.data))
562
563
        # fail case
564
        link_id = 2
565
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
566
        response = api.get(url)
567
        self.assertEqual(response.status_code, 404, response.data)
568
        self.assertEqual(msg_fail, json.loads(response.data))
569
570
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
571
    def test_add_link_metadata(self, mock_metadata_changes):
572
        """Test add_link_metadata."""
573
        mock_link = MagicMock(Link)
574
        mock_link.metadata = "A"
575
        self.napp.links = {'1': mock_link}
576
        msg_fail = 'Link not found'
577
        msg_success = 'Operation successful'
578
        payload = {"metadata": "A"}
579
        api = get_test_client(self.napp.controller, self.napp)
580
581
        link_id = 1
582
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
583
        response = api.post(url, data=json.dumps(payload),
584
                            content_type='application/json')
585
        self.assertEqual(response.status_code, 201, response.data)
586
        self.assertEqual(msg_success, json.loads(response.data))
587
        mock_metadata_changes.assert_called()
588
589
        # fail case
590
        link_id = 2
591
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
592
        response = api.post(url, data=json.dumps(payload),
593
                            content_type='application/json')
594
        self.assertEqual(response.status_code, 404, response.data)
595
        self.assertEqual(msg_fail, json.loads(response.data))
596
597
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
598
    def test_delete_link_metadata(self, mock_metadata_changes):
599
        """Test delete_link_metadata."""
600
        mock_link = MagicMock(Link)
601
        mock_link.metadata = "A"
602
        mock_link.remove_metadata.side_effect = [True, False]
603
        self.napp.links = {'1': mock_link}
604
        msg_fail = 'Link not found'
605
        msg_error_metadata = 'Metadata not found'
606
        msg_success = 'Operation successful'
607
        api = get_test_client(self.napp.controller, self.napp)
608
609
        link_id = 1
610
        key = 'A'
611
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
612
        response = api.delete(url)
613
        self.assertEqual(response.status_code, 200, response.data)
614
        self.assertEqual(msg_success, json.loads(response.data))
615
        mock_metadata_changes.assert_called()
616
617
        # fail case link not found
618
        link_id = 2
619
        key = 'A'
620
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
621
        response = api.delete(url)
622
        self.assertEqual(response.status_code, 404, response.data)
623
        self.assertEqual(msg_fail, json.loads(response.data))
624
625
        # fail case metadata not found
626
        link_id = 1
627
        key = 'A'
628
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
629
        response = api.delete(url)
630
        self.assertEqual(response.status_code, 404, response.data)
631
        self.assertEqual(msg_error_metadata, json.loads(response.data))
632
633
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
634
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
635
    def test_handle_new_switch(self, *args):
636
        """Test handle_new_switch."""
637
        (mock_instance_metadata, mock_notify_topology_update) = args
638
        mock_event = MagicMock()
639
        mock_switch = create_autospec(Switch)
640
        mock_event.content['switch'] = mock_switch
641
        self.napp.handle_new_switch(mock_event)
642
        mock_notify_topology_update.assert_called()
643
        mock_instance_metadata.assert_called()
644
645
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
646
    def test_handle_connection_lost(self, mock_notify_topology_update):
647
        """Test handle connection_lost."""
648
        mock_event = MagicMock()
649
        mock_switch = create_autospec(Switch)
650
        mock_switch.return_value = True
651
        mock_event.content['source'] = mock_switch
652
        self.napp.handle_connection_lost(mock_event)
653
        mock_notify_topology_update.assert_called()
654
655
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
656
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
657
    def test_handle_interface_up(self, *args):
658
        """Test handle_interface_up."""
659
        (mock_instance_metadata, mock_notify_topology_update) = args
660
        mock_event = MagicMock()
661
        mock_interface = create_autospec(Interface)
662
        mock_event.content['interface'] = mock_interface
663
        self.napp.handle_interface_up(mock_event)
664
        mock_notify_topology_update.assert_called()
665
        mock_instance_metadata.assert_called()
666
667
    @patch('napps.kytos.topology.main.Main.handle_interface_up')
668
    def test_handle_interface_created(self, mock_handle_interface_up):
669
        """Test handle interface created."""
670
        mock_event = MagicMock()
671
        self.napp.handle_interface_created(mock_event)
672
        mock_handle_interface_up.assert_called()
673
674
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
675
    @patch('napps.kytos.topology.main.Main.handle_interface_link_down')
676
    def test_handle_interface_down(self, *args):
677
        """Test handle interface down."""
678
        (mock_handle_interface_link_down, mock_notify_topology_update) = args
679
        mock_event = MagicMock()
680
        mock_interface = create_autospec(Interface)
681
        mock_event.content['interface'] = mock_interface
682
        self.napp.handle_interface_down(mock_event)
683
        mock_handle_interface_link_down.assert_called()
684
        mock_notify_topology_update.assert_called()
685
686
    @patch('napps.kytos.topology.main.Main.handle_interface_down')
687
    def test_interface_deleted(self, mock_handle_interface_link_down):
688
        """Test interface deleted."""
689
        mock_event = MagicMock()
690
        self.napp.handle_interface_deleted(mock_event)
691
        mock_handle_interface_link_down.assert_called()
692
693
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
694
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
695
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
696
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
697
    def test_interface_link_up(self, *args):
698
        """Test interface link_up."""
699
        (mock_status_change, mock_instance_metadata, mock_topology_update,
700
         mock_link_from_interface) = args
701
702
        now = time.time()
703
        mock_event = MagicMock()
704
        mock_interface_a = create_autospec(Interface)
705
        mock_interface_a.is_active.return_value = False
706
        mock_interface_b = create_autospec(Interface)
707
        mock_interface_b.is_active.return_value = True
708
        mock_link = create_autospec(Link)
709
        mock_link.get_metadata.return_value = now
710
        mock_link.is_active.side_effect = [False, True]
711
        mock_link.endpoint_a = mock_interface_a
712
        mock_link.endpoint_b = mock_interface_b
713
        mock_link_from_interface.return_value = mock_link
714
        content = {'interface': mock_interface_a}
715
        mock_event.content = content
716
        self.napp.link_up_timer = 1
717
        self.napp.handle_interface_link_up(mock_event)
718
        mock_topology_update.assert_called()
719
        mock_instance_metadata.assert_called()
720
        mock_status_change.assert_called()
721
722
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
723
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
724
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
725
    def test_interface_link_down(self, *args):
726
        """Test interface link down."""
727
        (mock_status_change, mock_topology_update,
728
         mock_link_from_interface) = args
729
730
        mock_event = MagicMock()
731
        mock_interface = create_autospec(Interface)
732
        mock_link = create_autospec(Link)
733
        mock_link.is_active.return_value = True
734
        mock_link_from_interface.return_value = mock_link
735
        mock_event.content['interface'] = mock_interface
736
        self.napp.handle_interface_link_down(mock_event)
737
        mock_topology_update.assert_called()
738
        mock_status_change.assert_called()
739
740
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
741
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
742
    def test_add_links(self, *args):
743
        """Test add_links."""
744
        (mock_notify_topology_update, mock_get_link_or_create) = args
745
        mock_event = MagicMock()
746
        self.napp.add_links(mock_event)
747
        mock_get_link_or_create.assert_called()
748
        mock_notify_topology_update.assert_called()
749
750
    @patch('napps.kytos.topology.main.Main._get_switches_dict')
751
    @patch('napps.kytos.topology.main.StoreHouse.save_status')
752
    def test_save_status_on_store(self, *args):
753
        """Test save_status_on_storehouse."""
754
        (mock_save_status, mock_get_switches_dict) = args
755
        self.napp.save_status_on_storehouse()
756
        mock_get_switches_dict.assert_called()
757
        mock_save_status.assert_called()
758
759
    @patch('napps.kytos.topology.main.KytosEvent')
760
    @patch('kytos.core.buffers.KytosEventBuffer.put')
761
    def test_notify_topology_update(self, *args):
762
        """Test notify_topology_update."""
763
        (mock_buffers_put, mock_event) = args
764
        self.napp.notify_topology_update()
765
        mock_event.assert_called()
766
        mock_buffers_put.assert_called()
767
768
    @patch('napps.kytos.topology.main.KytosEvent')
769
    @patch('kytos.core.buffers.KytosEventBuffer.put')
770
    def test_notify_link_status_change(self, *args):
771
        """Test notify link status change."""
772
        (mock_buffers_put, mock_event) = args
773
        mock_link = create_autospec(Link)
774
        self.napp.notify_link_status_change(mock_link)
775
        mock_event.assert_called()
776
        mock_buffers_put.assert_called()
777
778
    @patch('napps.kytos.topology.main.KytosEvent')
779
    @patch('kytos.core.buffers.KytosEventBuffer.put')
780
    @patch('napps.kytos.topology.main.isinstance')
781
    def test_notify_metadata_changes(self, *args):
782
        """Test notify metadata changes."""
783
        (mock_isinstance, mock_buffers_put, mock_event) = args
784
        mock_isinstance.return_value = True
785
        mock_obj = MagicMock()
786
        mock_action = create_autospec(Switch)
787
        self.napp.notify_metadata_changes(mock_obj, mock_action)
788
        mock_event.assert_called()
789
        mock_isinstance.assert_called()
790
        mock_buffers_put.assert_called()
791
792
    @patch('napps.kytos.topology.main.KytosEvent')
793
    @patch('kytos.core.buffers.KytosEventBuffer.put')
794
    def test_notify_port_created(self, *args):
795
        """Test notify port created."""
796
        (mock_buffers_put, mock_kytos_event) = args
797
        mock_event = MagicMock()
798
        self.napp.notify_port_created(mock_event)
799
        mock_kytos_event.assert_called()
800
        mock_buffers_put.assert_called()
801
802
    @patch('napps.kytos.topology.main.KytosEvent')
803
    @patch('kytos.core.buffers.KytosEventBuffer.put')
804
    def test_save_metadata_on_store(self, *args):
805
        """Test test_save_metadata_on_store."""
806
        (mock_buffers_put, mock_kytos_event) = args
807
        mock_event = MagicMock()
808
        mock_switch = MagicMock()
809
        mock_interface = MagicMock()
810
        mock_link = MagicMock()
811
        self.napp.store_items = {'switches': mock_switch,
812
                                 'interfaces': mock_interface,
813
                                 'links': mock_link}
814
        # test switches
815
        mock_event.content = {'switch': mock_switch}
816
        self.napp.save_metadata_on_store(mock_event)
817
        mock_kytos_event.assert_called()
818
        mock_buffers_put.assert_called()
819
820
        # test interfaces
821
        mock_event.content = {'interface': mock_interface}
822
        self.napp.save_metadata_on_store(mock_event)
823
        mock_kytos_event.assert_called()
824
        mock_buffers_put.assert_called()
825
826
        # test link
827
        mock_event.content = {'link': mock_link}
828
        self.napp.save_metadata_on_store(mock_event)
829
        mock_kytos_event.assert_called()
830
        mock_buffers_put.assert_called()
831
832
    @patch('napps.kytos.topology.main.KytosEvent')
833
    @patch('kytos.core.buffers.KytosEventBuffer.put')
834
    def test_verify_storehouse(self, *args):
835
        """Test verify_storehouse."""
836
        (mock_buffers_put, mock_kytos_event) = args
837
        mock_entities = MagicMock()
838
        self.napp.verify_storehouse(mock_entities)
839
        mock_buffers_put.assert_called()
840
        mock_kytos_event.assert_called()
841
842
    @patch('napps.kytos.topology.main.KytosEvent')
843
    @patch('kytos.core.buffers.KytosEventBuffer.put')
844
    def test_request_retrieve_entities(self, *args):
845
        """Test retrive_entities."""
846
        (mock_buffers_put, mock_kytos_event) = args
847
        mock_event = MagicMock()
848
        mock_data = MagicMock()
849
        mock_error = MagicMock()
850
        mock_event.content = {"namespace": "test_box"}
851
        self.napp.request_retrieve_entities(mock_event, mock_data, mock_error)
852
        mock_kytos_event.assert_called()
853
        mock_buffers_put.assert_called()
854
855
        self.napp.request_retrieve_entities(mock_event, None, mock_error)
856
        mock_kytos_event.assert_called()
857
        mock_buffers_put.assert_called()
858
859
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
860
    def test_handle_link_maintenance_start(self, status_change_mock):
861
        """Test handle_link_maintenance_start."""
862
        link1 = MagicMock()
863
        link1.id = 2
864
        link2 = MagicMock()
865
        link2.id = 3
866
        link3 = MagicMock()
867
        link3.id = 4
868
        content = {'links': [link1, link2]}
869
        event = MagicMock()
870
        event.content = content
871
        self.napp.links = {2: link1, 4: link3}
872
        self.napp.handle_link_maintenance_start(event)
873
        status_change_mock.assert_called_once_with(link1)
874
875
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
876
    def test_handle_link_maintenance_end(self, status_change_mock):
877
        """Test handle_link_maintenance_end."""
878
        link1 = MagicMock()
879
        link1.id = 2
880
        link2 = MagicMock()
881
        link2.id = 3
882
        link3 = MagicMock()
883
        link3.id = 4
884
        content = {'links': [link1, link2]}
885
        event = MagicMock()
886
        event.content = content
887
        self.napp.links = {2: link1, 4: link3}
888
        self.napp.handle_link_maintenance_end(event)
889
        status_change_mock.assert_called_once_with(link1)
890
891 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...
892
    def test_handle_switch_maintenance_start(self, handle_link_down_mock):
893
        """Test handle_switch_maintenance_start."""
894
        switch1 = MagicMock()
895
        interface1 = MagicMock()
896
        interface1.is_active.return_value = True
897
        interface2 = MagicMock()
898
        interface2.is_active.return_value = False
899
        interface3 = MagicMock()
900
        interface3.is_active.return_value = True
901
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
902
        switch2 = MagicMock()
903
        interface4 = MagicMock()
904
        interface4.is_active.return_value = False
905
        interface5 = MagicMock()
906
        interface5.is_active.return_value = True
907
        switch2.interfaces = {1: interface4, 2: interface5}
908
        content = {'switches': [switch1, switch2]}
909
        event = MagicMock()
910
        event.content = content
911
        self.napp.handle_switch_maintenance_start(event)
912
        self.assertEqual(handle_link_down_mock.call_count, 3)
913
914 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...
915
    def test_handle_switch_maintenance_end(self, handle_link_up_mock):
916
        """Test handle_switch_maintenance_end."""
917
        switch1 = MagicMock()
918
        interface1 = MagicMock()
919
        interface1.is_active.return_value = True
920
        interface2 = MagicMock()
921
        interface2.is_active.return_value = False
922
        interface3 = MagicMock()
923
        interface3.is_active.return_value = True
924
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
925
        switch2 = MagicMock()
926
        interface4 = MagicMock()
927
        interface4.is_active.return_value = False
928
        interface5 = MagicMock()
929
        interface5.is_active.return_value = True
930
        switch2.interfaces = {1: interface4, 2: interface5}
931
        content = {'switches': [switch1, switch2]}
932
        event = MagicMock()
933
        event.content = content
934
        self.napp.handle_switch_maintenance_end(event)
935
        self.assertEqual(handle_link_up_mock.call_count, 5)
936