Passed
Push — master ( 4bf6f4...81fe6d )
by Vinicius
02:40 queued 17s
created

test_flow_builder_failover   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 949
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 682
dl 0
loc 949
ccs 152
cts 152
cp 1
rs 9.9179
c 0
b 0
f 0
wmc 9

3 Functions

Rating   Name   Duplication   Size   Complexity  
B test_handle_failover_old_path_diff_svlan() 0 402 3
B test_handle_failover_link_down() 0 286 3
B test_handle_failover_old_path_same_svlan() 0 244 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": {
160
                        "in_port": 1,
161
                        "dl_vlan": 100,
162
                        "dl_type": 2048,
163
                        "nw_proto": 6,
164
                    },
165
                    "cookie": 12163852417568094784,
166
                    "owner": "telemetry_int",
167
                    "table_group": "evpl",
168
                    "table_id": 0,
169
                    "priority": 20100,
170
                    "instructions": [
171
                        {
172
                            "instruction_type": "apply_actions",
173
                            "actions": [{"action_type": "push_int"}],
174
                        },
175
                        {"instruction_type": "goto_table", "table_id": 2},
176
                    ],
177
                },
178
                "switch": "00:00:00:00:00:00:00:01",
179
            },
180
            {
181
                "flow": {
182
                    "match": {
183
                        "in_port": 1,
184
                        "dl_vlan": 100,
185
                        "dl_type": 2048,
186
                        "nw_proto": 17,
187
                    },
188
                    "cookie": 12163852417568094784,
189
                    "owner": "telemetry_int",
190
                    "table_group": "evpl",
191
                    "table_id": 0,
192
                    "priority": 20100,
193
                    "instructions": [
194
                        {
195
                            "instruction_type": "apply_actions",
196
                            "actions": [{"action_type": "push_int"}],
197
                        },
198
                        {"instruction_type": "goto_table", "table_id": 2},
199
                    ],
200
                },
201
                "switch": "00:00:00:00:00:00:00:01",
202
            },
203
            {
204
                "flow": {
205
                    "match": {"in_port": 1, "dl_vlan": 100},
206
                    "cookie": 12163852417568094784,
207
                    "owner": "telemetry_int",
208
                    "table_group": "evpl",
209
                    "table_id": 2,
210
                    "priority": 20000,
211
                    "instructions": [
212
                        {
213
                            "instruction_type": "apply_actions",
214
                            "actions": [
215
                                {"action_type": "add_int_metadata"},
216
                                {"action_type": "push_vlan", "tag_type": "s"},
217
                                {"action_type": "set_vlan", "vlan_id": 1},
218
                                {"action_type": "output", "port": 3},
219
                            ],
220
                        }
221
                    ],
222
                },
223
                "switch": "00:00:00:00:00:00:00:01",
224
            },
225
            {
226
                "flow": {
227
                    "match": {
228
                        "in_port": 1,
229
                        "dl_vlan": 100,
230
                        "dl_type": 2048,
231
                        "nw_proto": 6,
232
                    },
233
                    "cookie": 12163852417568094784,
234
                    "owner": "telemetry_int",
235
                    "table_group": "evpl",
236
                    "table_id": 0,
237
                    "priority": 20100,
238
                    "instructions": [
239
                        {
240
                            "instruction_type": "apply_actions",
241
                            "actions": [{"action_type": "push_int"}],
242
                        },
243
                        {"instruction_type": "goto_table", "table_id": 2},
244
                    ],
245
                },
246
                "switch": "00:00:00:00:00:00:00:03",
247
            },
248
            {
249
                "flow": {
250
                    "match": {
251
                        "in_port": 1,
252
                        "dl_vlan": 100,
253
                        "dl_type": 2048,
254
                        "nw_proto": 17,
255
                    },
256
                    "cookie": 12163852417568094784,
257
                    "owner": "telemetry_int",
258
                    "table_group": "evpl",
259
                    "table_id": 0,
260
                    "priority": 20100,
261
                    "instructions": [
262
                        {
263
                            "instruction_type": "apply_actions",
264
                            "actions": [{"action_type": "push_int"}],
265
                        },
266
                        {"instruction_type": "goto_table", "table_id": 2},
267
                    ],
268
                },
269
                "switch": "00:00:00:00:00:00:00:03",
270
            },
271
            {
272
                "flow": {
273
                    "match": {"in_port": 1, "dl_vlan": 100},
274
                    "cookie": 12163852417568094784,
275
                    "owner": "telemetry_int",
276
                    "table_group": "evpl",
277
                    "table_id": 2,
278
                    "priority": 20000,
279
                    "instructions": [
280
                        {
281
                            "instruction_type": "apply_actions",
282
                            "actions": [
283
                                {"action_type": "add_int_metadata"},
284
                                {"action_type": "push_vlan", "tag_type": "s"},
285
                                {"action_type": "set_vlan", "vlan_id": 1},
286
                                {"action_type": "output", "port": 2},
287
                            ],
288
                        }
289
                    ],
290
                },
291
                "switch": "00:00:00:00:00:00:00:03",
292
            },
293
        ]
294
    }
295
296 1
    serd = json.dumps(expected_built_flows)
297 1
    assert json.dumps(int_manager._install_int_flows.call_args[0][0]) == serd
298
299
300 1
async def test_handle_failover_old_path_same_svlan() -> None:
301
    """Test handle failover_old_path_same_svlan.
302
303
               +----+                                              +----+
304
              5|    |6                                            5|    |6
305
           +---+----v---+            +------------+           +----+----v---+
306
        1  |            |            |            |           |             |1
307
    -------+            |3         2 |            |3        2 |             +-------
308
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
309
     100   |            |            |            |           |             | 100
310
           |            |            |            |           |             |
311
           +------------+            +------------+           +-------------+
312
                |4                                                   3|
313
                |_____________________________________________________|
314
    """
315
316 1
    controller = get_controller_mock()
317 1
    int_manager = INTManager(controller)
318 1
    get_proxy_port_or_raise = MagicMock()
319 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
320
321 1
    dpid_a = "00:00:00:00:00:00:00:01"
322 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
323 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
324 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
325 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
326 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
327 1
    mock_interface_a5.status = EntityStatus.UP
328 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
329 1
    mock_interface_a6.status = EntityStatus.UP
330 1
    mock_interface_a5.metadata = {
331
        "looped": {
332
            "port_numbers": [
333
                mock_interface_a5.port_number,
334
                mock_interface_a6.port_number,
335
            ]
336
        }
337
    }
338
339 1
    dpid_z = "00:00:00:00:00:00:00:03"
340 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
341 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
342 1
    mock_interface_z1.status = EntityStatus.UP
343 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
344 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
345 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
346 1
    mock_interface_z5.status = EntityStatus.UP
347 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
348 1
    mock_interface_z6.status = EntityStatus.UP
349 1
    mock_interface_z5.metadata = {
350
        "looped": {
351
            "port_numbers": [
352
                mock_interface_z5.port_number,
353
                mock_interface_z6.port_number,
354
            ]
355
        }
356
    }
357
358 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
359
        mock_interface_a5.port_number: mock_interface_a5,
360
        mock_interface_a6.port_number: mock_interface_a6,
361
    }[port_no]
362
363 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
364
        mock_interface_z5.port_number: mock_interface_z5,
365
        mock_interface_z6.port_number: mock_interface_z6,
366
    }[port_no]
367
368 1
    pp_a = ProxyPort(controller, source=mock_interface_a5)
369 1
    assert pp_a.source == mock_interface_a5
370 1
    assert pp_a.destination == mock_interface_a6
371 1
    pp_z = ProxyPort(controller, source=mock_interface_z5)
372 1
    assert pp_z.source == mock_interface_z5
373 1
    assert pp_z.destination == mock_interface_z6
374
375 1
    evcs_data = {
376
        "ceaf53b16c3a40": {
377
            "removed_flows": {
378
                "00:00:00:00:00:00:00:01": [
379
                    {
380
                        "cookie": 12307967605643950656,
381
                        "match": {"in_port": 4, "dl_vlan": 1},
382
                        "cookie_mask": 18446744073709551615,
383
                    }
384
                ],
385
                "00:00:00:00:00:00:00:03": [
386
                    {
387
                        "cookie": 12307967605643950656,
388
                        "match": {"in_port": 3, "dl_vlan": 1},
389
                        "cookie_mask": 18446744073709551615,
390
                    }
391
                ],
392
            },
393
            "current_path": [
394
                {
395
                    "id": "78282c4d5",
396
                    "endpoint_a": {
397
                        "id": "00: 00:00:00:00:00:00:01:3",
398
                        "name": "s1-eth3",
399
                        "port_number": 3,
400
                        "mac": "b2:ac:2b:ac:87:bb",
401
                        "switch": "00:00:00:00:00:00:00:01",
402
                        "type": "interface",
403
                        "nni": True,
404
                        "uni": False,
405
                        "speed": 1250000000.0,
406
                        "metadata": {},
407
                        "lldp": True,
408
                        "active": True,
409
                        "enabled": True,
410
                        "status": "UP",
411
                        "status_reason": [],
412
                        "link": "78282c4d5",
413
                    },
414
                    "endpoint_b": {
415
                        "id": "00:00:00:00:00:00:00:02:2",
416
                        "name": "s2-eth2",
417
                        "port_number": 2,
418
                        "mac": "62:50:49:d7:79:8a",
419
                        "switch": "00:00:00:00:00:00:00:02",
420
                        "type": "interface",
421
                        "nni": True,
422
                        "uni": False,
423
                        "speed": 1250000000.0,
424
                        "metadata": {},
425
                        "lldp": True,
426
                        "active": True,
427
                        "enabled": True,
428
                        "status": "UP",
429
                        "status_reason": [],
430
                        "link": "78282c4d5",
431
                    },
432
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
433
                    "active": True,
434
                    "enabled": True,
435
                    "status": "UP",
436
                    "status_reason": [],
437
                },
438
                {
439
                    "id": "4d42dc085",
440
                    "endpoint_a": {
441
                        "id": "00:00:00:00:00:00:00:02:3",
442
                        "name": "s2-eth3",
443
                        "port_number": 3,
444
                        "mac": "76:82:ef:6e:d2:9d",
445
                        "switch": "00:00:00:00:00:00:00:02",
446
                        "type": "interface",
447
                        "nni": True,
448
                        "uni": False,
449
                        "speed": 1250000000.0,
450
                        "metadata": {},
451
                        "lldp": True,
452
                        "active": True,
453
                        "enabled": True,
454
                        "status": "UP",
455
                        "status_reason ": [],
456
                        "link": "4d42dc085",
457
                    },
458
                    "endpoint_b": {
459
                        "id": "00:00:00:00:00:00:00:03:2",
460
                        "name": "s3-eth2",
461
                        "port_number": 2,
462
                        "mac": "6a:c1:51:b1:a9:8a",
463
                        "switch": "00:00:00:00:00:00:00:03",
464
                        "type": "interface",
465
                        "nni": True,
466
                        "uni": False,
467
                        "speed": 1250000000.0,
468
                        "metadata": {},
469
                        "lldp": True,
470
                        "active": True,
471
                        "enabled": True,
472
                        "status": "UP",
473
                        "status_reason": [],
474
                        "link": "4d42dc085",
475
                    },
476
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
477
                    "active": True,
478
                    "enabled": True,
479
                    "status": "UP",
480
                    "status_reason": [],
481
                },
482
            ],
483
            "evc_id": "ceaf53b16c3a40",
484
            "id": "ceaf53b16c3a40",
485
            "name": "inter_evpl",
486
            "metadata": {
487
                "telemetry_request": {},
488
                "telemetry": {
489
                    "enabled": True,
490
                    "status": "UP",
491
                    "status_reason": [],
492
                    "status_updated_at": "2024-06-11T16:56:29",
493
                },
494
            },
495
            "active": True,
496
            "enabled": True,
497
            "uni_a": {
498
                "interface_id": "00:00:00:00:00:00:00:01:1",
499
                "tag": {"tag_type": "vlan", "value": 100},
500
            },
501
            "uni_z": {
502
                "interface_id": "00:00:00:00:00:00:00:03:1",
503
                "tag": {"tag_type": "vlan", "value": 100},
504
            },
505
        }
506
    }
507
508 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
509 1
    int_manager._send_flows = AsyncMock()
510 1
    int_manager._install_int_flows = AsyncMock()
511 1
    int_manager._remove_int_flows = AsyncMock()
512 1
    int_manager.remove_int_flows = AsyncMock()
513 1
    await int_manager.handle_failover_flows(evcs_data, "failover_old_path")
514 1
    assert int_manager._install_int_flows.call_count == 0
515 1
    assert int_manager._remove_int_flows.call_count == 1
516 1
    assert int_manager.remove_int_flows.call_count == 0
517
518 1
    expected_built_flows = {
519
        "12307967605643950656": [
520
            {
521
                "flow": {
522
                    "cookie": 12163852417568094784,
523
                    "match": {"in_port": 4, "dl_vlan": 1},
524
                    "cookie_mask": 18446744073709551615,
525
                    "priority": 21000,
526
                    "table_group": "evpl",
527
                },
528
                "switch": "00:00:00:00:00:00:00:01",
529
            },
530
            {
531
                "flow": {
532
                    "cookie": 12163852417568094784,
533
                    "match": {"in_port": 3, "dl_vlan": 1},
534
                    "cookie_mask": 18446744073709551615,
535
                    "priority": 21000,
536
                    "table_group": "evpl",
537
                },
538
                "switch": "00:00:00:00:00:00:00:03",
539
            },
540
        ]
541
    }
542 1
    serd = json.dumps(expected_built_flows)
543 1
    assert json.dumps(int_manager._remove_int_flows.call_args[0][0]) == serd
544
545
546
# pylint: disable=too-many-statements
547 1
async def test_handle_failover_old_path_diff_svlan() -> None:
548
    """Test handle failover_old_path_diff_svlan.
549
550
               +----+                                              +----+
551
              5|    |6                                            5|    |6
552
           +---+----v---+            +------------+           +----+----v---+
553
        1  |            |            |            |           |             |1
554
    -------+            |3         2 |            |3        2 |             +-------
555
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
556
     100   |            |            |            |           |             | 100
557
           |            |            |            |           |             |
558
           +------------+            +------------+           +-------------+
559
                |4                                                   3|
560
                |_____________________________________________________|
561
    """
562
563 1
    controller = get_controller_mock()
564 1
    int_manager = INTManager(controller)
565 1
    get_proxy_port_or_raise = MagicMock()
566 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
567
568 1
    dpid_a = "00:00:00:00:00:00:00:01"
569 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
570 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
571 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
572 1
    mock_interface_a4 = get_interface_mock("s1-eth4", 4, mock_switch_a)
573 1
    mock_interface_a4.id = f"{dpid_a}:{mock_interface_a4.port_number}"
574 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
575 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
576 1
    mock_interface_a4.status = EntityStatus.UP
577 1
    mock_interface_a5.status = EntityStatus.UP
578 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
579 1
    mock_interface_a6.status = EntityStatus.UP
580 1
    mock_interface_a5.metadata = {
581
        "looped": {
582
            "port_numbers": [
583
                mock_interface_a5.port_number,
584
                mock_interface_a6.port_number,
585
            ]
586
        }
587
    }
588
589 1
    dpid_z = "00:00:00:00:00:00:00:03"
590 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
591 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
592 1
    mock_interface_z1.status = EntityStatus.UP
593 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
594 1
    mock_interface_z3 = get_interface_mock("s1-eth3", 3, mock_switch_z)
595 1
    mock_interface_z3.status = EntityStatus.UP
596 1
    mock_interface_z3.id = f"{dpid_z}:{mock_interface_z3.port_number}"
597 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
598 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
599 1
    mock_interface_z5.status = EntityStatus.UP
600 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
601 1
    mock_interface_z6.status = EntityStatus.UP
602 1
    mock_interface_z5.metadata = {
603
        "looped": {
604
            "port_numbers": [
605
                mock_interface_z5.port_number,
606
                mock_interface_z6.port_number,
607
            ]
608
        }
609
    }
610
611 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
612
        mock_interface_a5.port_number: mock_interface_a5,
613
        mock_interface_a6.port_number: mock_interface_a6,
614
    }[port_no]
615
616 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
617
        mock_interface_z5.port_number: mock_interface_z5,
618
        mock_interface_z6.port_number: mock_interface_z6,
619
    }[port_no]
620
621 1
    pp_a = ProxyPort(controller, source=mock_interface_a5)
622 1
    assert pp_a.source == mock_interface_a5
623 1
    assert pp_a.destination == mock_interface_a6
624 1
    pp_z = ProxyPort(controller, source=mock_interface_z5)
625 1
    assert pp_z.source == mock_interface_z5
626 1
    assert pp_z.destination == mock_interface_z6
627
628 1
    evcs_data = {
629
        "ceaf53b16c3a40": {
630
            "removed_flows": {
631
                "00:00:00:00:00:00:00:01": [
632
                    {
633
                        "cookie": 12307967605643950656,
634
                        "match": {"in_port": 4, "dl_vlan": 2},
635
                        "cookie_mask": 18446744073709551615,
636
                    }
637
                ],
638
                "00:00:00:00:00:00:00:03": [
639
                    {
640
                        "cookie": 12307967605643950656,
641
                        "match": {"in_port": 3, "dl_vlan": 2},
642
                        "cookie_mask": 18446744073709551615,
643
                    }
644
                ],
645
            },
646
            "current_path": [
647
                {
648
                    "id": "78282c4d5",
649
                    "endpoint_a": {
650
                        "id": "00:00:00:00:00:00:00:01:3",
651
                        "name": "s1-eth3",
652
                        "port_number": 3,
653
                        "mac": "b2:ac:2b:ac:87:bb",
654
                        "switch": "00:00:00:00:00:00:00:01",
655
                        "type": "interface",
656
                        "nni": True,
657
                        "uni": False,
658
                        "speed": 1250000000.0,
659
                        "metadata": {},
660
                        "lldp": True,
661
                        "active": True,
662
                        "enabled": True,
663
                        "status": "UP",
664
                        "status_reason": [],
665
                        "link": "78282c4d5",
666
                    },
667
                    "endpoint_b": {
668
                        "id": "00:00:00:00:00:00:00:02:2",
669
                        "name": "s2-eth2",
670
                        "port_number": 2,
671
                        "mac": "62:50:49:d7:79:8a",
672
                        "switch": "00:00:00:00:00:00:00:02",
673
                        "type": "interface",
674
                        "nni": True,
675
                        "uni": False,
676
                        "speed": 1250000000.0,
677
                        "metadata": {},
678
                        "lldp": True,
679
                        "active": True,
680
                        "enabled": True,
681
                        "status": "UP",
682
                        "status_reason": [],
683
                        "link": "78282c4d5",
684
                    },
685
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
686
                    "active": True,
687
                    "enabled": True,
688
                    "status": "UP",
689
                    "status_reason": [],
690
                },
691
                {
692
                    "id": "4d42dc085",
693
                    "endpoint_a": {
694
                        "id": "00:00:00:00:00:00:00:02:3",
695
                        "name": "s2-eth3",
696
                        "port_number": 3,
697
                        "mac": "76:82:ef:6e:d2:9d",
698
                        "switch": "00:00:00:00:00:00:00:02",
699
                        "type": "interface",
700
                        "nni": True,
701
                        "uni": False,
702
                        "speed": 1250000000.0,
703
                        "metadata": {},
704
                        "lldp": True,
705
                        "active": True,
706
                        "enabled": True,
707
                        "status": "UP",
708
                        "status_reason ": [],
709
                        "link": "4d42dc085",
710
                    },
711
                    "endpoint_b": {
712
                        "id": "00:00:00:00:00:00:00:03:2",
713
                        "name": "s3-eth2",
714
                        "port_number": 2,
715
                        "mac": "6a:c1: 51:b1:a9:8a",
716
                        "switch": "00:00:00:00:00:00:00:03",
717
                        "type": "interface",
718
                        "nni": True,
719
                        "uni": False,
720
                        "speed": 1250000000.0,
721
                        "metadata": {},
722
                        "lldp": True,
723
                        "active": True,
724
                        "enabled": True,
725
                        "status": "UP",
726
                        "status_reason": [],
727
                        "link": "4d42dc085",
728
                    },
729
                    "metadata": {"s_vlan": {"tag_type": "vlan", "value": 1}},
730
                    "active": True,
731
                    "enabled": True,
732
                    "status": "UP",
733
                    "status_reason": [],
734
                },
735
            ],
736
            "evc_id": "ceaf53b16c3a40",
737
            "id": "ceaf53b16c3a40",
738
            "name": "inter_evpl",
739
            "metadata": {
740
                "telemetry_request": {},
741
                "telemetry": {
742
                    "enabled": True,
743
                    "status": "UP",
744
                    "status_reason": [],
745
                    "status_updated_at": "2024-06-11T16:56:29",
746
                },
747
            },
748
            "active": True,
749
            "enabled": True,
750
            "uni_a": {
751
                "interface_id": "00:00:00:00:00:00:00:01:1",
752
                "tag": {"tag_type": "vlan", "value": 100},
753
            },
754
            "uni_z": {
755
                "interface_id": "00:00:00:00:00:00:00:03:1",
756
                "tag": {"tag_type": "vlan", "value": 100},
757
            },
758
        }
759
    }
760
761 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
762 1
    int_manager._send_flows = AsyncMock()
763 1
    int_manager._install_int_flows = AsyncMock()
764 1
    int_manager._remove_int_flows = AsyncMock()
765 1
    int_manager.remove_int_flows = AsyncMock()
766 1
    await int_manager.handle_failover_flows(evcs_data, "failover_deployed")
767 1
    assert int_manager._install_int_flows.call_count == 0
768 1
    assert int_manager._remove_int_flows.call_count == 1
769 1
    assert int_manager.remove_int_flows.call_count == 0
770
771 1
    expected_built_flows = {
772
        "12307967605643950656": [
773
            {
774
                "flow": {
775
                    "cookie": 12163852417568094784,
776
                    "match": {
777
                        "in_port": 4,
778
                        "dl_vlan": 2,
779
                        "dl_type": 2048,
780
                        "nw_proto": 6,
781
                    },
782
                    "cookie_mask": 18446744073709551615,
783
                    "priority": 21100,
784
                    "table_group": "evpl",
785
                    "owner": "telemetry_int",
786
                    "instructions": [
787
                        {
788
                            "instruction_type": "apply_actions",
789
                            "actions": [
790
                                {"action_type": "add_int_metadata"},
791
                                {"action_type": "output", "port": 5},
792
                            ],
793
                        }
794
                    ],
795
                },
796
                "switch": "00:00:00:00:00:00:00:01",
797
            },
798
            {
799
                "flow": {
800
                    "cookie": 12163852417568094784,
801
                    "match": {
802
                        "in_port": 4,
803
                        "dl_vlan": 2,
804
                        "dl_type": 2048,
805
                        "nw_proto": 17,
806
                    },
807
                    "cookie_mask": 18446744073709551615,
808
                    "priority": 21100,
809
                    "table_group": "evpl",
810
                    "owner": "telemetry_int",
811
                    "instructions": [
812
                        {
813
                            "instruction_type": "apply_actions",
814
                            "actions": [
815
                                {"action_type": "add_int_metadata"},
816
                                {"action_type": "output", "port": 5},
817
                            ],
818
                        }
819
                    ],
820
                },
821
                "switch": "00:00:00:00:00:00:00:01",
822
            },
823
            {
824
                "flow": {
825
                    "cookie": 12163852417568094784,
826
                    "match": {"in_port": 6, "dl_vlan": 2},
827
                    "cookie_mask": 18446744073709551615,
828
                    "priority": 21000,
829
                    "table_group": "evpl",
830
                    "owner": "telemetry_int",
831
                    "instructions": [
832
                        {
833
                            "instruction_type": "apply_actions",
834
                            "actions": [{"action_type": "send_report"}],
835
                        },
836
                        {"instruction_type": "goto_table", "table_id": 2},
837
                    ],
838
                },
839
                "switch": "00:00:00:00:00:00:00:01",
840
            },
841
            {
842
                "flow": {
843
                    "cookie": 12163852417568094784,
844
                    "match": {"in_port": 6, "dl_vlan": 2},
845
                    "cookie_mask": 18446744073709551615,
846
                    "priority": 21000,
847
                    "table_group": "evpl",
848
                    "owner": "telemetry_int",
849
                    "instructions": [
850
                        {
851
                            "instruction_type": "apply_actions",
852
                            "actions": [{"action_type": "pop_int"}],
853
                        }
854
                    ],
855
                    "table_id": 2,
856
                },
857
                "switch": "00:00:00:00:00:00:00:01",
858
            },
859
            {
860
                "flow": {
861
                    "cookie": 12163852417568094784,
862
                    "match": {
863
                        "in_port": 3,
864
                        "dl_vlan": 2,
865
                        "dl_type": 2048,
866
                        "nw_proto": 6,
867
                    },
868
                    "cookie_mask": 18446744073709551615,
869
                    "priority": 21100,
870
                    "table_group": "evpl",
871
                    "owner": "telemetry_int",
872
                    "instructions": [
873
                        {
874
                            "instruction_type": "apply_actions",
875
                            "actions": [
876
                                {"action_type": "add_int_metadata"},
877
                                {"action_type": "output", "port": 5},
878
                            ],
879
                        }
880
                    ],
881
                },
882
                "switch": "00:00:00:00:00:00:00:03",
883
            },
884
            {
885
                "flow": {
886
                    "cookie": 12163852417568094784,
887
                    "match": {
888
                        "in_port": 3,
889
                        "dl_vlan": 2,
890
                        "dl_type": 2048,
891
                        "nw_proto": 17,
892
                    },
893
                    "cookie_mask": 18446744073709551615,
894
                    "priority": 21100,
895
                    "table_group": "evpl",
896
                    "owner": "telemetry_int",
897
                    "instructions": [
898
                        {
899
                            "instruction_type": "apply_actions",
900
                            "actions": [
901
                                {"action_type": "add_int_metadata"},
902
                                {"action_type": "output", "port": 5},
903
                            ],
904
                        }
905
                    ],
906
                },
907
                "switch": "00:00:00:00:00:00:00:03",
908
            },
909
            {
910
                "flow": {
911
                    "cookie": 12163852417568094784,
912
                    "match": {"in_port": 6, "dl_vlan": 2},
913
                    "cookie_mask": 18446744073709551615,
914
                    "priority": 21000,
915
                    "table_group": "evpl",
916
                    "owner": "telemetry_int",
917
                    "instructions": [
918
                        {
919
                            "instruction_type": "apply_actions",
920
                            "actions": [{"action_type": "send_report"}],
921
                        },
922
                        {"instruction_type": "goto_table", "table_id": 2},
923
                    ],
924
                },
925
                "switch": "00:00:00:00:00:00:00:03",
926
            },
927
            {
928
                "flow": {
929
                    "cookie": 12163852417568094784,
930
                    "match": {"in_port": 6, "dl_vlan": 2},
931
                    "cookie_mask": 18446744073709551615,
932
                    "priority": 21000,
933
                    "table_group": "evpl",
934
                    "owner": "telemetry_int",
935
                    "instructions": [
936
                        {
937
                            "instruction_type": "apply_actions",
938
                            "actions": [{"action_type": "pop_int"}],
939
                        }
940
                    ],
941
                    "table_id": 2,
942
                },
943
                "switch": "00:00:00:00:00:00:00:03",
944
            },
945
        ]
946
    }
947 1
    serd = json.dumps(expected_built_flows)
948
    assert json.dumps(int_manager._remove_int_flows.call_args[0][0]) == serd
949