test_flow_builder_failover   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 859
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 620
dl 0
loc 859
ccs 152
cts 152
cp 1
rs 9.98
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 402 3
B test_handle_failover_old_path_same_svlan() 0 246 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(controller, 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(controller, 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(controller, 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(controller, 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": {"in_port": 4, "dl_vlan": 1},
432
                    "cookie_mask": 18446744073709551615,
433
                    "priority": 21000,
434
                    "table_group": "evpl",
435
                    "owner": "telemetry_int",
436
                },
437
                "switch": "00:00:00:00:00:00:00:01",
438
            },
439
            {
440
                "flow": {
441
                    "cookie": 12163852417568094784,
442
                    "match": {"in_port": 3, "dl_vlan": 1},
443
                    "cookie_mask": 18446744073709551615,
444
                    "priority": 21000,
445
                    "table_group": "evpl",
446
                    "owner": "telemetry_int",
447
                },
448
                "switch": "00:00:00:00:00:00:00:03",
449
            },
450
        ]
451
    }
452 1
    serd = json.dumps(expected_built_flows)
453 1
    assert json.dumps(int_manager._remove_int_flows.call_args[0][0]) == serd
454
455
456
# pylint: disable=too-many-statements
457 1
async def test_handle_failover_old_path_diff_svlan() -> None:
458
    """Test handle failover_old_path_diff_svlan.
459
460
               +----+                                              +----+
461
              5|    |6                                            5|    |6
462
           +---+----v---+            +------------+           +----+----v---+
463
        1  |            |            |            |           |             |1
464
    -------+            |3         2 |            |3        2 |             +-------
465
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
466
     100   |            |            |            |           |             | 100
467
           |            |            |            |           |             |
468
           +------------+            +------------+           +-------------+
469
                |4                                                   3|
470
                |_____________________________________________________|
471
    """
472
473 1
    controller = get_controller_mock()
474 1
    int_manager = INTManager(controller)
475 1
    get_proxy_port_or_raise = MagicMock()
476 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
477
478 1
    dpid_a = "00:00:00:00:00:00:00:01"
479 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
480 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
481 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
482 1
    mock_interface_a4 = get_interface_mock("s1-eth4", 4, mock_switch_a)
483 1
    mock_interface_a4.id = f"{dpid_a}:{mock_interface_a4.port_number}"
484 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
485 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
486 1
    mock_interface_a4.status = EntityStatus.UP
487 1
    mock_interface_a5.status = EntityStatus.UP
488 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
489 1
    mock_interface_a6.status = EntityStatus.UP
490 1
    mock_interface_a5.metadata = {
491
        "looped": {
492
            "port_numbers": [
493
                mock_interface_a5.port_number,
494
                mock_interface_a6.port_number,
495
            ]
496
        }
497
    }
498
499 1
    dpid_z = "00:00:00:00:00:00:00:03"
500 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
501 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
502 1
    mock_interface_z1.status = EntityStatus.UP
503 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
504 1
    mock_interface_z3 = get_interface_mock("s1-eth3", 3, mock_switch_z)
505 1
    mock_interface_z3.status = EntityStatus.UP
506 1
    mock_interface_z3.id = f"{dpid_z}:{mock_interface_z3.port_number}"
507 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
508 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
509 1
    mock_interface_z5.status = EntityStatus.UP
510 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
511 1
    mock_interface_z6.status = EntityStatus.UP
512 1
    mock_interface_z5.metadata = {
513
        "looped": {
514
            "port_numbers": [
515
                mock_interface_z5.port_number,
516
                mock_interface_z6.port_number,
517
            ]
518
        }
519
    }
520
521 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
522
        mock_interface_a5.port_number: mock_interface_a5,
523
        mock_interface_a6.port_number: mock_interface_a6,
524
    }[port_no]
525
526 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
527
        mock_interface_z5.port_number: mock_interface_z5,
528
        mock_interface_z6.port_number: mock_interface_z6,
529
    }[port_no]
530
531 1
    pp_a = ProxyPort(controller, source=mock_interface_a5)
532 1
    assert pp_a.source == mock_interface_a5
533 1
    assert pp_a.destination == mock_interface_a6
534 1
    pp_z = ProxyPort(controller, source=mock_interface_z5)
535 1
    assert pp_z.source == mock_interface_z5
536 1
    assert pp_z.destination == mock_interface_z6
537
538 1
    evcs_data = {
539
        "ceaf53b16c3a40": {
540
            "removed_flows": {
541
                "00:00:00:00:00:00:00:01": [
542
                    {
543
                        "cookie": 12307967605643950656,
544
                        "match": {"in_port": 4, "dl_vlan": 2},
545
                        "cookie_mask": 18446744073709551615,
546
                    }
547
                ],
548
                "00:00:00:00:00:00:00:03": [
549
                    {
550
                        "cookie": 12307967605643950656,
551
                        "match": {"in_port": 3, "dl_vlan": 2},
552
                        "cookie_mask": 18446744073709551615,
553
                    }
554
                ],
555
            },
556
            "current_path": [
557
                {
558
                    "id": "78282c4d5",
559
                    "endpoint_a": {
560
                        "id": "00:00:00:00:00:00:00:01:3",
561
                        "name": "s1-eth3",
562
                        "port_number": 3,
563
                        "mac": "b2:ac:2b:ac:87:bb",
564
                        "switch": "00:00:00:00:00:00:00:01",
565
                        "type": "interface",
566
                        "nni": True,
567
                        "uni": False,
568
                        "speed": 1250000000.0,
569
                        "metadata": {},
570
                        "lldp": True,
571
                        "active": True,
572
                        "enabled": True,
573
                        "status": "UP",
574
                        "status_reason": [],
575
                        "link": "78282c4d5",
576
                    },
577
                    "endpoint_b": {
578
                        "id": "00:00:00:00:00:00:00:02:2",
579
                        "name": "s2-eth2",
580
                        "port_number": 2,
581
                        "mac": "62:50:49:d7:79:8a",
582
                        "switch": "00:00:00:00:00:00:00:02",
583
                        "type": "interface",
584
                        "nni": True,
585
                        "uni": False,
586
                        "speed": 1250000000.0,
587
                        "metadata": {},
588
                        "lldp": True,
589
                        "active": True,
590
                        "enabled": True,
591
                        "status": "UP",
592
                        "status_reason": [],
593
                        "link": "78282c4d5",
594
                    },
595
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
596
                    "active": True,
597
                    "enabled": True,
598
                    "status": "UP",
599
                    "status_reason": [],
600
                },
601
                {
602
                    "id": "4d42dc085",
603
                    "endpoint_a": {
604
                        "id": "00:00:00:00:00:00:00:02:3",
605
                        "name": "s2-eth3",
606
                        "port_number": 3,
607
                        "mac": "76:82:ef:6e:d2:9d",
608
                        "switch": "00:00:00:00:00:00:00:02",
609
                        "type": "interface",
610
                        "nni": True,
611
                        "uni": False,
612
                        "speed": 1250000000.0,
613
                        "metadata": {},
614
                        "lldp": True,
615
                        "active": True,
616
                        "enabled": True,
617
                        "status": "UP",
618
                        "status_reason ": [],
619
                        "link": "4d42dc085",
620
                    },
621
                    "endpoint_b": {
622
                        "id": "00:00:00:00:00:00:00:03:2",
623
                        "name": "s3-eth2",
624
                        "port_number": 2,
625
                        "mac": "6a:c1: 51:b1:a9:8a",
626
                        "switch": "00:00:00:00:00:00:00:03",
627
                        "type": "interface",
628
                        "nni": True,
629
                        "uni": False,
630
                        "speed": 1250000000.0,
631
                        "metadata": {},
632
                        "lldp": True,
633
                        "active": True,
634
                        "enabled": True,
635
                        "status": "UP",
636
                        "status_reason": [],
637
                        "link": "4d42dc085",
638
                    },
639
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
640
                    "active": True,
641
                    "enabled": True,
642
                    "status": "UP",
643
                    "status_reason": [],
644
                },
645
            ],
646
            "evc_id": "ceaf53b16c3a40",
647
            "id": "ceaf53b16c3a40",
648
            "name": "inter_evpl",
649
            "metadata": {
650
                "telemetry_request": {},
651
                "telemetry": {
652
                    "enabled": True,
653
                    "status": "UP",
654
                    "status_reason": [],
655
                    "status_updated_at": "2024-06-11T16:56:29",
656
                },
657
            },
658
            "active": True,
659
            "enabled": True,
660
            "uni_a": {
661
                "interface_id": "00:00:00:00:00:00:00:01:1",
662
                "tag": {"tag_type": "vlan", "value": 100},
663
            },
664
            "uni_z": {
665
                "interface_id": "00:00:00:00:00:00:00:03:1",
666
                "tag": {"tag_type": "vlan", "value": 100},
667
            },
668
        }
669
    }
670
671 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
672 1
    int_manager._send_flows = AsyncMock()
673 1
    int_manager._install_int_flows = AsyncMock()
674 1
    int_manager._remove_int_flows = AsyncMock()
675 1
    int_manager.remove_int_flows = AsyncMock()
676 1
    await int_manager.handle_failover_flows(evcs_data, "failover_deployed")
677 1
    assert int_manager._install_int_flows.call_count == 0
678 1
    assert int_manager._remove_int_flows.call_count == 1
679 1
    assert int_manager.remove_int_flows.call_count == 0
680
681 1
    expected_built_flows = {
682
        "12307967605643950656": [
683
            {
684
                "flow": {
685
                    "cookie": 12163852417568094784,
686
                    "match": {
687
                        "in_port": 4,
688
                        "dl_vlan": 2,
689
                        "dl_type": 2048,
690
                        "nw_proto": 6,
691
                    },
692
                    "cookie_mask": 18446744073709551615,
693
                    "priority": 21100,
694
                    "table_group": "evpl",
695
                    "owner": "telemetry_int",
696
                    "instructions": [
697
                        {
698
                            "instruction_type": "apply_actions",
699
                            "actions": [
700
                                {"action_type": "add_int_metadata"},
701
                                {"action_type": "output", "port": 5},
702
                            ],
703
                        }
704
                    ],
705
                },
706
                "switch": "00:00:00:00:00:00:00:01",
707
            },
708
            {
709
                "flow": {
710
                    "cookie": 12163852417568094784,
711
                    "match": {
712
                        "in_port": 4,
713
                        "dl_vlan": 2,
714
                        "dl_type": 2048,
715
                        "nw_proto": 17,
716
                    },
717
                    "cookie_mask": 18446744073709551615,
718
                    "priority": 21100,
719
                    "table_group": "evpl",
720
                    "owner": "telemetry_int",
721
                    "instructions": [
722
                        {
723
                            "instruction_type": "apply_actions",
724
                            "actions": [
725
                                {"action_type": "add_int_metadata"},
726
                                {"action_type": "output", "port": 5},
727
                            ],
728
                        }
729
                    ],
730
                },
731
                "switch": "00:00:00:00:00:00:00:01",
732
            },
733
            {
734
                "flow": {
735
                    "cookie": 12163852417568094784,
736
                    "match": {"in_port": 6, "dl_vlan": 2},
737
                    "cookie_mask": 18446744073709551615,
738
                    "priority": 21000,
739
                    "table_group": "evpl",
740
                    "owner": "telemetry_int",
741
                    "instructions": [
742
                        {
743
                            "instruction_type": "apply_actions",
744
                            "actions": [{"action_type": "send_report"}],
745
                        },
746
                        {"instruction_type": "goto_table", "table_id": 2},
747
                    ],
748
                },
749
                "switch": "00:00:00:00:00:00:00:01",
750
            },
751
            {
752
                "flow": {
753
                    "cookie": 12163852417568094784,
754
                    "match": {"in_port": 6, "dl_vlan": 2},
755
                    "cookie_mask": 18446744073709551615,
756
                    "priority": 21000,
757
                    "table_group": "evpl",
758
                    "owner": "telemetry_int",
759
                    "instructions": [
760
                        {
761
                            "instruction_type": "apply_actions",
762
                            "actions": [{"action_type": "pop_int"}],
763
                        }
764
                    ],
765
                    "table_id": 2,
766
                },
767
                "switch": "00:00:00:00:00:00:00:01",
768
            },
769
            {
770
                "flow": {
771
                    "cookie": 12163852417568094784,
772
                    "match": {
773
                        "in_port": 3,
774
                        "dl_vlan": 2,
775
                        "dl_type": 2048,
776
                        "nw_proto": 6,
777
                    },
778
                    "cookie_mask": 18446744073709551615,
779
                    "priority": 21100,
780
                    "table_group": "evpl",
781
                    "owner": "telemetry_int",
782
                    "instructions": [
783
                        {
784
                            "instruction_type": "apply_actions",
785
                            "actions": [
786
                                {"action_type": "add_int_metadata"},
787
                                {"action_type": "output", "port": 5},
788
                            ],
789
                        }
790
                    ],
791
                },
792
                "switch": "00:00:00:00:00:00:00:03",
793
            },
794
            {
795
                "flow": {
796
                    "cookie": 12163852417568094784,
797
                    "match": {
798
                        "in_port": 3,
799
                        "dl_vlan": 2,
800
                        "dl_type": 2048,
801
                        "nw_proto": 17,
802
                    },
803
                    "cookie_mask": 18446744073709551615,
804
                    "priority": 21100,
805
                    "table_group": "evpl",
806
                    "owner": "telemetry_int",
807
                    "instructions": [
808
                        {
809
                            "instruction_type": "apply_actions",
810
                            "actions": [
811
                                {"action_type": "add_int_metadata"},
812
                                {"action_type": "output", "port": 5},
813
                            ],
814
                        }
815
                    ],
816
                },
817
                "switch": "00:00:00:00:00:00:00:03",
818
            },
819
            {
820
                "flow": {
821
                    "cookie": 12163852417568094784,
822
                    "match": {"in_port": 6, "dl_vlan": 2},
823
                    "cookie_mask": 18446744073709551615,
824
                    "priority": 21000,
825
                    "table_group": "evpl",
826
                    "owner": "telemetry_int",
827
                    "instructions": [
828
                        {
829
                            "instruction_type": "apply_actions",
830
                            "actions": [{"action_type": "send_report"}],
831
                        },
832
                        {"instruction_type": "goto_table", "table_id": 2},
833
                    ],
834
                },
835
                "switch": "00:00:00:00:00:00:00:03",
836
            },
837
            {
838
                "flow": {
839
                    "cookie": 12163852417568094784,
840
                    "match": {"in_port": 6, "dl_vlan": 2},
841
                    "cookie_mask": 18446744073709551615,
842
                    "priority": 21000,
843
                    "table_group": "evpl",
844
                    "owner": "telemetry_int",
845
                    "instructions": [
846
                        {
847
                            "instruction_type": "apply_actions",
848
                            "actions": [{"action_type": "pop_int"}],
849
                        }
850
                    ],
851
                    "table_id": 2,
852
                },
853
                "switch": "00:00:00:00:00:00:00:03",
854
            },
855
        ]
856
    }
857 1
    serd = json.dumps(expected_built_flows)
858
    assert json.dumps(int_manager._remove_int_flows.call_args[0][0]) == serd
859