Passed
Pull Request — master (#72)
by macartur
08:39 queued 06:24
created

build.tests.models.test_evc_deploy   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 484
Duplicated Lines 16.12 %

Importance

Changes 0
Metric Value
eloc 363
dl 78
loc 484
rs 10
c 0
b 0
f 0
wmc 16

16 Methods

Rating   Name   Duplication   Size   Complexity  
A TestEVC.test_deploy_fail() 39 39 1
A TestEVC.test_prepare_pop_flow() 0 23 1
A TestEVC.test_should_deploy_case3() 0 14 1
A TestEVC.test_deploy_successfully() 39 39 1
A TestEVC.test_should_deploy_case4() 0 14 1
A TestEVC.test_send_flow_mods_case1() 0 11 1
A TestEVC.test_remove_current_flows() 0 33 1
B TestEVC.test_install_uni_flows() 0 80 1
A TestEVC.test_should_deploy_case1() 0 14 1
B TestEVC.test_deploy_without_path_case1() 0 46 1
A TestEVC.test_should_deploy_case2() 0 14 1
A TestEVC.test_install_nni_flows() 0 53 1
A TestEVC.test_primary_links_zipped() 0 3 1
A TestEVC.test_prepare_push_flow() 0 30 1
A TestEVC.test_prepare_flow_mod() 0 23 1
A TestEVC.test_send_flow_mods_case2() 0 11 1

How to fix   Duplicated Code   

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:

1
"""Method to thest EVCDeploy class."""
2
import sys
3
from unittest import TestCase
4
from unittest.mock import Mock, patch
5
6
from kytos.core.interface import UNI, Interface
7
from kytos.core.switch import Switch
8
from kytos.core.common import EntityStatus
9
10
# pylint: disable=wrong-import-position
11
sys.path.insert(0, '/var/lib/kytos/napps/..')
12
# pylint: enable=wrong-import-position
13
14
from napps.kytos.mef_eline.models import EVC, Path  # NOQA
15
from napps.kytos.mef_eline.settings import MANAGER_URL  # NOQA
16
from napps.kytos.mef_eline.tests.helpers import get_link_mocked, get_uni_mocked  # NOQA
17
18
19
class TestEVC(TestCase):  # pylint: disable=too-many-public-methods
20
    """Tests to verify EVC class."""
21
22
    def test_primary_links_zipped(self):
23
        """Test primary links zipped method."""
24
        pass
25
26
    @staticmethod
27
    @patch('napps.kytos.mef_eline.models.log')
28
    def test_should_deploy_case1(log_mock):
29
        """Test should deploy method without primary links."""
30
        log_mock.debug.return_value = True
31
        attributes = {
32
            "name": "custom_name",
33
            "uni_a": get_uni_mocked(is_valid=True),
34
            "uni_z": get_uni_mocked(is_valid=True)
35
        }
36
37
        evc = EVC(**attributes)
38
        evc.should_deploy()
39
        log_mock.debug.assert_called_with('Path is empty.')
40
41
    @patch('napps.kytos.mef_eline.models.log')
42
    def test_should_deploy_case2(self, log_mock):
43
        """Test should deploy method with disable circuit."""
44
        log_mock.debug.return_value = True
45
        attributes = {
46
            "name": "custom_name",
47
            "uni_a": get_uni_mocked(is_valid=True),
48
            "uni_z": get_uni_mocked(is_valid=True),
49
            "primary_links": [get_link_mocked(), get_link_mocked()]
50
        }
51
        evc = EVC(**attributes)
52
53
        self.assertFalse(evc.should_deploy(attributes['primary_links']))
54
        log_mock.debug.assert_called_with(f'{evc} is disabled.')
55
56
    @patch('napps.kytos.mef_eline.models.log')
57
    def test_should_deploy_case3(self, log_mock):
58
        """Test should deploy method with enabled and not active circuit."""
59
        log_mock.debug.return_value = True
60
        attributes = {
61
            "name": "custom_name",
62
            "uni_a": get_uni_mocked(is_valid=True),
63
            "uni_z": get_uni_mocked(is_valid=True),
64
            "primary_links": [get_link_mocked(), get_link_mocked()],
65
            "enabled": True
66
        }
67
        evc = EVC(**attributes)
68
        self.assertTrue(evc.should_deploy(attributes['primary_links']))
69
        log_mock.debug.assert_called_with(f'{evc} will be deployed.')
70
71
    @patch('napps.kytos.mef_eline.models.log')
72
    def test_should_deploy_case4(self, log_mock):
73
        """Test should deploy method with enabled and active circuit."""
74
        log_mock.debug.return_value = True
75
        attributes = {
76
            "name": "custom_name",
77
            "uni_a": get_uni_mocked(is_valid=True),
78
            "uni_z": get_uni_mocked(is_valid=True),
79
            "primary_links": [get_link_mocked(), get_link_mocked()],
80
            "enabled": True,
81
            "active": True
82
        }
83
        evc = EVC(**attributes)
84
        self.assertFalse(evc.should_deploy(attributes['primary_links']))
85
86
    @patch('napps.kytos.mef_eline.models.requests')
87
    def test_send_flow_mods_case1(self, requests_mock):
88
        """Test if you are sending flow_mods."""
89
        flow_mods = {"id": 20}
90
        switch = Mock(spec=Switch, id=1)
91
        EVC.send_flow_mods(switch, flow_mods)
92
        expected_endpoint = f"{MANAGER_URL}/flows/{switch.id}"
93
        expected_data = {"flows": flow_mods}
94
        self.assertEqual(requests_mock.post.call_count, 1)
95
        requests_mock.post.assert_called_once_with(expected_endpoint,
96
                                                   json=expected_data)
97
98
    @patch('napps.kytos.mef_eline.models.requests')
99
    def test_send_flow_mods_case2(self, requests_mock):
100
        """Test if you are sending flow_mods."""
101
        flow_mods = {"id": 20}
102
        switch = Mock(spec=Switch, id=1)
103
        EVC.send_flow_mods(switch, flow_mods, command='delete')
104
        expected_endpoint = f"{MANAGER_URL}/delete/{switch.id}"
105
        expected_data = {"flows": flow_mods}
106
        self.assertEqual(requests_mock.post.call_count, 1)
107
        requests_mock.post.assert_called_once_with(expected_endpoint,
108
                                                   json=expected_data)
109
110
    def test_prepare_flow_mod(self):
111
        """Test prepare flow_mod method."""
112
        interface_a = Interface('eth0', 1, Mock(spec=Switch))
113
        interface_z = Interface('eth1', 3, Mock(spec=Switch))
114
        attributes = {
115
            "name": "custom_name",
116
            "uni_a": get_uni_mocked(is_valid=True),
117
            "uni_z": get_uni_mocked(is_valid=True),
118
            "primary_links": [get_link_mocked(), get_link_mocked()],
119
            "enabled": True,
120
            "active": True
121
        }
122
        evc = EVC(**attributes)
123
        flow_mod = evc.prepare_flow_mod(interface_a, interface_z)
124
        expected_flow_mod = {
125
                           'match': {'in_port': interface_a.port_number},
126
                           'cookie': evc.get_cookie(),
127
                           'actions': [
128
                                       {'action_type': 'output',
129
                                        'port': interface_z.port_number}
130
                           ]
131
        }
132
        self.assertEqual(expected_flow_mod, flow_mod)
133
134
    def test_prepare_pop_flow(self):
135
        """Test prepare pop flow  method."""
136
        attributes = {
137
            "name": "custom_name",
138
            "uni_a": get_uni_mocked(interface_port=1, is_valid=True),
139
            "uni_z": get_uni_mocked(interface_port=2, is_valid=True),
140
        }
141
        evc = EVC(**attributes)
142
        interface_a = evc.uni_a.interface
143
        interface_z = evc.uni_z.interface
144
        in_vlan = 10
145
        flow_mod = evc.prepare_pop_flow(interface_a, interface_z, in_vlan)
146
        expected_flow_mod = {
147
            'match': {'in_port': interface_a.port_number, 'dl_vlan': in_vlan},
148
            'cookie': evc.get_cookie(),
149
            'actions': [
150
                        {'action_type': 'pop_vlan'},
151
                        {'action_type': 'output',
152
                         'port': interface_z.port_number
153
                         }
154
            ]
155
        }
156
        self.assertEqual(expected_flow_mod, flow_mod)
157
158
    def test_prepare_push_flow(self):
159
        """Test prepare push flow method."""
160
        attributes = {
161
            "name": "custom_name",
162
            "uni_a": get_uni_mocked(interface_port=1, is_valid=True),
163
            "uni_z": get_uni_mocked(interface_port=2, is_valid=True),
164
        }
165
        evc = EVC(**attributes)
166
        interface_a = evc.uni_a.interface
167
        interface_z = evc.uni_z.interface
168
        in_vlan_a = 10
169
        out_vlan_a = 20
170
        in_vlan_z = 3
171
        flow_mod = evc.prepare_push_flow(interface_a, interface_z,
172
                                         in_vlan_a, out_vlan_a, in_vlan_z)
173
        expected_flow_mod = {
174
            'match': {'in_port': interface_a.port_number,
175
                      'dl_vlan': in_vlan_a
176
                      },
177
            'cookie': evc.get_cookie(),
178
            'actions': [
179
                        {'action_type': 'set_vlan', 'vlan_id': in_vlan_z},
180
                        {'action_type': 'push_vlan', 'tag_type': 's'},
181
                        {'action_type': 'set_vlan', 'vlan_id': out_vlan_a},
182
                        {'action_type': 'output',
183
                         'port': interface_z.port_number
184
                         }
185
            ]
186
        }
187
        self.assertEqual(expected_flow_mod, flow_mod)
188
189
    @staticmethod
190
    @patch('napps.kytos.mef_eline.models.EVC.send_flow_mods')
191
    def test_install_uni_flows(send_flow_mods_mock):
192
        """Test install uni flows method.
193
194
        This test will verify the flows send to the send_flow_mods method.
195
        """
196
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
197
                               switch_id="switch_uni_a", is_valid=True)
198
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
199
                               switch_id="switch_uni_z", is_valid=True)
200
201
        attributes = {
202
            "name": "custom_name",
203
            "uni_a": uni_a,
204
            "uni_z": uni_z,
205
            "primary_links": [
206
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
207
                                metadata={"s_vlan": 5}),
208
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
209
                                metadata={"s_vlan": 6})
210
            ]
211
        }
212
        evc = EVC(**attributes)
213
        evc.install_uni_flows(attributes['primary_links'])
214
215
        expected_flow_mod_a = [
216
            {'match': {'in_port': uni_a.interface.port_number,
217
                       'dl_vlan': uni_a.user_tag.value},
218
             'cookie': evc.get_cookie(),
219
             'actions': [
220
                {'action_type': 'set_vlan', 'vlan_id': uni_z.user_tag.value},
221
                {'action_type': 'push_vlan', 'tag_type': 's'},
222
                {'action_type': 'set_vlan',
223
                 'vlan_id': evc.primary_links[0].get_metadata('s_vlan').value},
224
                {'action_type': 'output',
225
                 'port': evc.primary_links[0].endpoint_a.port_number}
226
             ]},
227
            {'match': {
228
                'in_port': evc.primary_links[0].endpoint_a.port_number,
229
                'dl_vlan': evc.primary_links[0].get_metadata('s_vlan').value
230
             },
231
             'cookie': evc.get_cookie(),
232
             'actions': [
233
                {'action_type': 'pop_vlan'},
234
                {'action_type': 'output', 'port': uni_a.interface.port_number}
235
             ]
236
             }
237
        ]
238
        send_flow_mods_mock.assert_any_call(uni_a.interface.switch,
239
                                            expected_flow_mod_a)
240
241
        expected_flow_mod_z = [
242
            {'match': {'in_port': uni_z.interface.port_number,
243
                       'dl_vlan': uni_z.user_tag.value},
244
             'cookie': evc.get_cookie(),
245
             'actions': [
246
                {'action_type': 'set_vlan', 'vlan_id': uni_a.user_tag.value},
247
                {'action_type': 'push_vlan', 'tag_type': 's'},
248
                {'action_type': 'set_vlan',
249
                 'vlan_id': evc.primary_links[-1].get_metadata('s_vlan').value
250
                 },
251
                {'action_type': 'output',
252
                 'port': evc.primary_links[-1].endpoint_b.port_number}
253
              ]
254
             },
255
            {'match': {
256
                 'in_port': evc.primary_links[-1].endpoint_b.port_number,
257
                 'dl_vlan': evc.primary_links[-1].get_metadata('s_vlan').value
258
             },
259
             'cookie': evc.get_cookie(),
260
             'actions': [
261
                {'action_type': 'pop_vlan'},
262
                {'action_type': 'output', 'port': uni_z.interface.port_number}
263
              ]
264
             }
265
        ]
266
267
        send_flow_mods_mock.assert_any_call(uni_z.interface.switch,
268
                                            expected_flow_mod_z)
269
270
    @staticmethod
271
    @patch('napps.kytos.mef_eline.models.EVC.send_flow_mods')
272
    def test_install_nni_flows(send_flow_mods_mock):
273
        """Test install nni flows method.
274
275
        This test will verify the flows send to the send_flow_mods method.
276
        """
277
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
278
                               switch_id="switch_uni_a", is_valid=True)
279
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
280
                               switch_id="switch_uni_z", is_valid=True)
281
282
        attributes = {
283
            "name": "custom_name",
284
            "uni_a": uni_a,
285
            "uni_z": uni_z,
286
            "primary_links": [
287
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
288
                                metadata={"s_vlan": 5}),
289
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
290
                                metadata={"s_vlan": 6})
291
            ]
292
        }
293
        evc = EVC(**attributes)
294
        evc.install_nni_flows(attributes['primary_links'])
295
296
        in_vlan = evc.primary_links[0].get_metadata('s_vlan').value
297
        out_vlan = evc.primary_links[-1].get_metadata('s_vlan').value
298
299
        in_port = evc.primary_links[0].endpoint_b.port_number
300
        out_port = evc.primary_links[-1].endpoint_a.port_number
301
302
        expected_flow_mods = [
303
            {
304
             'match': {'in_port': in_port, 'dl_vlan': in_vlan},
305
             'cookie': evc.get_cookie(),
306
             'actions': [
307
                    {'action_type': 'set_vlan', 'vlan_id': out_vlan},
308
                    {'action_type': 'output', 'port': out_port}
309
                ]
310
             },
311
            {
312
             'match': {'in_port': out_port, 'dl_vlan': out_vlan},
313
             'cookie': evc.get_cookie(),
314
             'actions': [
315
                {'action_type': 'set_vlan', 'vlan_id': in_vlan},
316
                {'action_type': 'output', 'port': in_port}
317
              ]
318
             }
319
        ]
320
321
        switch = evc.primary_links[0].endpoint_b.switch
322
        send_flow_mods_mock.assert_called_once_with(switch, expected_flow_mods)
323
324 View Code Duplication
    @patch('napps.kytos.mef_eline.models.log')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
325
    @patch('napps.kytos.mef_eline.models.EVC.choose_vlans')
326
    @patch('napps.kytos.mef_eline.models.EVC.install_nni_flows')
327
    @patch('napps.kytos.mef_eline.models.EVC.install_uni_flows')
328
    @patch('napps.kytos.mef_eline.models.EVC.activate')
329
    @patch('napps.kytos.mef_eline.models.EVC.should_deploy')
330
    def test_deploy_successfully(self, *args):
331
        """Test if all methods to deploy are called."""
332
        (should_deploy_mock, activate_mock, install_uni_flows_mock,
333
         install_nni_flows, chose_vlans_mock, log_mock) = args
334
335
        should_deploy_mock.return_value = True
336
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
337
                               switch_id="switch_uni_a", is_valid=True)
338
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
339
                               switch_id="switch_uni_z", is_valid=True)
340
341
        attributes = {
342
            "name": "custom_name",
343
            "uni_a": uni_a,
344
            "uni_z": uni_z,
345
            "primary_links": [
346
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
347
                                metadata={"s_vlan": 5}),
348
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
349
                                metadata={"s_vlan": 6})
350
            ]
351
        }
352
353
        evc = EVC(**attributes)
354
        deployed = evc.deploy(attributes['primary_links'])
355
356
        self.assertEqual(should_deploy_mock.call_count, 1)
357
        self.assertEqual(activate_mock.call_count, 1)
358
        self.assertEqual(install_uni_flows_mock.call_count, 1)
359
        self.assertEqual(install_nni_flows.call_count, 1)
360
        self.assertEqual(chose_vlans_mock.call_count, 1)
361
        log_mock.info.assert_called_once_with(f"{evc} was deployed.")
362
        self.assertTrue(deployed)
363
364 View Code Duplication
    @patch('napps.kytos.mef_eline.models.log')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
365
    @patch('napps.kytos.mef_eline.models.EVC.choose_vlans')
366
    @patch('napps.kytos.mef_eline.models.EVC.install_nni_flows')
367
    @patch('napps.kytos.mef_eline.models.EVC.install_uni_flows')
368
    @patch('napps.kytos.mef_eline.models.EVC.activate')
369
    @patch('napps.kytos.mef_eline.models.EVC.should_deploy')
370
    def test_deploy_fail(self, *args):
371
        """Test if all methods is ignored when the should_deploy is false."""
372
        (should_deploy_mock, activate_mock, install_uni_flows_mock,
373
         install_nni_flows, chose_vlans_mock, log_mock) = args
374
375
        should_deploy_mock.return_value = False
376
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
377
                               switch_id="switch_uni_a", is_valid=True)
378
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
379
                               switch_id="switch_uni_z", is_valid=True)
380
381
        attributes = {
382
            "name": "custom_name",
383
            "uni_a": uni_a,
384
            "uni_z": uni_z,
385
            "primary_links": [
386
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
387
                                metadata={"s_vlan": 5}),
388
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
389
                                metadata={"s_vlan": 6})
390
            ]
391
        }
392
393
        evc = EVC(**attributes)
394
        deployed = evc.deploy()
395
396
        self.assertEqual(should_deploy_mock.call_count, 1)
397
        self.assertEqual(activate_mock.call_count, 0)
398
        self.assertEqual(install_uni_flows_mock.call_count, 0)
399
        self.assertEqual(install_nni_flows.call_count, 0)
400
        self.assertEqual(chose_vlans_mock.call_count, 0)
401
        self.assertEqual(log_mock.info.call_count, 0)
402
        self.assertFalse(deployed)
403
404
    @patch('napps.kytos.mef_eline.models.log')
405
    @patch('napps.kytos.mef_eline.models.EVC.choose_vlans')
406
    @patch('napps.kytos.mef_eline.models.EVC.install_nni_flows')
407
    @patch('napps.kytos.mef_eline.models.EVC.install_uni_flows')
408
    @patch('napps.kytos.mef_eline.models.EVC.activate')
409
    @patch('napps.kytos.mef_eline.models.EVC.should_deploy')
410
    @patch('napps.kytos.mef_eline.models.EVC.discover_new_path')
411
    def test_deploy_without_path_case1(self, *args):
412
        """Test if not path is found a dynamic path is used."""
413
        (discover_new_path_mocked, should_deploy_mock, activate_mock,
414
         install_uni_flows_mock, install_nni_flows, chose_vlans_mock,
415
         log_mock) = args
416
417
        should_deploy_mock.return_value = True
418
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
419
                               switch_id="switch_uni_a", is_valid=True)
420
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
421
                               switch_id="switch_uni_z", is_valid=True)
422
423
        attributes = {
424
            "name": "custom_name",
425
            "uni_a": uni_a,
426
            "uni_z": uni_z,
427
            "enabled": True,
428
            "dynamic_backup_path": True
429
        }
430
431
        dynamic_backup_path = Path([
432
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
433
                                metadata={"s_vlan": 5}),
434
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
435
                                metadata={"s_vlan": 6})
436
        ])
437
438
        evc = EVC(**attributes)
439
        discover_new_path_mocked.return_value = dynamic_backup_path
440
        deployed = evc.deploy()
441
442
        self.assertEqual(should_deploy_mock.call_count, 1)
443
        self.assertEqual(discover_new_path_mocked.call_count, 1)
444
        self.assertEqual(activate_mock.call_count, 1)
445
        self.assertEqual(install_uni_flows_mock.call_count, 1)
446
        self.assertEqual(install_nni_flows.call_count, 1)
447
        self.assertEqual(chose_vlans_mock.call_count, 1)
448
        self.assertEqual(log_mock.info.call_count, 1)
449
        self.assertTrue(deployed)
450
451
    @patch('napps.kytos.mef_eline.models.EVC.send_flow_mods')
452
    def test_remove_current_flows(self, send_flow_mods_mocked):
453
        """Test remove current flows."""
454
        uni_a = get_uni_mocked(interface_port=2, tag_value=82,
455
                               switch_id="switch_uni_a", is_valid=True)
456
        uni_z = get_uni_mocked(interface_port=3, tag_value=83,
457
                               switch_id="switch_uni_z", is_valid=True)
458
459
        attributes = {
460
            "name": "custom_name",
461
            "uni_a": uni_a,
462
            "uni_z": uni_z,
463
            "active": True,
464
            "enabled": True,
465
            "primary_links": [
466
                get_link_mocked(endpoint_a_port=9, endpoint_b_port=10,
467
                                metadata={"s_vlan": 5}),
468
                get_link_mocked(endpoint_a_port=11, endpoint_b_port=12,
469
                                metadata={"s_vlan": 6})
470
            ]
471
        }
472
473
        evc = EVC(**attributes)
474
        evc.current_path = evc.primary_links
475
        evc.remove_current_flows()
476
477
        self.assertEqual(send_flow_mods_mocked.call_count, 2)
478
        self.assertFalse(evc.is_active())
479
        flows = [{'cookie': evc.get_cookie()}]
480
        switch1 = evc.primary_links[0].endpoint_a.switch
481
        switch2 = evc.primary_links[0].endpoint_b.switch
482
        send_flow_mods_mocked.assert_called_with(switch1, flows, 'delete')
483
        send_flow_mods_mocked.assert_called_with(switch2, flows, 'delete')
484