Passed
Pull Request — master (#123)
by
unknown
02:27
created

TestMain.test_restore_links()   A

Complexity

Conditions 1

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nop 1
dl 0
loc 22
rs 9.55
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_interface_mock,
12
                               get_test_client, get_link_mock)
13
14
15
from tests.unit.helpers import get_controller_mock, get_napp_urls
16
17
18
# pylint: disable=too-many-public-methods
19
class TestMain(TestCase):
20
    """Test the Main class."""
21
22
    # pylint: disable=too-many-public-methods, protected-access,C0302
23
24
    def setUp(self):
25
        """Execute steps before each tests.
26
27
        Set the server_name_url_url from kytos/topology
28
        """
29
        self.server_name_url = 'http://localhost:8181/api/kytos/topology'
30
31
        patch('kytos.core.helpers.run_on_thread', lambda x: x).start()
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
                           '.*.network_status.updated',
46
                           '.*.interface.is.nni',
47
                           '.*.connection.lost',
48
                           '.*.switch.interface.created',
49
                           '.*.switch.interface.deleted',
50
                           '.*.switch.interface.link_down',
51
                           '.*.switch.interface.link_up',
52
                           '.*.switch.(new|reconnected)',
53
                           '.*.switch.port.created',
54
                           'kytos/topology.*.metadata.*']
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 = self.napp._get_link_or_create(mock_interface_a,
118
                                             mock_interface_b)
119
        self.assertEqual(link.endpoint_a.id, dpid_a)
120
        self.assertEqual(link.endpoint_b.id, dpid_b)
121
122
    def test_get_link_from_interface(self):
123
        """Test _get_link_from_interface."""
124
        mock_switch_a = get_switch_mock("00:00:00:00:00:00:00:01", 0x04)
125
        mock_switch_b = get_switch_mock("00:00:00:00:00:00:00:02", 0x04)
126
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
127
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
128
        mock_interface_c = get_interface_mock('s2-eth1', 2, mock_switch_b)
129
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
130
        self.napp.links = {'0e2b5d7bc858b9f38db11b69': mock_link}
131
        response = self.napp._get_link_from_interface(mock_interface_a)
132
        self.assertEqual(response, mock_link)
133
134
        response = self.napp._get_link_from_interface(mock_interface_c)
135
        self.assertEqual(response, None)
136
137
    def test_get_topology(self):
138
        """Test get_topology."""
139
        dpid_a = "00:00:00:00:00:00:00:01"
140
        dpid_b = "00:00:00:00:00:00:00:02"
141
        expected = {
142
                      "topology": {
143
                        "switches": {
144
                          "00:00:00:00:00:00:00:01": {
145
                            "metadata": {
146
                              "lat": "0.0",
147
                              "lng": "-30.0"
148
                            }
149
                          },
150
                          "00:00:00:00:00:00:00:02": {
151
                            "metadata": {
152
                              "lat": "0.0",
153
                              "lng": "-30.0"
154
                            }
155
                          }
156
                        },
157
                        "links": {
158
                          "cf0f4071be4": {
159
                            "id": "cf0f4071be4"
160
                          }
161
                        }
162
                      }
163
                    }
164
165
        mock_switch_a = get_switch_mock(dpid_a, 0x04)
166
        mock_switch_b = get_switch_mock(dpid_b, 0x04)
167
        mock_interface_a = get_interface_mock('s1-eth1', 1, mock_switch_a)
168
        mock_interface_b = get_interface_mock('s2-eth1', 1, mock_switch_b)
169
170
        mock_link = get_link_mock(mock_interface_a, mock_interface_b)
171
        mock_link.id = 'cf0f4071be4'
172
        mock_switch_a.id = dpid_a
173
        mock_switch_a.as_dict.return_value = {'metadata': {'lat': '0.0',
174
                                              'lng': '-30.0'}}
175
        mock_switch_b.id = dpid_b
176
        mock_switch_b.as_dict.return_value = {'metadata': {'lat': '0.0',
177
                                              'lng': '-30.0'}}
178
179
        self.napp.controller.switches = {dpid_a: mock_switch_a,
180
                                         dpid_b: mock_switch_b}
181
182
        self.napp.links = {"cf0f4071be4": mock_link}
183
        mock_link.as_dict.return_value = {"id": "cf0f4071be4"}
184
        api = get_test_client(self.napp.controller, self.napp)
185
186
        url = f'{self.server_name_url}/v3/'
187
        response = api.get(url)
188
        self.assertEqual(response.status_code, 200)
189
        self.assertEqual(json.loads(response.data), expected)
190
191
    @patch('napps.kytos.topology.main.StoreHouse.get_data')
192
    def test_load_network_status(self, mock_storehouse_get_data):
193
        """Test _load_network_status."""
194
        status = {
195
            'network_status': {
196
                'id': 'network_status',
197
                'links': {
198
                    '4d42dc08522': {
199
                        'enabled': True,
200
                        'endpoint_a': {
201
                            'switch': '00:00:00:00:00:00:00:01',
202
                            'id': '00:00:00:00:00:00:00:00:1'
203
                        },
204
                        'endpoint_b': {
205
                            'switch': '00:00:00:00:00:00:00:01',
206
                            'id': '00:00:00:00:00:00:00:00:2'
207
                        }
208
                    }
209
                },
210
                'switches': {
211
                    '00:00:00:00:00:00:00:01': {
212
                        'dpid': '00:00:00:00:00:00:00:01',
213
                        'enabled': True,
214
                        'id': '00:00:00:00:00:00:00:01',
215
                        'interfaces': {
216
                            '00:00:00:00:00:00:00:01:1': {
217
                                'enabled': True,
218
                                'lldp': True,
219
                                'id': '00:00:00:00:00:00:00:00:1',
220
                            }
221
                        }
222
                    }
223
                }
224
            }
225
        }
226
        switches_expected = {'00:00:00:00:00:00:00:01': True}
227
        interfaces_expected = {'00:00:00:00:00:00:00:01:1': (True, True)}
228
        mock_storehouse_get_data.return_value = status
229
        self.napp._load_network_status()
230
        self.assertDictEqual(switches_expected, self.napp.switches_state)
231
        self.assertDictEqual(interfaces_expected, self.napp.interfaces_state)
232
        self.assertDictEqual(status['network_status']['links'],
233
                             self.napp.links_state)
234
235
    # pylint: disable=too-many-locals
236
    def test_restore_network_status(self):
237
        """Test restore_network_status."""
238
        dpid = '00:00:00:00:00:00:00:01'
239
        mock_switch = get_switch_mock(dpid)
240
        mock_switch.id = dpid
241
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
242
        mock_switch.interfaces = {1: mock_interface}
243
        self.napp.controller.switches = {dpid: mock_switch}
244
        self.napp.switches_state = {dpid: True}
245
        self.napp.interfaces_state = {'00:00:00:00:00:00:00:01:1': (True,
246
                                                                    True)}
247
248
        # enable
249
        self.napp.restore_network_status(mock_switch)
250
        self.assertEqual(mock_switch.enable.call_count, 1)
251
        self.assertEqual(mock_interface.enable.call_count, 1)
252
        self.assertEqual(mock_interface.lldp, True)
253
254
        # disable
255
        self.napp.switches_state = {dpid: False}
256
        self.napp.interfaces_state = {'00:00:00:00:00:00:00:01:1': (False,
257
                                                                    False)}
258
        self.napp.restore_network_status(mock_switch)
259
        self.assertEqual(mock_switch.disable.call_count, 1)
260
        self.assertEqual(mock_interface.disable.call_count, 1)
261
        self.assertEqual(mock_interface.lldp, False)
262
263
    def test_restore_links(self):
264
        """Test restore_link."""
265
        dpid = '00:00:00:00:00:00:00:01'
266
        dpid_b = '00:00:00:00:00:00:00:02'
267
        link_id = '4d42dc08522'
268
        mock_switch_a = get_switch_mock(dpid)
269
        mock_switch_b = get_switch_mock(dpid_b)
270
        mock_interface_a_1 = get_interface_mock('s1-eth1', 1, mock_switch_a)
271
        mock_interface_b_1 = get_interface_mock('s2-eth1', 1, mock_switch_b)
272
        mock_link = get_link_mock(mock_interface_a_1, mock_interface_b_1)
273
        mock_link.id = link_id
274
        self.napp.links = {link_id: mock_link}
275
        self.napp.links_state = {link_id: {"enabled": True}}
276
277
        # enable link
278
        self.napp._restore_links(mock_link)
279
        self.assertEqual(mock_link.enable.call_count, 1)
280
281
        # disable link
282
        self.napp.links_state = {link_id: {"enabled": False}}
283
        self.napp._restore_links(mock_link)
284
        self.assertEqual(mock_link.disable.call_count, 1)
285
286 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...
287
    def test_enable_switch(self, mock_save_status):
288
        """Test enable_switch."""
289
        dpid = "00:00:00:00:00:00:00:01"
290
        mock_switch = get_switch_mock(dpid)
291
        self.napp.controller.switches = {dpid: mock_switch}
292
        api = get_test_client(self.napp.controller, self.napp)
293
294
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
295
        response = api.post(url)
296
        self.assertEqual(response.status_code, 201, response.data)
297
        self.assertEqual(mock_switch.enable.call_count, 1)
298
        mock_save_status.assert_called()
299
300
        # fail case
301
        mock_switch.enable.call_count = 0
302
        dpid = "00:00:00:00:00:00:00:02"
303
        url = f'{self.server_name_url}/v3/switches/{dpid}/enable'
304
        response = api.post(url)
305
        self.assertEqual(response.status_code, 404, response.data)
306
        self.assertEqual(mock_switch.enable.call_count, 0)
307
308 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...
309
    def test_disable_switch(self, mock_save_status):
310
        """Test disable_switch."""
311
        dpid = "00:00:00:00:00:00:00:01"
312
        mock_switch = get_switch_mock(dpid)
313
        self.napp.controller.switches = {dpid: mock_switch}
314
        api = get_test_client(self.napp.controller, self.napp)
315
316
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
317
        response = api.post(url)
318
        self.assertEqual(response.status_code, 201, response.data)
319
        self.assertEqual(mock_switch.disable.call_count, 1)
320
        mock_save_status.assert_called()
321
322
        # fail case
323
        mock_switch.disable.call_count = 0
324
        dpid = "00:00:00:00:00:00:00:02"
325
        url = f'{self.server_name_url}/v3/switches/{dpid}/disable'
326
        response = api.post(url)
327
        self.assertEqual(response.status_code, 404, response.data)
328
        self.assertEqual(mock_switch.disable.call_count, 0)
329
330
    def test_get_switch_metadata(self):
331
        """Test get_switch_metadata."""
332
        dpid = "00:00:00:00:00:00:00:01"
333
        mock_switch = get_switch_mock(dpid)
334
        mock_switch.metadata = "A"
335
        self.napp.controller.switches = {dpid: mock_switch}
336
        api = get_test_client(self.napp.controller, self.napp)
337
338
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
339
        response = api.get(url)
340
        self.assertEqual(response.status_code, 200, response.data)
341
342
        # fail case
343
        dpid = "00:00:00:00:00:00:00:02"
344
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
345
        response = api.get(url)
346
        self.assertEqual(response.status_code, 404, response.data)
347
348
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
349
    def test_add_switch_metadata(self, mock_metadata_changes):
350
        """Test add_switch_metadata."""
351
        dpid = "00:00:00:00:00:00:00:01"
352
        mock_switch = get_switch_mock(dpid)
353
        self.napp.controller.switches = {dpid: mock_switch}
354
        api = get_test_client(self.napp.controller, self.napp)
355
        payload = {"data": "A"}
356
357
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
358
        response = api.post(url, data=json.dumps(payload),
359
                            content_type='application/json')
360
        self.assertEqual(response.status_code, 201, response.data)
361
        mock_metadata_changes.assert_called()
362
363
        # fail case
364
        dpid = "00:00:00:00:00:00:00:02"
365
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata'
366
        response = api.post(url, data=json.dumps(payload),
367
                            content_type='application/json')
368
        self.assertEqual(response.status_code, 404, response.data)
369
370
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
371
    def test_delete_switch_metadata(self, mock_metadata_changes):
372
        """Test delete_switch_metadata."""
373
        dpid = "00:00:00:00:00:00:00:01"
374
        mock_switch = get_switch_mock(dpid)
375
        self.napp.controller.switches = {dpid: mock_switch}
376
        api = get_test_client(self.napp.controller, self.napp)
377
378
        key = "A"
379
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
380
        response = api.delete(url)
381
        mock_metadata_changes.assert_called()
382
        self.assertEqual(response.status_code, 200, response.data)
383
384
        # fail case
385
        key = "A"
386
        dpid = "00:00:00:00:00:00:00:02"
387
        url = f'{self.server_name_url}/v3/switches/{dpid}/metadata/{key}'
388
        response = api.delete(url)
389
        mock_metadata_changes.assert_called()
390
        self.assertEqual(response.status_code, 404, response.data)
391
392 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...
393
    def test_enable_interfaces(self, mock_save_status):
394
        """Test enable_interfaces."""
395
        dpid = '00:00:00:00:00:00:00:01'
396
        mock_switch = get_switch_mock(dpid)
397
        mock_interface_1 = get_interface_mock('s1-eth1', 1, mock_switch)
398
        mock_interface_2 = get_interface_mock('s1-eth2', 2, mock_switch)
399
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
400
        self.napp.controller.switches = {dpid: mock_switch}
401
        api = get_test_client(self.napp.controller, self.napp)
402
403
        interface_id = '00:00:00:00:00:00:00:01:1'
404
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
405
        response = api.post(url)
406
        self.assertEqual(response.status_code, 200, response.data)
407
        self.assertEqual(mock_interface_1.enable.call_count, 1)
408
        self.assertEqual(mock_interface_2.enable.call_count, 0)
409
        mock_save_status.assert_called()
410
411
        mock_interface_1.enable.call_count = 0
412
        mock_interface_2.enable.call_count = 0
413
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
414
        response = api.post(url)
415
        self.assertEqual(response.status_code, 200, response.data)
416
        self.assertEqual(mock_interface_1.enable.call_count, 1)
417
        self.assertEqual(mock_interface_2.enable.call_count, 1)
418
419
        # test interface not found
420
        interface_id = '00:00:00:00:00:00:00:01:3'
421
        mock_interface_1.enable.call_count = 0
422
        mock_interface_2.enable.call_count = 0
423
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/enable'
424
        response = api.post(url)
425
        self.assertEqual(response.status_code, 409, response.data)
426
        self.assertEqual(mock_interface_1.enable.call_count, 0)
427
        self.assertEqual(mock_interface_2.enable.call_count, 0)
428
429
        # test switch not found
430
        dpid = '00:00:00:00:00:00:00:02'
431
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/enable'
432
        response = api.post(url)
433
        self.assertEqual(response.status_code, 404, response.data)
434
        self.assertEqual(mock_interface_1.enable.call_count, 0)
435
        self.assertEqual(mock_interface_2.enable.call_count, 0)
436
437 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...
438
    def test_disable_interfaces(self, mock_save_status):
439
        """Test disable_interfaces."""
440
        interface_id = '00:00:00:00:00:00:00:01:1'
441
        dpid = '00:00:00:00:00:00:00:01'
442
        mock_switch = get_switch_mock(dpid)
443
        mock_interface_1 = get_interface_mock('s1-eth1', 1, mock_switch)
444
        mock_interface_2 = get_interface_mock('s1-eth2', 2, mock_switch)
445
        mock_switch.interfaces = {1: mock_interface_1, 2: mock_interface_2}
446
        self.napp.controller.switches = {dpid: mock_switch}
447
        api = get_test_client(self.napp.controller, self.napp)
448
449
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
450
        response = api.post(url)
451
        self.assertEqual(response.status_code, 200, response.data)
452
        self.assertEqual(mock_interface_1.disable.call_count, 1)
453
        self.assertEqual(mock_interface_2.disable.call_count, 0)
454
        mock_save_status.assert_called()
455
456
        mock_interface_1.disable.call_count = 0
457
        mock_interface_2.disable.call_count = 0
458
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
459
        response = api.post(url)
460
        self.assertEqual(response.status_code, 200, response.data)
461
        self.assertEqual(mock_interface_1.disable.call_count, 1)
462
        self.assertEqual(mock_interface_2.disable.call_count, 1)
463
464
        # test interface not found
465
        interface_id = '00:00:00:00:00:00:00:01:3'
466
        mock_interface_1.disable.call_count = 0
467
        mock_interface_2.disable.call_count = 0
468
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/disable'
469
        response = api.post(url)
470
        self.assertEqual(response.status_code, 409, response.data)
471
        self.assertEqual(mock_interface_1.disable.call_count, 0)
472
        self.assertEqual(mock_interface_2.disable.call_count, 0)
473
474
        # test switch not found
475
        dpid = '00:00:00:00:00:00:00:02'
476
        url = f'{self.server_name_url}/v3/interfaces/switch/{dpid}/disable'
477
        response = api.post(url)
478
        self.assertEqual(response.status_code, 404, response.data)
479
        self.assertEqual(mock_interface_1.disable.call_count, 0)
480
        self.assertEqual(mock_interface_2.disable.call_count, 0)
481
482
    def test_get_interface_metadata(self):
483
        """Test get_interface_metada."""
484
        interface_id = '00:00:00:00:00:00:00:01:1'
485
        dpid = '00:00:00:00:00:00:00:01'
486
        mock_switch = get_switch_mock(dpid)
487
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
488
        mock_interface.metadata = {"metada": "A"}
489
        mock_switch.interfaces = {1: mock_interface}
490
        self.napp.controller.switches = {dpid: mock_switch}
491
        api = get_test_client(self.napp.controller, self.napp)
492
493
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
494
        response = api.get(url)
495
        self.assertEqual(response.status_code, 200, response.data)
496
497
        # fail case switch not found
498
        interface_id = '00:00:00:00:00:00:00:02:1'
499
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
500
        response = api.get(url)
501
        self.assertEqual(response.status_code, 404, response.data)
502
503
        # fail case interface not found
504
        interface_id = '00:00:00:00:00:00:00:01:2'
505
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
506
        response = api.get(url)
507
        self.assertEqual(response.status_code, 404, response.data)
508
509
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
510
    def test_add_interface_metadata(self, mock_metadata_changes):
511
        """Test add_interface_metadata."""
512
        interface_id = '00:00:00:00:00:00:00:01:1'
513
        dpid = '00:00:00:00:00:00:00:01'
514
        mock_switch = get_switch_mock(dpid)
515
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
516
        mock_interface.metadata = {"metada": "A"}
517
        mock_switch.interfaces = {1: mock_interface}
518
        self.napp.controller.switches = {dpid: mock_switch}
519
        api = get_test_client(self.napp.controller, self.napp)
520
521
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
522
        payload = {"metada": "A"}
523
        response = api.post(url, data=json.dumps(payload),
524
                            content_type='application/json')
525
        self.assertEqual(response.status_code, 201, response.data)
526
        mock_metadata_changes.assert_called()
527
528
        # fail case switch not found
529
        interface_id = '00:00:00:00:00:00:00:02:1'
530
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
531
        response = api.post(url, data=json.dumps(payload),
532
                            content_type='application/json')
533
        self.assertEqual(response.status_code, 404, response.data)
534
535
        # fail case interface not found
536
        interface_id = '00:00:00:00:00:00:00:01:2'
537
        url = f'{self.server_name_url}/v3/interfaces/{interface_id}/metadata'
538
        response = api.post(url, data=json.dumps(payload),
539
                            content_type='application/json')
540
        self.assertEqual(response.status_code, 404, response.data)
541
542
    def test_delete_interface_metadata(self):
543
        """Test delete_interface_metadata."""
544
        interface_id = '00:00:00:00:00:00:00:01:1'
545
        dpid = '00:00:00:00:00:00:00:01'
546
        iface_url = '/v3/interfaces/'
547
        mock_switch = get_switch_mock(dpid)
548
        mock_interface = get_interface_mock('s1-eth1', 1, mock_switch)
549
        mock_interface.remove_metadata.side_effect = [True, False]
550
        mock_interface.metadata = {"metada": "A"}
551
        mock_switch.interfaces = {1: mock_interface}
552
        self.napp.controller.switches = {'00:00:00:00:00:00:00:01':
553
                                         mock_switch}
554
        api = get_test_client(self.napp.controller, self.napp)
555
556
        key = 'A'
557
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
558
        response = api.delete(url)
559
        self.assertEqual(response.status_code, 200, response.data)
560
561
        # fail case switch not found
562
        key = 'A'
563
        interface_id = '00:00:00:00:00:00:00:02:1'
564
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
565
        response = api.delete(url)
566
        self.assertEqual(response.status_code, 404, response.data)
567
568
        # fail case interface not found
569
        key = 'A'
570
        interface_id = '00:00:00:00:00:00:00:01:2'
571
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
572
        response = api.delete(url)
573
        self.assertEqual(response.status_code, 404, response.data)
574
575
        # fail case metadata not found
576
        key = 'A'
577
        interface_id = '00:00:00:00:00:00:00:01:1'
578
        url = f'{self.server_name_url}{iface_url}{interface_id}/metadata/{key}'
579
        response = api.delete(url)
580
        self.assertEqual(response.status_code, 404, response.data)
581
582
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
583
    def test_enable_link(self, mock_save_status):
584
        """Test enable_link."""
585
        mock_link = MagicMock(Link)
586
        self.napp.links = {'1': mock_link}
587
        api = get_test_client(self.napp.controller, self.napp)
588
        mock_save_status.return_value = True
589
590
        link_id = 1
591
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
592
        response = api.post(url)
593
        self.assertEqual(response.status_code, 201, response.data)
594
        self.assertEqual(mock_link.enable.call_count, 1)
595
596
        # fail case
597
        link_id = 2
598
        url = f'{self.server_name_url}/v3/links/{link_id}/enable'
599
        response = api.post(url)
600
        self.assertEqual(response.status_code, 404, response.data)
601
602
    @patch('napps.kytos.topology.main.Main.save_status_on_storehouse')
603
    def test_disable_link(self, mock_save_status):
604
        """Test disable_link."""
605
        mock_link = MagicMock(Link)
606
        self.napp.links = {'1': mock_link}
607
        api = get_test_client(self.napp.controller, self.napp)
608
        mock_save_status.return_value = True
609
610
        link_id = 1
611
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
612
        response = api.post(url)
613
        self.assertEqual(response.status_code, 201, response.data)
614
        self.assertEqual(mock_link.disable.call_count, 1)
615
616
        # fail case
617
        link_id = 2
618
        url = f'{self.server_name_url}/v3/links/{link_id}/disable'
619
        response = api.post(url)
620
        self.assertEqual(response.status_code, 404, response.data)
621
622
    def test_get_link_metadata(self):
623
        """Test get_link_metadata."""
624
        mock_link = MagicMock(Link)
625
        mock_link.metadata = "A"
626
        self.napp.links = {'1': mock_link}
627
        msg_success = {"metadata": "A"}
628
        api = get_test_client(self.napp.controller, self.napp)
629
630
        link_id = 1
631
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
632
        response = api.get(url)
633
        self.assertEqual(response.status_code, 200, response.data)
634
        self.assertEqual(msg_success, json.loads(response.data))
635
636
        # fail case
637
        link_id = 2
638
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
639
        response = api.get(url)
640
        self.assertEqual(response.status_code, 404, response.data)
641
642
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
643
    def test_add_link_metadata(self, mock_metadata_changes):
644
        """Test add_link_metadata."""
645
        mock_link = MagicMock(Link)
646
        mock_link.metadata = "A"
647
        self.napp.links = {'1': mock_link}
648
        payload = {"metadata": "A"}
649
        api = get_test_client(self.napp.controller, self.napp)
650
651
        link_id = 1
652
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
653
        response = api.post(url, data=json.dumps(payload),
654
                            content_type='application/json')
655
        self.assertEqual(response.status_code, 201, response.data)
656
        mock_metadata_changes.assert_called()
657
658
        # fail case
659
        link_id = 2
660
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata'
661
        response = api.post(url, data=json.dumps(payload),
662
                            content_type='application/json')
663
        self.assertEqual(response.status_code, 404, response.data)
664
665
    @patch('napps.kytos.topology.main.Main.notify_metadata_changes')
666
    def test_delete_link_metadata(self, mock_metadata_changes):
667
        """Test delete_link_metadata."""
668
        mock_link = MagicMock(Link)
669
        mock_link.metadata = "A"
670
        mock_link.remove_metadata.side_effect = [True, False]
671
        self.napp.links = {'1': mock_link}
672
        api = get_test_client(self.napp.controller, self.napp)
673
674
        link_id = 1
675
        key = 'A'
676
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
677
        response = api.delete(url)
678
        self.assertEqual(response.status_code, 200, response.data)
679
        mock_metadata_changes.assert_called()
680
681
        # fail case link not found
682
        link_id = 2
683
        key = 'A'
684
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
685
        response = api.delete(url)
686
        self.assertEqual(response.status_code, 404, response.data)
687
688
        # fail case metadata not found
689
        link_id = 1
690
        key = 'A'
691
        url = f'{self.server_name_url}/v3/links/{link_id}/metadata/{key}'
692
        response = api.delete(url)
693
        self.assertEqual(response.status_code, 404, response.data)
694
695
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
696
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
697
    def test_handle_new_switch(self, *args):
698
        """Test handle_new_switch."""
699
        (mock_instance_metadata, mock_notify_topology_update) = args
700
        mock_event = MagicMock()
701
        mock_switch = create_autospec(Switch)
702
        mock_event.content['switch'] = mock_switch
703
        self.napp.handle_new_switch(mock_event)
704
        mock_notify_topology_update.assert_called()
705
        mock_instance_metadata.assert_called()
706
707
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
708
    def test_handle_connection_lost(self, mock_notify_topology_update):
709
        """Test handle connection_lost."""
710
        mock_event = MagicMock()
711
        mock_switch = create_autospec(Switch)
712
        mock_switch.return_value = True
713
        mock_event.content['source'] = mock_switch
714
        self.napp.handle_connection_lost(mock_event)
715
        mock_notify_topology_update.assert_called()
716
717
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
718
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
719
    def test_handle_interface_up(self, *args):
720
        """Test handle_interface_up."""
721
        (mock_instance_metadata, mock_notify_topology_update) = args
722
        mock_event = MagicMock()
723
        mock_interface = create_autospec(Interface)
724
        mock_event.content['interface'] = mock_interface
725
        self.napp.handle_interface_up(mock_event)
726
        mock_notify_topology_update.assert_called()
727
        mock_instance_metadata.assert_called()
728
729
    @patch('napps.kytos.topology.main.Main.handle_interface_up')
730
    def test_handle_interface_created(self, mock_handle_interface_up):
731
        """Test handle interface created."""
732
        mock_event = MagicMock()
733
        self.napp.handle_interface_created(mock_event)
734
        mock_handle_interface_up.assert_called()
735
736
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
737
    @patch('napps.kytos.topology.main.Main.handle_interface_link_down')
738
    def test_handle_interface_down(self, *args):
739
        """Test handle interface down."""
740
        (mock_handle_interface_link_down, mock_notify_topology_update) = args
741
        mock_event = MagicMock()
742
        mock_interface = create_autospec(Interface)
743
        mock_event.content['interface'] = mock_interface
744
        self.napp.handle_interface_down(mock_event)
745
        mock_handle_interface_link_down.assert_called()
746
        mock_notify_topology_update.assert_called()
747
748
    @patch('napps.kytos.topology.main.Main.handle_interface_down')
749
    def test_interface_deleted(self, mock_handle_interface_link_down):
750
        """Test interface deleted."""
751
        mock_event = MagicMock()
752
        self.napp.handle_interface_deleted(mock_event)
753
        mock_handle_interface_link_down.assert_called()
754
755
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
756
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
757
    @patch('napps.kytos.topology.main.Main.update_instance_metadata')
758
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
759
    def test_interface_link_up(self, *args):
760
        """Test interface link_up."""
761
        (mock_status_change, mock_instance_metadata, mock_topology_update,
762
         mock_link_from_interface) = args
763
764
        now = time.time()
765
        mock_event = MagicMock()
766
        mock_interface_a = create_autospec(Interface)
767
        mock_interface_a.is_active.return_value = False
768
        mock_interface_b = create_autospec(Interface)
769
        mock_interface_b.is_active.return_value = True
770
        mock_link = create_autospec(Link)
771
        mock_link.get_metadata.return_value = now
772
        mock_link.is_active.side_effect = [False, True]
773
        mock_link.endpoint_a = mock_interface_a
774
        mock_link.endpoint_b = mock_interface_b
775
        mock_link_from_interface.return_value = mock_link
776
        content = {'interface': mock_interface_a}
777
        mock_event.content = content
778
        self.napp.link_up_timer = 1
779
        self.napp.handle_interface_link_up(mock_event)
780
        mock_topology_update.assert_called()
781
        mock_instance_metadata.assert_called()
782
        mock_status_change.assert_called()
783
784
    @patch('napps.kytos.topology.main.Main._get_link_from_interface')
785
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
786
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
787
    def test_interface_link_down(self, *args):
788
        """Test interface link down."""
789
        (mock_status_change, mock_topology_update,
790
         mock_link_from_interface) = args
791
792
        mock_event = MagicMock()
793
        mock_interface = create_autospec(Interface)
794
        mock_link = create_autospec(Link)
795
        mock_link.is_active.return_value = True
796
        mock_link_from_interface.return_value = mock_link
797
        mock_event.content['interface'] = mock_interface
798
        self.napp.handle_interface_link_down(mock_event)
799
        mock_topology_update.assert_called()
800
        mock_status_change.assert_called()
801
802
    @patch('napps.kytos.topology.main.Main._get_link_or_create')
803
    @patch('napps.kytos.topology.main.Main.notify_topology_update')
804
    def test_add_links(self, *args):
805
        """Test add_links."""
806
        (mock_notify_topology_update, mock_get_link_or_create) = args
807
        mock_event = MagicMock()
808
        self.napp.add_links(mock_event)
809
        mock_get_link_or_create.assert_called()
810
        mock_notify_topology_update.assert_called()
811
812
    @patch('napps.kytos.topology.main.Main._get_switches_dict')
813
    @patch('napps.kytos.topology.main.StoreHouse.save_status')
814
    def test_save_status_on_store(self, *args):
815
        """Test save_status_on_storehouse."""
816
        (mock_save_status, mock_get_switches_dict) = args
817
        self.napp.save_status_on_storehouse()
818
        mock_get_switches_dict.assert_called()
819
        mock_save_status.assert_called()
820
821
    @patch('napps.kytos.topology.main.KytosEvent')
822
    @patch('kytos.core.buffers.KytosEventBuffer.put')
823
    def test_notify_topology_update(self, *args):
824
        """Test notify_topology_update."""
825
        (mock_buffers_put, mock_event) = args
826
        self.napp.notify_topology_update()
827
        mock_event.assert_called()
828
        mock_buffers_put.assert_called()
829
830
    @patch('napps.kytos.topology.main.KytosEvent')
831
    @patch('kytos.core.buffers.KytosEventBuffer.put')
832
    def test_notify_link_status_change(self, *args):
833
        """Test notify link status change."""
834
        (mock_buffers_put, mock_event) = args
835
        mock_link = create_autospec(Link)
836
        self.napp.notify_link_status_change(mock_link)
837
        mock_event.assert_called()
838
        mock_buffers_put.assert_called()
839
840
    @patch('napps.kytos.topology.main.KytosEvent')
841
    @patch('kytos.core.buffers.KytosEventBuffer.put')
842
    @patch('napps.kytos.topology.main.isinstance')
843
    def test_notify_metadata_changes(self, *args):
844
        """Test notify metadata changes."""
845
        (mock_isinstance, mock_buffers_put, mock_event) = args
846
        mock_isinstance.return_value = True
847
        mock_obj = MagicMock()
848
        mock_action = create_autospec(Switch)
849
        self.napp.notify_metadata_changes(mock_obj, mock_action)
850
        mock_event.assert_called()
851
        mock_isinstance.assert_called()
852
        mock_buffers_put.assert_called()
853
854
    @patch('napps.kytos.topology.main.KytosEvent')
855
    @patch('kytos.core.buffers.KytosEventBuffer.put')
856
    def test_notify_port_created(self, *args):
857
        """Test notify port created."""
858
        (mock_buffers_put, mock_kytos_event) = args
859
        mock_event = MagicMock()
860
        self.napp.notify_port_created(mock_event)
861
        mock_kytos_event.assert_called()
862
        mock_buffers_put.assert_called()
863
864
    @patch('napps.kytos.topology.main.KytosEvent')
865
    @patch('kytos.core.buffers.KytosEventBuffer.put')
866
    def test_save_metadata_on_store(self, *args):
867
        """Test test_save_metadata_on_store."""
868
        (mock_buffers_put, mock_kytos_event) = args
869
        mock_event = MagicMock()
870
        mock_switch = MagicMock()
871
        mock_interface = MagicMock()
872
        mock_link = MagicMock()
873
        self.napp.store_items = {'switches': mock_switch,
874
                                 'interfaces': mock_interface,
875
                                 'links': mock_link}
876
        # test switches
877
        mock_event.content = {'switch': mock_switch}
878
        self.napp.save_metadata_on_store(mock_event)
879
        mock_kytos_event.assert_called()
880
        mock_buffers_put.assert_called()
881
882
        # test interfaces
883
        mock_event.content = {'interface': mock_interface}
884
        self.napp.save_metadata_on_store(mock_event)
885
        mock_kytos_event.assert_called()
886
        mock_buffers_put.assert_called()
887
888
        # test link
889
        mock_event.content = {'link': mock_link}
890
        self.napp.save_metadata_on_store(mock_event)
891
        mock_kytos_event.assert_called()
892
        mock_buffers_put.assert_called()
893
894
    @patch('napps.kytos.topology.main.KytosEvent')
895
    @patch('kytos.core.buffers.KytosEventBuffer.put')
896
    def test_verify_storehouse(self, *args):
897
        """Test verify_storehouse."""
898
        (mock_buffers_put, mock_kytos_event) = args
899
        mock_entities = MagicMock()
900
        self.napp.verify_storehouse(mock_entities)
901
        mock_buffers_put.assert_called()
902
        mock_kytos_event.assert_called()
903
904
    @patch('napps.kytos.topology.main.KytosEvent')
905
    @patch('kytos.core.buffers.KytosEventBuffer.put')
906
    def test_request_retrieve_entities(self, *args):
907
        """Test retrive_entities."""
908
        (mock_buffers_put, mock_kytos_event) = args
909
        mock_event = MagicMock()
910
        mock_data = MagicMock()
911
        mock_error = MagicMock()
912
        mock_event.content = {"namespace": "test_box"}
913
        self.napp.request_retrieve_entities(mock_event, mock_data, mock_error)
914
        mock_kytos_event.assert_called()
915
        mock_buffers_put.assert_called()
916
917
        self.napp.request_retrieve_entities(mock_event, None, mock_error)
918
        mock_kytos_event.assert_called()
919
        mock_buffers_put.assert_called()
920
921
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
922
    def test_handle_link_maintenance_start(self, status_change_mock):
923
        """Test handle_link_maintenance_start."""
924
        link1 = MagicMock()
925
        link1.id = 2
926
        link2 = MagicMock()
927
        link2.id = 3
928
        link3 = MagicMock()
929
        link3.id = 4
930
        content = {'links': [link1, link2]}
931
        event = MagicMock()
932
        event.content = content
933
        self.napp.links = {2: link1, 4: link3}
934
        self.napp.handle_link_maintenance_start(event)
935
        status_change_mock.assert_called_once_with(link1)
936
937
    @patch('napps.kytos.topology.main.Main.notify_link_status_change')
938
    def test_handle_link_maintenance_end(self, status_change_mock):
939
        """Test handle_link_maintenance_end."""
940
        link1 = MagicMock()
941
        link1.id = 2
942
        link2 = MagicMock()
943
        link2.id = 3
944
        link3 = MagicMock()
945
        link3.id = 4
946
        content = {'links': [link1, link2]}
947
        event = MagicMock()
948
        event.content = content
949
        self.napp.links = {2: link1, 4: link3}
950
        self.napp.handle_link_maintenance_end(event)
951
        status_change_mock.assert_called_once_with(link1)
952
953 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...
954
    def test_handle_switch_maintenance_start(self, handle_link_down_mock):
955
        """Test handle_switch_maintenance_start."""
956
        switch1 = MagicMock()
957
        interface1 = MagicMock()
958
        interface1.is_active.return_value = True
959
        interface2 = MagicMock()
960
        interface2.is_active.return_value = False
961
        interface3 = MagicMock()
962
        interface3.is_active.return_value = True
963
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
964
        switch2 = MagicMock()
965
        interface4 = MagicMock()
966
        interface4.is_active.return_value = False
967
        interface5 = MagicMock()
968
        interface5.is_active.return_value = True
969
        switch2.interfaces = {1: interface4, 2: interface5}
970
        content = {'switches': [switch1, switch2]}
971
        event = MagicMock()
972
        event.content = content
973
        self.napp.handle_switch_maintenance_start(event)
974
        self.assertEqual(handle_link_down_mock.call_count, 3)
975
976 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...
977
    def test_handle_switch_maintenance_end(self, handle_link_up_mock):
978
        """Test handle_switch_maintenance_end."""
979
        switch1 = MagicMock()
980
        interface1 = MagicMock()
981
        interface1.is_active.return_value = True
982
        interface2 = MagicMock()
983
        interface2.is_active.return_value = False
984
        interface3 = MagicMock()
985
        interface3.is_active.return_value = True
986
        switch1.interfaces = {1: interface1, 2: interface2, 3: interface3}
987
        switch2 = MagicMock()
988
        interface4 = MagicMock()
989
        interface4.is_active.return_value = False
990
        interface5 = MagicMock()
991
        interface5.is_active.return_value = True
992
        switch2.interfaces = {1: interface4, 2: interface5}
993
        content = {'switches': [switch1, switch2]}
994
        event = MagicMock()
995
        event.content = content
996
        self.napp.handle_switch_maintenance_end(event)
997
        self.assertEqual(handle_link_up_mock.call_count, 5)
998