]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_ecmp_topo2/test_ebgp_ecmp_topo2.py
Merge pull request #9422 from pguibert6WIND/update_autort_l3vni
[mirror_frr.git] / tests / topotests / bgp_ecmp_topo2 / test_ebgp_ecmp_topo2.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2019 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
6 # ("NetDEF") in this file.
7 #
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
11 # in all copies.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 # OF THIS SOFTWARE.
21 #
22
23
24 """
25 Following tests are covered to test ecmp functionality on EBGP.
26 1. Verify routes installed as per maximum-paths configuration (8/16/32)
27 2. Disable/Shut selected paths nexthops and verify other next are installed in
28 the RIB of DUT. Enable interfaces and verify RIB count.
29 3. Verify BGP table and RIB in DUT after clear BGP routes and neighbors.
30 4. Verify routes are cleared from BGP and RIB table of DUT when
31 redistribute static configuration is removed.
32 5. Shut BGP neigbors one by one and verify BGP and routing table updated
33 accordingly in DUT
34 6. Delete static routes and verify routers are cleared from BGP table and RIB
35 of DUT.
36 7. Verify routes are cleared from BGP and RIB table of DUT when advertise
37 network configuration is removed.
38 """
39 import os
40 import sys
41 import time
42 import pytest
43
44 # Save the Current Working Directory to find configuration files.
45 CWD = os.path.dirname(os.path.realpath(__file__))
46 sys.path.append(os.path.join(CWD, "../"))
47 sys.path.append(os.path.join(CWD, "../../"))
48
49 # pylint: disable=C0413
50 # Import topogen and topotest helpers
51 from lib.topogen import Topogen, get_topogen
52
53 from lib.common_config import (
54 start_topology,
55 write_test_header,
56 write_test_footer,
57 verify_rib,
58 create_static_routes,
59 check_address_types,
60 interface_status,
61 reset_config_on_routers,
62 required_linux_kernel_version,
63 )
64 from lib.topolog import logger
65 from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
66 from lib.topojson import build_config_from_json
67
68
69 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
70
71
72 # Global variables
73 NEXT_HOPS = {"ipv4": [], "ipv6": []}
74 INTF_LIST_R3 = []
75 INTF_LIST_R2 = []
76 NETWORK = {"ipv4": "11.0.20.1/32", "ipv6": "1::/64"}
77 NEXT_HOP_IP = {"ipv4": "10.0.0.1", "ipv6": "fd00::1"}
78 BGP_CONVERGENCE = False
79
80
81 def setup_module(mod):
82 """
83 Sets up the pytest environment.
84
85 * `mod`: module name
86 """
87 global NEXT_HOPS, INTF_LIST_R3, INTF_LIST_R2, TEST_STATIC
88 global ADDR_TYPES
89
90 # Required linux kernel version for this suite to run.
91 result = required_linux_kernel_version("4.15")
92 if result is not True:
93 pytest.skip("Kernel requirements are not met")
94
95 testsuite_run_time = time.asctime(time.localtime(time.time()))
96 logger.info("Testsuite start time: {}".format(testsuite_run_time))
97 logger.info("=" * 40)
98
99 logger.info("Running setup_module to create topology")
100
101 # This function initiates the topology build with Topogen...
102 json_file = "{}/ebgp_ecmp_topo2.json".format(CWD)
103 tgen = Topogen(json_file, mod.__name__)
104 global topo
105 topo = tgen.json_topo
106
107 # Starting topology, create tmp files which are loaded to routers
108 # to start deamons and then start routers
109 start_topology(tgen)
110
111 # Creating configuration from JSON
112 build_config_from_json(tgen, topo)
113
114 # Don't run this test if we have any failure.
115 if tgen.routers_have_failure():
116 pytest.skip(tgen.errors)
117
118 # tgen.mininet_cli()
119 # Api call verify whether BGP is converged
120 ADDR_TYPES = check_address_types()
121
122 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
123 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format(
124 BGP_CONVERGENCE
125 )
126
127 link_data = [
128 val for links, val in topo["routers"]["r2"]["links"].items() if "r3" in links
129 ]
130 for adt in ADDR_TYPES:
131 NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data]
132 if adt == "ipv4":
133 NEXT_HOPS[adt] = sorted(NEXT_HOPS[adt], key=lambda x: int(x.split(".")[2]))
134 elif adt == "ipv6":
135 NEXT_HOPS[adt] = sorted(
136 NEXT_HOPS[adt], key=lambda x: int(x.split(":")[-3], 16)
137 )
138
139 INTF_LIST_R2 = [val["interface"].split("/")[0] for val in link_data]
140 INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1]))
141
142 link_data = [
143 val for links, val in topo["routers"]["r3"]["links"].items() if "r2" in links
144 ]
145 INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data]
146 INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1]))
147
148 # STATIC_ROUTE = True
149 logger.info("Running setup_module() done")
150
151
152 def teardown_module():
153 """
154 Teardown the pytest environment.
155
156 * `mod`: module name
157 """
158
159 logger.info("Running teardown_module to delete topology")
160
161 tgen = get_topogen()
162
163 # Stop toplogy and Remove tmp files
164 tgen.stop_topology()
165
166
167 def static_or_nw(tgen, topo, tc_name, test_type, dut):
168
169 if test_type == "redist_static":
170 input_dict_static = {
171 dut: {
172 "static_routes": [
173 {"network": NETWORK["ipv4"], "next_hop": NEXT_HOP_IP["ipv4"]},
174 {"network": NETWORK["ipv6"], "next_hop": NEXT_HOP_IP["ipv6"]},
175 ]
176 }
177 }
178 logger.info("Configuring static route on router %s", dut)
179 result = create_static_routes(tgen, input_dict_static)
180 assert result is True, "Testcase {} : Failed \n Error: {}".format(
181 tc_name, result
182 )
183
184 input_dict_2 = {
185 dut: {
186 "bgp": {
187 "address_family": {
188 "ipv4": {
189 "unicast": {"redistribute": [{"redist_type": "static"}]}
190 },
191 "ipv6": {
192 "unicast": {"redistribute": [{"redist_type": "static"}]}
193 },
194 }
195 }
196 }
197 }
198
199 logger.info("Configuring redistribute static route on router %s", dut)
200 result = create_router_bgp(tgen, topo, input_dict_2)
201 assert result is True, "Testcase {} : Failed \n Error: {}".format(
202 tc_name, result
203 )
204
205 elif test_type == "advertise_nw":
206 input_dict_nw = {
207 dut: {
208 "bgp": {
209 "address_family": {
210 "ipv4": {
211 "unicast": {
212 "advertise_networks": [{"network": NETWORK["ipv4"]}]
213 }
214 },
215 "ipv6": {
216 "unicast": {
217 "advertise_networks": [{"network": NETWORK["ipv6"]}]
218 }
219 },
220 }
221 }
222 }
223 }
224
225 logger.info(
226 "Advertising networks %s %s from router %s",
227 NETWORK["ipv4"],
228 NETWORK["ipv6"],
229 dut,
230 )
231 result = create_router_bgp(tgen, topo, input_dict_nw)
232 assert result is True, "Testcase {} : Failed \n Error: {}".format(
233 tc_name, result
234 )
235
236
237 @pytest.mark.parametrize("ecmp_num", ["8", "16", "32"])
238 @pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
239 def test_modify_ecmp_max_paths(request, ecmp_num, test_type):
240 """
241 Verify routes installed as per maximum-paths
242 configuration (8/16/32).
243 """
244
245 tc_name = request.node.name
246 write_test_header(tc_name)
247 tgen = get_topogen()
248
249 reset_config_on_routers(tgen)
250
251 static_or_nw(tgen, topo, tc_name, test_type, "r2")
252
253 input_dict = {
254 "r3": {
255 "bgp": {
256 "address_family": {
257 "ipv4": {
258 "unicast": {
259 "maximum_paths": {
260 "ebgp": ecmp_num,
261 }
262 }
263 },
264 "ipv6": {
265 "unicast": {
266 "maximum_paths": {
267 "ebgp": ecmp_num,
268 }
269 }
270 },
271 }
272 }
273 }
274 }
275
276 logger.info("Configuring bgp maximum-paths %s on router r3", ecmp_num)
277 result = create_router_bgp(tgen, topo, input_dict)
278 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
279
280 # Verifying RIB routes
281 dut = "r3"
282 protocol = "bgp"
283
284 for addr_type in ADDR_TYPES:
285 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
286
287 logger.info("Verifying %s routes on r3", addr_type)
288
289 # Only test the count of nexthops; the actual nexthop addresses
290 # can vary and are not deterministic.
291 #
292 result = verify_rib(
293 tgen,
294 addr_type,
295 dut,
296 input_dict_1,
297 next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)],
298 protocol=protocol,
299 count_only=True,
300 )
301
302 assert result is True, "Testcase {} : Failed \n Error: {}".format(
303 tc_name, result
304 )
305
306 write_test_footer(tc_name)
307
308
309 @pytest.mark.parametrize("ecmp_num", ["8", "16", "32"])
310 @pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
311 def test_ecmp_after_clear_bgp(request, ecmp_num, test_type):
312 """Verify BGP table and RIB in DUT after clear BGP routes and neighbors"""
313
314 tc_name = request.node.name
315 write_test_header(tc_name)
316 tgen = get_topogen()
317
318 reset_config_on_routers(tgen)
319
320 # Verifying RIB routes
321 dut = "r3"
322 protocol = "bgp"
323
324 static_or_nw(tgen, topo, tc_name, test_type, "r2")
325 for addr_type in ADDR_TYPES:
326 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
327
328 logger.info("Verifying %s routes on r3", addr_type)
329 result = verify_rib(
330 tgen,
331 addr_type,
332 dut,
333 input_dict_1,
334 next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)],
335 protocol=protocol,
336 )
337 assert result is True, "Testcase {} : Failed \n Error: {}".format(
338 tc_name, result
339 )
340
341 # Clear BGP
342 for addr_type in ADDR_TYPES:
343 clear_bgp(tgen, addr_type, dut)
344
345 # Verify BGP convergence
346 result = verify_bgp_convergence(tgen, topo)
347 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
348
349 for addr_type in ADDR_TYPES:
350 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
351 logger.info("Verifying %s routes on r3", addr_type)
352 result = verify_rib(
353 tgen,
354 addr_type,
355 dut,
356 input_dict_1,
357 next_hop=NEXT_HOPS[addr_type][: int(ecmp_num)],
358 protocol=protocol,
359 )
360 assert result is True, "Testcase {} : Failed \n Error: {}".format(
361 tc_name, result
362 )
363
364 write_test_footer(tc_name)
365
366
367 def test_ecmp_remove_redistribute_static(request):
368 """Verify routes are cleared from BGP and RIB table of DUT when
369 redistribute static configuration is removed."""
370
371 tc_name = request.node.name
372 write_test_header(tc_name)
373 tgen = get_topogen()
374
375 reset_config_on_routers(tgen)
376 static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
377 for addr_type in ADDR_TYPES:
378
379 # Verifying RIB routes
380 dut = "r3"
381 protocol = "bgp"
382 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
383
384 logger.info("Verifying %s routes on r3", addr_type)
385 result = verify_rib(
386 tgen,
387 addr_type,
388 dut,
389 input_dict_1,
390 next_hop=NEXT_HOPS[addr_type],
391 protocol=protocol,
392 )
393 assert result is True, "Testcase {} : Failed \n Error: {}".format(
394 tc_name, result
395 )
396
397 input_dict_2 = {
398 "r2": {
399 "bgp": {
400 "address_family": {
401 "ipv4": {
402 "unicast": {
403 "redistribute": [{"redist_type": "static", "delete": True}]
404 }
405 },
406 "ipv6": {
407 "unicast": {
408 "redistribute": [{"redist_type": "static", "delete": True}]
409 }
410 },
411 }
412 }
413 }
414 }
415
416 logger.info("Remove redistribute static")
417 result = create_router_bgp(tgen, topo, input_dict_2)
418 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
419
420 for addr_type in ADDR_TYPES:
421
422 # Verifying RIB routes
423 dut = "r3"
424 protocol = "bgp"
425 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
426
427 logger.info("Verifying %s routes on r3 are deleted", addr_type)
428 result = verify_rib(
429 tgen,
430 addr_type,
431 dut,
432 input_dict_1,
433 next_hop=[],
434 protocol=protocol,
435 expected=False,
436 )
437 assert (
438 result is not True
439 ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
440
441 logger.info("Enable redistribute static")
442 input_dict_2 = {
443 "r2": {
444 "bgp": {
445 "address_family": {
446 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
447 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
448 }
449 }
450 }
451 }
452 result = create_router_bgp(tgen, topo, input_dict_2)
453 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
454
455 for addr_type in ADDR_TYPES:
456 # Verifying RIB routes
457 dut = "r3"
458 protocol = "bgp"
459 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
460 logger.info("Verifying %s routes on r3", addr_type)
461 result = verify_rib(
462 tgen,
463 addr_type,
464 dut,
465 input_dict_1,
466 next_hop=NEXT_HOPS[addr_type],
467 protocol=protocol,
468 )
469 assert result is True, "Testcase {} : Failed \n Error: {}".format(
470 tc_name, result
471 )
472
473 write_test_footer(tc_name)
474
475
476 @pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
477 def test_ecmp_shut_bgp_neighbor(request, test_type):
478 """Shut BGP neigbors one by one and verify BGP and routing table updated
479 accordingly in DUT"""
480
481 tc_name = request.node.name
482 write_test_header(tc_name)
483 tgen = get_topogen()
484
485 logger.info(INTF_LIST_R2)
486 # Verifying RIB routes
487 dut = "r3"
488 protocol = "bgp"
489
490 reset_config_on_routers(tgen)
491 static_or_nw(tgen, topo, tc_name, test_type, "r2")
492
493 for addr_type in ADDR_TYPES:
494 input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
495
496 logger.info("Verifying %s routes on r3", addr_type)
497 result = verify_rib(
498 tgen,
499 addr_type,
500 dut,
501 input_dict,
502 next_hop=NEXT_HOPS[addr_type],
503 protocol=protocol,
504 )
505 assert result is True, "Testcase {} : Failed \n Error: {}".format(
506 tc_name, result
507 )
508
509 for intf_num in range(len(INTF_LIST_R2) + 1, 16):
510 intf_val = INTF_LIST_R2[intf_num : intf_num + 16]
511
512 input_dict_1 = {"r2": {"interface_list": [intf_val], "status": "down"}}
513 logger.info("Shutting down neighbor interface {} on r2".format(intf_val))
514 result = interface_status(tgen, topo, input_dict_1)
515 assert result is True, "Testcase {} : Failed \n Error: {}".format(
516 tc_name, result
517 )
518
519 for addr_type in ADDR_TYPES:
520 if intf_num + 16 < 32:
521 check_hops = NEXT_HOPS[addr_type]
522 else:
523 check_hops = []
524
525 input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
526 logger.info("Verifying %s routes on r3", addr_type)
527 result = verify_rib(
528 tgen, addr_type, dut, input_dict, next_hop=check_hops, protocol=protocol
529 )
530 assert result is True, "Testcase {} : Failed \n Error: {}".format(
531 tc_name, result
532 )
533
534 input_dict_1 = {"r2": {"interface_list": INTF_LIST_R2, "status": "up"}}
535
536 logger.info("Enabling all neighbor interface {} on r2")
537 result = interface_status(tgen, topo, input_dict_1)
538 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
539
540 static_or_nw(tgen, topo, tc_name, test_type, "r2")
541 for addr_type in ADDR_TYPES:
542 input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
543
544 logger.info("Verifying %s routes on r3", addr_type)
545 result = verify_rib(
546 tgen,
547 addr_type,
548 dut,
549 input_dict,
550 next_hop=NEXT_HOPS[addr_type],
551 protocol=protocol,
552 )
553 assert result is True, "Testcase {} : Failed \n Error: {}".format(
554 tc_name, result
555 )
556
557 write_test_footer(tc_name)
558
559
560 def test_ecmp_remove_static_route(request):
561 """
562 Delete static routes and verify routers are cleared from BGP table,
563 and RIB of DUT.
564 """
565
566 tc_name = request.node.name
567 write_test_header(tc_name)
568 tgen = get_topogen()
569
570 # Verifying RIB routes
571 dut = "r3"
572 protocol = "bgp"
573
574 reset_config_on_routers(tgen)
575
576 static_or_nw(tgen, topo, tc_name, "redist_static", "r2")
577 for addr_type in ADDR_TYPES:
578 input_dict_1 = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
579
580 logger.info("Verifying %s routes on r3", addr_type)
581 result = verify_rib(
582 tgen,
583 addr_type,
584 dut,
585 input_dict_1,
586 next_hop=NEXT_HOPS[addr_type],
587 protocol=protocol,
588 )
589 assert result is True, "Testcase {} : Failed \n Error: {}".format(
590 tc_name, result
591 )
592
593 for addr_type in ADDR_TYPES:
594 input_dict_2 = {
595 "r2": {
596 "static_routes": [
597 {
598 "network": NETWORK[addr_type],
599 "next_hop": NEXT_HOP_IP[addr_type],
600 "delete": True,
601 }
602 ]
603 }
604 }
605
606 logger.info("Remove static routes")
607 result = create_static_routes(tgen, input_dict_2)
608 assert result is True, "Testcase {} : Failed \n Error: {}".format(
609 tc_name, result
610 )
611
612 logger.info("Verifying %s routes on r3 are removed", addr_type)
613 result = verify_rib(
614 tgen,
615 addr_type,
616 dut,
617 input_dict_2,
618 next_hop=[],
619 protocol=protocol,
620 expected=False,
621 )
622 assert (
623 result is not True
624 ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
625
626 for addr_type in ADDR_TYPES:
627 # Enable static routes
628 input_dict_4 = {
629 "r2": {
630 "static_routes": [
631 {"network": NETWORK[addr_type], "next_hop": NEXT_HOP_IP[addr_type]}
632 ]
633 }
634 }
635
636 logger.info("Enable static route")
637 result = create_static_routes(tgen, input_dict_4)
638 assert result is True, "Testcase {} : Failed \n Error: {}".format(
639 tc_name, result
640 )
641
642 logger.info("Verifying %s routes on r3", addr_type)
643 result = verify_rib(
644 tgen,
645 addr_type,
646 dut,
647 input_dict_4,
648 next_hop=NEXT_HOPS[addr_type],
649 protocol=protocol,
650 )
651 assert result is True, "Testcase {} : Failed \n Error: {}".format(
652 tc_name, result
653 )
654
655
656 def test_ecmp_remove_nw_advertise(request):
657 """
658 Verify routes are cleared from BGP and RIB table of DUT,
659 when advertise network configuration is removed
660 """
661
662 tc_name = request.node.name
663 write_test_header(tc_name)
664 tgen = get_topogen()
665
666 # Verifying RIB routes
667 dut = "r3"
668 protocol = "bgp"
669
670 reset_config_on_routers(tgen)
671 static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
672 for addr_type in ADDR_TYPES:
673 input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
674
675 logger.info("Verifying %s routes on r3", addr_type)
676 result = verify_rib(
677 tgen,
678 addr_type,
679 dut,
680 input_dict,
681 next_hop=NEXT_HOPS[addr_type],
682 protocol=protocol,
683 )
684 assert result is True, "Testcase {} : Failed \n Error: {}".format(
685 tc_name, result
686 )
687
688 input_dict_3 = {
689 "r2": {
690 "bgp": {
691 "address_family": {
692 "ipv4": {
693 "unicast": {
694 "advertise_networks": [
695 {"network": NETWORK["ipv4"], "delete": True}
696 ]
697 }
698 },
699 "ipv6": {
700 "unicast": {
701 "advertise_networks": [
702 {"network": NETWORK["ipv6"], "delete": True}
703 ]
704 }
705 },
706 }
707 }
708 }
709 }
710
711 logger.info("Withdraw advertised networks")
712 result = create_router_bgp(tgen, topo, input_dict_3)
713 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
714
715 for addr_type in ADDR_TYPES:
716 input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
717
718 logger.info("Verifying %s routes on r3", addr_type)
719 result = verify_rib(
720 tgen,
721 addr_type,
722 dut,
723 input_dict,
724 next_hop=[],
725 protocol=protocol,
726 expected=False,
727 )
728 assert (
729 result is not True
730 ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
731
732 static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
733 for addr_type in ADDR_TYPES:
734 input_dict = {"r3": {"static_routes": [{"network": NETWORK[addr_type]}]}}
735 logger.info("Verifying %s routes on r3", addr_type)
736 result = verify_rib(
737 tgen,
738 addr_type,
739 dut,
740 input_dict,
741 next_hop=NEXT_HOPS[addr_type],
742 protocol=protocol,
743 )
744 assert result is True, "Testcase {} : Failed \n Error: {}".format(
745 tc_name, result
746 )
747
748 write_test_footer(tc_name)
749
750
751 if __name__ == "__main__":
752 args = ["-s"] + sys.argv[1:]
753 sys.exit(pytest.main(args))