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