test_flow_builder_failover   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 873
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 632
dl 0
loc 873
ccs 152
cts 152
cp 1
rs 9.968
c 0
b 0
f 0
wmc 9

3 Functions

Rating   Name   Duplication   Size   Complexity  
B test_handle_failover_link_down() 0 194 3
B test_handle_failover_old_path_diff_svlan() 0 334 3
B test_handle_failover_old_path_same_svlan() 0 328 3
1
"""Test flowbuilder failover flows."""
2
3 1
import json
4
5 1
from unittest.mock import AsyncMock, MagicMock
6 1
from napps.kytos.telemetry_int.managers.int import INTManager
7 1
from napps.kytos.telemetry_int.proxy_port import ProxyPort
8 1
from kytos.lib.helpers import get_controller_mock, get_switch_mock, get_interface_mock
9 1
from kytos.core.common import EntityStatus
10
11
12 1
async def test_handle_failover_link_down() -> None:
13
    """Test handle failover_link_down.
14
15
               +----+                                              +----+
16
              5|    |6                                            5|    |6
17
           +---+----v---+            +------------+           +----+----v---+
18
        1  |            |            |            |           |             |1
19
    -------+            |3         2 |            |3        2 |             +-------
20
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
21
     100   |            |            |            |           |             | 100
22
           |            |            |            |           |             |
23
           +------------+            +------------+           +-------------+
24
                |4                                                   3|
25
                |_____________________________________________________|
26
    """
27
28 1
    controller = get_controller_mock()
29 1
    int_manager = INTManager(controller)
30 1
    get_proxy_port_or_raise = MagicMock()
31 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
32
33 1
    dpid_a = "00:00:00:00:00:00:00:01"
34 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
35 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
36 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
37 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
38 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
39 1
    mock_interface_a5.status = EntityStatus.UP
40 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
41 1
    mock_interface_a6.status = EntityStatus.UP
42 1
    mock_interface_a5.metadata = {
43
        "looped": {
44
            "port_numbers": [
45
                mock_interface_a5.port_number,
46
                mock_interface_a6.port_number,
47
            ]
48
        }
49
    }
50
51 1
    dpid_z = "00:00:00:00:00:00:00:03"
52 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
53 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
54 1
    mock_interface_z1.status = EntityStatus.UP
55 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
56 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
57 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
58 1
    mock_interface_z5.status = EntityStatus.UP
59 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
60 1
    mock_interface_z6.status = EntityStatus.UP
61 1
    mock_interface_z5.metadata = {
62
        "looped": {
63
            "port_numbers": [
64
                mock_interface_z5.port_number,
65
                mock_interface_z6.port_number,
66
            ]
67
        }
68
    }
69
70 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
71
        mock_interface_a5.port_number: mock_interface_a5,
72
        mock_interface_a6.port_number: mock_interface_a6,
73
    }[port_no]
74
75 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
76
        mock_interface_z5.port_number: mock_interface_z5,
77
        mock_interface_z6.port_number: mock_interface_z6,
78
    }[port_no]
79
80 1
    pp_a = ProxyPort(source=mock_interface_a5)
81 1
    assert pp_a.source == mock_interface_a5
82 1
    assert pp_a.destination == mock_interface_a6
83 1
    pp_z = ProxyPort(source=mock_interface_z5)
84 1
    assert pp_z.source == mock_interface_z5
85 1
    assert pp_z.destination == mock_interface_z6
86
87 1
    evcs_data = {
88
        "ceaf53b16c3a40": {
89
            "flows": {
90
                "00:00:00:00:00:00:00:01": [
91
                    {
92
                        "match": {"in_port": 1, "dl_vlan": 100},
93
                        "cookie": 12307967605643950656,
94
                        "actions": [
95
                            {"action_type": "push_vlan", "tag_type": "s"},
96
                            {"action_type": "set_vlan", "vlan_id": 1},
97
                            {"action_type": "output", "port": 3},
98
                        ],
99
                        "owner": "mef_eline",
100
                        "table_group": "evpl",
101
                        "table_id": 0,
102
                        "priority": 20000,
103
                    }
104
                ],
105
                "00:00:00:00:00:00:00:03": [
106
                    {
107
                        "match": {"in_port": 1, "dl_vlan": 100},
108
                        "cookie": 12307967605643950656,
109
                        "actions": [
110
                            {"action_type": "push_vlan", "tag_type": "s"},
111
                            {"action_type": "set_vlan", "vlan_id": 1},
112
                            {"action_type": "output", "port": 2},
113
                        ],
114
                        "owner": "mef_eline",
115
                        "table_group": "evpl",
116
                        "table_id": 0,
117
                        "priority": 20000,
118
                    }
119
                ],
120
            },
121
            "evc_id": "ceaf53b16c3a40",
122
            "id": "ceaf53b16c3a40",
123
            "name": "inter_evpl",
124
            "metadata": {
125
                "telemetry_request": {},
126
                "telemetry": {
127
                    "enabled": True,
128
                    "status": "UP",
129
                    "status_reason": [],
130
                    "status_updated_at": "2024-06-11T16:56:29",
131
                },
132
            },
133
            "active": True,
134
            "enabled": True,
135
            "uni_a": {
136
                "interface_id": "00:00:00:00:00:00:00:01:1",
137
                "tag": {"tag_type": "vlan", "value": 100},
138
            },
139
            "uni_z": {
140
                "interface_id": "00:00:00:00:00:00:00:03:1",
141
                "tag": {"tag_type": "vlan", "value": 100},
142
            },
143
        }
144
    }
145
146 1
    int_manager._send_flows = AsyncMock()
147 1
    int_manager._install_int_flows = AsyncMock()
148 1
    int_manager._remove_int_flows = AsyncMock()
149 1
    int_manager.remove_int_flows = AsyncMock()
150 1
    await int_manager.handle_failover_flows(evcs_data, "failover_link_down")
151 1
    assert int_manager._install_int_flows.call_count == 1
152 1
    assert int_manager._remove_int_flows.call_count == 0
153 1
    assert int_manager.remove_int_flows.call_count == 0
154
155 1
    expected_built_flows = {
156
        "12307967605643950656": [
157
            {
158
                "flow": {
159
                    "match": {"in_port": 1, "dl_vlan": 100},
160
                    "cookie": 12163852417568094784,
161
                    "owner": "telemetry_int",
162
                    "table_group": "evpl",
163
                    "table_id": 2,
164
                    "priority": 20000,
165
                    "instructions": [
166
                        {
167
                            "instruction_type": "apply_actions",
168
                            "actions": [
169
                                {"action_type": "add_int_metadata"},
170
                                {"action_type": "push_vlan", "tag_type": "s"},
171
                                {"action_type": "set_vlan", "vlan_id": 1},
172
                                {"action_type": "output", "port": 3},
173
                            ],
174
                        }
175
                    ],
176
                },
177
                "switch": "00:00:00:00:00:00:00:01",
178
            },
179
            {
180
                "flow": {
181
                    "match": {"in_port": 1, "dl_vlan": 100},
182
                    "cookie": 12163852417568094784,
183
                    "owner": "telemetry_int",
184
                    "table_group": "evpl",
185
                    "table_id": 2,
186
                    "priority": 20000,
187
                    "instructions": [
188
                        {
189
                            "instruction_type": "apply_actions",
190
                            "actions": [
191
                                {"action_type": "add_int_metadata"},
192
                                {"action_type": "push_vlan", "tag_type": "s"},
193
                                {"action_type": "set_vlan", "vlan_id": 1},
194
                                {"action_type": "output", "port": 2},
195
                            ],
196
                        }
197
                    ],
198
                },
199
                "switch": "00:00:00:00:00:00:00:03",
200
            },
201
        ]
202
    }
203
204 1
    serd = json.dumps(expected_built_flows)
205 1
    assert json.dumps(int_manager._install_int_flows.call_args[0][0]) == serd
206
207
208 1
async def test_handle_failover_old_path_same_svlan() -> None:
209
    """Test handle failover_old_path_same_svlan.
210
211
               +----+                                              +----+
212
              5|    |6                                            5|    |6
213
           +---+----v---+            +------------+           +----+----v---+
214
        1  |            |            |            |           |             |1
215
    -------+            |3         2 |            |3        2 |             +-------
216
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
217
     100   |            |            |            |           |             | 100
218
           |            |            |            |           |             |
219
           +------------+            +------------+           +-------------+
220
                |4                                                   3|
221
                |_____________________________________________________|
222
    """
223
224 1
    controller = get_controller_mock()
225 1
    int_manager = INTManager(controller)
226 1
    get_proxy_port_or_raise = MagicMock()
227 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
228
229 1
    dpid_a = "00:00:00:00:00:00:00:01"
230 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
231 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
232 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
233 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
234 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
235 1
    mock_interface_a5.status = EntityStatus.UP
236 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
237 1
    mock_interface_a6.status = EntityStatus.UP
238 1
    mock_interface_a5.metadata = {
239
        "looped": {
240
            "port_numbers": [
241
                mock_interface_a5.port_number,
242
                mock_interface_a6.port_number,
243
            ]
244
        }
245
    }
246
247 1
    dpid_z = "00:00:00:00:00:00:00:03"
248 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
249 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
250 1
    mock_interface_z1.status = EntityStatus.UP
251 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
252 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
253 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
254 1
    mock_interface_z5.status = EntityStatus.UP
255 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
256 1
    mock_interface_z6.status = EntityStatus.UP
257 1
    mock_interface_z5.metadata = {
258
        "looped": {
259
            "port_numbers": [
260
                mock_interface_z5.port_number,
261
                mock_interface_z6.port_number,
262
            ]
263
        }
264
    }
265
266 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
267
        mock_interface_a5.port_number: mock_interface_a5,
268
        mock_interface_a6.port_number: mock_interface_a6,
269
    }[port_no]
270
271 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
272
        mock_interface_z5.port_number: mock_interface_z5,
273
        mock_interface_z6.port_number: mock_interface_z6,
274
    }[port_no]
275
276 1
    pp_a = ProxyPort(source=mock_interface_a5)
277 1
    assert pp_a.source == mock_interface_a5
278 1
    assert pp_a.destination == mock_interface_a6
279 1
    pp_z = ProxyPort(source=mock_interface_z5)
280 1
    assert pp_z.source == mock_interface_z5
281 1
    assert pp_z.destination == mock_interface_z6
282
283 1
    evcs_data = {
284
        "ceaf53b16c3a40": {
285
            "removed_flows": {
286
                "00:00:00:00:00:00:00:01": [
287
                    {
288
                        "cookie": 12307967605643950656,
289
                        "match": {"in_port": 4, "dl_vlan": 1},
290
                        "cookie_mask": 18446744073709551615,
291
                    }
292
                ],
293
                "00:00:00:00:00:00:00:03": [
294
                    {
295
                        "cookie": 12307967605643950656,
296
                        "match": {"in_port": 3, "dl_vlan": 1},
297
                        "cookie_mask": 18446744073709551615,
298
                    }
299
                ],
300
            },
301
            "current_path": [
302
                {
303
                    "id": "78282c4d5",
304
                    "endpoint_a": {
305
                        "id": "00: 00:00:00:00:00:00:01:3",
306
                        "name": "s1-eth3",
307
                        "port_number": 3,
308
                        "mac": "b2:ac:2b:ac:87:bb",
309
                        "switch": "00:00:00:00:00:00:00:01",
310
                        "type": "interface",
311
                        "nni": True,
312
                        "uni": False,
313
                        "speed": 1250000000.0,
314
                        "metadata": {},
315
                        "lldp": True,
316
                        "active": True,
317
                        "enabled": True,
318
                        "status": "UP",
319
                        "status_reason": [],
320
                        "link": "78282c4d5",
321
                    },
322
                    "endpoint_b": {
323
                        "id": "00:00:00:00:00:00:00:02:2",
324
                        "name": "s2-eth2",
325
                        "port_number": 2,
326
                        "mac": "62:50:49:d7:79:8a",
327
                        "switch": "00:00:00:00:00:00:00:02",
328
                        "type": "interface",
329
                        "nni": True,
330
                        "uni": False,
331
                        "speed": 1250000000.0,
332
                        "metadata": {},
333
                        "lldp": True,
334
                        "active": True,
335
                        "enabled": True,
336
                        "status": "UP",
337
                        "status_reason": [],
338
                        "link": "78282c4d5",
339
                    },
340
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
341
                    "active": True,
342
                    "enabled": True,
343
                    "status": "UP",
344
                    "status_reason": [],
345
                },
346
                {
347
                    "id": "4d42dc085",
348
                    "endpoint_a": {
349
                        "id": "00:00:00:00:00:00:00:02:3",
350
                        "name": "s2-eth3",
351
                        "port_number": 3,
352
                        "mac": "76:82:ef:6e:d2:9d",
353
                        "switch": "00:00:00:00:00:00:00:02",
354
                        "type": "interface",
355
                        "nni": True,
356
                        "uni": False,
357
                        "speed": 1250000000.0,
358
                        "metadata": {},
359
                        "lldp": True,
360
                        "active": True,
361
                        "enabled": True,
362
                        "status": "UP",
363
                        "status_reason ": [],
364
                        "link": "4d42dc085",
365
                    },
366
                    "endpoint_b": {
367
                        "id": "00:00:00:00:00:00:00:03:2",
368
                        "name": "s3-eth2",
369
                        "port_number": 2,
370
                        "mac": "6a:c1:51:b1:a9:8a",
371
                        "switch": "00:00:00:00:00:00:00:03",
372
                        "type": "interface",
373
                        "nni": True,
374
                        "uni": False,
375
                        "speed": 1250000000.0,
376
                        "metadata": {},
377
                        "lldp": True,
378
                        "active": True,
379
                        "enabled": True,
380
                        "status": "UP",
381
                        "status_reason": [],
382
                        "link": "4d42dc085",
383
                    },
384
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
385
                    "active": True,
386
                    "enabled": True,
387
                    "status": "UP",
388
                    "status_reason": [],
389
                },
390
            ],
391
            "evc_id": "ceaf53b16c3a40",
392
            "id": "ceaf53b16c3a40",
393
            "name": "inter_evpl",
394
            "metadata": {
395
                "telemetry_request": {},
396
                "telemetry": {
397
                    "enabled": True,
398
                    "status": "UP",
399
                    "status_reason": [],
400
                    "status_updated_at": "2024-06-11T16:56:29",
401
                },
402
            },
403
            "active": True,
404
            "enabled": True,
405
            "uni_a": {
406
                "interface_id": "00:00:00:00:00:00:00:01:1",
407
                "tag": {"tag_type": "vlan", "value": 100},
408
            },
409
            "uni_z": {
410
                "interface_id": "00:00:00:00:00:00:00:03:1",
411
                "tag": {"tag_type": "vlan", "value": 100},
412
            },
413
        }
414
    }
415
416 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
417 1
    int_manager._send_flows = AsyncMock()
418 1
    int_manager._install_int_flows = AsyncMock()
419 1
    int_manager._remove_int_flows = AsyncMock()
420 1
    int_manager.remove_int_flows = AsyncMock()
421 1
    await int_manager.handle_failover_flows(evcs_data, "failover_old_path")
422 1
    assert int_manager._install_int_flows.call_count == 0
423 1
    assert int_manager._remove_int_flows.call_count == 1
424 1
    assert int_manager.remove_int_flows.call_count == 0
425
426 1
    expected_built_flows = {
427
        "12307967605643950656": [
428
            {
429
                "flow": {
430
                    "cookie": 12163852417568094784,
431
                    "match": {
432
                        "in_port": 4,
433
                        "dl_vlan": 1,
434
                        "dl_type": 2048,
435
                        "nw_proto": 6,
436
                    },
437
                    "cookie_mask": 18446744073709551615,
438
                    "priority": 21100,
439
                    "table_group": "evpl",
440
                    "owner": "telemetry_int",
441
                    "instructions": [
442
                        {
443
                            "instruction_type": "apply_actions",
444
                            "actions": [
445
                                {"action_type": "add_int_metadata"},
446
                                {"action_type": "pop_vlan"},
447
                                {"action_type": "output", "port": 5},
448
                            ],
449
                        }
450
                    ],
451
                },
452
                "switch": "00:00:00:00:00:00:00:01",
453
            },
454
            {
455
                "flow": {
456
                    "cookie": 12163852417568094784,
457
                    "match": {
458
                        "in_port": 4,
459
                        "dl_vlan": 1,
460
                        "dl_type": 2048,
461
                        "nw_proto": 17,
462
                    },
463
                    "cookie_mask": 18446744073709551615,
464
                    "priority": 21100,
465
                    "table_group": "evpl",
466
                    "owner": "telemetry_int",
467
                    "instructions": [
468
                        {
469
                            "instruction_type": "apply_actions",
470
                            "actions": [
471
                                {"action_type": "add_int_metadata"},
472
                                {"action_type": "pop_vlan"},
473
                                {"action_type": "output", "port": 5},
474
                            ],
475
                        }
476
                    ],
477
                },
478
                "switch": "00:00:00:00:00:00:00:01",
479
            },
480
            {
481
                "flow": {
482
                    "cookie": 12163852417568094784,
483
                    "match": {
484
                        "in_port": 3,
485
                        "dl_vlan": 1,
486
                        "dl_type": 2048,
487
                        "nw_proto": 6,
488
                    },
489
                    "cookie_mask": 18446744073709551615,
490
                    "priority": 21100,
491
                    "table_group": "evpl",
492
                    "owner": "telemetry_int",
493
                    "instructions": [
494
                        {
495
                            "instruction_type": "apply_actions",
496
                            "actions": [
497
                                {"action_type": "add_int_metadata"},
498
                                {"action_type": "pop_vlan"},
499
                                {"action_type": "output", "port": 5},
500
                            ],
501
                        }
502
                    ],
503
                },
504
                "switch": "00:00:00:00:00:00:00:03",
505
            },
506
            {
507
                "flow": {
508
                    "cookie": 12163852417568094784,
509
                    "match": {
510
                        "in_port": 3,
511
                        "dl_vlan": 1,
512
                        "dl_type": 2048,
513
                        "nw_proto": 17,
514
                    },
515
                    "cookie_mask": 18446744073709551615,
516
                    "priority": 21100,
517
                    "table_group": "evpl",
518
                    "owner": "telemetry_int",
519
                    "instructions": [
520
                        {
521
                            "instruction_type": "apply_actions",
522
                            "actions": [
523
                                {"action_type": "add_int_metadata"},
524
                                {"action_type": "pop_vlan"},
525
                                {"action_type": "output", "port": 5},
526
                            ],
527
                        }
528
                    ],
529
                },
530
                "switch": "00:00:00:00:00:00:00:03",
531
            },
532
        ]
533
    }
534 1
    serd = json.dumps(expected_built_flows)
535 1
    assert json.dumps(int_manager._remove_int_flows.call_args[0][0]) == serd
536
537
538
# pylint: disable=too-many-statements
539 1
async def test_handle_failover_old_path_diff_svlan() -> None:
540
    """Test handle failover_old_path_diff_svlan.
541
542
               +----+                                              +----+
543
              5|    |6                                            5|    |6
544
           +---+----v---+            +------------+           +----+----v---+
545
        1  |            |            |            |           |             |1
546
    -------+            |3         2 |            |3        2 |             +-------
547
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
548
     100   |            |            |            |           |             | 100
549
           |            |            |            |           |             |
550
           +------------+            +------------+           +-------------+
551
                |4                                                   3|
552
                |_____________________________________________________|
553
    """
554
555 1
    controller = get_controller_mock()
556 1
    int_manager = INTManager(controller)
557 1
    get_proxy_port_or_raise = MagicMock()
558 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
559
560 1
    dpid_a = "00:00:00:00:00:00:00:01"
561 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
562 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
563 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
564 1
    mock_interface_a4 = get_interface_mock("s1-eth4", 4, mock_switch_a)
565 1
    mock_interface_a4.id = f"{dpid_a}:{mock_interface_a4.port_number}"
566 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
567 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
568 1
    mock_interface_a4.status = EntityStatus.UP
569 1
    mock_interface_a5.status = EntityStatus.UP
570 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
571 1
    mock_interface_a6.status = EntityStatus.UP
572 1
    mock_interface_a5.metadata = {
573
        "looped": {
574
            "port_numbers": [
575
                mock_interface_a5.port_number,
576
                mock_interface_a6.port_number,
577
            ]
578
        }
579
    }
580
581 1
    dpid_z = "00:00:00:00:00:00:00:03"
582 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
583 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
584 1
    mock_interface_z1.status = EntityStatus.UP
585 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
586 1
    mock_interface_z3 = get_interface_mock("s1-eth3", 3, mock_switch_z)
587 1
    mock_interface_z3.status = EntityStatus.UP
588 1
    mock_interface_z3.id = f"{dpid_z}:{mock_interface_z3.port_number}"
589 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
590 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
591 1
    mock_interface_z5.status = EntityStatus.UP
592 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
593 1
    mock_interface_z6.status = EntityStatus.UP
594 1
    mock_interface_z5.metadata = {
595
        "looped": {
596
            "port_numbers": [
597
                mock_interface_z5.port_number,
598
                mock_interface_z6.port_number,
599
            ]
600
        }
601
    }
602
603 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
604
        mock_interface_a5.port_number: mock_interface_a5,
605
        mock_interface_a6.port_number: mock_interface_a6,
606
    }[port_no]
607
608 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
609
        mock_interface_z5.port_number: mock_interface_z5,
610
        mock_interface_z6.port_number: mock_interface_z6,
611
    }[port_no]
612
613 1
    pp_a = ProxyPort(source=mock_interface_a5)
614 1
    assert pp_a.source == mock_interface_a5
615 1
    assert pp_a.destination == mock_interface_a6
616 1
    pp_z = ProxyPort(source=mock_interface_z5)
617 1
    assert pp_z.source == mock_interface_z5
618 1
    assert pp_z.destination == mock_interface_z6
619
620 1
    evcs_data = {
621
        "ceaf53b16c3a40": {
622
            "removed_flows": {
623
                "00:00:00:00:00:00:00:01": [
624
                    {
625
                        "cookie": 12307967605643950656,
626
                        "match": {"in_port": 4, "dl_vlan": 2},
627
                        "cookie_mask": 18446744073709551615,
628
                    }
629
                ],
630
                "00:00:00:00:00:00:00:03": [
631
                    {
632
                        "cookie": 12307967605643950656,
633
                        "match": {"in_port": 3, "dl_vlan": 2},
634
                        "cookie_mask": 18446744073709551615,
635
                    }
636
                ],
637
            },
638
            "current_path": [
639
                {
640
                    "id": "78282c4d5",
641
                    "endpoint_a": {
642
                        "id": "00:00:00:00:00:00:00:01:3",
643
                        "name": "s1-eth3",
644
                        "port_number": 3,
645
                        "mac": "b2:ac:2b:ac:87:bb",
646
                        "switch": "00:00:00:00:00:00:00:01",
647
                        "type": "interface",
648
                        "nni": True,
649
                        "uni": False,
650
                        "speed": 1250000000.0,
651
                        "metadata": {},
652
                        "lldp": True,
653
                        "active": True,
654
                        "enabled": True,
655
                        "status": "UP",
656
                        "status_reason": [],
657
                        "link": "78282c4d5",
658
                    },
659
                    "endpoint_b": {
660
                        "id": "00:00:00:00:00:00:00:02:2",
661
                        "name": "s2-eth2",
662
                        "port_number": 2,
663
                        "mac": "62:50:49:d7:79:8a",
664
                        "switch": "00:00:00:00:00:00:00:02",
665
                        "type": "interface",
666
                        "nni": True,
667
                        "uni": False,
668
                        "speed": 1250000000.0,
669
                        "metadata": {},
670
                        "lldp": True,
671
                        "active": True,
672
                        "enabled": True,
673
                        "status": "UP",
674
                        "status_reason": [],
675
                        "link": "78282c4d5",
676
                    },
677
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
678
                    "active": True,
679
                    "enabled": True,
680
                    "status": "UP",
681
                    "status_reason": [],
682
                },
683
                {
684
                    "id": "4d42dc085",
685
                    "endpoint_a": {
686
                        "id": "00:00:00:00:00:00:00:02:3",
687
                        "name": "s2-eth3",
688
                        "port_number": 3,
689
                        "mac": "76:82:ef:6e:d2:9d",
690
                        "switch": "00:00:00:00:00:00:00:02",
691
                        "type": "interface",
692
                        "nni": True,
693
                        "uni": False,
694
                        "speed": 1250000000.0,
695
                        "metadata": {},
696
                        "lldp": True,
697
                        "active": True,
698
                        "enabled": True,
699
                        "status": "UP",
700
                        "status_reason ": [],
701
                        "link": "4d42dc085",
702
                    },
703
                    "endpoint_b": {
704
                        "id": "00:00:00:00:00:00:00:03:2",
705
                        "name": "s3-eth2",
706
                        "port_number": 2,
707
                        "mac": "6a:c1: 51:b1:a9:8a",
708
                        "switch": "00:00:00:00:00:00:00:03",
709
                        "type": "interface",
710
                        "nni": True,
711
                        "uni": False,
712
                        "speed": 1250000000.0,
713
                        "metadata": {},
714
                        "lldp": True,
715
                        "active": True,
716
                        "enabled": True,
717
                        "status": "UP",
718
                        "status_reason": [],
719
                        "link": "4d42dc085",
720
                    },
721
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
722
                    "active": True,
723
                    "enabled": True,
724
                    "status": "UP",
725
                    "status_reason": [],
726
                },
727
            ],
728
            "evc_id": "ceaf53b16c3a40",
729
            "id": "ceaf53b16c3a40",
730
            "name": "inter_evpl",
731
            "metadata": {
732
                "telemetry_request": {},
733
                "telemetry": {
734
                    "enabled": True,
735
                    "status": "UP",
736
                    "status_reason": [],
737
                    "status_updated_at": "2024-06-11T16:56:29",
738
                },
739
            },
740
            "active": True,
741
            "enabled": True,
742
            "uni_a": {
743
                "interface_id": "00:00:00:00:00:00:00:01:1",
744
                "tag": {"tag_type": "vlan", "value": 100},
745
            },
746
            "uni_z": {
747
                "interface_id": "00:00:00:00:00:00:00:03:1",
748
                "tag": {"tag_type": "vlan", "value": 100},
749
            },
750
        }
751
    }
752
753 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
754 1
    int_manager._send_flows = AsyncMock()
755 1
    int_manager._install_int_flows = AsyncMock()
756 1
    int_manager._remove_int_flows = AsyncMock()
757 1
    int_manager.remove_int_flows = AsyncMock()
758 1
    await int_manager.handle_failover_flows(evcs_data, "failover_deployed")
759 1
    assert int_manager._install_int_flows.call_count == 0
760 1
    assert int_manager._remove_int_flows.call_count == 1
761 1
    assert int_manager.remove_int_flows.call_count == 0
762
763 1
    expected_built_flows = {
764
        "12307967605643950656": [
765
            {
766
                "flow": {
767
                    "cookie": 12163852417568094784,
768
                    "match": {
769
                        "in_port": 4,
770
                        "dl_vlan": 2,
771
                        "dl_type": 2048,
772
                        "nw_proto": 6,
773
                    },
774
                    "cookie_mask": 18446744073709551615,
775
                    "priority": 21100,
776
                    "table_group": "evpl",
777
                    "owner": "telemetry_int",
778
                    "instructions": [
779
                        {
780
                            "instruction_type": "apply_actions",
781
                            "actions": [
782
                                {"action_type": "add_int_metadata"},
783
                                {"action_type": "pop_vlan"},
784
                                {"action_type": "output", "port": 5},
785
                            ],
786
                        }
787
                    ],
788
                },
789
                "switch": "00:00:00:00:00:00:00:01",
790
            },
791
            {
792
                "flow": {
793
                    "cookie": 12163852417568094784,
794
                    "match": {
795
                        "in_port": 4,
796
                        "dl_vlan": 2,
797
                        "dl_type": 2048,
798
                        "nw_proto": 17,
799
                    },
800
                    "cookie_mask": 18446744073709551615,
801
                    "priority": 21100,
802
                    "table_group": "evpl",
803
                    "owner": "telemetry_int",
804
                    "instructions": [
805
                        {
806
                            "instruction_type": "apply_actions",
807
                            "actions": [
808
                                {"action_type": "add_int_metadata"},
809
                                {"action_type": "pop_vlan"},
810
                                {"action_type": "output", "port": 5},
811
                            ],
812
                        }
813
                    ],
814
                },
815
                "switch": "00:00:00:00:00:00:00:01",
816
            },
817
            {
818
                "flow": {
819
                    "cookie": 12163852417568094784,
820
                    "match": {
821
                        "in_port": 3,
822
                        "dl_vlan": 2,
823
                        "dl_type": 2048,
824
                        "nw_proto": 6,
825
                    },
826
                    "cookie_mask": 18446744073709551615,
827
                    "priority": 21100,
828
                    "table_group": "evpl",
829
                    "owner": "telemetry_int",
830
                    "instructions": [
831
                        {
832
                            "instruction_type": "apply_actions",
833
                            "actions": [
834
                                {"action_type": "add_int_metadata"},
835
                                {"action_type": "pop_vlan"},
836
                                {"action_type": "output", "port": 5},
837
                            ],
838
                        }
839
                    ],
840
                },
841
                "switch": "00:00:00:00:00:00:00:03",
842
            },
843
            {
844
                "flow": {
845
                    "cookie": 12163852417568094784,
846
                    "match": {
847
                        "in_port": 3,
848
                        "dl_vlan": 2,
849
                        "dl_type": 2048,
850
                        "nw_proto": 17,
851
                    },
852
                    "cookie_mask": 18446744073709551615,
853
                    "priority": 21100,
854
                    "table_group": "evpl",
855
                    "owner": "telemetry_int",
856
                    "instructions": [
857
                        {
858
                            "instruction_type": "apply_actions",
859
                            "actions": [
860
                                {"action_type": "add_int_metadata"},
861
                                {"action_type": "pop_vlan"},
862
                                {"action_type": "output", "port": 5},
863
                            ],
864
                        }
865
                    ],
866
                },
867
                "switch": "00:00:00:00:00:00:00:03",
868
            },
869
        ]
870
    }
871 1
    serd = json.dumps(expected_built_flows)
872
    assert json.dumps(int_manager._remove_int_flows.call_args[0][0]) == serd
873