TestEVC.test_deploy_error()   B
last analyzed

Complexity

Conditions 1

Size

Total Lines 72
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 56
nop 2
dl 0
loc 72
rs 8.44
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""Method to thest EVCDeploy class."""
2
import sys
3
from unittest import TestCase
4
from unittest.mock import MagicMock, Mock, patch
5
6
from kytos.core.interface import Interface
7
from kytos.core.switch import Switch
8
9
# pylint: disable=wrong-import-position
10
sys.path.insert(0, "/var/lib/kytos/napps/..")
11
# pylint: enable=wrong-import-position
12
13
from napps.kytos.mef_eline.models import EVC, Path  # NOQA
14
from napps.kytos.mef_eline.settings import MANAGER_URL  # NOQA
15
from napps.kytos.mef_eline.exceptions import FlowModException  # NOQA
16
from napps.kytos.mef_eline.tests.helpers import (
17
    get_link_mocked,
18
    get_uni_mocked,
19
    get_controller_mock,
20
)  # NOQA
21
22
23
class TestEVC(TestCase):  # pylint: disable=too-many-public-methods
24
    """Tests to verify EVC class."""
25
26
    def test_primary_links_zipped(self):
27
        """Test primary links zipped method."""
28
29
    @staticmethod
30
    @patch("napps.kytos.mef_eline.models.evc.log")
31
    def test_should_deploy_case1(log_mock):
32
        """Test should deploy method without primary links."""
33
        log_mock.debug.return_value = True
34
        attributes = {
35
            "controller": get_controller_mock(),
36
            "name": "custom_name",
37
            "uni_a": get_uni_mocked(is_valid=True),
38
            "uni_z": get_uni_mocked(is_valid=True),
39
        }
40
41
        evc = EVC(**attributes)
42
        evc.should_deploy()
43
        log_mock.debug.assert_called_with("Path is empty.")
44
45
    @patch("napps.kytos.mef_eline.models.evc.log")
46
    def test_should_deploy_case2(self, log_mock):
47
        """Test should deploy method with disable circuit."""
48
        log_mock.debug.return_value = True
49
        attributes = {
50
            "controller": get_controller_mock(),
51
            "name": "custom_name",
52
            "uni_a": get_uni_mocked(is_valid=True),
53
            "uni_z": get_uni_mocked(is_valid=True),
54
            "primary_links": [get_link_mocked(), get_link_mocked()],
55
        }
56
        evc = EVC(**attributes)
57
58
        self.assertFalse(evc.should_deploy(attributes["primary_links"]))
59
        log_mock.debug.assert_called_with(f"{evc} is disabled.")
60
61
    @patch("napps.kytos.mef_eline.models.evc.log")
62
    def test_should_deploy_case3(self, log_mock):
63
        """Test should deploy method with enabled and not active circuit."""
64
        log_mock.debug.return_value = True
65
        attributes = {
66
            "controller": get_controller_mock(),
67
            "name": "custom_name",
68
            "uni_a": get_uni_mocked(is_valid=True),
69
            "uni_z": get_uni_mocked(is_valid=True),
70
            "primary_links": [get_link_mocked(), get_link_mocked()],
71
            "enabled": True,
72
        }
73
        evc = EVC(**attributes)
74
        self.assertTrue(evc.should_deploy(attributes["primary_links"]))
75
        log_mock.debug.assert_called_with(f"{evc} will be deployed.")
76
77
    @patch("napps.kytos.mef_eline.models.evc.log")
78
    def test_should_deploy_case4(self, log_mock):
79
        """Test should deploy method with enabled and active circuit."""
80
        log_mock.debug.return_value = True
81
        attributes = {
82
            "controller": get_controller_mock(),
83
            "name": "custom_name",
84
            "uni_a": get_uni_mocked(is_valid=True),
85
            "uni_z": get_uni_mocked(is_valid=True),
86
            "primary_links": [get_link_mocked(), get_link_mocked()],
87
            "enabled": True,
88
            "active": True,
89
        }
90
        evc = EVC(**attributes)
91
        self.assertFalse(evc.should_deploy(attributes["primary_links"]))
92
93
    @patch("napps.kytos.mef_eline.models.evc.requests")
94
    def test_send_flow_mods_case1(self, requests_mock):
95
        """Test if you are sending flow_mods."""
96
        flow_mods = {"id": 20}
97
        switch = Mock(spec=Switch, id=1)
98
99
        response = MagicMock()
100
        response.status_code = 201
101
        requests_mock.post.return_value = response
102
103
        # pylint: disable=protected-access
104
        EVC._send_flow_mods(switch, flow_mods)
105
106
        expected_endpoint = f"{MANAGER_URL}/flows/{switch.id}"
107
        expected_data = {"flows": flow_mods, "force": False}
108
        self.assertEqual(requests_mock.post.call_count, 1)
109
        requests_mock.post.assert_called_once_with(
110
            expected_endpoint, json=expected_data
111
        )
112
113
    @patch("napps.kytos.mef_eline.models.evc.requests")
114
    def test_send_flow_mods_case2(self, requests_mock):
115
        """Test if you are sending flow_mods."""
116
        flow_mods = {"id": 20}
117
        switch = Mock(spec=Switch, id=1)
118
        response = MagicMock()
119
        response.status_code = 201
120
        requests_mock.post.return_value = response
121
122
        # pylint: disable=protected-access
123
        EVC._send_flow_mods(switch, flow_mods, command='delete', force=True)
124
125
        expected_endpoint = f"{MANAGER_URL}/delete/{switch.id}"
126
        expected_data = {"flows": flow_mods, "force": True}
127
        self.assertEqual(requests_mock.post.call_count, 1)
128
        requests_mock.post.assert_called_once_with(
129
            expected_endpoint, json=expected_data
130
        )
131
132
    def test_prepare_flow_mod(self):
133
        """Test prepare flow_mod method."""
134
        interface_a = Interface("eth0", 1, Mock(spec=Switch))
135
        interface_z = Interface("eth1", 3, Mock(spec=Switch))
136
        attributes = {
137
            "controller": get_controller_mock(),
138
            "name": "custom_name",
139
            "uni_a": get_uni_mocked(is_valid=True),
140
            "uni_z": get_uni_mocked(is_valid=True),
141
            "primary_links": [get_link_mocked(), get_link_mocked()],
142
            "enabled": True,
143
            "active": True,
144
        }
145
        evc = EVC(**attributes)
146
147
        # pylint: disable=protected-access
148
        flow_mod = evc._prepare_flow_mod(interface_a, interface_z)
149
        expected_flow_mod = {
150
            "match": {"in_port": interface_a.port_number},
151
            "cookie": evc.get_cookie(),
152
            "actions": [
153
                {"action_type": "output", "port": interface_z.port_number}
154
            ],
155
        }
156
        self.assertEqual(expected_flow_mod, flow_mod)
157
158
    def test_prepare_pop_flow(self):
159
        """Test prepare pop flow  method."""
160
        attributes = {
161
            "controller": get_controller_mock(),
162
            "name": "custom_name",
163
            "uni_a": get_uni_mocked(interface_port=1, is_valid=True),
164
            "uni_z": get_uni_mocked(interface_port=2, is_valid=True),
165
        }
166
        evc = EVC(**attributes)
167
        interface_a = evc.uni_a.interface
168
        interface_z = evc.uni_z.interface
169
        in_vlan = 10
170
171
        # pylint: disable=protected-access
172
        flow_mod = evc._prepare_pop_flow(
173
            interface_a, interface_z, in_vlan
174
        )
175
176
        expected_flow_mod = {
177
            "match": {"in_port": interface_a.port_number, "dl_vlan": in_vlan},
178
            "cookie": evc.get_cookie(),
179
            "actions": [
180
                {"action_type": "pop_vlan"},
181
                {"action_type": "output", "port": interface_z.port_number},
182
            ],
183
        }
184
        self.assertEqual(expected_flow_mod, flow_mod)
185
186
    def test_prepare_push_flow(self):
187
        """Test prepare push flow method."""
188
        attributes = {
189
            "controller": get_controller_mock(),
190
            "name": "custom_name",
191
            "uni_a": get_uni_mocked(interface_port=1, is_valid=True),
192
            "uni_z": get_uni_mocked(interface_port=2, is_valid=True),
193
        }
194
        evc = EVC(**attributes)
195
        interface_a = evc.uni_a.interface
196
        interface_z = evc.uni_z.interface
197
        out_vlan_a = 20
198
199
        for in_vlan_a in (10, None):
200
            for in_vlan_z in (3, None):
201
                with self.subTest(in_vlan_a=in_vlan_a, in_vlan_z=in_vlan_z):
202
                    # pylint: disable=protected-access
203
                    flow_mod = evc._prepare_push_flow(interface_a, interface_z,
204
                                                      in_vlan_a, out_vlan_a,
205
                                                      in_vlan_z)
206
207
                    expected_flow_mod = {
208
                        'match': {'in_port': interface_a.port_number},
209
                        'cookie': evc.get_cookie(),
210
                        'actions': [
211
                            {'action_type': 'push_vlan', 'tag_type': 's'},
212
                            {'action_type': 'set_vlan', 'vlan_id': out_vlan_a},
213
                            {
214
                                'action_type': 'output',
215
                                'port': interface_z.port_number
216
                            }
217
                        ]
218
                    }
219
                    if in_vlan_a and in_vlan_z:
220
                        expected_flow_mod['match']['dl_vlan'] = in_vlan_a
221
                        expected_flow_mod['actions'].insert(0, {
222
                            'action_type': 'set_vlan', 'vlan_id': in_vlan_z
223
                        })
224
                    elif in_vlan_a:
225
                        expected_flow_mod['match']['dl_vlan'] = in_vlan_a
226
                        expected_flow_mod['actions'].insert(0, {
227
                            'action_type': 'pop_vlan'
228
                        })
229
                    elif in_vlan_z:
230
                        expected_flow_mod['actions'].insert(0, {
231
                            'action_type': 'set_vlan', 'vlan_id': in_vlan_z
232
                        })
233
                        expected_flow_mod['actions'].insert(0, {
234
                            'action_type': 'push_vlan', 'tag_type': 'c'
235
                        })
236
                    self.assertEqual(expected_flow_mod, flow_mod)
237
238
    @staticmethod
239
    @patch("napps.kytos.mef_eline.models.evc.EVC._send_flow_mods")
240
    def test_install_uni_flows(send_flow_mods_mock):
241
        """Test install uni flows method.
242
243
        This test will verify the flows send to the send_flow_mods method.
244
        """
245
        uni_a = get_uni_mocked(
246
            interface_port=2,
247
            tag_value=82,
248
            switch_id="switch_uni_a",
249
            is_valid=True,
250
        )
251
        uni_z = get_uni_mocked(
252
            interface_port=3,
253
            tag_value=83,
254
            switch_id="switch_uni_z",
255
            is_valid=True,
256
        )
257
258
        attributes = {
259
            "controller": get_controller_mock(),
260
            "name": "custom_name",
261
            "uni_a": uni_a,
262
            "uni_z": uni_z,
263
            "primary_links": [
264
                get_link_mocked(
265
                    endpoint_a_port=9,
266
                    endpoint_b_port=10,
267
                    metadata={"s_vlan": 5},
268
                ),
269
                get_link_mocked(
270
                    endpoint_a_port=11,
271
                    endpoint_b_port=12,
272
                    metadata={"s_vlan": 6},
273
                ),
274
            ],
275
        }
276
        evc = EVC(**attributes)
277
278
        # pylint: disable=protected-access
279
        evc._install_uni_flows(attributes["primary_links"])
280
281
        expected_flow_mod_a = [
282
            {
283
                "match": {
284
                    "in_port": uni_a.interface.port_number,
285
                    "dl_vlan": uni_a.user_tag.value,
286
                },
287
                "cookie": evc.get_cookie(),
288
                "actions": [
289
                    {
290
                        "action_type": "set_vlan",
291
                        "vlan_id": uni_z.user_tag.value
292
                    },
293
                    {"action_type": "push_vlan", "tag_type": "s"},
294
                    {
295
                        "action_type": "set_vlan",
296
                        "vlan_id": evc.primary_links[0]
297
                        .get_metadata("s_vlan")
298
                        .value,
299
                    },
300
                    {
301
                        "action_type": "output",
302
                        "port": evc.primary_links[0].endpoint_a.port_number,
303
                    },
304
                ],
305
            },
306
            {
307
                "match": {
308
                    "in_port": evc.primary_links[0].endpoint_a.port_number,
309
                    "dl_vlan": evc.primary_links[0]
310
                    .get_metadata("s_vlan")
311
                    .value,
312
                },
313
                "cookie": evc.get_cookie(),
314
                "actions": [
315
                    {"action_type": "pop_vlan"},
316
                    {
317
                        "action_type": "output",
318
                        "port": uni_a.interface.port_number,
319
                    },
320
                ],
321
            },
322
        ]
323
324
        send_flow_mods_mock.assert_any_call(
325
            uni_a.interface.switch, expected_flow_mod_a
326
        )
327
328
        expected_flow_mod_z = [
329
            {
330
                "match": {
331
                    "in_port": uni_z.interface.port_number,
332
                    "dl_vlan": uni_z.user_tag.value,
333
                },
334
                "cookie": evc.get_cookie(),
335
                "actions": [
336
                    {
337
                        "action_type": "set_vlan",
338
                        "vlan_id": uni_a.user_tag.value
339
                    },
340
                    {"action_type": "push_vlan", "tag_type": "s"},
341
                    {
342
                        "action_type": "set_vlan",
343
                        "vlan_id": evc.primary_links[-1]
344
                        .get_metadata("s_vlan")
345
                        .value,
346
                    },
347
                    {
348
                        "action_type": "output",
349
                        "port": evc.primary_links[-1].endpoint_b.port_number,
350
                    },
351
                ],
352
            },
353
            {
354
                "match": {
355
                    "in_port": evc.primary_links[-1].endpoint_b.port_number,
356
                    "dl_vlan": evc.primary_links[-1]
357
                    .get_metadata("s_vlan")
358
                    .value,
359
                },
360
                "cookie": evc.get_cookie(),
361
                "actions": [
362
                    {"action_type": "pop_vlan"},
363
                    {
364
                        "action_type": "output",
365
                        "port": uni_z.interface.port_number,
366
                    },
367
                ],
368
            },
369
        ]
370
371
        send_flow_mods_mock.assert_any_call(
372
            uni_z.interface.switch, expected_flow_mod_z
373
        )
374
375
    @staticmethod
376
    @patch("napps.kytos.mef_eline.models.evc.EVC._send_flow_mods")
377
    def test_install_nni_flows(send_flow_mods_mock):
378
        """Test install nni flows method.
379
380
        This test will verify the flows send to the send_flow_mods method.
381
        """
382
        uni_a = get_uni_mocked(
383
            interface_port=2,
384
            tag_value=82,
385
            switch_id="switch_uni_a",
386
            is_valid=True,
387
        )
388
        uni_z = get_uni_mocked(
389
            interface_port=3,
390
            tag_value=83,
391
            switch_id="switch_uni_z",
392
            is_valid=True,
393
        )
394
395
        attributes = {
396
            "controller": get_controller_mock(),
397
            "name": "custom_name",
398
            "uni_a": uni_a,
399
            "uni_z": uni_z,
400
            "primary_links": [
401
                get_link_mocked(
402
                    endpoint_a_port=9,
403
                    endpoint_b_port=10,
404
                    metadata={"s_vlan": 5},
405
                ),
406
                get_link_mocked(
407
                    endpoint_a_port=11,
408
                    endpoint_b_port=12,
409
                    metadata={"s_vlan": 6},
410
                ),
411
            ],
412
        }
413
        evc = EVC(**attributes)
414
415
        # pylint: disable=protected-access
416
        evc._install_nni_flows(attributes["primary_links"])
417
418
        in_vlan = evc.primary_links[0].get_metadata("s_vlan").value
419
        out_vlan = evc.primary_links[-1].get_metadata("s_vlan").value
420
421
        in_port = evc.primary_links[0].endpoint_b.port_number
422
        out_port = evc.primary_links[-1].endpoint_a.port_number
423
424
        expected_flow_mods = [
425
            {
426
                "match": {"in_port": in_port, "dl_vlan": in_vlan},
427
                "cookie": evc.get_cookie(),
428
                "actions": [
429
                    {"action_type": "set_vlan", "vlan_id": out_vlan},
430
                    {"action_type": "output", "port": out_port},
431
                ],
432
            },
433
            {
434
                "match": {"in_port": out_port, "dl_vlan": out_vlan},
435
                "cookie": evc.get_cookie(),
436
                "actions": [
437
                    {"action_type": "set_vlan", "vlan_id": in_vlan},
438
                    {"action_type": "output", "port": in_port},
439
                ],
440
            },
441
        ]
442
443
        switch = evc.primary_links[0].endpoint_b.switch
444
        send_flow_mods_mock.assert_called_once_with(switch, expected_flow_mods)
445
446
    @patch("requests.post")
447
    @patch("napps.kytos.mef_eline.storehouse.StoreHouse.save_evc")
448
    @patch("napps.kytos.mef_eline.models.evc.log")
449
    @patch("napps.kytos.mef_eline.models.path.Path.choose_vlans")
450
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
451
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_uni_flows")
452
    @patch("napps.kytos.mef_eline.models.evc.EVC.activate")
453
    @patch("napps.kytos.mef_eline.models.evc.EVC.should_deploy")
454
    def test_deploy_successfully(self, *args):
455
        """Test if all methods to deploy are called."""
456
        # pylint: disable=too-many-locals
457
        (
458
            should_deploy_mock,
459
            activate_mock,
460
            install_uni_flows_mock,
461
            install_nni_flows,
462
            chose_vlans_mock,
463
            log_mock,
464
            _,
465
            requests_mock,
466
        ) = args
467
468
        response = MagicMock()
469
        response.status_code = 201
470
        requests_mock.return_value = response
471
472
        should_deploy_mock.return_value = True
473
        uni_a = get_uni_mocked(
474
            interface_port=2,
475
            tag_value=82,
476
            switch_id="switch_uni_a",
477
            is_valid=True,
478
        )
479
        uni_z = get_uni_mocked(
480
            interface_port=3,
481
            tag_value=83,
482
            switch_id="switch_uni_z",
483
            is_valid=True,
484
        )
485
        primary_links = [
486
            get_link_mocked(
487
                endpoint_a_port=9, endpoint_b_port=10, metadata={"s_vlan": 5}
488
            ),
489
            get_link_mocked(
490
                endpoint_a_port=11, endpoint_b_port=12, metadata={"s_vlan": 6}
491
            ),
492
        ]
493
494
        attributes = {
495
            "controller": get_controller_mock(),
496
            "name": "custom_name",
497
            "uni_a": uni_a,
498
            "uni_z": uni_z,
499
            "primary_links": primary_links,
500
            "queue_id": 5,
501
        }
502
503
        # Setup path to deploy
504
        path = Path()
505
        path.append(primary_links[0])
506
        path.append(primary_links[1])
507
508
        evc = EVC(**attributes)
509
510
        deployed = evc.deploy_to_path(path)
511
512
        self.assertEqual(should_deploy_mock.call_count, 1)
513
        self.assertEqual(activate_mock.call_count, 1)
514
        self.assertEqual(install_uni_flows_mock.call_count, 1)
515
        self.assertEqual(install_nni_flows.call_count, 1)
516
        self.assertEqual(chose_vlans_mock.call_count, 1)
517
        log_mock.info.assert_called_with(f"{evc} was deployed.")
518
        self.assertTrue(deployed)
519
520
    @patch("requests.post")
521
    @patch("napps.kytos.mef_eline.models.evc.log")
522
    @patch(
523
        "napps.kytos.mef_eline.models.evc.EVC.discover_new_paths",
524
        return_value=[],
525
    )
526
    @patch("napps.kytos.mef_eline.models.path.Path.choose_vlans")
527
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
528
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_uni_flows")
529
    @patch("napps.kytos.mef_eline.models.evc.EVC.activate")
530
    @patch(
531
        "napps.kytos.mef_eline.models.evc.EVC.should_deploy",
532
        return_value=False,
533
    )
534
    @patch("napps.kytos.mef_eline.models.EVC.sync")
535
    def test_deploy_fail(self, *args):
536
        """Test if all methods is ignored when the should_deploy is false."""
537
        # pylint: disable=too-many-locals
538
        (
539
            sync_mock,
540
            should_deploy_mock,
541
            activate_mock,
542
            install_uni_flows_mock,
543
            install_nni_flows,
544
            choose_vlans_mock,
545
            discover_new_paths,
546
            log_mock,
547
            requests_mock,
548
        ) = args
549
550
        response = MagicMock()
551
        response.status_code = 201
552
        requests_mock.return_value = response
553
554
        uni_a = get_uni_mocked(
555
            interface_port=2,
556
            tag_value=82,
557
            switch_id="switch_uni_a",
558
            switch_dpid="switch_dpid_uni_a",
559
            is_valid=True,
560
        )
561
        uni_z = get_uni_mocked(
562
            interface_port=3,
563
            tag_value=83,
564
            switch_id="switch_uni_z",
565
            switch_dpid="switch_dpid_uni_a",
566
            is_valid=True,
567
        )
568
569
        attributes = {
570
            "controller": get_controller_mock(),
571
            "name": "custom_name",
572
            "uni_a": uni_a,
573
            "uni_z": uni_z,
574
            "primary_links": [
575
                get_link_mocked(
576
                    endpoint_a_port=9,
577
                    endpoint_b_port=10,
578
                    metadata={"s_vlan": 5},
579
                ),
580
                get_link_mocked(
581
                    endpoint_a_port=11,
582
                    endpoint_b_port=12,
583
                    metadata={"s_vlan": 6},
584
                ),
585
            ],
586
        }
587
588
        evc = EVC(**attributes)
589
        deployed = evc.deploy_to_path()
590
591
        self.assertEqual(discover_new_paths.call_count, 1)
592
        self.assertEqual(should_deploy_mock.call_count, 1)
593
        self.assertEqual(activate_mock.call_count, 0)
594
        self.assertEqual(install_uni_flows_mock.call_count, 0)
595
        self.assertEqual(install_nni_flows.call_count, 0)
596
        self.assertEqual(choose_vlans_mock.call_count, 0)
597
        self.assertEqual(log_mock.info.call_count, 0)
598
        self.assertEqual(sync_mock.call_count, 1)
599
        self.assertFalse(deployed)
600
601
    @patch("napps.kytos.mef_eline.models.evc.log")
602
    @patch(
603
        "napps.kytos.mef_eline.models.evc.EVC.discover_new_paths",
604
        return_value=[],
605
    )
606
    @patch("napps.kytos.mef_eline.models.path.Path.choose_vlans")
607
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
608
    @patch("napps.kytos.mef_eline.models.evc.EVC.should_deploy")
609
    @patch("napps.kytos.mef_eline.models.evc.EVC.remove_current_flows")
610
    @patch("napps.kytos.mef_eline.models.evc.EVC.sync")
611
    def test_deploy_error(self, *args):
612
        """Test if all methods is ignored when the should_deploy is false."""
613
        # pylint: disable=too-many-locals
614
        (
615
            sync_mock,
616
            remove_current_flows,
617
            should_deploy_mock,
618
            install_nni_flows,
619
            choose_vlans_mock,
620
            discover_new_paths,
621
            log_mock,
622
        ) = args
623
624
        install_nni_flows.side_effect = FlowModException
625
        should_deploy_mock.return_value = True
626
        uni_a = get_uni_mocked(
627
            interface_port=2,
628
            tag_value=82,
629
            switch_id="switch_uni_a",
630
            is_valid=True,
631
        )
632
        uni_z = get_uni_mocked(
633
            interface_port=3,
634
            tag_value=83,
635
            switch_id="switch_uni_z",
636
            is_valid=True,
637
        )
638
639
        primary_links = [
640
            get_link_mocked(
641
                endpoint_a_port=9, endpoint_b_port=10, metadata={"s_vlan": 5}
642
            ),
643
            get_link_mocked(
644
                endpoint_a_port=11, endpoint_b_port=12, metadata={"s_vlan": 6}
645
            ),
646
        ]
647
648
        attributes = {
649
            "controller": get_controller_mock(),
650
            "name": "custom_name",
651
            "uni_a": uni_a,
652
            "uni_z": uni_z,
653
            "primary_links": primary_links,
654
            "queue_id": 5,
655
        }
656
        # Setup path to deploy
657
        path = Path()
658
        path.append(primary_links[0])
659
        path.append(primary_links[1])
660
661
        evc = EVC(**attributes)
662
663
        deployed = evc.deploy_to_path(path)
664
665
        self.assertEqual(discover_new_paths.call_count, 0)
666
        self.assertEqual(should_deploy_mock.call_count, 1)
667
        self.assertEqual(install_nni_flows.call_count, 1)
668
        self.assertEqual(choose_vlans_mock.call_count, 1)
669
        self.assertEqual(log_mock.error.call_count, 1)
670
        self.assertEqual(sync_mock.call_count, 0)
671
        self.assertEqual(remove_current_flows.call_count, 2)
672
        self.assertFalse(deployed)
673
674
    @patch("napps.kytos.mef_eline.models.evc.EVC.deploy_to_path")
675
    @patch("napps.kytos.mef_eline.models.evc.EVC.discover_new_paths")
676
    def test_deploy_to_backup_path1(
677
        self, discover_new_paths_mocked, deploy_to_path_mocked
678
    ):
679
        """Test deployment when dynamic_backup_path is False in same switch"""
680
        uni_a = get_uni_mocked(interface_port=2, tag_value=82, is_valid=True)
681
        uni_z = get_uni_mocked(interface_port=3, tag_value=83, is_valid=True)
682
683
        switch = Mock(spec=Switch)
684
        uni_a.interface.switch = switch
685
        uni_z.interface.switch = switch
686
687
        attributes = {
688
            "controller": get_controller_mock(),
689
            "name": "custom_name",
690
            "uni_a": uni_a,
691
            "uni_z": uni_z,
692
            "enabled": True,
693
            "dynamic_backup_path": False,
694
        }
695
696
        evc = EVC(**attributes)
697
        discover_new_paths_mocked.return_value = []
698
        deploy_to_path_mocked.return_value = True
699
700
        # storehouse initialization mock
701
        evc._storehouse.box = Mock()  # pylint: disable=protected-access
702
        evc._storehouse.box.data = {}  # pylint: disable=protected-access
703
704
        deployed = evc.deploy_to_backup_path()
705
706
        deploy_to_path_mocked.assert_called_once_with()
707
        self.assertEqual(deployed, True)
708
709
    @patch("requests.post")
710
    @patch("napps.kytos.mef_eline.storehouse.StoreHouse.save_evc")
711
    @patch("napps.kytos.mef_eline.models.evc.log")
712
    @patch("napps.kytos.mef_eline.models.path.Path.choose_vlans")
713
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
714
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_uni_flows")
715
    @patch("napps.kytos.mef_eline.models.evc.EVC.activate")
716
    @patch("napps.kytos.mef_eline.models.evc.EVC.should_deploy")
717
    @patch("napps.kytos.mef_eline.models.evc.EVC.discover_new_paths")
718
    def test_deploy_without_path_case1(self, *args):
719
        """Test if not path is found a dynamic path is used."""
720
        # pylint: disable=too-many-locals
721
        (
722
            discover_new_paths_mocked,
723
            should_deploy_mock,
724
            activate_mock,
725
            install_uni_flows_mock,
726
            install_nni_flows,
727
            chose_vlans_mock,
728
            log_mock,
729
            _,
730
            requests_mock,
731
        ) = args
732
733
        response = MagicMock()
734
        response.status_code = 201
735
        requests_mock.return_value = response
736
737
        should_deploy_mock.return_value = False
738
        uni_a = get_uni_mocked(
739
            interface_port=2,
740
            tag_value=82,
741
            switch_id="switch_uni_a",
742
            is_valid=True,
743
        )
744
        uni_z = get_uni_mocked(
745
            interface_port=3,
746
            tag_value=83,
747
            switch_id="switch_uni_z",
748
            is_valid=True,
749
        )
750
751
        attributes = {
752
            "controller": get_controller_mock(),
753
            "name": "custom_name",
754
            "uni_a": uni_a,
755
            "uni_z": uni_z,
756
            "enabled": True,
757
            "dynamic_backup_path": False,
758
        }
759
760
        dynamic_backup_path = Path(
761
            [
762
                get_link_mocked(
763
                    endpoint_a_port=9,
764
                    endpoint_b_port=10,
765
                    metadata={"s_vlan": 5},
766
                ),
767
                get_link_mocked(
768
                    endpoint_a_port=11,
769
                    endpoint_b_port=12,
770
                    metadata={"s_vlan": 6},
771
                ),
772
            ]
773
        )
774
775
        evc = EVC(**attributes)
776
        discover_new_paths_mocked.return_value = [dynamic_backup_path]
777
778
        deployed = evc.deploy_to_path()
779
780
        self.assertEqual(should_deploy_mock.call_count, 1)
781
        self.assertEqual(discover_new_paths_mocked.call_count, 1)
782
        self.assertEqual(activate_mock.call_count, 1)
783
        self.assertEqual(install_uni_flows_mock.call_count, 1)
784
        self.assertEqual(install_nni_flows.call_count, 1)
785
        self.assertEqual(chose_vlans_mock.call_count, 1)
786
        log_mock.info.assert_called_with(f"{evc} was deployed.")
787
        self.assertTrue(deployed)
788
789
    @patch("napps.kytos.mef_eline.models.evc.notify_link_available_tags")
790
    @patch("napps.kytos.mef_eline.models.evc.EVC._send_flow_mods")
791
    def test_remove_current_flows(self, send_flow_mods_mocked, notify_mock):
792
        """Test remove current flows."""
793
        uni_a = get_uni_mocked(
794
            interface_port=2,
795
            tag_value=82,
796
            switch_id="switch_uni_a",
797
            is_valid=True,
798
        )
799
        uni_z = get_uni_mocked(
800
            interface_port=3,
801
            tag_value=83,
802
            switch_id="switch_uni_z",
803
            is_valid=True,
804
        )
805
806
        switch_a = Switch("00:00:00:00:00:01")
807
        switch_b = Switch("00:00:00:00:00:02")
808
        switch_c = Switch("00:00:00:00:00:03")
809
810
        attributes = {
811
            "controller": get_controller_mock(),
812
            "name": "custom_name",
813
            "uni_a": uni_a,
814
            "uni_z": uni_z,
815
            "active": True,
816
            "enabled": True,
817
            "primary_links": [
818
                get_link_mocked(
819
                    switch_a=switch_a,
820
                    switch_b=switch_b,
821
                    endpoint_a_port=9,
822
                    endpoint_b_port=10,
823
                    metadata={"s_vlan": 5},
824
                ),
825
                get_link_mocked(
826
                    switch_a=switch_b,
827
                    switch_b=switch_c,
828
                    endpoint_a_port=11,
829
                    endpoint_b_port=12,
830
                    metadata={"s_vlan": 6},
831
                ),
832
            ],
833
        }
834
835
        evc = EVC(**attributes)
836
837
        # storehouse initialization mock
838
        evc._storehouse.box = Mock()  # pylint: disable=protected-access
839
        evc._storehouse.box.data = {}  # pylint: disable=protected-access
840
841
        evc.current_path = evc.primary_links
842
        evc.remove_current_flows()
843
        notify_mock.assert_called()
844
845
        self.assertEqual(send_flow_mods_mocked.call_count, 5)
846
        self.assertFalse(evc.is_active())
847
        flows = [
848
            {"cookie": evc.get_cookie(), "cookie_mask": 18446744073709551615}
849
        ]
850
        switch_1 = evc.primary_links[0].endpoint_a.switch
851
        switch_2 = evc.primary_links[0].endpoint_b.switch
852
        send_flow_mods_mocked.assert_any_call(switch_1, flows, 'delete',
853
                                              force=True)
854
        send_flow_mods_mocked.assert_any_call(switch_2, flows, 'delete',
855
                                              force=True)
856