test_flow_builder_inter_evc   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 1123
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 753
dl 0
loc 1123
ccs 166
cts 166
cp 1
rs 9.847
c 0
b 0
f 0
wmc 11

4 Functions

Rating   Name   Duplication   Size   Complexity  
B test_build_int_flows_inter_evpl_no_proxy_ports() 0 414 2
A test_bulkd_inter_sink_flows_cases() 0 45 2
B test_build_int_flows_inter_evpl() 0 515 4
B test_build_int_flows_inter_evpl_flows_count_evc_metadata_proxy_port_enabled() 0 123 3
1
"""Test flow_builder."""
2
3 1
import pytest
4
5 1
from unittest.mock import MagicMock
6 1
from napps.kytos.telemetry_int.managers.flow_builder import FlowBuilder
7 1
from napps.kytos.telemetry_int.managers.int import INTManager
8 1
from napps.kytos.telemetry_int.utils import get_cookie
9 1
from napps.kytos.telemetry_int.proxy_port import ProxyPort
10 1
from napps.kytos.telemetry_int.exceptions import ProxyPortMetadataNotFound
11 1
from napps.kytos.telemetry_int import settings
12 1
from napps.kytos.telemetry_int.kytos_api_helper import _map_stored_flows_by_cookies
13 1
from kytos.lib.helpers import get_controller_mock, get_switch_mock, get_interface_mock
14 1
from kytos.core.common import EntityStatus
15
16
# pylint: disable=too-many-lines, too-many-statements
17
18
19 1
def test_build_int_flows_inter_evpl(
20
    evcs_data, inter_evc_evpl_set_queue_flows_data
21
) -> None:
22
    """Test build INT flows inter EVPL.
23
24
               +----+                                              +----+
25
              5|    |6                                            5|    |6
26
           +---+----v---+            +------------+           +----+----v---+
27
        1  |            |            |            |           |             |1
28
    -------+            |3         2 |            |3        2 |             +-------
29
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
30
     101   |            |            |            |           |             | 102
31
           |            |            |            |           |             |
32
           +------------+            +------------+           +-------------+
33
34
    """
35 1
    controller = get_controller_mock()
36 1
    int_manager = INTManager(controller)
37 1
    get_proxy_port_or_raise = MagicMock()
38 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
39
40 1
    evc_id = "16a76ae61b2f46"
41 1
    dpid_a = "00:00:00:00:00:00:00:01"
42 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
43 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
44 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
45 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
46 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
47 1
    mock_interface_a5.status = EntityStatus.UP
48 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
49 1
    mock_interface_a6.status = EntityStatus.UP
50 1
    mock_interface_a5.metadata = {
51
        "looped": {
52
            "port_numbers": [
53
                mock_interface_a5.port_number,
54
                mock_interface_a6.port_number,
55
            ]
56
        }
57
    }
58
59 1
    dpid_z = "00:00:00:00:00:00:00:03"
60 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
61 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
62 1
    mock_interface_z1.status = EntityStatus.UP
63 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
64 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
65 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
66 1
    mock_interface_z5.status = EntityStatus.UP
67 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
68 1
    mock_interface_z6.status = EntityStatus.UP
69 1
    mock_interface_z5.metadata = {
70
        "looped": {
71
            "port_numbers": [
72
                mock_interface_z5.port_number,
73
                mock_interface_z6.port_number,
74
            ]
75
        }
76
    }
77
78 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
79
        mock_interface_a5.port_number: mock_interface_a5,
80
        mock_interface_a6.port_number: mock_interface_a6,
81
    }[port_no]
82
83 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
84
        mock_interface_z5.port_number: mock_interface_z5,
85
        mock_interface_z6.port_number: mock_interface_z6,
86
    }[port_no]
87
88 1
    pp_a = ProxyPort(source=mock_interface_a5)
89 1
    assert pp_a.source == mock_interface_a5
90 1
    assert pp_a.destination == mock_interface_a6
91 1
    pp_z = ProxyPort(source=mock_interface_z5)
92 1
    assert pp_z.source == mock_interface_z5
93 1
    assert pp_z.destination == mock_interface_z6
94
95 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
96 1
    evcs_data = {evc_id: evcs_data[evc_id]}
97 1
    evcs_data = int_manager._validate_map_enable_evcs(evcs_data)
98 1
    stored_flows = _map_stored_flows_by_cookies(inter_evc_evpl_set_queue_flows_data)
99
100 1
    cookie = get_cookie(evc_id, settings.MEF_COOKIE_PREFIX)
101 1
    flows = FlowBuilder().build_int_flows(evcs_data, stored_flows)[cookie]
102
103 1
    n_expected_source_flows, n_expected_hop_flows, n_expected_sink_flows = 3, 2, 4
104 1
    assert (
105
        len(flows)
106
        == (n_expected_source_flows + n_expected_hop_flows + n_expected_sink_flows) * 2
107
    )
108
109 1
    expected_uni_a_source_flows = [
110
        {
111
            "flow": {
112
                "owner": "telemetry_int",
113
                "cookie": int(0xA816A76AE61B2F46),
114
                "match": {"in_port": 1, "dl_vlan": 101, "dl_type": 2048, "nw_proto": 6},
115
                "table_id": 0,
116
                "table_group": "evpl",
117
                "priority": 20100,
118
                "idle_timeout": 0,
119
                "hard_timeout": 0,
120
                "instructions": [
121
                    {
122
                        "instruction_type": "apply_actions",
123
                        "actions": [{"action_type": "push_int"}],
124
                    },
125
                    {"instruction_type": "goto_table", "table_id": 2},
126
                ],
127
            }
128
        },
129
        {
130
            "flow": {
131
                "owner": "telemetry_int",
132
                "cookie": int(0xA816A76AE61B2F46),
133
                "match": {
134
                    "in_port": 1,
135
                    "dl_vlan": 101,
136
                    "dl_type": 2048,
137
                    "nw_proto": 17,
138
                },
139
                "table_id": 0,
140
                "table_group": "evpl",
141
                "priority": 20100,
142
                "idle_timeout": 0,
143
                "hard_timeout": 0,
144
                "instructions": [
145
                    {
146
                        "instruction_type": "apply_actions",
147
                        "actions": [{"action_type": "push_int"}],
148
                    },
149
                    {"instruction_type": "goto_table", "table_id": 2},
150
                ],
151
            },
152
        },
153
        {
154
            "flow": {
155
                "owner": "telemetry_int",
156
                "cookie": int(0xA816A76AE61B2F46),
157
                "match": {"in_port": 1, "dl_vlan": 101},
158
                "table_id": 2,
159
                "table_group": "evpl",
160
                "priority": 20000,
161
                "idle_timeout": 0,
162
                "hard_timeout": 0,
163
                "instructions": [
164
                    {
165
                        "instruction_type": "apply_actions",
166
                        "actions": [
167
                            {"action_type": "add_int_metadata"},
168
                            {"action_type": "set_vlan", "vlan_id": 102},
169
                            {"action_type": "push_vlan", "tag_type": "s"},
170
                            {"action_type": "set_vlan", "vlan_id": 1},
171
                            {"action_type": "set_queue", "queue_id": 1},
172
                            {"action_type": "output", "port": 3},
173
                        ],
174
                    }
175
                ],
176
            },
177
        },
178
    ]
179
180 1
    expected_uni_z_source_flows = [
181
        {
182
            "flow": {
183
                "owner": "telemetry_int",
184
                "cookie": int(0xA816A76AE61B2F46),
185
                "match": {"in_port": 1, "dl_vlan": 102, "dl_type": 2048, "nw_proto": 6},
186
                "table_id": 0,
187
                "table_group": "evpl",
188
                "priority": 20100,
189
                "idle_timeout": 0,
190
                "hard_timeout": 0,
191
                "instructions": [
192
                    {
193
                        "instruction_type": "apply_actions",
194
                        "actions": [{"action_type": "push_int"}],
195
                    },
196
                    {"instruction_type": "goto_table", "table_id": 2},
197
                ],
198
            },
199
        },
200
        {
201
            "flow": {
202
                "owner": "telemetry_int",
203
                "cookie": int(0xA816A76AE61B2F46),
204
                "match": {
205
                    "in_port": 1,
206
                    "dl_vlan": 102,
207
                    "dl_type": 2048,
208
                    "nw_proto": 17,
209
                },
210
                "table_id": 0,
211
                "table_group": "evpl",
212
                "priority": 20100,
213
                "idle_timeout": 0,
214
                "hard_timeout": 0,
215
                "instructions": [
216
                    {
217
                        "instruction_type": "apply_actions",
218
                        "actions": [{"action_type": "push_int"}],
219
                    },
220
                    {"instruction_type": "goto_table", "table_id": 2},
221
                ],
222
            },
223
        },
224
        {
225
            "flow": {
226
                "owner": "telemetry_int",
227
                "cookie": int(0xA816A76AE61B2F46),
228
                "match": {"in_port": 1, "dl_vlan": 102},
229
                "table_id": 2,
230
                "table_group": "evpl",
231
                "priority": 20000,
232
                "idle_timeout": 0,
233
                "hard_timeout": 0,
234
                "instructions": [
235
                    {
236
                        "instruction_type": "apply_actions",
237
                        "actions": [
238
                            {"action_type": "add_int_metadata"},
239
                            {"action_type": "set_vlan", "vlan_id": 101},
240
                            {"action_type": "push_vlan", "tag_type": "s"},
241
                            {"action_type": "set_vlan", "vlan_id": 1},
242
                            {"action_type": "set_queue", "queue_id": 1},
243
                            {"action_type": "output", "port": 2},
244
                        ],
245
                    }
246
                ],
247
            },
248
        },
249
    ]
250
251 1
    expected_hop_flows = [
252
        {
253
            "flow": {
254
                "owner": "telemetry_int",
255
                "cookie": int(0xA816A76AE61B2F46),
256
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
257
                "table_id": 0,
258
                "table_group": "evpl",
259
                "priority": 20100,
260
                "idle_timeout": 0,
261
                "hard_timeout": 0,
262
                "instructions": [
263
                    {
264
                        "instruction_type": "apply_actions",
265
                        "actions": [
266
                            {"action_type": "add_int_metadata"},
267
                            {"action_type": "set_vlan", "vlan_id": 1},
268
                            {"action_type": "set_queue", "queue_id": 1},
269
                            {"action_type": "output", "port": 3},
270
                        ],
271
                    }
272
                ],
273
            },
274
        },
275
        {
276
            "flow": {
277
                "owner": "telemetry_int",
278
                "cookie": int(0xA816A76AE61B2F46),
279
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
280
                "table_id": 0,
281
                "table_group": "evpl",
282
                "priority": 20100,
283
                "idle_timeout": 0,
284
                "hard_timeout": 0,
285
                "instructions": [
286
                    {
287
                        "instruction_type": "apply_actions",
288
                        "actions": [
289
                            {"action_type": "add_int_metadata"},
290
                            {"action_type": "set_vlan", "vlan_id": 1},
291
                            {"action_type": "set_queue", "queue_id": 1},
292
                            {"action_type": "output", "port": 3},
293
                        ],
294
                    }
295
                ],
296
            },
297
        },
298
        {
299
            "flow": {
300
                "owner": "telemetry_int",
301
                "cookie": int(0xA816A76AE61B2F46),
302
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
303
                "table_id": 0,
304
                "table_group": "evpl",
305
                "priority": 20100,
306
                "idle_timeout": 0,
307
                "hard_timeout": 0,
308
                "instructions": [
309
                    {
310
                        "instruction_type": "apply_actions",
311
                        "actions": [
312
                            {"action_type": "add_int_metadata"},
313
                            {"action_type": "set_vlan", "vlan_id": 1},
314
                            {"action_type": "set_queue", "queue_id": 1},
315
                            {"action_type": "output", "port": 2},
316
                        ],
317
                    }
318
                ],
319
            },
320
        },
321
        {
322
            "flow": {
323
                "owner": "telemetry_int",
324
                "cookie": int(0xA816A76AE61B2F46),
325
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
326
                "table_id": 0,
327
                "table_group": "evpl",
328
                "priority": 20100,
329
                "idle_timeout": 0,
330
                "hard_timeout": 0,
331
                "instructions": [
332
                    {
333
                        "instruction_type": "apply_actions",
334
                        "actions": [
335
                            {"action_type": "add_int_metadata"},
336
                            {"action_type": "set_vlan", "vlan_id": 1},
337
                            {"action_type": "set_queue", "queue_id": 1},
338
                            {"action_type": "output", "port": 2},
339
                        ],
340
                    }
341
                ],
342
            },
343
        },
344
    ]
345
346 1
    expected_uni_z_sink_flows = [
347
        {
348
            "flow": {
349
                "owner": "telemetry_int",
350
                "cookie": int(0xA816A76AE61B2F46),
351
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
352
                "table_id": 0,
353
                "table_group": "evpl",
354
                "priority": 20100,
355
                "idle_timeout": 0,
356
                "hard_timeout": 0,
357
                "instructions": [
358
                    {
359
                        "instruction_type": "apply_actions",
360
                        "actions": [
361
                            {"action_type": "add_int_metadata"},
362
                            {"action_type": "set_queue", "queue_id": 1},
363
                            {"action_type": "output", "port": 5},
364
                        ],
365
                    }
366
                ],
367
            },
368
        },
369
        {
370
            "flow": {
371
                "owner": "telemetry_int",
372
                "cookie": int(0xA816A76AE61B2F46),
373
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
374
                "table_id": 0,
375
                "table_group": "evpl",
376
                "priority": 20100,
377
                "idle_timeout": 0,
378
                "hard_timeout": 0,
379
                "instructions": [
380
                    {
381
                        "instruction_type": "apply_actions",
382
                        "actions": [
383
                            {"action_type": "add_int_metadata"},
384
                            {"action_type": "set_queue", "queue_id": 1},
385
                            {"action_type": "output", "port": 5},
386
                        ],
387
                    }
388
                ],
389
            },
390
        },
391
        {
392
            "flow": {
393
                "owner": "telemetry_int",
394
                "cookie": int(0xA816A76AE61B2F46),
395
                "match": {"in_port": 6, "dl_vlan": 1},
396
                "table_id": 0,
397
                "table_group": "evpl",
398
                "priority": 20000,
399
                "idle_timeout": 0,
400
                "hard_timeout": 0,
401
                "instructions": [
402
                    {
403
                        "instruction_type": "apply_actions",
404
                        "actions": [{"action_type": "send_report"}],
405
                    },
406
                    {"instruction_type": "goto_table", "table_id": 2},
407
                ],
408
            },
409
        },
410
        {
411
            "flow": {
412
                "owner": "telemetry_int",
413
                "cookie": int(0xA816A76AE61B2F46),
414
                "match": {"in_port": 6, "dl_vlan": 1},
415
                "table_id": 2,
416
                "table_group": "evpl",
417
                "priority": 20000,
418
                "idle_timeout": 0,
419
                "hard_timeout": 0,
420
                "instructions": [
421
                    {
422
                        "instruction_type": "apply_actions",
423
                        "actions": [
424
                            {"action_type": "pop_int"},
425
                            {"action_type": "pop_vlan"},
426
                            {"action_type": "set_queue", "queue_id": 1},
427
                            {"action_type": "output", "port": 1},
428
                        ],
429
                    }
430
                ],
431
            }
432
        },
433
    ]
434
435 1
    expected_uni_a_sink_flows = [
436
        {
437
            "flow": {
438
                "owner": "telemetry_int",
439
                "cookie": int(0xA816A76AE61B2F46),
440
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
441
                "table_id": 0,
442
                "table_group": "evpl",
443
                "priority": 20100,
444
                "idle_timeout": 0,
445
                "hard_timeout": 0,
446
                "instructions": [
447
                    {
448
                        "instruction_type": "apply_actions",
449
                        "actions": [
450
                            {"action_type": "add_int_metadata"},
451
                            {"action_type": "set_queue", "queue_id": 1},
452
                            {"action_type": "output", "port": 5},
453
                        ],
454
                    }
455
                ],
456
            },
457
        },
458
        {
459
            "flow": {
460
                "owner": "telemetry_int",
461
                "cookie": int(0xA816A76AE61B2F46),
462
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
463
                "table_id": 0,
464
                "table_group": "evpl",
465
                "priority": 20100,
466
                "idle_timeout": 0,
467
                "hard_timeout": 0,
468
                "instructions": [
469
                    {
470
                        "instruction_type": "apply_actions",
471
                        "actions": [
472
                            {"action_type": "add_int_metadata"},
473
                            {"action_type": "set_queue", "queue_id": 1},
474
                            {"action_type": "output", "port": 5},
475
                        ],
476
                    }
477
                ],
478
            },
479
        },
480
        {
481
            "flow": {
482
                "owner": "telemetry_int",
483
                "cookie": int(0xA816A76AE61B2F46),
484
                "match": {"in_port": 6, "dl_vlan": 1},
485
                "table_id": 0,
486
                "table_group": "evpl",
487
                "priority": 20000,
488
                "idle_timeout": 0,
489
                "hard_timeout": 0,
490
                "instructions": [
491
                    {
492
                        "instruction_type": "apply_actions",
493
                        "actions": [{"action_type": "send_report"}],
494
                    },
495
                    {"instruction_type": "goto_table", "table_id": 2},
496
                ],
497
            },
498
        },
499
        {
500
            "flow": {
501
                "owner": "telemetry_int",
502
                "cookie": int(0xA816A76AE61B2F46),
503
                "match": {"in_port": 6, "dl_vlan": 1},
504
                "table_id": 2,
505
                "table_group": "evpl",
506
                "priority": 20000,
507
                "idle_timeout": 0,
508
                "hard_timeout": 0,
509
                "instructions": [
510
                    {
511
                        "instruction_type": "apply_actions",
512
                        "actions": [
513
                            {"action_type": "pop_int"},
514
                            {"action_type": "pop_vlan"},
515
                            {"action_type": "set_queue", "queue_id": 1},
516
                            {"action_type": "output", "port": 1},
517
                        ],
518
                    }
519
                ],
520
            },
521
        },
522
    ]
523
524 1
    expected_flows = (
525
        expected_uni_a_source_flows
526
        + expected_uni_z_source_flows
527
        + expected_hop_flows
528
        + expected_uni_z_sink_flows
529
        + expected_uni_a_sink_flows
530
    )
531
532 1
    for i, flow in enumerate(flows):
533 1
        assert (i, flow["flow"]) == (i, expected_flows[i]["flow"])
534
535
536 1
def test_build_int_flows_inter_evpl_flows_count_evc_metadata_proxy_port_enabled(
537
    evcs_data, inter_evc_evpl_set_queue_flows_data
538
) -> None:
539
    """Test build INT flows inter EVPL with proxy_port_enabled EVC metadata.
540
541
               +----+                                              +----+
542
              5|    |6                                            5|    |6
543
           +---+----v---+            +------------+           +----+----v---+
544
        1  |            |            |            |           |             |1
545
    -------+            |3         2 |            |3        2 |             +-------
546
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
547
     101   |            |            |            |           |             | 102
548
           |            |            |            |           |             |
549
           +------------+            +------------+           +-------------+
550
551
    """
552 1
    controller = get_controller_mock()
553 1
    int_manager = INTManager(controller)
554 1
    get_proxy_port_or_raise = MagicMock()
555 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
556
557 1
    evc_id = "16a76ae61b2f46"
558 1
    dpid_a = "00:00:00:00:00:00:00:01"
559 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
560 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
561 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
562 1
    mock_interface_a5 = get_interface_mock("s1-eth5", 5, mock_switch_a)
563 1
    mock_interface_a1.metadata = {"proxy_port": mock_interface_a5.port_number}
564 1
    mock_interface_a5.status = EntityStatus.UP
565 1
    mock_interface_a6 = get_interface_mock("s1-eth6", 6, mock_switch_a)
566 1
    mock_interface_a6.status = EntityStatus.UP
567 1
    mock_interface_a5.metadata = {
568
        "looped": {
569
            "port_numbers": [
570
                mock_interface_a5.port_number,
571
                mock_interface_a6.port_number,
572
            ]
573
        }
574
    }
575
576 1
    dpid_z = "00:00:00:00:00:00:00:03"
577 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
578 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
579 1
    mock_interface_z1.status = EntityStatus.UP
580 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
581 1
    mock_interface_z5 = get_interface_mock("s1-eth5", 5, mock_switch_z)
582 1
    mock_interface_z1.metadata = {"proxy_port": mock_interface_z5.port_number}
583 1
    mock_interface_z5.status = EntityStatus.UP
584 1
    mock_interface_z6 = get_interface_mock("s1-eth6", 6, mock_switch_z)
585 1
    mock_interface_z6.status = EntityStatus.UP
586 1
    mock_interface_z5.metadata = {
587
        "looped": {
588
            "port_numbers": [
589
                mock_interface_z5.port_number,
590
                mock_interface_z6.port_number,
591
            ]
592
        }
593
    }
594
595 1
    mock_switch_a.get_interface_by_port_no = lambda port_no: {
596
        mock_interface_a5.port_number: mock_interface_a5,
597
        mock_interface_a6.port_number: mock_interface_a6,
598
    }[port_no]
599
600 1
    mock_switch_z.get_interface_by_port_no = lambda port_no: {
601
        mock_interface_z5.port_number: mock_interface_z5,
602
        mock_interface_z6.port_number: mock_interface_z6,
603
    }[port_no]
604
605 1
    pp_a = ProxyPort(source=mock_interface_a5)
606 1
    assert pp_a.source == mock_interface_a5
607 1
    assert pp_a.destination == mock_interface_a6
608 1
    pp_z = ProxyPort(source=mock_interface_z5)
609 1
    assert pp_z.source == mock_interface_z5
610 1
    assert pp_z.destination == mock_interface_z6
611
612 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
613
614
    # This will overwrite not to use proxy_port from the interface metadata
615 1
    evcs_data[evc_id]["metadata"]["proxy_port_enabled"] = False
616
617 1
    evcs_data = {evc_id: evcs_data[evc_id]}
618 1
    evcs_data = int_manager._validate_map_enable_evcs(evcs_data)
619 1
    stored_flows = _map_stored_flows_by_cookies(inter_evc_evpl_set_queue_flows_data)
620
621 1
    cookie = get_cookie(evc_id, settings.MEF_COOKIE_PREFIX)
622 1
    flows = FlowBuilder().build_int_flows(evcs_data, stored_flows)[cookie]
623
624
    # This test case is only asserting expected flows numbers to avoid repetition,
625
    # similar test cases already assert the expected flow contents
626
627 1
    n_expected_source_flows, n_expected_hop_flows, n_expected_sink_flows = 3, 2, 3
628 1
    assert (
629
        len(flows)
630
        == (n_expected_source_flows + n_expected_hop_flows + n_expected_sink_flows) * 2
631
    )
632
633
    # This will no longer overwrite, so the proxy_port flows will be built
634 1
    evcs_data[evc_id]["metadata"].pop("proxy_port_enabled")
635 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
636
637 1
    evcs_data = int_manager._validate_map_enable_evcs(evcs_data)
638 1
    stored_flows = _map_stored_flows_by_cookies(inter_evc_evpl_set_queue_flows_data)
639 1
    flows = FlowBuilder().build_int_flows(evcs_data, stored_flows)[cookie]
640
641 1
    n_expected_source_flows, n_expected_hop_flows, n_expected_sink_flows = 3, 2, 4
642 1
    assert (
643
        len(flows)
644
        == (n_expected_source_flows + n_expected_hop_flows + n_expected_sink_flows) * 2
645
    )
646
647
    # This will no longer overwrite too, so the proxy_port flows will be built
648 1
    evcs_data[evc_id]["metadata"]["proxy_port_enabled"] = True
649 1
    get_proxy_port_or_raise.side_effect = [pp_a, pp_z]
650
651 1
    evcs_data = int_manager._validate_map_enable_evcs(evcs_data)
652 1
    stored_flows = _map_stored_flows_by_cookies(inter_evc_evpl_set_queue_flows_data)
653 1
    flows = FlowBuilder().build_int_flows(evcs_data, stored_flows)[cookie]
654
655 1
    n_expected_source_flows, n_expected_hop_flows, n_expected_sink_flows = 3, 2, 4
656 1
    assert (
657
        len(flows)
658
        == (n_expected_source_flows + n_expected_hop_flows + n_expected_sink_flows) * 2
659
    )
660
661
662 1
def test_build_int_flows_inter_evpl_no_proxy_ports(
663
    evcs_data, inter_evc_evpl_flows_data
664
) -> None:
665
    """Test build INT flows inter EVPL.
666
667
           +---+----v---+            +------------+           +----+----v---+
668
        1  |            |            |            |           |             |1
669
    -------+            |3         2 |            |3        2 |             +-------
670
     vlan  |     s1     +------------+    s2      +-----------+    s3       | vlan
671
     101   |            |            |            |           |             | 102
672
           |            |            |            |           |             |
673
           +------------+            +------------+           +-------------+
674
675
    """
676 1
    controller = get_controller_mock()
677 1
    int_manager = INTManager(controller)
678 1
    get_proxy_port_or_raise = MagicMock()
679 1
    exc = ProxyPortMetadataNotFound("evc_id", "not found")
680 1
    get_proxy_port_or_raise.side_effect = exc
681 1
    int_manager.get_proxy_port_or_raise = get_proxy_port_or_raise
682
683 1
    evc_id = "16a76ae61b2f46"
684 1
    dpid_a = "00:00:00:00:00:00:00:01"
685 1
    mock_switch_a = get_switch_mock(dpid_a, 0x04)
686 1
    mock_interface_a1 = get_interface_mock("s1-eth1", 1, mock_switch_a)
687 1
    mock_interface_a1.status = EntityStatus.UP
688 1
    mock_interface_a1.id = f"{dpid_a}:{mock_interface_a1.port_number}"
689
690 1
    dpid_z = "00:00:00:00:00:00:00:03"
691 1
    mock_switch_z = get_switch_mock(dpid_z, 0x04)
692 1
    mock_interface_z1 = get_interface_mock("s1-eth1", 1, mock_switch_z)
693 1
    mock_interface_z1.status = EntityStatus.UP
694 1
    mock_interface_z1.id = f"{dpid_z}:{mock_interface_z1.port_number}"
695
696 1
    evcs_data = {evc_id: evcs_data[evc_id]}
697 1
    evcs_data = int_manager._validate_map_enable_evcs(evcs_data)
698 1
    stored_flows = _map_stored_flows_by_cookies(inter_evc_evpl_flows_data)
699
700 1
    cookie = get_cookie(evc_id, settings.MEF_COOKIE_PREFIX)
701 1
    flows = FlowBuilder().build_int_flows(evcs_data, stored_flows)[cookie]
702
703 1
    n_expected_source_flows, n_expected_hop_flows, n_expected_sink_flows = 3, 2, 3
704 1
    assert (
705
        len(flows)
706
        == (n_expected_source_flows + n_expected_hop_flows + n_expected_sink_flows) * 2
707
    )
708
709 1
    expected_uni_a_source_flows = [
710
        {
711
            "flow": {
712
                "owner": "telemetry_int",
713
                "cookie": int(0xA816A76AE61B2F46),
714
                "match": {"in_port": 1, "dl_vlan": 101, "dl_type": 2048, "nw_proto": 6},
715
                "table_id": 0,
716
                "table_group": "evpl",
717
                "priority": 20100,
718
                "idle_timeout": 0,
719
                "hard_timeout": 0,
720
                "instructions": [
721
                    {
722
                        "instruction_type": "apply_actions",
723
                        "actions": [{"action_type": "push_int"}],
724
                    },
725
                    {"instruction_type": "goto_table", "table_id": 2},
726
                ],
727
            }
728
        },
729
        {
730
            "flow": {
731
                "owner": "telemetry_int",
732
                "cookie": int(0xA816A76AE61B2F46),
733
                "match": {
734
                    "in_port": 1,
735
                    "dl_vlan": 101,
736
                    "dl_type": 2048,
737
                    "nw_proto": 17,
738
                },
739
                "table_id": 0,
740
                "table_group": "evpl",
741
                "priority": 20100,
742
                "idle_timeout": 0,
743
                "hard_timeout": 0,
744
                "instructions": [
745
                    {
746
                        "instruction_type": "apply_actions",
747
                        "actions": [{"action_type": "push_int"}],
748
                    },
749
                    {"instruction_type": "goto_table", "table_id": 2},
750
                ],
751
            },
752
        },
753
        {
754
            "flow": {
755
                "owner": "telemetry_int",
756
                "cookie": int(0xA816A76AE61B2F46),
757
                "match": {"in_port": 1, "dl_vlan": 101},
758
                "table_id": 2,
759
                "table_group": "evpl",
760
                "priority": 20000,
761
                "idle_timeout": 0,
762
                "hard_timeout": 0,
763
                "instructions": [
764
                    {
765
                        "instruction_type": "apply_actions",
766
                        "actions": [
767
                            {"action_type": "add_int_metadata"},
768
                            {"action_type": "set_vlan", "vlan_id": 102},
769
                            {"action_type": "push_vlan", "tag_type": "s"},
770
                            {"action_type": "set_vlan", "vlan_id": 1},
771
                            {"action_type": "output", "port": 3},
772
                        ],
773
                    }
774
                ],
775
            },
776
        },
777
    ]
778
779 1
    expected_uni_z_source_flows = [
780
        {
781
            "flow": {
782
                "owner": "telemetry_int",
783
                "cookie": int(0xA816A76AE61B2F46),
784
                "match": {"in_port": 1, "dl_vlan": 102, "dl_type": 2048, "nw_proto": 6},
785
                "table_id": 0,
786
                "table_group": "evpl",
787
                "priority": 20100,
788
                "idle_timeout": 0,
789
                "hard_timeout": 0,
790
                "instructions": [
791
                    {
792
                        "instruction_type": "apply_actions",
793
                        "actions": [{"action_type": "push_int"}],
794
                    },
795
                    {"instruction_type": "goto_table", "table_id": 2},
796
                ],
797
            },
798
        },
799
        {
800
            "flow": {
801
                "owner": "telemetry_int",
802
                "cookie": int(0xA816A76AE61B2F46),
803
                "match": {
804
                    "in_port": 1,
805
                    "dl_vlan": 102,
806
                    "dl_type": 2048,
807
                    "nw_proto": 17,
808
                },
809
                "table_id": 0,
810
                "table_group": "evpl",
811
                "priority": 20100,
812
                "idle_timeout": 0,
813
                "hard_timeout": 0,
814
                "instructions": [
815
                    {
816
                        "instruction_type": "apply_actions",
817
                        "actions": [{"action_type": "push_int"}],
818
                    },
819
                    {"instruction_type": "goto_table", "table_id": 2},
820
                ],
821
            },
822
        },
823
        {
824
            "flow": {
825
                "owner": "telemetry_int",
826
                "cookie": int(0xA816A76AE61B2F46),
827
                "match": {"in_port": 1, "dl_vlan": 102},
828
                "table_id": 2,
829
                "table_group": "evpl",
830
                "priority": 20000,
831
                "idle_timeout": 0,
832
                "hard_timeout": 0,
833
                "instructions": [
834
                    {
835
                        "instruction_type": "apply_actions",
836
                        "actions": [
837
                            {"action_type": "add_int_metadata"},
838
                            {"action_type": "set_vlan", "vlan_id": 101},
839
                            {"action_type": "push_vlan", "tag_type": "s"},
840
                            {"action_type": "set_vlan", "vlan_id": 1},
841
                            {"action_type": "output", "port": 2},
842
                        ],
843
                    }
844
                ],
845
            },
846
        },
847
    ]
848
849 1
    expected_hop_flows = [
850
        {
851
            "flow": {
852
                "owner": "telemetry_int",
853
                "cookie": int(0xA816A76AE61B2F46),
854
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
855
                "table_id": 0,
856
                "table_group": "evpl",
857
                "priority": 20100,
858
                "idle_timeout": 0,
859
                "hard_timeout": 0,
860
                "instructions": [
861
                    {
862
                        "instruction_type": "apply_actions",
863
                        "actions": [
864
                            {"action_type": "add_int_metadata"},
865
                            {"action_type": "set_vlan", "vlan_id": 1},
866
                            {"action_type": "output", "port": 3},
867
                        ],
868
                    }
869
                ],
870
            },
871
        },
872
        {
873
            "flow": {
874
                "owner": "telemetry_int",
875
                "cookie": int(0xA816A76AE61B2F46),
876
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
877
                "table_id": 0,
878
                "table_group": "evpl",
879
                "priority": 20100,
880
                "idle_timeout": 0,
881
                "hard_timeout": 0,
882
                "instructions": [
883
                    {
884
                        "instruction_type": "apply_actions",
885
                        "actions": [
886
                            {"action_type": "add_int_metadata"},
887
                            {"action_type": "set_vlan", "vlan_id": 1},
888
                            {"action_type": "output", "port": 3},
889
                        ],
890
                    }
891
                ],
892
            },
893
        },
894
        {
895
            "flow": {
896
                "owner": "telemetry_int",
897
                "cookie": int(0xA816A76AE61B2F46),
898
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
899
                "table_id": 0,
900
                "table_group": "evpl",
901
                "priority": 20100,
902
                "idle_timeout": 0,
903
                "hard_timeout": 0,
904
                "instructions": [
905
                    {
906
                        "instruction_type": "apply_actions",
907
                        "actions": [
908
                            {"action_type": "add_int_metadata"},
909
                            {"action_type": "set_vlan", "vlan_id": 1},
910
                            {"action_type": "output", "port": 2},
911
                        ],
912
                    }
913
                ],
914
            },
915
        },
916
        {
917
            "flow": {
918
                "owner": "telemetry_int",
919
                "cookie": int(0xA816A76AE61B2F46),
920
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
921
                "table_id": 0,
922
                "table_group": "evpl",
923
                "priority": 20100,
924
                "idle_timeout": 0,
925
                "hard_timeout": 0,
926
                "instructions": [
927
                    {
928
                        "instruction_type": "apply_actions",
929
                        "actions": [
930
                            {"action_type": "add_int_metadata"},
931
                            {"action_type": "set_vlan", "vlan_id": 1},
932
                            {"action_type": "output", "port": 2},
933
                        ],
934
                    }
935
                ],
936
            },
937
        },
938
    ]
939
940 1
    expected_uni_z_sink_flows = [
941
        {
942
            "flow": {
943
                "owner": "telemetry_int",
944
                "cookie": int(0xA816A76AE61B2F46),
945
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
946
                "table_id": 0,
947
                "table_group": "evpl",
948
                "priority": 20100,
949
                "idle_timeout": 0,
950
                "hard_timeout": 0,
951
                "instructions": [
952
                    {
953
                        "instruction_type": "apply_actions",
954
                        "actions": [{"action_type": "send_report"}],
955
                    },
956
                    {"instruction_type": "goto_table", "table_id": 2},
957
                ],
958
            },
959
        },
960
        {
961
            "flow": {
962
                "owner": "telemetry_int",
963
                "cookie": int(0xA816A76AE61B2F46),
964
                "match": {"in_port": 2, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
965
                "table_id": 0,
966
                "table_group": "evpl",
967
                "priority": 20100,
968
                "idle_timeout": 0,
969
                "hard_timeout": 0,
970
                "instructions": [
971
                    {
972
                        "instruction_type": "apply_actions",
973
                        "actions": [{"action_type": "send_report"}],
974
                    },
975
                    {"instruction_type": "goto_table", "table_id": 2},
976
                ],
977
            },
978
        },
979
        {
980
            "flow": {
981
                "owner": "telemetry_int",
982
                "cookie": int(0xA816A76AE61B2F46),
983
                "match": {"in_port": 2, "dl_vlan": 1},
984
                "table_id": 2,
985
                "table_group": "evpl",
986
                "priority": 20000,
987
                "idle_timeout": 0,
988
                "hard_timeout": 0,
989
                "instructions": [
990
                    {
991
                        "instruction_type": "apply_actions",
992
                        "actions": [
993
                            {"action_type": "pop_int"},
994
                            {"action_type": "pop_vlan"},
995
                            {"action_type": "output", "port": 1},
996
                        ],
997
                    }
998
                ],
999
            }
1000
        },
1001
    ]
1002
1003 1
    expected_uni_a_sink_flows = [
1004
        {
1005
            "flow": {
1006
                "owner": "telemetry_int",
1007
                "cookie": int(0xA816A76AE61B2F46),
1008
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 6},
1009
                "table_id": 0,
1010
                "table_group": "evpl",
1011
                "priority": 20100,
1012
                "idle_timeout": 0,
1013
                "hard_timeout": 0,
1014
                "instructions": [
1015
                    {
1016
                        "instruction_type": "apply_actions",
1017
                        "actions": [{"action_type": "send_report"}],
1018
                    },
1019
                    {"instruction_type": "goto_table", "table_id": 2},
1020
                ],
1021
            },
1022
        },
1023
        {
1024
            "flow": {
1025
                "owner": "telemetry_int",
1026
                "cookie": int(0xA816A76AE61B2F46),
1027
                "match": {"in_port": 3, "dl_vlan": 1, "dl_type": 2048, "nw_proto": 17},
1028
                "table_id": 0,
1029
                "table_group": "evpl",
1030
                "priority": 20100,
1031
                "idle_timeout": 0,
1032
                "hard_timeout": 0,
1033
                "instructions": [
1034
                    {
1035
                        "instruction_type": "apply_actions",
1036
                        "actions": [{"action_type": "send_report"}],
1037
                    },
1038
                    {"instruction_type": "goto_table", "table_id": 2},
1039
                ],
1040
            },
1041
        },
1042
        {
1043
            "flow": {
1044
                "owner": "telemetry_int",
1045
                "cookie": int(0xA816A76AE61B2F46),
1046
                "match": {"in_port": 3, "dl_vlan": 1},
1047
                "table_id": 2,
1048
                "table_group": "evpl",
1049
                "priority": 20000,
1050
                "idle_timeout": 0,
1051
                "hard_timeout": 0,
1052
                "instructions": [
1053
                    {
1054
                        "instruction_type": "apply_actions",
1055
                        "actions": [
1056
                            {"action_type": "pop_int"},
1057
                            {"action_type": "pop_vlan"},
1058
                            {"action_type": "output", "port": 1},
1059
                        ],
1060
                    }
1061
                ],
1062
            },
1063
        },
1064
    ]
1065
1066 1
    expected_flows = (
1067
        expected_uni_a_source_flows
1068
        + expected_uni_z_source_flows
1069
        + expected_hop_flows
1070
        + expected_uni_z_sink_flows
1071
        + expected_uni_a_sink_flows
1072
    )
1073
1074 1
    for i, flow in enumerate(flows):
1075 1
        assert (i, flow["flow"]) == (i, expected_flows[i]["flow"])
1076
1077
1078 1
@pytest.mark.parametrize(
1079
    "evc,uni_key,expected_method",
1080
    [
1081
        ({"uni_a": {"proxy_port": 1}, "metadata": {}}, "uni_a", "proxy_flows"),
1082
        ({"uni_a": {}, "metadata": {}}, "uni_a", "no_proxy_flows"),
1083
        (
1084
            {"uni_a": {"proxy_port": 1}, "metadata": {"proxy_port_enabled": False}},
1085
            "uni_a",
1086
            "no_proxy_flows",
1087
        ),
1088
        (
1089
            {"uni_a": {"proxy_port": 1}, "metadata": {"proxy_port_enabled": True}},
1090
            "uni_a",
1091
            "proxy_flows",
1092
        ),
1093
        (
1094
            {"uni_a": {}, "metadata": {"proxy_port_enabled": True}},
1095
            "uni_a",
1096
            "proxy_flows",
1097
        ),
1098
        (
1099
            {"uni_a": {}, "metadata": {}},
1100
            "uni_a",
1101
            "no_proxy_flows",
1102
        ),
1103
    ],
1104
)
1105 1
def test_bulkd_inter_sink_flows_cases(evc, uni_key, expected_method) -> None:
1106
    """Test build_int_sink_flows for inter EVCs.
1107
1108
    By default inter EVC build not flows without proxy, and proxy metadata
1109
    at the EVC level has higher precedence than derived proxy_port interface metadata
1110
    """
1111 1
    controller = get_controller_mock()
1112 1
    int_manager = INTManager(controller)
1113 1
    no_proxy_port_method, proxy_port_method = MagicMock(), MagicMock()
1114 1
    int_manager.flow_builder._build_int_sink_flows_no_proxy_port = no_proxy_port_method
1115 1
    int_manager.flow_builder._build_int_sink_flows_proxy_port = proxy_port_method
1116 1
    int_manager.flow_builder._build_int_sink_flows(uni_key, evc, {})
1117 1
    if expected_method == "proxy_flows":
1118 1
        assert proxy_port_method.call_count == 1
1119 1
        assert not no_proxy_port_method.call_count
1120
    else:
1121 1
        assert no_proxy_port_method.call_count == 1
1122
        assert not proxy_port_method.call_count
1123