Passed
Pull Request — master (#349)
by
unknown
07:30
created

TestLinkProtection.test_are_unis_active()   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 13
nop 1
dl 0
loc 19
ccs 12
cts 12
cp 1
crap 1
rs 9.75
c 0
b 0
f 0
1
"""Module to test the LinkProtection class."""
2 1
import sys
3 1
from unittest.mock import MagicMock, patch
4
5 1
from kytos.core.common import EntityStatus
6 1
from kytos.lib.helpers import get_controller_mock
7 1
from napps.kytos.mef_eline.models import EVC, Path  # NOQA pycodestyle
8 1
from napps.kytos.mef_eline.tests.helpers import (
9
    get_link_mocked,
10
    get_uni_mocked,
11
    get_mocked_requests,
12
    id_to_interface_mock
13
)  # NOQA pycodestyle
14
15
16 1
sys.path.insert(0, "/var/lib/kytos/napps/..")
17
18
19 1
DEPLOY_TO_PRIMARY_PATH = (
20
    "napps.kytos.mef_eline.models.evc.LinkProtection.deploy_to_primary_path"
21
)
22 1
DEPLOY_TO_BACKUP_PATH = (
23
    "napps.kytos.mef_eline.models.evc.LinkProtection.deploy_to_backup_path"
24
)
25 1
GET_BEST_PATH = (
26
    "napps.kytos.mef_eline.models.path.DynamicPathManager.get_best_path"
27
)
28
29
30 1
class TestLinkProtection():  # pylint: disable=too-many-public-methods
31
    """Tests to validate LinkProtection class."""
32
33 1
    def setup_method(self):
34
        """Set up method"""
35 1
        primary_path = [
36
            get_link_mocked(
37
                endpoint_a_port=9,
38
                endpoint_b_port=10,
39
                metadata={"s_vlan": 5},
40
                status=EntityStatus.UP,
41
            ),
42
            get_link_mocked(
43
                endpoint_a_port=11,
44
                endpoint_b_port=12,
45
                metadata={"s_vlan": 6},
46
                status=EntityStatus.DOWN,
47
            ),
48
        ]
49 1
        backup_path = [
50
            get_link_mocked(
51
                endpoint_a_port=13,
52
                endpoint_b_port=14,
53
                metadata={"s_vlan": 5},
54
                status=EntityStatus.DOWN,
55
            ),
56
            get_link_mocked(
57
                endpoint_a_port=11,
58
                endpoint_b_port=12,
59
                metadata={"s_vlan": 6},
60
                status=EntityStatus.DOWN,
61
            ),
62
        ]
63 1
        attributes = {
64
            "controller": get_controller_mock(),
65
            "name": "circuit_1",
66
            "uni_a": get_uni_mocked(is_valid=True),
67
            "uni_z": get_uni_mocked(is_valid=True),
68
            "primary_path": primary_path,
69
            "backup_path": backup_path,
70
            "enabled": True,
71
            "dynamic_backup_path": True,
72
        }
73 1
        self.evc = EVC(**attributes)
74
75 1
    async def test_is_using_backup_path(self):
76
        """Test test is using backup path."""
77
78 1
        attributes = {
79
            "controller": get_controller_mock(),
80
            "name": "circuit_1",
81
            "uni_a": get_uni_mocked(is_valid=True),
82
            "uni_z": get_uni_mocked(is_valid=True),
83
            "backup_path": [
84
                get_link_mocked(
85
                    endpoint_a_port=10,
86
                    endpoint_b_port=9,
87
                    metadata={"s_vlan": 5},
88
                ),
89
                get_link_mocked(
90
                    endpoint_a_port=12,
91
                    endpoint_b_port=11,
92
                    metadata={"s_vlan": 6},
93
                ),
94
            ],
95
        }
96
97 1
        evc = EVC(**attributes)
98 1
        assert evc.is_using_backup_path() is False
99 1
        evc.current_path = evc.backup_path
100 1
        assert evc.is_using_backup_path()
101
102 1
    async def test_is_using_primary_path(self):
103
        """Test test is using primary path."""
104 1
        primary_path = [
105
            get_link_mocked(
106
                endpoint_a_port=10, endpoint_b_port=9, metadata={"s_vlan": 5}
107
            ),
108
            get_link_mocked(
109
                endpoint_a_port=12, endpoint_b_port=11, metadata={"s_vlan": 6}
110
            ),
111
        ]
112
113 1
        attributes = {
114
            "controller": get_controller_mock(),
115
            "name": "circuit_2",
116
            "uni_a": get_uni_mocked(is_valid=True),
117
            "uni_z": get_uni_mocked(is_valid=True),
118
            "primary_path": primary_path,
119
        }
120 1
        evc = EVC(**attributes)
121 1
        assert evc.is_using_primary_path() is False
122 1
        evc.current_path = evc.primary_path
123 1
        assert evc.is_using_primary_path()
124
125 1
    @patch("napps.kytos.mef_eline.models.evc.log")
126 1
    async def test_deploy_to_case_1(self, log_mocked):
127
        """Test if the path is equal to current_path."""
128 1
        primary_path = [
129
            get_link_mocked(
130
                endpoint_a_port=10, endpoint_b_port=9, metadata={"s_vlan": 5}
131
            ),
132
            get_link_mocked(
133
                endpoint_a_port=12, endpoint_b_port=11, metadata={"s_vlan": 6}
134
            ),
135
        ]
136 1
        attributes = {
137
            "controller": get_controller_mock(),
138
            "name": "circuit_3",
139
            "uni_a": get_uni_mocked(is_valid=True),
140
            "uni_z": get_uni_mocked(is_valid=True),
141
            "primary_path": primary_path,
142
        }
143 1
        evc = EVC(**attributes)
144 1
        evc.current_path = evc.primary_path
145
146 1
        expected_deployed = evc.deploy_to("primary_path", evc.primary_path)
147 1
        expected_msg = "primary_path is equal to current_path."
148 1
        log_mocked.debug.assert_called_with(expected_msg)
149 1
        assert expected_deployed
150
151
    # pylint: disable=too-many-arguments
152 1
    @patch("napps.kytos.mef_eline.models.evc.notify_link_available_tags")
153 1
    @patch("requests.post")
154 1
    @patch("napps.kytos.mef_eline.controllers.ELineController.upsert_evc")
155 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
156 1
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
157 1
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_uni_flows")
158 1
    @patch("napps.kytos.mef_eline.models.path.Path.status", EntityStatus.UP)
159 1
    async def test_deploy_to_case_2(
160
        self,
161
        install_uni_flows_mocked,
162
        install_nni_flows_mocked,
163
        deploy_mocked,
164
        _,
165
        requests_mock,
166
        notify_mock
167
    ):
168
        """Test deploy with all links up."""
169 1
        deploy_mocked.return_value = True
170 1
        response = MagicMock()
171 1
        response.status_code = 201
172 1
        requests_mock.return_value = response
173
174 1
        primary_path = [
175
            get_link_mocked(status=EntityStatus.UP),
176
            get_link_mocked(status=EntityStatus.UP),
177
        ]
178 1
        attributes = {
179
            "controller": get_controller_mock(),
180
            "name": "circuit_4",
181
            "uni_a": get_uni_mocked(is_valid=True),
182
            "uni_z": get_uni_mocked(is_valid=True),
183
            "primary_path": primary_path,
184
            "enabled": True,
185
        }
186 1
        evc = EVC(**attributes)
187
188 1
        deployed = evc.deploy_to("primary_path", evc.primary_path)
189 1
        install_uni_flows_mocked.assert_called_with(evc.primary_path)
190 1
        install_nni_flows_mocked.assert_called_with(evc.primary_path)
191 1
        assert deployed
192 1
        notify_mock.assert_called()
193
194 1
    @patch("requests.get", side_effect=get_mocked_requests)
195 1
    async def test_deploy_to_case_3(self, requests_mocked):
196
        # pylint: disable=unused-argument
197
        """Test deploy with one link down."""
198 1
        link1 = get_link_mocked()
199 1
        link2 = get_link_mocked()
200 1
        link1.id = "abc"
201 1
        link2.id = "def"
202 1
        primary_path = [link1, link2]
203 1
        attributes = {
204
            "controller": get_controller_mock(),
205
            "name": "circuit_5",
206
            "uni_a": get_uni_mocked(is_valid=True),
207
            "uni_z": get_uni_mocked(is_valid=True),
208
            "primary_path": primary_path,
209
            "enabled": True,
210
        }
211 1
        evc = EVC(**attributes)
212
213 1
        deployed = evc.deploy_to("primary_path", evc.primary_path)
214 1
        assert deployed is False
215
216 1
    @patch("napps.kytos.mef_eline.models.evc.log")
217 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy._send_flow_mods")
218 1
    @patch(DEPLOY_TO_BACKUP_PATH)
219 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
220 1
    @patch("napps.kytos.mef_eline.models.path.Path.status")
221 1
    async def test_handle_link_down_case_1(
222
        self,
223
        path_status_mocked,
224
        deploy_mocked,
225
        deploy_to_mocked,
226
        _send_flow_mods_mocked,
227
        log_mocked,
228
    ):
229
        """Test if deploy_to backup path is called."""
230 1
        deploy_mocked.return_value = True
231 1
        path_status_mocked.side_effect = [EntityStatus.DOWN, EntityStatus.UP]
232
233 1
        self.evc.current_path = self.evc.primary_path
234 1
        self.evc.activate()
235 1
        deploy_to_mocked.reset_mock()
236 1
        current_handle_link_down = self.evc.handle_link_down()
237 1
        assert deploy_mocked.call_count == 0
238 1
        deploy_to_mocked.assert_called_once()
239
240 1
        assert current_handle_link_down
241 1
        msg = f"{self.evc} deployed after link down."
242 1
        log_mocked.debug.assert_called_once_with(msg)
243
244 1 View Code Duplication
    @patch("napps.kytos.mef_eline.models.evc.log")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
245 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
246 1
    @patch(DEPLOY_TO_PRIMARY_PATH)
247 1
    @patch("napps.kytos.mef_eline.models.path.Path.status")
248 1
    async def test_handle_link_down_case_2(
249
        self, path_status_mocked, deploy_to_mocked, deploy_mocked, log_mocked
250
    ):
251
        """Test if deploy_to backup path is called."""
252 1
        deploy_mocked.return_value = True
253 1
        deploy_to_mocked.return_value = True
254 1
        path_status_mocked.side_effect = [EntityStatus.UP, EntityStatus.DOWN]
255 1
        primary_path = [
256
            get_link_mocked(
257
                endpoint_a_port=7,
258
                endpoint_b_port=8,
259
                metadata={"s_vlan": 5},
260
                status=EntityStatus.UP,
261
            ),
262
            get_link_mocked(
263
                endpoint_a_port=11,
264
                endpoint_b_port=12,
265
                metadata={"s_vlan": 6},
266
                status=EntityStatus.UP,
267
            ),
268
        ]
269 1
        backup_path = [
270
            get_link_mocked(
271
                endpoint_a_port=7,
272
                endpoint_b_port=10,
273
                metadata={"s_vlan": 5},
274
                status=EntityStatus.DOWN,
275
            ),
276
            get_link_mocked(
277
                endpoint_a_port=15,
278
                endpoint_b_port=12,
279
                metadata={"s_vlan": 6},
280
                status=EntityStatus.UP,
281
            ),
282
        ]
283 1
        attributes = {
284
            "controller": get_controller_mock(),
285
            "name": "circuit_13",
286
            "uni_a": get_uni_mocked(is_valid=True),
287
            "uni_z": get_uni_mocked(is_valid=True),
288
            "primary_path": primary_path,
289
            "backup_path": backup_path,
290
            "enabled": True,
291
        }
292
293 1
        evc = EVC(**attributes)
294 1
        evc.current_path = evc.backup_path
295 1
        deploy_to_mocked.reset_mock()
296 1
        current_handle_link_down = evc.handle_link_down()
297 1
        assert deploy_mocked.call_count == 0
298 1
        deploy_to_mocked.assert_called_once()
299 1
        assert current_handle_link_down
300 1
        msg = f"{evc} deployed after link down."
301 1
        log_mocked.debug.assert_called_once_with(msg)
302
303 1
    @patch("napps.kytos.mef_eline.controllers.ELineController.upsert_evc")
304 1
    @patch("napps.kytos.mef_eline.models.evc.log")
305 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
306 1
    @patch(DEPLOY_TO_PRIMARY_PATH)
307 1
    @patch("napps.kytos.mef_eline.models.path.DynamicPathManager.get_paths")
308 1
    @patch("napps.kytos.mef_eline.models.path.Path.status", EntityStatus.DOWN)
309 1
    async def test_handle_link_down_case_3(
310
        self, get_paths_mocked, deploy_to_mocked, deploy_mocked, log_mocked, _
311
    ):
312
        """Test if circuit without dynamic path is return failed."""
313 1
        deploy_mocked.return_value = False
314 1
        deploy_to_mocked.return_value = False
315 1
        primary_path = [
316
            get_link_mocked(
317
                endpoint_a_port=9,
318
                endpoint_b_port=10,
319
                metadata={"s_vlan": 5},
320
                status=EntityStatus.DOWN,
321
            ),
322
            get_link_mocked(
323
                endpoint_a_port=11,
324
                endpoint_b_port=12,
325
                metadata={"s_vlan": 6},
326
                status=EntityStatus.UP,
327
            ),
328
        ]
329 1
        backup_path = [
330
            get_link_mocked(
331
                endpoint_a_port=9,
332
                endpoint_b_port=10,
333
                metadata={"s_vlan": 5},
334
                status=EntityStatus.DOWN,
335
            ),
336
            get_link_mocked(
337
                endpoint_a_port=13,
338
                endpoint_b_port=14,
339
                metadata={"s_vlan": 6},
340
                status=EntityStatus.UP,
341
            ),
342
        ]
343 1
        attributes = {
344
            "controller": get_controller_mock(),
345
            "name": "circuit_7",
346
            "uni_a": get_uni_mocked(is_valid=True),
347
            "uni_z": get_uni_mocked(is_valid=True),
348
            "primary_path": primary_path,
349
            "backup_path": backup_path,
350
            "enabled": True,
351
        }
352
353 1
        evc = EVC(**attributes)
354 1
        evc.current_path = evc.backup_path
355 1
        deploy_to_mocked.reset_mock()
356 1
        current_handle_link_down = evc.handle_link_down()
357
358 1
        assert get_paths_mocked.call_count == 0
359 1
        assert deploy_mocked.call_count == 0
360 1
        assert deploy_to_mocked.call_count == 1
361
362 1
        assert current_handle_link_down is False
363 1
        msg = f"Failed to re-deploy {evc} after link down."
364 1
        log_mocked.debug.assert_called_once_with(msg)
365
366 1 View Code Duplication
    @patch("napps.kytos.mef_eline.models.evc.log")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
367 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy_to_path")
368 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy._send_flow_mods")
369 1
    @patch(DEPLOY_TO_PRIMARY_PATH)
370 1
    @patch("napps.kytos.mef_eline.models.path.Path.status", EntityStatus.DOWN)
371 1
    async def test_handle_link_down_case_4(
372
        self,
373
        deploy_to_mocked,
374
        _send_flow_mods_mocked,
375
        deploy_mocked,
376
        log_mocked,
377
    ):
378
        """Test if circuit with dynamic path is return success."""
379 1
        deploy_mocked.return_value = True
380 1
        deploy_to_mocked.return_value = False
381 1
        primary_path = [
382
            get_link_mocked(
383
                endpoint_a_port=9,
384
                endpoint_b_port=10,
385
                metadata={"s_vlan": 5},
386
                status=EntityStatus.DOWN,
387
            ),
388
            get_link_mocked(
389
                endpoint_a_port=11,
390
                endpoint_b_port=12,
391
                metadata={"s_vlan": 6},
392
                status=EntityStatus.UP,
393
            ),
394
        ]
395 1
        backup_path = [
396
            get_link_mocked(
397
                endpoint_a_port=9,
398
                endpoint_b_port=10,
399
                metadata={"s_vlan": 5},
400
                status=EntityStatus.DOWN,
401
            ),
402
            get_link_mocked(
403
                endpoint_a_port=13,
404
                endpoint_b_port=14,
405
                metadata={"s_vlan": 6},
406
                status=EntityStatus.UP,
407
            ),
408
        ]
409 1
        attributes = {
410
            "controller": get_controller_mock(),
411
            "name": "circuit_8",
412
            "uni_a": get_uni_mocked(is_valid=True),
413
            "uni_z": get_uni_mocked(is_valid=True),
414
            "primary_path": primary_path,
415
            "backup_path": backup_path,
416
            "enabled": True,
417
            "dynamic_backup_path": True,
418
        }
419
420 1
        evc = EVC(**attributes)
421 1
        evc.current_path = evc.backup_path
422
423 1
        deploy_to_mocked.reset_mock()
424 1
        current_handle_link_down = evc.handle_link_down()
425 1
        assert deploy_to_mocked.call_count == 1
426
427 1
        assert current_handle_link_down
428 1
        msg = f"{evc} deployed after link down."
429 1
        log_mocked.debug.assert_called_with(msg)
430
431 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
432 1
    @patch("napps.kytos.mef_eline.models.evc.LinkProtection.deploy_to")
433 1
    async def test_handle_link_up_case_1(
434
        self,
435
        deploy_to_mocked,
436
        deploy_mocked
437
    ):
438
        """Test if handle link up do nothing when is using primary path."""
439 1
        deploy_mocked.return_value = True
440 1
        deploy_to_mocked.return_value = True
441 1
        primary_path = [
442
            get_link_mocked(
443
                endpoint_a_port=9,
444
                endpoint_b_port=10,
445
                metadata={"s_vlan": 5},
446
                status=EntityStatus.UP,
447
            ),
448
            get_link_mocked(
449
                endpoint_a_port=11,
450
                endpoint_b_port=12,
451
                metadata={"s_vlan": 6},
452
                status=EntityStatus.UP,
453
            ),
454
        ]
455 1
        backup_path = [
456
            get_link_mocked(
457
                endpoint_a_port=9,
458
                endpoint_b_port=14,
459
                metadata={"s_vlan": 5},
460
                status=EntityStatus.UP,
461
            ),
462
            get_link_mocked(
463
                endpoint_a_port=15,
464
                endpoint_b_port=12,
465
                metadata={"s_vlan": 6},
466
                status=EntityStatus.UP,
467
            ),
468
        ]
469 1
        attributes = {
470
            "controller": get_controller_mock(),
471
            "name": "circuit_9",
472
            "uni_a": get_uni_mocked(is_valid=True),
473
            "uni_z": get_uni_mocked(is_valid=True),
474
            "primary_path": primary_path,
475
            "backup_path": backup_path,
476
            "enabled": True,
477
            "dynamic_backup_path": True,
478
        }
479
480 1
        evc = EVC(**attributes)
481 1
        evc.current_path = evc.primary_path
482 1
        deploy_to_mocked.reset_mock()
483 1
        current_handle_link_up = evc.handle_link_up(backup_path[0])
484 1
        assert deploy_mocked.call_count == 0
485 1
        assert deploy_to_mocked.call_count == 0
486 1
        assert current_handle_link_up
487
488 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
489 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy_to_path")
490 1
    @patch("napps.kytos.mef_eline.models.path.Path.status", EntityStatus.UP)
491 1
    async def test_handle_link_up_case_2(
492
        self,
493
        deploy_to_path_mocked,
494
        deploy_mocked
495
    ):
496
        """Test if it is changing from backup_path to primary_path."""
497 1
        deploy_mocked.return_value = True
498 1
        deploy_to_path_mocked.return_value = True
499 1
        primary_path = [
500
            get_link_mocked(
501
                endpoint_a_port=9,
502
                endpoint_b_port=10,
503
                metadata={"s_vlan": 5},
504
                status=EntityStatus.UP,
505
            ),
506
            get_link_mocked(
507
                endpoint_a_port=11,
508
                endpoint_b_port=12,
509
                metadata={"s_vlan": 6},
510
                status=EntityStatus.UP,
511
            ),
512
        ]
513 1
        backup_path = [
514
            get_link_mocked(
515
                endpoint_a_port=9,
516
                endpoint_b_port=14,
517
                metadata={"s_vlan": 5},
518
                status=EntityStatus.UP,
519
            ),
520
            get_link_mocked(
521
                endpoint_a_port=15,
522
                endpoint_b_port=12,
523
                metadata={"s_vlan": 6},
524
                status=EntityStatus.UP,
525
            ),
526
        ]
527 1
        attributes = {
528
            "controller": get_controller_mock(),
529
            "name": "circuit_10",
530
            "uni_a": get_uni_mocked(is_valid=True),
531
            "uni_z": get_uni_mocked(is_valid=True),
532
            "primary_path": primary_path,
533
            "backup_path": backup_path,
534
            "enabled": True,
535
            "dynamic_backup_path": True,
536
        }
537
538 1
        evc = EVC(**attributes)
539 1
        evc.current_path = evc.backup_path
540 1
        deploy_to_path_mocked.reset_mock()
541 1
        current_handle_link_up = evc.handle_link_up(primary_path[0])
542 1
        assert deploy_mocked.call_count == 0
543 1
        assert deploy_to_path_mocked.call_count == 1
544 1
        deploy_to_path_mocked.assert_called_once_with(evc.primary_path)
545 1
        assert current_handle_link_up
546
547 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy")
548 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy_to_path")
549 1
    @patch(GET_BEST_PATH)
550 1
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
551 1
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_uni_flows")
552 1
    @patch("napps.kytos.mef_eline.models.path.Path.status", EntityStatus.UP)
553 1
    async def test_handle_link_up_case_3(
554
        self,
555
        _install_uni_flows_mocked,
556
        _install_nni_flows_mocked,
557
        get_best_path_mocked,
558
        deploy_to_path_mocked,
559
        deploy_mocked,
560
    ):
561
        """Test if it is deployed after the backup is up."""
562 1
        deploy_mocked.return_value = True
563 1
        deploy_to_path_mocked.return_value = True
564 1
        primary_path = [
565
            get_link_mocked(
566
                endpoint_a_port=9,
567
                endpoint_b_port=10,
568
                metadata={"s_vlan": 5},
569
                status=EntityStatus.DOWN,
570
            ),
571
            get_link_mocked(
572
                endpoint_a_port=11,
573
                endpoint_b_port=12,
574
                metadata={"s_vlan": 6},
575
                status=EntityStatus.UP,
576
            ),
577
        ]
578 1
        backup_path = [
579
            get_link_mocked(
580
                endpoint_a_port=9,
581
                endpoint_b_port=14,
582
                metadata={"s_vlan": 5},
583
                status=EntityStatus.DOWN,
584
            ),
585
            get_link_mocked(
586
                endpoint_a_port=15,
587
                endpoint_b_port=12,
588
                metadata={"s_vlan": 6},
589
                status=EntityStatus.UP,
590
            ),
591
        ]
592 1
        attributes = {
593
            "controller": get_controller_mock(),
594
            "name": "circuit_11",
595
            "uni_a": get_uni_mocked(is_valid=True),
596
            "uni_z": get_uni_mocked(is_valid=True),
597
            "primary_path": primary_path,
598
            "backup_path": backup_path,
599
            "enabled": True,
600
            "dynamic_backup_path": True,
601
        }
602
603 1
        evc = EVC(**attributes)
604
605 1
        evc.current_path = Path([])
606 1
        deploy_to_path_mocked.reset_mock()
607 1
        current_handle_link_up = evc.handle_link_up(backup_path[0])
608
609 1
        assert get_best_path_mocked.call_count == 0
610 1
        assert deploy_mocked.call_count == 0
611 1
        assert deploy_to_path_mocked.call_count == 1
612 1
        deploy_to_path_mocked.assert_called_once_with(evc.backup_path)
613 1
        assert current_handle_link_up
614
615 1
    @patch("napps.kytos.mef_eline.models.evc.EVCDeploy.deploy_to_path")
616 1
    @patch(GET_BEST_PATH)
617 1
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_nni_flows")
618 1
    @patch("napps.kytos.mef_eline.models.evc.EVC._install_uni_flows")
619 1
    @patch("napps.kytos.mef_eline.models.path.Path.status", EntityStatus.DOWN)
620 1
    async def test_handle_link_up_case_4(self, *args):
621
        """Test if not path is found a dynamic path is used."""
622 1
        (
623
            _install_uni_flows_mocked,
624
            _install_nni_flows_mocked,
625
            get_best_path_mocked,
626
            deploy_to_path_mocked,
627
        ) = args
628
629 1
        deploy_to_path_mocked.return_value = True
630
631 1
        primary_path = [
632
            get_link_mocked(
633
                endpoint_a_port=9,
634
                endpoint_b_port=10,
635
                metadata={"s_vlan": 5},
636
                status=EntityStatus.UP,
637
            ),
638
            get_link_mocked(
639
                endpoint_a_port=11,
640
                endpoint_b_port=12,
641
                metadata={"s_vlan": 6},
642
                status=EntityStatus.DOWN,
643
            ),
644
        ]
645 1
        backup_path = [
646
            get_link_mocked(
647
                endpoint_a_port=13,
648
                endpoint_b_port=14,
649
                metadata={"s_vlan": 5},
650
                status=EntityStatus.DOWN,
651
            ),
652
            get_link_mocked(
653
                endpoint_a_port=11,
654
                endpoint_b_port=12,
655
                metadata={"s_vlan": 6},
656
                status=EntityStatus.DOWN,
657
            ),
658
        ]
659
660
        # Setup best_path mock
661 1
        best_path = Path()
662 1
        best_path.append(primary_path[0])
663 1
        get_best_path_mocked.return_value = best_path
664
665 1
        attributes = {
666
            "controller": get_controller_mock(),
667
            "name": "circuit_12",
668
            "uni_a": get_uni_mocked(is_valid=True),
669
            "uni_z": get_uni_mocked(is_valid=True),
670
            "primary_path": primary_path,
671
            "backup_path": backup_path,
672
            "enabled": True,
673
            "dynamic_backup_path": True,
674
        }
675
676 1
        evc = EVC(**attributes)
677 1
        evc.current_path = Path([])
678
679 1
        deploy_to_path_mocked.reset_mock()
680 1
        current_handle_link_up = evc.handle_link_up(backup_path[0])
681
682 1
        assert get_best_path_mocked.call_count == 0
683 1
        assert deploy_to_path_mocked.call_count == 1
684 1
        deploy_to_path_mocked.assert_called_once_with()
685 1
        assert current_handle_link_up
686
687 1
    async def test_handle_link_up_case_5(self):
688
        """Test handle_link_up method."""
689 1
        return_false_mock = MagicMock(return_value=False)
690 1
        self.evc.is_using_primary_path = return_false_mock
691 1
        self.evc.primary_path.is_affected_by_link = return_false_mock
692 1
        self.evc.is_using_backup_path = MagicMock(return_value=True)
693 1
        assert self.evc.handle_link_up(MagicMock())
694
695
        # not possible to deploy this evc (it will not benefit from link up)
696 1
        self.evc.is_using_backup_path = return_false_mock
697 1
        self.evc.is_using_dynamic_path = return_false_mock
698 1
        self.evc.backup_path.is_affected_by_link = return_false_mock
699 1
        self.evc.dynamic_backup_path = True
700 1
        self.evc.deploy_to_path = return_false_mock
701 1
        assert self.evc.handle_link_up(MagicMock())
702
703 1
    async def test_get_interface_from_switch(self):
704
        """Test get_interface_from_switch"""
705 1
        interface = id_to_interface_mock('00:01:1')
706 1
        interface.switch.interfaces = {1: interface}
707 1
        switches = {
708
            '00:01': interface.switch
709
        }
710 1
        uni = get_uni_mocked(is_valid=True, switch_dpid='00:01')
711 1
        actual_interface = self.evc.get_interface_from_switch(uni, switches)
712 1
        assert interface == actual_interface
713
714 1
    @patch("napps.kytos.mef_eline.models.evc.EVCBase.sync")
715 1
    async def test_handle_topology_update(self, mock_sync):
716
        """Test handle_topology_update"""
717 1
        self.evc.get_interface_from_switch = MagicMock()
718 1
        self.evc.is_uni_interface_active = MagicMock()
719 1
        self.evc.activate = MagicMock()
720 1
        self.evc.deactivate = MagicMock()
721 1
        interface = id_to_interface_mock('00:01:1')
722
723 1
        self.evc.is_uni_interface_active.return_value = (True, None)
724 1
        self.evc._active = False
725 1
        self.evc.handle_topology_update('mocked_switches')
726 1
        assert self.evc.activate.call_count == 1
727 1
        assert self.evc.deactivate.call_count == 0
728 1
        assert mock_sync.call_count == 1
729
730 1
        self.evc.is_uni_interface_active.return_value = (False, interface)
731 1
        self.evc._active = True
732 1
        self.evc.handle_topology_update('mocked_switches')
733 1
        assert self.evc.activate.call_count == 1
734 1
        assert self.evc.deactivate.call_count == 1
735 1
        assert mock_sync.call_count == 2
736
737 1
        self.evc.is_uni_interface_active.return_value = (True, None)
738 1
        self.evc._active = True
739 1
        self.evc.handle_topology_update('mocked_switches')
740 1
        assert self.evc.activate.call_count == 1
741 1
        assert self.evc.deactivate.call_count == 1
742 1
        assert mock_sync.call_count == 2
743
744 1
    async def test_handle_topology_update_error(self):
745
        """Test handle_topology_update with error and early return"""
746 1
        self.evc.get_interface_from_switch = MagicMock()
747 1
        self.evc.get_interface_from_switch.side_effect = KeyError
748 1
        self.evc.is_uni_interface_active = MagicMock()
749
750 1
        self.evc.handle_topology_update('mocked_switches')
751 1
        assert self.evc.is_uni_interface_active.call_count == 0
752
753 1
    async def test_are_unis_active(self):
754
        """Test are_unis_active"""
755 1
        interface = id_to_interface_mock('00:01:1')
756
757 1
        interface.switch.interfaces = {1: interface}
758 1
        switches = {
759
            'custom_switch_dpid': interface.switch
760
        }
761
762 1
        interface.status_reason = set()
763 1
        interface.status = EntityStatus.UP
764 1
        assert self.evc.are_unis_active(switches) is True
765
766 1
        interface.status_reason = {'disabled'}
767 1
        assert self.evc.are_unis_active(switches) is False
768
769 1
        interface.status_reason = set()
770 1
        interface.status = EntityStatus.DISABLED
771 1
        assert self.evc.are_unis_active(switches) is False
772
773 1
    async def test_is_uni_interface_active(self):
774
        """Test is_uni_interface_active"""
775 1
        interface_a = id_to_interface_mock('00:01:1')
776 1
        interface_a.status_reason = set()
777 1
        interface_z = id_to_interface_mock('00:03:1')
778 1
        interface_z.status_reason = set()
779
780 1
        interface_a.status = EntityStatus.UP
781 1
        interface_z.status = EntityStatus.UP
782 1
        actual = self.evc.is_uni_interface_active(interface_a, interface_z)
783 1
        interfaces = {
784
            '00:01:1': {"status": "UP", "status_reason": set()},
785
            '00:03:1': {"status": "UP", "status_reason": set()},
786
        }
787 1
        expected = (True, interfaces)
788 1
        assert actual == expected
789
790 1
        interface_a.status = EntityStatus.DOWN
791 1
        actual = self.evc.is_uni_interface_active(interface_a, interface_z)
792 1
        interfaces = {
793
            '00:01:1': {'status': 'DOWN', 'status_reason': set()}
794
        }
795 1
        expected = (False, interfaces)
796 1
        assert actual == expected
797
798 1
        interface_a.status = EntityStatus.UP
799 1
        interface_z.status = EntityStatus.DOWN
800 1
        actual = self.evc.is_uni_interface_active(interface_a, interface_z)
801 1
        interfaces = {
802
            '00:03:1': {'status': 'DOWN', 'status_reason': set()}
803
        }
804 1
        expected = (False, interfaces)
805
        assert actual == expected
806