Passed
Pull Request — master (#121)
by
unknown
02:38 queued 10s
created

build.tests.unit.test_main   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 965
Duplicated Lines 23.01 %

Importance

Changes 0
Metric Value
eloc 759
dl 222
loc 965
rs 8.721
c 0
b 0
f 0
wmc 44

43 Methods

Rating   Name   Duplication   Size   Complexity  
B TestMain.test_verify_api_urls() 48 48 1
A TestMain.test_get_event_listeners() 0 19 1
A TestMain.setUp() 0 12 2
A TestMain.test_handle_new_switch() 0 11 1
A TestMain.test_handle_switch_maintenance_start() 22 22 1
A TestMain.test_save_metadata_on_store() 0 29 1
A TestMain.test_notify_port_created() 0 9 1
A TestMain.test_disable_switch() 21 21 1
A TestMain.test_disable_link() 0 17 1
A TestMain.test_add_switch_metadata() 0 21 1
A TestMain.test_notify_topology_update() 0 8 1
A TestMain.test_get_switch_metadata() 0 17 1
A TestMain.test_get_link_from_interface() 0 14 1
A TestMain.test_add_links() 0 9 1
B TestMain.test_get_topology() 0 53 1
A TestMain.test_notify_link_status_change() 0 9 1
A TestMain.test_enable_link() 0 17 1
A TestMain.test_verify_storehouse() 0 9 1
A TestMain.test_handle_interface_down() 0 11 1
A TestMain.test_save_status_on_store() 0 8 1
A TestMain.test_interface_link_up() 0 28 1
B TestMain.test_restore_network_status() 0 66 1
A TestMain.test_add_interface_metadata() 0 32 1
A TestMain.test_enable_switch() 21 21 1
A TestMain.test_delete_interface_metadata() 0 39 1
A TestMain.test_handle_interface_up() 0 11 1
A TestMain.test_handle_switch_maintenance_end() 22 22 1
B TestMain.test_enable_interfaces() 44 44 1
A TestMain.test_get_interface_metadata() 0 26 1
A TestMain.test_request_retrieve_entities() 0 16 1
A TestMain.test_delete_switch_metadata() 0 21 1
A TestMain.test_handle_link_maintenance_start() 0 15 1
A TestMain.test_get_link_or_create() 0 15 1
A TestMain.test_interface_deleted() 0 6 1
A TestMain.test_handle_link_maintenance_end() 0 15 1
B TestMain.test_disable_interfaces() 44 44 1
A TestMain.test_add_link_metadata() 0 22 1
A TestMain.test_get_link_metadata() 0 19 1
A TestMain.test_delete_link_metadata() 0 29 1
A TestMain.test_interface_link_down() 0 17 1
A TestMain.test_handle_connection_lost() 0 9 1
A TestMain.test_notify_metadata_changes() 0 13 1
A TestMain.test_handle_interface_created() 0 6 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like build.tests.unit.test_main often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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