From b839bbdb920adad551bd8c9c9070d69d0adeee54 Mon Sep 17 00:00:00 2001 From: ansrajpu-git <113939367+ansrajpu-git@users.noreply.github.com> Date: Mon, 28 Oct 2024 16:53:24 -0400 Subject: [PATCH 001/221] [Qos]Updating lldp error regex for loganalyzer ignore (#14022) Approach What is the motivation for this PR? The lldp error encountered during test run not getting captured for loganalyzer ignore How did you do it? Enhanced the regex pattern to consider the lldp multi-asic instance --- tests/qos/test_qos_sai.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qos/test_qos_sai.py b/tests/qos/test_qos_sai.py index 59595294f29..4f5e68244bd 100644 --- a/tests/qos/test_qos_sai.py +++ b/tests/qos/test_qos_sai.py @@ -67,8 +67,8 @@ def ignore_expected_loganalyzer_exception(get_src_dst_asic_and_duts, loganalyzer ignore_regex = [ ".*ERR syncd[0-9]*#syncd.*brcm_sai_set_switch_attribute.*updating switch mac addr failed with error.*", # The following error log is related to the bug of https://github.com/sonic-net/sonic-buildimage/issues/13265 - ".*ERR lldp#lldpmgrd.*Command failed.*lldpcli.*configure.*ports.*unable to connect to socket.*", - ".*ERR lldp#lldpmgrd.*Command failed.*lldpcli.*configure.*ports.*lldp.*unknown command from argument" + ".*ERR lldp[0-9]*#lldpmgrd.*Command failed.*lldpcli.*configure.*ports.*unable to connect to socket.*", + ".*ERR lldp[0-9]*#lldpmgrd.*Command failed.*lldpcli.*configure.*ports.*lldp.*unknown command from argument" ".*configure.*command was failed.*times, disabling retry.*" # Error related to syncd socket-timeout intermittenly ".*ERR syncd[0-9]*#dsserve: _ds2tty broken pipe.*" From 5b88fa22c5c3104db037e66b184267746d5f3a58 Mon Sep 17 00:00:00 2001 From: rbpittman Date: Mon, 28 Oct 2024 23:33:18 -0400 Subject: [PATCH 002/221] Adapt Cisco PFC counters (#15087) * Ignore XON frames and lossy frames for Cisco-8122. Fix some typos * Only run config checks when required. * Remove old lines. --- tests/qos/test_pfc_counters.py | 44 +++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/tests/qos/test_pfc_counters.py b/tests/qos/test_pfc_counters.py index 287e7c13a55..a508494d4f0 100644 --- a/tests/qos/test_pfc_counters.py +++ b/tests/qos/test_pfc_counters.py @@ -24,7 +24,7 @@ PFC_GEN_FILE_RELATIVE_PATH = r'../../ansible/roles/test/files/helpers/pfc_gen.py' """ Expected PFC generator path at the leaf fanout switch """ PFC_GEN_FILE_DEST = r'~/pfc_gen.py' -PFC_GEN_FILE_ABSULOTE_PATH = r'/root/pfc_gen_cpu.py' +PFC_GEN_FILE_ABSOLUTE_PATH = r'/root/pfc_gen_cpu.py' """ Number of generated packets for each test case """ PKT_COUNT = 10 @@ -70,7 +70,7 @@ def setup_testbed(fanouthosts, duthost, leaf_fanouts): # noqa F811 def run_test(fanouthosts, duthost, conn_graph_facts, fanout_graph_facts, leaf_fanouts, # noqa F811 - is_pfc=True, pause_time=65535, check_continous_pfc=False): + is_pfc=True, pause_time=65535, check_continuous_pfc=False): """ @Summary: Run test for Ethernet flow control (FC) or priority-based flow control (PFC) @param duthost: The object for interacting with DUT through ansible @@ -80,17 +80,21 @@ def run_test(fanouthosts, duthost, conn_graph_facts, fanout_graph_facts, leaf_fa @param pause_time: Pause time quanta (0-65535) in the frame. 0 means unpause. """ setup_testbed(fanouthosts, duthost, leaf_fanouts) + asic = duthost.asic_instance() conn_facts = conn_graph_facts['device_conn'][duthost.hostname] onyx_pfc_container_name = 'storm' - int_status = duthost.show_interface(command="status")[ + int_status = asic.show_interface(command="status")[ 'ansible_facts']['int_status'] - """ We only test active physical interfaces """ active_phy_intfs = [intf for intf in int_status if intf.startswith('Ethernet') and int_status[intf]['admin_state'] == 'up' and int_status[intf]['oper_state'] == 'up'] - if not check_continous_pfc: + only_lossless_rx_counters = "Cisco-8122" in asic.sonichost.facts["hwsku"] + no_xon_counters = "Cisco-8122" in asic.sonichost.facts["hwsku"] + if only_lossless_rx_counters: + config_facts = asic.config_facts(host=asic.hostname, source='persistent')['ansible_facts'] + if not check_continuous_pfc: """ Generate PFC or FC packets for active physical interfaces """ for intf in active_phy_intfs: peer_device = conn_facts[intf]['peerdevice'] @@ -114,7 +118,7 @@ def run_test(fanouthosts, duthost, conn_graph_facts, fanout_graph_facts, leaf_fa for priority in range(PRIO_COUNT): if fanout_hwsku == "MLNX-OS": cmd = 'docker exec %s "python %s -i %s -p %d -t %d -n %d"' % ( - onyx_pfc_container_name, PFC_GEN_FILE_ABSULOTE_PATH, + onyx_pfc_container_name, PFC_GEN_FILE_ABSOLUTE_PATH, peer_port_name, 2 ** priority, pause_time, PKT_COUNT) peerdev_ans.host.config(cmd) else: @@ -124,7 +128,7 @@ def run_test(fanouthosts, duthost, conn_graph_facts, fanout_graph_facts, leaf_fa else: if fanout_hwsku == "MLNX-OS": cmd = 'docker exec %s "python %s -i %s -g -t %d -n %d"' % ( - onyx_pfc_container_name, PFC_GEN_FILE_ABSULOTE_PATH, peer_port_name, pause_time, PKT_COUNT) + onyx_pfc_container_name, PFC_GEN_FILE_ABSOLUTE_PATH, peer_port_name, pause_time, PKT_COUNT) peerdev_ans.host.config(cmd) else: cmd = "sudo python %s -i %s -g -t %d -n %d" % ( @@ -137,13 +141,25 @@ def run_test(fanouthosts, duthost, conn_graph_facts, fanout_graph_facts, leaf_fa """ Check results """ counter_facts = duthost.sonic_pfc_counters(method="get")[ 'ansible_facts'] - + if only_lossless_rx_counters: + pfc_enabled_prios = [int(prio) for prio in config_facts["PORT_QOS_MAP"][intf]['pfc_enable'].split(',')] + failures = [] for intf in active_phy_intfs: - if is_pfc: - assert counter_facts[intf]['Rx'] == [ - str(PKT_COUNT)] * PRIO_COUNT + if is_pfc and (not no_xon_counters or pause_time != 0): + if only_lossless_rx_counters: + expected_prios = [str(PKT_COUNT if prio in pfc_enabled_prios else 0) for prio in range(PRIO_COUNT)] + else: + expected_prios = [str(PKT_COUNT)] * PRIO_COUNT else: - assert counter_facts[intf]['Rx'] == ['0'] * PRIO_COUNT + # Expect 0 counters when "no_xon_counters and pause_time == 0", i.e. when + # device does not support XON counters and the frame is XON. + expected_prios = ['0'] * PRIO_COUNT + logger.info("Verifying PFC RX count matches {}".format(expected_prios)) + if counter_facts[intf]['Rx'] != expected_prios: + failures.append((counter_facts[intf]['Rx'], expected_prios)) + for failure in failures: + logger.error("Got {}, expected {}".format(*failure)) + assert len(failures) == 0, "PFC RX counter increment not matching expected for above logged cases." else: for intf in active_phy_intfs: @@ -171,7 +187,7 @@ def run_test(fanouthosts, duthost, conn_graph_facts, fanout_graph_facts, leaf_fa if fanout_hwsku == "MLNX-OS": cmd = 'docker exec %s "python %s -i %s -p %d -t %d -n %d"' % ( - onyx_pfc_container_name, PFC_GEN_FILE_ABSULOTE_PATH, + onyx_pfc_container_name, PFC_GEN_FILE_ABSOLUTE_PATH, peer_port_name, 2 ** priority, pause_time, PKT_COUNT) peerdev_ans.host.config(cmd) else: @@ -229,4 +245,4 @@ def test_continous_pfc(fanouthosts, duthosts, rand_one_tgen_dut_hostname, conn_graph_facts, fanout_graph_facts, leaf_fanouts): # noqa F811 duthost = duthosts[rand_one_tgen_dut_hostname] run_test(fanouthosts, duthost, conn_graph_facts, - fanout_graph_facts, leaf_fanouts, check_continous_pfc=True) + fanout_graph_facts, leaf_fanouts, check_continuous_pfc=True) From 7a3707dd0249f87d119995be177803d4e13283ba Mon Sep 17 00:00:00 2001 From: ansrajpu-git <113939367+ansrajpu-git@users.noreply.github.com> Date: Tue, 29 Oct 2024 00:17:05 -0400 Subject: [PATCH 003/221] [QoS]Test_buffer_model test skip for Nokia platform (#13690) What is the motivation for this PR? Test suite was executing skipped test. How did you do it? Updated the conditional mark skip condition How did you verify/test it? Executed the test and verify the results --- .../common/plugins/conditional_mark/tests_mark_conditions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 667f015a1ff..22aaddb7495 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1318,7 +1318,7 @@ qos/test_buffer.py::test_buffer_model_test: reason: "Running only on mellanox devices and covered by unit testing / M0/MX topo does not support qos" conditions_logical_operator: or conditions: - - "asic_type in ['mellanox']" + - "asic_type in ['mellanox'] or asic_subtype in ['broadcom-dnx']" - "topo_type in ['m0', 'mx']" qos/test_buffer_traditional.py: From 08b0718da2bc7fc0efdd5dc73bf83435e58c12cb Mon Sep 17 00:00:00 2001 From: Zhixin Zhu <44230426+zhixzhu@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:37:50 +0800 Subject: [PATCH 004/221] Update policer rate for cisco-8000 (#14459) * update policy rate for cisco-8000 Signed-off-by: Zhixin Zhu * update cisco-8000 CIR config Signed-off-by: Zhixin Zhu --------- Signed-off-by: Zhixin Zhu --- .../test/files/ptftests/py3/copp_tests.py | 21 +++++++++++++++++++ tests/copp/copp_utils.py | 11 +++++----- tests/copp/scripts/update_copp_config.py | 14 ++++++++++--- tests/copp/test_copp.py | 1 + 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/ansible/roles/test/files/ptftests/py3/copp_tests.py b/ansible/roles/test/files/ptftests/py3/copp_tests.py index 6ad9e1a4874..42fd1435845 100644 --- a/ansible/roles/test/files/ptftests/py3/copp_tests.py +++ b/ansible/roles/test/files/ptftests/py3/copp_tests.py @@ -81,6 +81,7 @@ def __init__(self): self.hw_sku == "Cisco-8111-O62C2"): self.PPS_LIMIT_MAX = self.PPS_LIMIT * 1.4 self.asic_type = test_params.get('asic_type', None) + self.platform = test_params.get('platform', None) self.topo_type = test_params.get('topo_type', None) def log(self, message, debug=False): @@ -350,6 +351,11 @@ def __init__(self): # Marvell based platforms have cir/cbs in steps of 125 if self.hw_sku in {"Nokia-M0-7215", "Nokia-7215", "Nokia-7215-A1"}: self.PPS_LIMIT = 250 + # Cisco G100 based platform has CIR 600 + elif self.asic_type == "cisco-8000" and "8111" in self.platform: + self.PPS_LIMIT = 600 + elif self.asic_type == "cisco-8000": + self.PPS_LIMIT = 400 # M0 devices have CIR of 300 for DHCP elif self.topo_type in {"m0", "mx"}: self.PPS_LIMIT = 300 @@ -394,6 +400,11 @@ def __init__(self): # Marvell based platforms have cir/cbs in steps of 125 if self.hw_sku in {"Nokia-M0-7215", "Nokia-7215", "Nokia-7215-A1"}: self.PPS_LIMIT = 250 + # Cisco G100 based platform has CIR 600 + elif self.asic_type == "cisco-8000" and "8111" in self.platform: + self.PPS_LIMIT = 600 + elif self.asic_type == "cisco-8000": + self.PPS_LIMIT = 400 # M0 devices have CIR of 300 for DHCP elif self.topo_type in {"m0", "mx"}: self.PPS_LIMIT = 300 @@ -457,6 +468,11 @@ def __init__(self): # Marvell based platforms have cir/cbs in steps of 125 if self.hw_sku in {"Nokia-M0-7215", "Nokia-7215", "Nokia-7215-A1"}: self.PPS_LIMIT = 250 + # Cisco G100 based platform has CIR 600 + elif self.asic_type == "cisco-8000" and "8111" in self.platform: + self.PPS_LIMIT = 600 + elif self.asic_type == "cisco-8000": + self.PPS_LIMIT = 400 # M0 devices have CIR of 300 for DHCP elif self.topo_type in {"m0", "mx"}: self.PPS_LIMIT = 300 @@ -488,6 +504,11 @@ def __init__(self): # Marvell based platforms have cir/cbs in steps of 125 if self.hw_sku in {"Nokia-M0-7215", "Nokia-7215", "Nokia-7215-A1"}: self.PPS_LIMIT = 250 + # Cisco G100 based platform has CIR 600 + elif self.asic_type == "cisco-8000" and "8111" in self.platform: + self.PPS_LIMIT = 600 + elif self.asic_type == "cisco-8000": + self.PPS_LIMIT = 400 # M0 devices have CIR of 300 for DHCP elif self.topo_type in {"m0", "mx"}: self.PPS_LIMIT = 300 diff --git a/tests/copp/copp_utils.py b/tests/copp/copp_utils.py index 3d39cfc8cd5..0b44aa3bca2 100644 --- a/tests/copp/copp_utils.py +++ b/tests/copp/copp_utils.py @@ -63,11 +63,12 @@ def limit_policer(dut, pps_limit, nn_target_namespace): config_format = "config_db" dut.script( - cmd="{} {} {} {} {}".format(_UPDATE_COPP_SCRIPT, - pps_limit, - _BASE_COPP_CONFIG, - _TEMP_COPP_CONFIG, - config_format) + cmd="{} {} {} {} {} {}".format(_UPDATE_COPP_SCRIPT, + pps_limit, + _BASE_COPP_CONFIG, + _TEMP_COPP_CONFIG, + config_format, + dut.facts["asic_type"]) ) if config_format == "app_db": diff --git a/tests/copp/scripts/update_copp_config.py b/tests/copp/scripts/update_copp_config.py index a362a63f8fb..1322a2bce63 100644 --- a/tests/copp/scripts/update_copp_config.py +++ b/tests/copp/scripts/update_copp_config.py @@ -50,7 +50,7 @@ import sys -def generate_limited_pps_config(pps_limit, input_config_file, output_config_file, config_format="app_db"): +def generate_limited_pps_config(pps_limit, input_config_file, output_config_file, config_format="app_db", asic_type=""): """Modifies a COPP config to use the specified rate limit. Notes: @@ -91,7 +91,11 @@ def generate_limited_pps_config(pps_limit, input_config_file, output_config_file group_config["cir"] = DEFAULT_PPS_LIMIT group_config["cbs"] = DEFAULT_PPS_LIMIT elif tg == "queue4_group3": - continue + if asic_type == "cisco-8000": + group_config["cir"] = "400" + group_config["cbs"] = "400" + else: + continue else: if "cir" in group_config: group_config["cir"] = pps_limit @@ -109,5 +113,9 @@ def generate_limited_pps_config(pps_limit, input_config_file, output_config_file config_format = "app_db" else: config_format = ARGS[3] + if len(ARGS) < 5: + asic_type = "" + else: + asic_type = ARGS[4] - generate_limited_pps_config(ARGS[0], ARGS[1], ARGS[2], config_format) + generate_limited_pps_config(ARGS[0], ARGS[1], ARGS[2], config_format, asic_type) diff --git a/tests/copp/test_copp.py b/tests/copp/test_copp.py index 2d575fd2098..d96526e2c59 100644 --- a/tests/copp/test_copp.py +++ b/tests/copp/test_copp.py @@ -292,6 +292,7 @@ def _copp_runner(dut, ptf, protocol, test_params, dut_type, has_trap=True, skip_ "has_trap": has_trap, "hw_sku": dut.facts["hwsku"], "asic_type": dut.facts["asic_type"], + "platform": dut.facts["platform"], "topo_type": test_params.topo_type} dut_ip = dut.mgmt_ip From 020ea348a6483a19e016adb469084bb05a98f849 Mon Sep 17 00:00:00 2001 From: Yaqiang Zhu Date: Tue, 29 Oct 2024 14:51:41 +0800 Subject: [PATCH 005/221] [dhcp_relay][dualtor] Add test case for DHCP drop on standby tor (#15110) What is the motivation for this PR? Add test to verify DHCP packets are dropped by standby tor #5627 How did you do it? Verify packet drop count by cacl How did you verify/test it? Run test on dualtor / t0 topos, all passed --- tests/dhcp_relay/test_dhcp_relay.py | 44 +++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/tests/dhcp_relay/test_dhcp_relay.py b/tests/dhcp_relay/test_dhcp_relay.py index 9f5a4dda0c3..99e622dbe8c 100644 --- a/tests/dhcp_relay/test_dhcp_relay.py +++ b/tests/dhcp_relay/test_dhcp_relay.py @@ -150,9 +150,46 @@ def start_dhcp_monitor_debug_counter(duthost): assert False, "Failed to start dhcpmon in debug counter mode\n" +def get_acl_count_by_mark(rand_unselected_dut, mark): + output = rand_unselected_dut.shell("iptables -nvL DHCP | grep 'DROP' | grep '{}' | awk '{{print $1}}'" + .format(mark)) + pytest_assert(output["rc"] == 0 and len(output["stdout_lines"]) == 1, + "Failed get DHCP acl count for {}, err: {}".format(mark, output["stderr"])) + return int(output["stdout"].strip()) + + +@pytest.fixture(scope="function") +def verify_acl_drop_on_standby_tor(rand_unselected_dut, dut_dhcp_relay_data, testing_config, tbinfo): + testing_mode, _ = testing_config + if testing_mode == DUAL_TOR_MODE and "dualtor-aa" not in tbinfo["topo"]["name"]: + pre_client_dhcp_acl_counts = {} + for dhcp_relay in dut_dhcp_relay_data: + client_interface_name = dhcp_relay["client_iface"]["name"] + # Get acl mark per interface + output = (rand_unselected_dut + .shell(r"ebtables -L INPUT | grep '\-i {} \-j mark \-\-mark\-set' | awk '{{print $6}}'" + .format(client_interface_name))) + pytest_assert(output["rc"] == 0 and len(output["stdout_lines"]) == 1, + "Failed get DHCP acl mark for {}, err: {}".format(client_interface_name, output["stderr"])) + mark = output["stdout"].strip() + pre_client_dhcp_acl_counts[client_interface_name] = {"mark": mark} + # Get acl count by acl mark + pre_client_dhcp_acl_counts[client_interface_name]["count"] = get_acl_count_by_mark(rand_unselected_dut, + mark) + + yield + + if testing_mode == DUAL_TOR_MODE and "dualtor-aa" not in tbinfo["topo"]["name"]: + for client_interface_name, item in pre_client_dhcp_acl_counts.items(): + after_count = get_acl_count_by_mark(rand_unselected_dut, item["mark"]) + pytest_assert(after_count == item["count"] + 2, "Drop count of {} {} is unexpected, pre: {}, after: {}" + .format(client_interface_name, item["mark"], item["count"], after_count)) + + def test_dhcp_relay_default(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config, setup_standby_ports_on_rand_unselected_tor, # noqa F811 - rand_unselected_dut, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 + rand_unselected_dut, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 + verify_acl_drop_on_standby_tor): # noqa F811 """Test DHCP relay functionality on T0 topology. For each DHCP relay agent running on the DuT, verify DHCP packets are relayed properly """ @@ -241,7 +278,7 @@ def test_dhcp_relay_with_source_port_ip_in_relay_enabled(ptfhost, dut_dhcp_relay validate_dut_routes_exist, testing_config, setup_standby_ports_on_rand_unselected_tor, # noqa F811 rand_unselected_dut, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - enable_source_port_ip_in_relay): + enable_source_port_ip_in_relay, verify_acl_drop_on_standby_tor): # noqa F811 """Test DHCP relay functionality on T0 topology. For each DHCP relay agent running on the DuT, verify DHCP packets are relayed properly """ @@ -464,7 +501,8 @@ def test_dhcp_relay_unicast_mac(ptfhost, dut_dhcp_relay_data, validate_dut_route def test_dhcp_relay_random_sport(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config, setup_standby_ports_on_rand_unselected_tor, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 + verify_acl_drop_on_standby_tor): # noqa F811 """Test DHCP relay functionality on T0 topology with random source port (sport) If the client is SNAT'd, the source port could be changed to a non-standard port (i.e., not 68). Verify that DHCP relay works with random high sport. From 9faa47bd404620c3bd29aca02ff0b2619ee5c5e8 Mon Sep 17 00:00:00 2001 From: Yawen Date: Tue, 29 Oct 2024 19:05:47 +1100 Subject: [PATCH 006/221] dhcp storm stress test (#14768) * dhcp storm stress test * fix pre-commit * fix pre-commit issues * no 2018 or 2019 branch, delete the skip condition * dhcp stress test, skip discover and request * Re-trigger check * skip for 7215 due to the buffer issue * skip for kvm * skip on 7215 or kvm --- .../ptftests/py3/dhcp_relay_stress_test.py | 247 ++++++++++++++++++ .../tests_mark_conditions.yaml | 21 ++ tests/dhcp_relay/test_dhcp_relay_stress.py | 121 ++++++++- 3 files changed, 388 insertions(+), 1 deletion(-) diff --git a/ansible/roles/test/files/ptftests/py3/dhcp_relay_stress_test.py b/ansible/roles/test/files/ptftests/py3/dhcp_relay_stress_test.py index 38eebb98528..05a91db5aa7 100644 --- a/ansible/roles/test/files/ptftests/py3/dhcp_relay_stress_test.py +++ b/ansible/roles/test/files/ptftests/py3/dhcp_relay_stress_test.py @@ -1,7 +1,12 @@ import time +import logging import ptf.testutils as testutils +import ptf.packet as scapy +from ptf.mask import Mask from dhcp_relay_test import DHCPTest +logger = logging.getLogger(__name__) + class DHCPContinuousStressTest(DHCPTest): """ @@ -37,3 +42,245 @@ def runTest(self): self.send_packet_with_interval(dhcp_request, client_port) for server_port in self.server_port_indices: self.send_packet_with_interval(dhcp_ack, server_port) + + +class DHCPStressDiscoverTest(DHCPTest): + def __init__(self): + DHCPTest.__init__(self) + + def setUp(self): + DHCPTest.setUp(self) + self.packets_send_duration = self.test_params["packets_send_duration"] + self.client_packets_per_sec = self.test_params["client_packets_per_sec"] + + # Simulate client coming on VLAN and broadcasting a DHCPDISCOVER message + def client_send_discover_stress(self, dst_mac, src_port): + # Form and send DHCPDISCOVER packet + dhcp_discover = self.create_dhcp_discover_packet(dst_mac, src_port) + end_time = time.time() + self.packets_send_duration + while time.time() < end_time: + testutils.send_packet(self, self.client_port_index, dhcp_discover) + time.sleep(1/self.client_packets_per_sec) + + def count_relayed_discover(self): + # Create a packet resembling a relayed DCHPDISCOVER packet + dhcp_discover_relayed = self.create_dhcp_discover_relayed_packet() + + # Mask off fields we don't care about matching + masked_discover = Mask(dhcp_discover_relayed) + masked_discover.set_do_not_care_scapy(scapy.Ether, "dst") + + masked_discover.set_do_not_care_scapy(scapy.IP, "version") + masked_discover.set_do_not_care_scapy(scapy.IP, "ihl") + masked_discover.set_do_not_care_scapy(scapy.IP, "tos") + masked_discover.set_do_not_care_scapy(scapy.IP, "len") + masked_discover.set_do_not_care_scapy(scapy.IP, "id") + masked_discover.set_do_not_care_scapy(scapy.IP, "flags") + masked_discover.set_do_not_care_scapy(scapy.IP, "frag") + masked_discover.set_do_not_care_scapy(scapy.IP, "ttl") + masked_discover.set_do_not_care_scapy(scapy.IP, "proto") + masked_discover.set_do_not_care_scapy(scapy.IP, "chksum") + masked_discover.set_do_not_care_scapy(scapy.IP, "src") + masked_discover.set_do_not_care_scapy(scapy.IP, "dst") + masked_discover.set_do_not_care_scapy(scapy.IP, "options") + + masked_discover.set_do_not_care_scapy(scapy.UDP, "chksum") + masked_discover.set_do_not_care_scapy(scapy.UDP, "len") + + masked_discover.set_do_not_care_scapy(scapy.BOOTP, "sname") + masked_discover.set_do_not_care_scapy(scapy.BOOTP, "file") + + discover_count = testutils.count_matched_packets_all_ports( + self, masked_discover, self.server_port_indices) + return discover_count + + def runTest(self): + self.client_send_discover_stress(self.dest_mac_address, self.client_udp_src_port) + discover_cnt = self.count_relayed_discover() + + # At the end of the test, overwrite the file with discover count. + try: + with open('/tmp/dhcp_stress_test_discover.json', 'w') as result_file: + result_file.write(str(discover_cnt)) + except Exception as e: + logger.error("Failed to write to the discover file: %s", repr(e)) + + +class DHCPStressOfferTest(DHCPTest): + def __init__(self): + DHCPTest.__init__(self) + + def setUp(self): + DHCPTest.setUp(self) + self.packets_send_duration = self.test_params["packets_send_duration"] + self.client_packets_per_sec = self.test_params["client_packets_per_sec"] + + # Simulate client coming on VLAN and broadcasting a DHCPOFFER message + def client_send_offer_stress(self): + dhcp_offer = self.create_dhcp_offer_packet() + end_time = time.time() + self.packets_send_duration + while time.time() < end_time: + testutils.send_packet(self, self.server_port_indices[0], dhcp_offer) + time.sleep(1/self.client_packets_per_sec) + + def count_relayed_offer(self): + # Create a packet resembling a relayed DCHPOFFER packet + dhcp_offer_relayed = self.create_dhcp_offer_relayed_packet() + + # Mask off fields we don't care about matching + masked_offer = Mask(dhcp_offer_relayed) + + masked_offer.set_do_not_care_scapy(scapy.IP, "version") + masked_offer.set_do_not_care_scapy(scapy.IP, "ihl") + masked_offer.set_do_not_care_scapy(scapy.IP, "tos") + masked_offer.set_do_not_care_scapy(scapy.IP, "len") + masked_offer.set_do_not_care_scapy(scapy.IP, "id") + masked_offer.set_do_not_care_scapy(scapy.IP, "flags") + masked_offer.set_do_not_care_scapy(scapy.IP, "frag") + masked_offer.set_do_not_care_scapy(scapy.IP, "ttl") + masked_offer.set_do_not_care_scapy(scapy.IP, "proto") + masked_offer.set_do_not_care_scapy(scapy.IP, "chksum") + masked_offer.set_do_not_care_scapy(scapy.IP, "options") + masked_offer.set_do_not_care_scapy(scapy.IP, "src") + masked_offer.set_do_not_care_scapy(scapy.IP, "dst") + + masked_offer.set_do_not_care_scapy(scapy.UDP, "len") + masked_offer.set_do_not_care_scapy(scapy.UDP, "chksum") + + masked_offer.set_do_not_care_scapy(scapy.BOOTP, "sname") + masked_offer.set_do_not_care_scapy(scapy.BOOTP, "file") + + offer_count = testutils.count_matched_packets(self, masked_offer, self.client_port_index) + return offer_count + + def runTest(self): + self.client_send_offer_stress() + offer_cnt = self.count_relayed_offer() + + # At the end of the test, overwrite the file with offer count. + try: + with open('/tmp/dhcp_stress_test_offer.json', 'w') as result_file: + result_file.write(str(offer_cnt)) + except Exception as e: + logger.error("Failed to write to the offer file: %s", repr(e)) + + +class DHCPStressRequestTest(DHCPTest): + def __init__(self): + DHCPTest.__init__(self) + + def setUp(self): + DHCPTest.setUp(self) + self.packets_send_duration = self.test_params["packets_send_duration"] + self.client_packets_per_sec = self.test_params["client_packets_per_sec"] + + # Simulate client coming on VLAN and broadcasting a DHCPREQUEST message + def client_send_request_stress(self, dst_mac, src_port): + # Form and send DHCPREQUEST packet + dhcp_request = self.create_dhcp_request_packet(dst_mac, src_port) + end_time = time.time() + self.packets_send_duration + while time.time() < end_time: + testutils.send_packet(self, self.client_port_index, dhcp_request) + time.sleep(1/self.client_packets_per_sec) + + def count_relayed_request(self): + # Create a packet resembling a relayed DCHPREQUEST packet + dhcp_request_relayed = self.create_dhcp_request_relayed_packet() + + # Mask off fields we don't care about matching + masked_request = Mask(dhcp_request_relayed) + masked_request.set_do_not_care_scapy(scapy.Ether, "dst") + + masked_request.set_do_not_care_scapy(scapy.IP, "version") + masked_request.set_do_not_care_scapy(scapy.IP, "ihl") + masked_request.set_do_not_care_scapy(scapy.IP, "tos") + masked_request.set_do_not_care_scapy(scapy.IP, "len") + masked_request.set_do_not_care_scapy(scapy.IP, "id") + masked_request.set_do_not_care_scapy(scapy.IP, "flags") + masked_request.set_do_not_care_scapy(scapy.IP, "frag") + masked_request.set_do_not_care_scapy(scapy.IP, "ttl") + masked_request.set_do_not_care_scapy(scapy.IP, "proto") + masked_request.set_do_not_care_scapy(scapy.IP, "chksum") + masked_request.set_do_not_care_scapy(scapy.IP, "src") + masked_request.set_do_not_care_scapy(scapy.IP, "dst") + masked_request.set_do_not_care_scapy(scapy.IP, "options") + + masked_request.set_do_not_care_scapy(scapy.UDP, "chksum") + masked_request.set_do_not_care_scapy(scapy.UDP, "len") + + masked_request.set_do_not_care_scapy(scapy.BOOTP, "sname") + masked_request.set_do_not_care_scapy(scapy.BOOTP, "file") + + request_count = testutils.count_matched_packets_all_ports( + self, masked_request, self.server_port_indices) + return request_count + + def runTest(self): + self.client_send_request_stress(self.dest_mac_address, self.client_udp_src_port) + request_cnt = self.count_relayed_request() + + # At the end of the test, overwrite the file with request count. + try: + with open('/tmp/dhcp_stress_test_request.json', 'w') as result_file: + result_file.write(str(request_cnt)) + except Exception as e: + logger.error("Failed to write to the request file: %s", repr(e)) + + +class DHCPStressAckTest(DHCPTest): + def __init__(self): + DHCPTest.__init__(self) + + def setUp(self): + DHCPTest.setUp(self) + self.packets_send_duration = self.test_params["packets_send_duration"] + self.client_packets_per_sec = self.test_params["client_packets_per_sec"] + + # Simulate client coming on VLAN and broadcasting a DHCPACK message + def client_send_ack_stress(self): + dhcp_ack = self.create_dhcp_ack_packet() + end_time = time.time() + self.packets_send_duration + while time.time() < end_time: + testutils.send_packet(self, self.server_port_indices[0], dhcp_ack) + time.sleep(1/self.client_packets_per_sec) + + def count_relayed_ack(self): + # Create a packet resembling a relayed DCHPACK packet + dhcp_ack_relayed = self.create_dhcp_ack_relayed_packet() + + # Mask off fields we don't care about matching + masked_ack = Mask(dhcp_ack_relayed) + + masked_ack.set_do_not_care_scapy(scapy.IP, "version") + masked_ack.set_do_not_care_scapy(scapy.IP, "ihl") + masked_ack.set_do_not_care_scapy(scapy.IP, "tos") + masked_ack.set_do_not_care_scapy(scapy.IP, "len") + masked_ack.set_do_not_care_scapy(scapy.IP, "id") + masked_ack.set_do_not_care_scapy(scapy.IP, "flags") + masked_ack.set_do_not_care_scapy(scapy.IP, "frag") + masked_ack.set_do_not_care_scapy(scapy.IP, "ttl") + masked_ack.set_do_not_care_scapy(scapy.IP, "proto") + masked_ack.set_do_not_care_scapy(scapy.IP, "chksum") + masked_ack.set_do_not_care_scapy(scapy.IP, "options") + masked_ack.set_do_not_care_scapy(scapy.IP, "src") + masked_ack.set_do_not_care_scapy(scapy.IP, "dst") + + masked_ack.set_do_not_care_scapy(scapy.UDP, "len") + masked_ack.set_do_not_care_scapy(scapy.UDP, "chksum") + + masked_ack.set_do_not_care_scapy(scapy.BOOTP, "sname") + masked_ack.set_do_not_care_scapy(scapy.BOOTP, "file") + + ack_count = testutils.count_matched_packets(self, masked_ack, self.client_port_index) + return ack_count + + def runTest(self): + self.client_send_ack_stress() + ack_cnt = self.count_relayed_ack() + + # At the end of the test, overwrite the file with ack count. + try: + with open('/tmp/dhcp_stress_test_ack.json', 'w') as result_file: + result_file.write(str(ack_cnt)) + except Exception as e: + logger.error("Failed to write to the ack file: %s", repr(e)) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 22aaddb7495..04dade44e36 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -363,6 +363,27 @@ dhcp_relay/test_dhcp_relay.py::test_dhcp_relay_unicast_mac: - "'dualtor' in topo_name and release in ['201811', '201911']" - "platform in ['x86_64-8111_32eh_o-r0']" +dhcp_relay/test_dhcp_relay_stress.py::test_dhcp_relay_stress: + skip: + reason: "1. Need to skip for platform armhf-nokia_ixs7215_52x-r0 due to buffer issues + 2. Need to skip for KVM due to low performance" + conditions_logical_operator: or + conditions: + - "platform in ['armhf-nokia_ixs7215_52x-r0']" + - "asic_type in ['vs']" + +dhcp_relay/test_dhcp_relay_stress.py::test_dhcp_relay_stress[discover]: + skip: + reason: "Testcase ignored due to github issue: https://github.com/sonic-net/sonic-mgmt/issues/14851" + conditions: + - "https://github.com/sonic-net/sonic-mgmt/issues/14851" + +dhcp_relay/test_dhcp_relay_stress.py::test_dhcp_relay_stress[request]: + skip: + reason: "Testcase ignored due to github issue: https://github.com/sonic-net/sonic-mgmt/issues/14851" + conditions: + - "https://github.com/sonic-net/sonic-mgmt/issues/14851" + dhcp_relay/test_dhcpv6_relay.py: skip: reason: "Need to skip for platform x86_64-8111_32eh_o-r0" diff --git a/tests/dhcp_relay/test_dhcp_relay_stress.py b/tests/dhcp_relay/test_dhcp_relay_stress.py index 5b12051b7fa..edfd94761ef 100644 --- a/tests/dhcp_relay/test_dhcp_relay_stress.py +++ b/tests/dhcp_relay/test_dhcp_relay_stress.py @@ -1,11 +1,12 @@ import pytest import time +import ptf.packet as scapy from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor_m # noqa F401 from tests.dhcp_relay.dhcp_relay_utils import restart_dhcp_service from tests.common.helpers.assertions import pytest_assert, pytest_require -from tests.common.utilities import wait_until +from tests.common.utilities import wait_until, capture_and_check_packet_on_dut from tests.ptf_runner import ptf_runner pytestmark = [ @@ -15,6 +16,7 @@ BROADCAST_MAC = 'ff:ff:ff:ff:ff:ff' DEFAULT_DHCP_CLIENT_PORT = 68 +DEFAULT_DHCP_SERVER_PORT = 67 def test_dhcp_relay_restart_with_stress(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config, @@ -95,3 +97,120 @@ def _check_socket_buffer(): "uplink_mac": str(dut_dhcp_relay_data[0]['uplink_mac']), "testing_mode": testing_mode}, log_file="/tmp/dhcp_relay_test.stress.DHCPTest.log", is_python3=True) + + +def check_dhcp_stress_status(duthost, test_duration_seconds): + # Monitor DHCP status during the test + start_time = time.time() + sleep_time = 30 + while time.time() - start_time < test_duration_seconds - sleep_time: + # Check the status of the DHCP container + dhcp_container_status = duthost.shell('docker ps | grep dhcp_relay')["stdout"] + if dhcp_container_status == "": + assert False, "DHCP container is NOT running." + + # Check CPU usage of the DHCP process + dhcp_cpu_usage = duthost.shell('show processes cpu --verbose | grep dhc | awk \'{print $9}\'')["stdout"] + if dhcp_cpu_usage: + dhcp_cpu_usage_lines = dhcp_cpu_usage.splitlines() + for cpu_usage in dhcp_cpu_usage_lines: + cpu_usage_float = float(cpu_usage) + assert cpu_usage_float < 50.0, "DHCP CPU usage is too high: {}%".format(cpu_usage_float) + + # Check the status of multiple DHCP processes inside the container + dhcp_process_status = duthost.shell( + 'docker exec dhcp_relay supervisorctl status | grep dhcp | grep -v dhcp6')["stdout"] + if dhcp_process_status: + dhcp_process_status_lines = dhcp_process_status.splitlines() + for dhcp_process_status_line in dhcp_process_status_lines: + process_name, process_status = dhcp_process_status_line.split()[0], dhcp_process_status_line.split()[1], + assert process_status == "RUNNING", "{} is not running!".format(process_name) + time.sleep(sleep_time) + + +@pytest.mark.parametrize('dhcp_type', ['discover', 'offer', 'request', 'ack']) +def test_dhcp_relay_stress(ptfhost, ptfadapter, dut_dhcp_relay_data, validate_dut_routes_exist, + testing_config, dhcp_type, clean_processes_after_stress_test): + """Test DHCP relay functionality on T0 topology + and verify that HCP relay service can handle the maximum load without failure. + """ + testing_mode, duthost = testing_config + packets_send_duration = 120 + client_packets_per_sec = 10000 + + for dhcp_relay in dut_dhcp_relay_data: + client_port_name = str(dhcp_relay['client_iface']['name']) + client_port_id = dhcp_relay['client_iface']['port_idx'] + client_mac = ptfadapter.dataplane.get_mac(0, client_port_id).decode('utf-8') + server_port_name = dhcp_relay['uplink_interfaces'][0] + server_mac = ptfadapter.dataplane.get_mac(0, dhcp_relay['uplink_port_indices'][0]).decode('utf-8') + num_dhcp_servers = len(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs']) + params = { + "hostname": duthost.hostname, + "client_port_index": client_port_id, + "client_iface_alias": str(dhcp_relay['client_iface']['alias']), + "other_client_ports": repr(dhcp_relay['other_client_ports']), + "leaf_port_indices": repr(dhcp_relay['uplink_port_indices']), + "num_dhcp_servers": len(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs']), + "server_ip": dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs'], + "relay_iface_ip": str(dhcp_relay['downlink_vlan_iface']['addr']), + "relay_iface_mac": str(dhcp_relay['downlink_vlan_iface']['mac']), + "relay_iface_netmask": str(dhcp_relay['downlink_vlan_iface']['mask']), + "dest_mac_address": BROADCAST_MAC, + "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, + "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], + "uplink_mac": str(dhcp_relay['uplink_mac']), + "packets_send_duration": packets_send_duration, + "client_packets_per_sec": client_packets_per_sec, + "testing_mode": testing_mode + } + count_file = '/tmp/dhcp_stress_test_{}.json'.format(dhcp_type) + + def _check_count_file_exists(): + command = 'ls {} > /dev/null 2>&1 && echo exists || echo missing'.format(count_file) + output = ptfhost.shell(command) + return not output['rc'] and output['stdout'].strip() == "exists" + + def _verify_server_packets(pkts): + actual_count = len([pkt for pkt in pkts if pkt[scapy.BOOTP].xid == 0]) * num_dhcp_servers + lower_bound = int(exp_count * 0.9) + upper_bound = int(exp_count * 1.1) + pytest_assert(lower_bound <= actual_count <= upper_bound, + "Mismatch: DUT count = {}, PTF count = {}.".format(actual_count, exp_count)) + + def _verify_client_packets(pkts): + actual_count = len([pkt for pkt in pkts if pkt[scapy.BOOTP].xid == 0]) + lower_bound = int(exp_count * 0.9) + upper_bound = int(exp_count * 1.1) + pytest_assert(lower_bound <= actual_count <= upper_bound, + "Mismatch: DUT count = {}, PTF count = {}.".format(actual_count, exp_count)) + + if dhcp_type in ['discover', 'request']: + interface = client_port_name + eth_src = client_mac + pkts_validator = _verify_server_packets + else: + interface = server_port_name + eth_src = server_mac + pkts_validator = _verify_client_packets + + with capture_and_check_packet_on_dut( + duthost=duthost, interface=interface, + pkts_filter="ether src %s and udp dst port %s" % (eth_src, DEFAULT_DHCP_SERVER_PORT), + pkts_validator=pkts_validator + ): + ptf_runner(ptfhost, "ptftests", "dhcp_relay_stress_test.DHCPStress{}Test".format(dhcp_type.capitalize()), + platform_dir="ptftests", params=params, + log_file="/tmp/dhcp_relay_stress_test.DHCPStressTest.log", + qlen=100000, is_python3=True, async_mode=True) + check_dhcp_stress_status(duthost, packets_send_duration) + pytest_assert(wait_until(600, 2, 0, _check_count_file_exists), "{} is missing".format(count_file)) + exp_count = int(ptfhost.shell('cat {}'.format(count_file))['stdout'].strip()) + ptfhost.shell('rm -f {}'.format(count_file)) + + +@pytest.fixture(scope="function") +def clean_processes_after_stress_test(ptfhost): + yield + ptfhost.shell("kill -9 $(ps aux | grep dhcp_relay_stress_test | grep -v 'grep' | awk '{print $2}')", + module_ignore_errors=True) From 9ba782072ec85c35f6c79f990f556e59f6eda08b Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Wed, 30 Oct 2024 02:37:32 +0800 Subject: [PATCH 007/221] Enhance generic hash script packet sending function (#14139) 1. In case of a weak nic, when packet is not received, resend the packet 2. Loop more times to make hash result more stable Change-Id: I89bfa1e4de43e281d82d736b102dc33a55a8e089 --- .../test/files/ptftests/py3/generic_hash_test.py | 13 +++++++++++-- tests/hash/generic_hash_helper.py | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ansible/roles/test/files/ptftests/py3/generic_hash_test.py b/ansible/roles/test/files/ptftests/py3/generic_hash_test.py index e73b2349b32..09c6699ef9f 100644 --- a/ansible/roles/test/files/ptftests/py3/generic_hash_test.py +++ b/ansible/roles/test/files/ptftests/py3/generic_hash_test.py @@ -379,8 +379,17 @@ def check_ip_route(self, pkt, masked_expected_pkt, sending_port): send the packet and check it is received by one of the expected ports """ testutils.send_packet(self, sending_port, pkt) - port_index, received = testutils.verify_packet_any_port( - self, masked_expected_pkt, self.expected_port_list, timeout=0.1) + try: + port_index, received = testutils.verify_packet_any_port( + self, masked_expected_pkt, self.expected_port_list, timeout=0.1) + except AssertionError: + logging.error("Traffic wasn't sent successfully, trying again") + logging.info(f"Expected packet: {masked_expected_pkt}") + for _ in range(5): + testutils.send_packet(self, sending_port, pkt, count=1) + time.sleep(0.1) + port_index, received = testutils.verify_packet_any_port( + self, masked_expected_pkt, self.expected_port_list, timeout=1) # The port_index is the index of expected_port_list, need to convert it to the ptf port index return self.expected_port_list[port_index], received diff --git a/tests/hash/generic_hash_helper.py b/tests/hash/generic_hash_helper.py index c5acb8afff7..b487284828a 100644 --- a/tests/hash/generic_hash_helper.py +++ b/tests/hash/generic_hash_helper.py @@ -58,7 +58,7 @@ l2_ports = set() vlans_to_remove = [] interfaces_to_startup = [] -balancing_test_times = 240 +balancing_test_times = 480 balancing_range = 0.25 balancing_range_in_port = 0.8 vxlan_ecmp_utils = VxLAN_Ecmp_Utils() From 8437245ee40b8079d60c4f481864b3deff331cb3 Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Wed, 30 Oct 2024 02:38:52 +0800 Subject: [PATCH 008/221] Exclude 0x0800 from the ethernet type range to fix RM #4064894 (#14738) Exclude 0x0800 from the ethernet type range to fix RM #4064894 Change-Id: Iddaf60ab6db516e776a3dc2524dda61fdee7b50c --- ansible/roles/test/files/ptftests/py3/generic_hash_test.py | 2 +- tests/hash/generic_hash_helper.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible/roles/test/files/ptftests/py3/generic_hash_test.py b/ansible/roles/test/files/ptftests/py3/generic_hash_test.py index 09c6699ef9f..467176dfa66 100644 --- a/ansible/roles/test/files/ptftests/py3/generic_hash_test.py +++ b/ansible/roles/test/files/ptftests/py3/generic_hash_test.py @@ -78,7 +78,7 @@ def setUp(self): self.ecmp_hash = self.test_params['ecmp_hash'] self.lag_hash = self.test_params['lag_hash'] self.vlan_range = self.test_params.get('vlan_range', [1032, 1060]) - self.ethertype_range = self.test_params.get('ethertype_range', [0x0800, 0x0900]) + self.ethertype_range = self.test_params.get('ethertype_range', [0x0801, 0x0900]) self.is_l2_test = self.test_params.get('is_l2_test', False) self.encap_type = self.test_params.get('encap_type') self.vxlan_port = self.test_params.get('vxlan_port', self.VXLAN_PORT) diff --git a/tests/hash/generic_hash_helper.py b/tests/hash/generic_hash_helper.py index b487284828a..df1625db8b0 100644 --- a/tests/hash/generic_hash_helper.py +++ b/tests/hash/generic_hash_helper.py @@ -22,7 +22,7 @@ 'None': {'src': [], 'dst': []}} PTF_QLEN = 20000 VLAN_RANGE = [1032, 1060] -ETHERTYPE_RANGE = [0x0800, 0x0900] +ETHERTYPE_RANGE = [0x0801, 0x0900] ENCAPSULATION = ['ipinip', 'vxlan', 'nvgre'] MELLANOX_SUPPORTED_HASH_ALGORITHM = ['CRC', 'CRC_CCITT'] DEFAULT_SUPPORTED_HASH_ALGORITHM = ['CRC', 'CRC_CCITT', 'RANDOM', 'XOR'] From a97f4a7a91a5c260588d09fe09b6142770769820 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:30:04 -0700 Subject: [PATCH 009/221] Fixing test_multidut_snappi. (#15037) Description of PR Summary: Minor fixes to test_multidut_snappi.py to make it pass in cisco-8000. Approach What is the motivation for this PR? There are minor issues in test_multidut_snappi.py that had caused it to fail in cisco-8000. This PR aims to fix these issues. How did you verify the change =========================================================================================================================== PASSES =========================================================================================================================== ______________________________________________________________________________________________________________ test_snappi[multidut_port_info0] ______________________________________________________________________________________________________________ ----------------------------------------------------------------------------- generated xml file: /run_logs/ixia/fixed_variables/2024-10-17-22-38-56/tr_2024-10-17-22-38-56.xml -------------------------------------- ---------------------------------------- INFO:root:Can not get Allure report URL. Please check logs --------------------- ---------------------------------------------------------------------------------------------- live log sessionfinish ------ ------------------------------------------------------------------------------------------------------------- 22:47:39 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ================================================================================================================== short test summary info ========================================================================================== ========================= PASSED snappi_tests/test_multidut_snappi.py::test_snappi[multidut_port_info0] ========================================================================================== =============== 1 passed, 4 warnings in 521.32s (0:08:41) ========================================================================================================== sonic@ixia-sonic-mgmt-whitebox:/data/tests$ co-authorized by: jianquanye@microsoft.com --- tests/snappi_tests/test_multidut_snappi.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/snappi_tests/test_multidut_snappi.py b/tests/snappi_tests/test_multidut_snappi.py index 66b980c4301..84a6bde8c55 100644 --- a/tests/snappi_tests/test_multidut_snappi.py +++ b/tests/snappi_tests/test_multidut_snappi.py @@ -5,10 +5,11 @@ from tests.common.helpers.assertions import pytest_assert, pytest_require from tests.common.fixtures.conn_graph_facts import conn_graph_facts, fanout_graph_facts_multidut # noqa: F401 from tests.common.snappi_tests.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port, snappi_api, \ - snappi_dut_base_config, get_snappi_ports, get_snappi_ports_for_rdma, cleanup_config # noqa: F401 + snappi_dut_base_config, get_snappi_ports, get_snappi_ports_for_rdma, cleanup_config, \ + get_snappi_ports_multi_dut # noqa: F401 from tests.common.snappi_tests.snappi_helpers import wait_for_arp from tests.common.snappi_tests.port import select_ports -from tests.common.snappi_tests.qos_fixtures import prio_dscp_map # noqa: F401 +from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, lossless_prio_list # noqa: F401 from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED logger = logging.getLogger(__name__) SNAPPI_POLL_DELAY_SEC = 2 @@ -18,6 +19,7 @@ @pytest.mark.disable_loganalyzer def __gen_all_to_all_traffic(testbed_config, + duthosts, port_config_list, conn_data, fanout_data, @@ -25,7 +27,11 @@ def __gen_all_to_all_traffic(testbed_config, prio_dscp_map # noqa: F811 ): - rate_percent = 100 / (len(port_config_list) - 1) + line_rate = 100 + if duthosts[0].facts['asic_type'] == "cisco-8000": + line_rate = 50 + rate_percent = line_rate / (len(port_config_list) - 1) + duration_sec = 2 pkt_size = 1024 @@ -135,7 +141,7 @@ def test_snappi(request, snappi_api) lossless_prio = random.sample(lossless_prio_list, 1) - lossless_prio = int(lossless_prio) + lossless_prio = int(lossless_prio[0]) pytest_require(len(port_config_list) >= 2, "This test requires at least 2 ports") @@ -144,7 +150,8 @@ def test_snappi(request, conn_data=conn_graph_facts, fanout_data=fanout_graph_facts_multidut, priority=int(lossless_prio), - prio_dscp_map=prio_dscp_map) + prio_dscp_map=prio_dscp_map, + duthosts=duthosts) pkt_size = config.flows[0].size.fixed rate_percent = config.flows[0].rate.percentage From 6acc725fdb815e8d983d9300ec6e651c7d00cac4 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:34:33 -0700 Subject: [PATCH 010/221] Move the lossy skip condition above. (#15096) Description of PR Summary: The skip for non-single-asic variant for the test:qos/test_qos_sai.py::ttestQosSaiPgSharedWatermark[wm_pg_shared_lossy] was added by #14892 in the wrong location. We need to move this skip before it checks for the wm_pg_shared_lossy key. Approach What is the motivation for this PR? The keyerror addressed in the PR:#14892 is still occuring, since the skip was added after the Key checking code. This PR moves it up above the Keychecking code. How did you do it? Moved the skip block above. How did you verify/test it? Ran it on my TB: co-authorized by: jianquanye@microsoft.com --- tests/qos/test_qos_sai.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/qos/test_qos_sai.py b/tests/qos/test_qos_sai.py index 4f5e68244bd..06152d3300b 100644 --- a/tests/qos/test_qos_sai.py +++ b/tests/qos/test_qos_sai.py @@ -1610,6 +1610,12 @@ def testQosSaiPgSharedWatermark( else: qosConfig = dutQosConfig["param"] + if dutTestParams["basicParams"].get("platform_asic", None) \ + == "cisco-8000": + if not get_src_dst_asic_and_duts['single_asic_test']: + if pgProfile == "wm_pg_shared_lossy": + pytest.skip("The lossy test is not valid for multiAsic configuration.") + if "wm_pg_shared_lossless" in pgProfile: pktsNumFillShared = qosConfig[pgProfile]["pkts_num_trig_pfc"] elif "wm_pg_shared_lossy" in pgProfile: @@ -1620,12 +1626,6 @@ def testQosSaiPgSharedWatermark( pktsNumFillShared = int( qosConfig[pgProfile]["pkts_num_trig_egr_drp"]) - 1 - if dutTestParams["basicParams"].get("platform_asic", None) \ - == "cisco-8000": - if not get_src_dst_asic_and_duts['single_asic_test']: - if pgProfile == "wm_pg_shared_lossy": - pytest.skip("The lossy test is not valid for multiAsic configuration.") - self.updateTestPortIdIp(dutConfig, get_src_dst_asic_and_duts) testParams = dict() From a20e75209449599c9be754fc13875f023a6b4ae1 Mon Sep 17 00:00:00 2001 From: agadia-cisco Date: Tue, 29 Oct 2024 18:00:20 -0700 Subject: [PATCH 011/221] fix for test_snmp_numpsu failure (#14860) * fix for test_snmp_numpsu tc failure * Trigger Pipeline again --- tests/snmp/test_snmp_psu.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/snmp/test_snmp_psu.py b/tests/snmp/test_snmp_psu.py index 05d2ce4942e..d6ef9907fed 100644 --- a/tests/snmp/test_snmp_psu.py +++ b/tests/snmp/test_snmp_psu.py @@ -31,8 +31,14 @@ def test_snmp_numpsu(duthosts, enum_supervisor_dut_hostname, localhost, creds_al assert int(res['rc']) == 0, "Failed to get number of PSUs" - numpsus = int(res['stdout']) - assert numpsus == len(snmp_facts['snmp_psu']) + output = res["stdout_lines"] + numpsus = None + if len(output): + try: + numpsus = int(output[-1]) + except (IndexError, ValueError): + pass + assert numpsus == len(snmp_facts['snmp_psu']), "PSUs count doesn't match" @pytest.mark.bsl From 9138f1f33143011fbf4b7ef7b9b3033a52ea7813 Mon Sep 17 00:00:00 2001 From: Ashwin Srinivasan <93744978+assrinivasan@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:29:11 -0700 Subject: [PATCH 012/221] Modified ssdhealth test to account for currently supported disk types (#14071) * Modified ssdhealth test to account for currently supported disk types * Print unsupported storage disk type before skipping test --- tests/platform_tests/cli/test_show_platform.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/platform_tests/cli/test_show_platform.py b/tests/platform_tests/cli/test_show_platform.py index f4ecbbc580d..741878c3323 100644 --- a/tests/platform_tests/cli/test_show_platform.py +++ b/tests/platform_tests/cli/test_show_platform.py @@ -447,11 +447,15 @@ def test_show_platform_ssdhealth(duthosts, enum_supervisor_dut_hostname): """ duthost = duthosts[enum_supervisor_dut_hostname] cmd = " ".join([CMD_SHOW_PLATFORM, "ssdhealth"]) + supported_disks = ["SATA", "NVME"] logging.info("Verifying output of '{}' on ''{}'...".format(cmd, duthost.hostname)) + ssdhealth_output_lines = duthost.command(cmd)["stdout_lines"] + if not any(disk_type in ssdhealth_output_lines[0] for disk_type in supported_disks): + pytest.skip("Disk Type {} is not supported".format(ssdhealth_output_lines[0].split(':')[-1])) ssdhealth_dict = util.parse_colon_speparated_lines(ssdhealth_output_lines) - expected_fields = {"Device Model", "Health", "Temperature"} + expected_fields = {"Disk Type", "Device Model", "Health", "Temperature"} actual_fields = set(ssdhealth_dict.keys()) missing_fields = expected_fields - actual_fields From 9a50f9832f427dba6e6e6d9507fa0170f6c2c1b6 Mon Sep 17 00:00:00 2001 From: Matthew Soulsby Date: Wed, 30 Oct 2024 13:27:52 +1100 Subject: [PATCH 013/221] tests-common: Handle PortInUseException for SSHConsoleConn (#15174) What is the motivation for this PR? This PR is intended to add more resilience to the dut_console tests, as if a testbed with a blocked port was selected for a nightly test, it would cause the dut_console tests to fail during setup. This provides a method for auto-recovery for these cases. How did you do it? By completing the following: Add connection types for each of the configuration menu types (Digi, Cisco, and Sonic) to allow for different command sequences to be accounted for Add function to clear a DUT's console port Add retry logic to add resilience to main DUT connection set up How did you verify/test it? This process was conducted on 5 testbeds, with at least one of each config menu type. Steps conducted during testing SSH into testbed using the console IP and console port - simulating a blocked port In a separate terminal, run any dut_console test individually During test setup, the connection from step 1 was terminated successfully The test then runs successfully Example test output Successful port reset (Digi config): Screenshot 2024-10-25 165601 Successful port reset (Sonic config): Screenshot 2024-10-25 183646 Sample failure Simulating config menu type is not defined (causing the port clear function to exit early), and a more descriptive error message is thrown regarding why the connection to the DUT is failing: Screenshot 2024-10-25 153008 Any platform specific information? N/A - this is a generalised solution which accounts for as many types of configuration menus as possible. --- ansible/files/sonic_lab_console_links.csv | 10 +- ansible/library/conn_graph_facts.py | 1 + tests/common/connections/base_console_conn.py | 6 + tests/common/connections/console_host.py | 14 ++- tests/common/connections/ssh_console_conn.py | 43 +++++-- tests/conftest.py | 109 ++++++++++++++++-- 6 files changed, 161 insertions(+), 22 deletions(-) diff --git a/ansible/files/sonic_lab_console_links.csv b/ansible/files/sonic_lab_console_links.csv index 75b8e386604..16926ee064b 100644 --- a/ansible/files/sonic_lab_console_links.csv +++ b/ansible/files/sonic_lab_console_links.csv @@ -1,5 +1,5 @@ -StartDevice,StartPort,EndDevice,Console_type,Proxy,BaudRate -console-1,10,str-msn2700-01,ssh,,9600 -console-2,11,str-7260-10,ssh,,9600 -console-1,12,str-7260-11,ssh,, -management-1,13,str-acs-serv-01,ssh,,9600 +StartDevice,StartPort,EndDevice,Console_type,Console_menu_type,Proxy,BaudRate +console-1,10,str-msn2700-01,ssh,,,9600 +console-2,11,str-7260-10,ssh,,,9600 +console-1,12,str-7260-11,ssh,,, +management-1,13,str-acs-serv-01,ssh,,,9600 diff --git a/ansible/library/conn_graph_facts.py b/ansible/library/conn_graph_facts.py index abc6dfbe16e..2663e94114c 100755 --- a/ansible/library/conn_graph_facts.py +++ b/ansible/library/conn_graph_facts.py @@ -349,6 +349,7 @@ def csv_to_graph_facts(self): "peerport": entry["StartPort"], "proxy": entry["Proxy"], "type": entry["Console_type"], + "menu_type": entry["Console_menu_type"], } } self.graph_facts["console_links"] = console_links diff --git a/tests/common/connections/base_console_conn.py b/tests/common/connections/base_console_conn.py index ec01696e2ab..c82297262c3 100644 --- a/tests/common/connections/base_console_conn.py +++ b/tests/common/connections/base_console_conn.py @@ -21,6 +21,12 @@ CONSOLE_SSH = "console_ssh" # Console login via SSH, then login to devices by 'menu ports' CONSOLE_SSH_MENU_PORTS = "console_ssh_menu_ports" +# Console login via SSH, no stage 2 login (Digi Config Menu) +CONSOLE_SSH_DIGI_CONFIG = "console_ssh_digi_config" +# Console login via SSH, no stage 2 login (SONiC switch config) +CONSOLE_SSH_SONIC_CONFIG = "console_ssh_sonic_config" +# Console login via SSH, no stage 2 login (Cisco switch config) +CONSOLE_SSH_CISCO_CONFIG = "console_ssh_cisco_config" class BaseConsoleConn(CiscoBaseConnection): diff --git a/tests/common/connections/console_host.py b/tests/common/connections/console_host.py index d02f40f0b27..313371e652d 100644 --- a/tests/common/connections/console_host.py +++ b/tests/common/connections/console_host.py @@ -1,11 +1,21 @@ -from .base_console_conn import CONSOLE_SSH, CONSOLE_SSH_MENU_PORTS, CONSOLE_TELNET +from .base_console_conn import ( + CONSOLE_SSH, + CONSOLE_SSH_CISCO_CONFIG, + CONSOLE_SSH_MENU_PORTS, + CONSOLE_TELNET, + CONSOLE_SSH_DIGI_CONFIG, + CONSOLE_SSH_SONIC_CONFIG +) from .telnet_console_conn import TelnetConsoleConn from .ssh_console_conn import SSHConsoleConn ConsoleTypeMapper = { CONSOLE_TELNET: TelnetConsoleConn, CONSOLE_SSH: SSHConsoleConn, - CONSOLE_SSH_MENU_PORTS: SSHConsoleConn + CONSOLE_SSH_MENU_PORTS: SSHConsoleConn, + CONSOLE_SSH_DIGI_CONFIG: SSHConsoleConn, + CONSOLE_SSH_SONIC_CONFIG: SSHConsoleConn, + CONSOLE_SSH_CISCO_CONFIG: SSHConsoleConn, } diff --git a/tests/common/connections/ssh_console_conn.py b/tests/common/connections/ssh_console_conn.py index ecc93b090a9..be53b050d97 100644 --- a/tests/common/connections/ssh_console_conn.py +++ b/tests/common/connections/ssh_console_conn.py @@ -1,6 +1,6 @@ import time import re -from .base_console_conn import BaseConsoleConn, CONSOLE_SSH +from .base_console_conn import CONSOLE_SSH_DIGI_CONFIG, BaseConsoleConn, CONSOLE_SSH from netmiko.ssh_exception import NetMikoAuthenticationException from paramiko.ssh_exception import SSHException @@ -15,10 +15,18 @@ def __init__(self, **kwargs): self.sonic_username = kwargs['sonic_username'] self.sonic_password = kwargs['sonic_password'] - if kwargs['console_type'] == CONSOLE_SSH: + # Store console type for later use + self.console_type = kwargs['console_type'] + + if self.console_type == CONSOLE_SSH: + # Login requires port to be provided kwargs['username'] = kwargs['console_username'] + r':' + str(kwargs['console_port']) self.menu_port = None + elif self.console_type.endswith("config"): + # Login to config menu only requires username + kwargs['username'] = kwargs['console_username'] else: + # Login requires menu port kwargs['username'] = kwargs['console_username'] self.menu_port = kwargs['console_port'] kwargs['password'] = kwargs['console_password'] @@ -30,10 +38,19 @@ def session_preparation(self): session_init_msg = self._test_channel_read() self.logger.debug(session_init_msg) - if re.search(r"Port is in use. Closing connection...", session_init_msg, flags=re.M): + if re.search( + r"(Port is in use. Closing connection...|Cannot connect: line \[\d{2}\] is busy)", + session_init_msg, + flags=re.M + ): console_port = self.username.split(':')[-1] raise PortInUseException(f"Host closed connection, as console port '{console_port}' is currently occupied.") + if self.console_type.endswith("config"): + # We can skip stage 2 login for config menu connections + self.session_preparation_finalise() + return + if (self.menu_port): # For devices logining via menu port, 2 additional login are needed # Since we have attempted all passwords in __init__ of base class until successful login @@ -54,7 +71,18 @@ def session_preparation(self): else: break - self.set_base_prompt() + self.session_preparation_finalise() + + def session_preparation_finalise(self): + """ + Helper function to handle final stages of session preparation. + """ + # Digi config menu has a unique prompt terminator (----->) + if self.console_type == CONSOLE_SSH_DIGI_CONFIG: + self.set_base_prompt(">") + else: + self.set_base_prompt() + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -151,9 +179,10 @@ def login_stage_2(self, raise NetMikoAuthenticationException(msg) def cleanup(self): - # Send an exit to logout from SONiC - self.send_command(command_string="exit", - expect_string="login:") + # If we are in SONiC, send an exit to logout + if not self.console_type.endswith("config"): + self.send_command(command_string="exit", + expect_string="login:") # remote_conn must be closed, or the SSH session will be kept on Digi, # and any other login is prevented self.remote_conn.close() diff --git a/tests/conftest.py b/tests/conftest.py index 1327e2d4504..8a2cff90483 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,6 +18,11 @@ from datetime import datetime from ipaddress import ip_interface, IPv4Interface +from tests.common.connections.base_console_conn import ( + CONSOLE_SSH_CISCO_CONFIG, + CONSOLE_SSH_DIGI_CONFIG, + CONSOLE_SSH_SONIC_CONFIG +) from tests.common.fixtures.conn_graph_facts import conn_graph_facts # noqa F401 from tests.common.devices.local import Localhost from tests.common.devices.ptf import PTFHost @@ -1883,24 +1888,112 @@ def duthost_console(duthosts, enum_supervisor_dut_hostname, localhost, conn_grap console_host = console_host.split("/")[0] console_port = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['peerport'] console_type = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['type'] + console_menu_type = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['menu_type'] console_username = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['proxy'] - console_type = "console_" + console_type + console_type = f"console_{console_type}" + console_menu_type = f"{console_type}_{console_menu_type}" # console password and sonic_password are lists, which may contain more than one password sonicadmin_alt_password = localhost.host.options['variable_manager']._hostvars[dut_hostname].get( "ansible_altpassword") - host = ConsoleHost(console_type=console_type, - console_host=console_host, - console_port=console_port, - sonic_username=creds['sonicadmin_user'], - sonic_password=[creds['sonicadmin_password'], sonicadmin_alt_password], - console_username=console_username, - console_password=creds['console_password'][console_type]) + sonic_password = [creds['sonicadmin_password'], sonicadmin_alt_password] + + # Attempt to clear the console port + try: + duthost_clear_console_port( + menu_type=console_menu_type, + console_host=console_host, + console_port=console_port, + console_username=console_username, + console_password=creds['console_password'][console_type] + ) + except Exception as e: + logger.warning(f"Issue trying to clear console port: {e}") + + # Set up console host + host = None + for attempt in range(1, 4): + try: + host = ConsoleHost(console_type=console_type, + console_host=console_host, + console_port=console_port, + sonic_username=creds['sonicadmin_user'], + sonic_password=sonic_password, + console_username=console_username, + console_password=creds['console_password'][console_type]) + break + except Exception as e: + logger.warning(f"Attempt {attempt}/3 failed: {e}") + continue + else: + raise Exception("Failed to set up connection to console port. See warning logs for details.") + yield host host.disconnect() +def duthost_clear_console_port( + menu_type: str, + console_host: str, + console_port: str, + console_username: str, + console_password: str +): + """ + Helper function to clear the console port for a given DUT. + Useful when a device has an occupied console port, preventing dut_console tests from running. + + Parameters: + menu_type: Connection type for the console's config menu (as expected by the ConsoleTypeMapper) + console_host: DUT host's console IP address + console_port: DUT host's console port, to be cleared + console_username: Username for the console account (overridden for Digi console) + console_password: Password for the console account + """ + if menu_type == "console_ssh_": + raise Exception("Device does not have a defined Console_menu_type.") + + # Override console user if the configuration menu is Digi, as this requires admin login + console_user = 'admin' if menu_type == CONSOLE_SSH_DIGI_CONFIG else console_username + + duthost_config_menu = ConsoleHost( + console_type=menu_type, + console_host=console_host, + console_port=console_port, + console_username=console_user, + console_password=console_password, + sonic_username=None, + sonic_password=None + ) + + # Command lists for each config menu type + # List of tuples, containing a command to execute, and an optional pattern to wait for + command_list = { + CONSOLE_SSH_DIGI_CONFIG: [ + ('2', None), # Enter serial port config + (console_port, None), # Choose DUT console port + ('a', None), # Enter port management + ('1', f'Port #{console_port} has been reset successfully.') # Reset chosen port + ], + CONSOLE_SSH_SONIC_CONFIG: [ + (f'sudo sonic-clear line {console_port}', None) # Clear DUT console port (requires sudo) + ], + CONSOLE_SSH_CISCO_CONFIG: [ + (f'clear line tty {console_port}', '[confirm]'), # Clear DUT console port + ('', '[OK]') # Confirm selection + ], + } + + for command, wait_for_pattern in command_list[menu_type]: + duthost_config_menu.write_channel(command + duthost_config_menu.RETURN) + duthost_config_menu.read_until_prompt_or_pattern(wait_for_pattern) + + duthost_config_menu.disconnect() + logger.info(f"Successfully cleared console port {console_port}, sleeping for 5 seconds") + time.sleep(5) + + @pytest.fixture(scope='session') def cleanup_cache_for_session(request): """ From d0624833c0f72e4a0f08c834bceab62c360f2be1 Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Wed, 30 Oct 2024 15:02:55 +1100 Subject: [PATCH 014/221] Fix various pfcwd config_db check failure (#15025) Description of PR Summary: Fixes # (issue) 29826096, 29826079, 29808432 Approach What is the motivation for this PR? Currently, for PFCWD, we are setting the config_db a certain way for our test case. However, after the tear down, we do not recover the ConfigDB setting to the original which leads to config_db_check issue How did you do it? This PR attempt to fix test_pfcwd_all_port_storm test_pfcwd_timer_accuracy pfcwd/test_pfc_config Since they're similar How did you verify/test it? I've verified on T2 chassis switch co-authorized by: jianquanye@microsoft.com --- tests/pfcwd/test_pfc_config.py | 8 ++++++-- tests/pfcwd/test_pfcwd_all_port_storm.py | 5 +++++ tests/pfcwd/test_pfcwd_timer_accuracy.py | 13 +++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/pfcwd/test_pfc_config.py b/tests/pfcwd/test_pfc_config.py index dea4d0b8a0e..b5ce414f1bf 100644 --- a/tests/pfcwd/test_pfc_config.py +++ b/tests/pfcwd/test_pfc_config.py @@ -158,11 +158,15 @@ def stop_pfcwd(duthosts, enum_rand_one_per_hwsku_frontend_hostname): Returns: None """ - yield duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] logger.info("--- Stop Pfcwd --") duthost.command("pfcwd stop") + yield + + logger.info("--- Start Pfcwd--") + duthost.command("pfcwd start_default") + @pytest.mark.usefixtures('cfg_setup') class TestPfcConfig(object): @@ -320,7 +324,7 @@ def test_default_cfg_after_load_mg(self, duthosts, enum_rand_one_per_hwsku_front None """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] - config_reload(duthost, config_source='minigraph') + config_reload(duthost, config_source='minigraph', safe_reload=True) # sleep 20 seconds to make sure configuration is loaded time.sleep(20) res = duthost.command('pfcwd show config') diff --git a/tests/pfcwd/test_pfcwd_all_port_storm.py b/tests/pfcwd/test_pfcwd_all_port_storm.py index 8cffd960b6f..89fa4589a8f 100644 --- a/tests/pfcwd/test_pfcwd_all_port_storm.py +++ b/tests/pfcwd/test_pfcwd_all_port_storm.py @@ -85,6 +85,11 @@ def stop_pfcwd(duthosts, enum_rand_one_per_hwsku_frontend_hostname): logger.info("--- Stop Pfcwd --") duthost.command("pfcwd stop") + yield + + logger.info("--- Start Pfcwd --") + duthost.command("pfcwd start_default") + @pytest.fixture(scope='class', autouse=True) def storm_test_setup_restore(setup_pfc_test, enum_fanout_graph_facts, duthosts, # noqa F811 diff --git a/tests/pfcwd/test_pfcwd_timer_accuracy.py b/tests/pfcwd/test_pfcwd_timer_accuracy.py index 72fdabb3220..417df2ec2bf 100644 --- a/tests/pfcwd/test_pfcwd_timer_accuracy.py +++ b/tests/pfcwd/test_pfcwd_timer_accuracy.py @@ -28,8 +28,8 @@ def pfc_queue_idx(pfcwd_timer_setup_restore): yield pfcwd_timer_setup_restore['storm_handle'].pfc_queue_idx -@pytest.fixture(scope='module', autouse=True) -def stop_pfcwd(duthosts, enum_rand_one_per_hwsku_frontend_hostname): +@pytest.fixture(scope='module') +def stop_pfcwd(duthosts, enum_rand_one_per_hwsku_frontend_hostname, core_dump_and_config_check): """ Fixture that stops PFC Watchdog before each test run @@ -40,6 +40,11 @@ def stop_pfcwd(duthosts, enum_rand_one_per_hwsku_frontend_hostname): logger.info("--- Stop Pfcwd --") duthost.command("pfcwd stop") + yield + + logger.info("--- Start Pfcwd --") + duthost.command("pfcwd start_default") + @pytest.fixture(autouse=True) def ignore_loganalyzer_exceptions(enum_rand_one_per_hwsku_frontend_hostname, loganalyzer): @@ -62,9 +67,9 @@ def ignore_loganalyzer_exceptions(enum_rand_one_per_hwsku_frontend_hostname, log yield -@pytest.fixture(scope='class', autouse=True) +@pytest.fixture(scope='module', autouse=True) def pfcwd_timer_setup_restore(setup_pfc_test, enum_fanout_graph_facts, duthosts, # noqa F811 - enum_rand_one_per_hwsku_frontend_hostname, fanouthosts): + enum_rand_one_per_hwsku_frontend_hostname, fanouthosts, stop_pfcwd): """ Fixture that inits the test vars, start PFCwd on ports and cleans up after the test run From c043990b7c36dc0de4753781d6953d0e4d40b5f2 Mon Sep 17 00:00:00 2001 From: agadia-cisco Date: Tue, 29 Oct 2024 23:06:59 -0700 Subject: [PATCH 015/221] Fixes for SNMP Tests Flakiness (#14945) Description of PR Summary: The PR contains changes to snmp_helpers.py which checks whether snmp-subagent process is up or not before proceeding in the test. Accordingly all the snmp tests were updated to accommodate the change. This fixes the SNMP tests failures due to information not gathered in get_snmp_facts. Approach What is the motivation for this PR? It has been observed that without snmp-subagent being up, SNMP tests proceeds to execution causing TC failures because snmp_facts isn't able to capture the device information. How did you do it? Check was added in snmp_helpers ensuring that snmp-subagent is up before calling snmp_facts. All TCs were updated with the change. How did you verify/test it? Had run the changes on 202405 image installed in T0 device & tests passed. co-authorized by: jianquanye@microsoft.com --- tests/cacl/test_cacl_function.py | 8 +++++--- tests/common/helpers/snmp_helpers.py | 19 +++++++++++++++---- tests/mvrf/test_mgmtvrf.py | 2 +- tests/snmp/test_snmp_cpu.py | 4 ++-- tests/snmp/test_snmp_default_route.py | 2 +- tests/snmp/test_snmp_fdb.py | 2 +- tests/snmp/test_snmp_interfaces.py | 6 +++--- tests/snmp/test_snmp_link_local.py | 2 +- tests/snmp/test_snmp_lldp.py | 2 +- tests/snmp/test_snmp_loopback.py | 2 +- tests/snmp/test_snmp_memory.py | 4 ++-- tests/snmp/test_snmp_pfc_counters.py | 2 +- tests/snmp/test_snmp_phy_entity.py | 2 +- tests/snmp/test_snmp_psu.py | 4 ++-- tests/snmp/test_snmp_queue.py | 2 +- tests/snmp/test_snmp_v2mib.py | 2 +- 16 files changed, 39 insertions(+), 26 deletions(-) diff --git a/tests/cacl/test_cacl_function.py b/tests/cacl/test_cacl_function.py index dc4cd8499f8..4a174022c54 100644 --- a/tests/cacl/test_cacl_function.py +++ b/tests/cacl/test_cacl_function.py @@ -34,7 +34,8 @@ def test_cacl_function(duthosts, enum_rand_one_per_hwsku_hostname, localhost, cr logging.warning("Will not check NTP connection. ntplib is not installed.") # Ensure we can gather basic SNMP facts from the device. Should fail on timeout - get_snmp_facts(localhost, + get_snmp_facts(duthost, + localhost, host=dut_mgmt_ip, version="v2c", community=creds['snmp_rocommunity'], @@ -83,7 +84,7 @@ def test_cacl_function(duthosts, enum_rand_one_per_hwsku_hostname, localhost, cr pytest_assert(res.is_failed, "SSH did not timeout when expected. {}".format(res.get('msg', ''))) # Ensure we CANNOT gather basic SNMP facts from the device - res = get_snmp_facts(localhost, host=dut_mgmt_ip, version='v2c', community=creds['snmp_rocommunity'], + res = get_snmp_facts(duthost, localhost, host=dut_mgmt_ip, version='v2c', community=creds['snmp_rocommunity'], module_ignore_errors=True) pytest_assert('ansible_facts' not in res and "No SNMP response received before timeout" in res.get('msg', '')) @@ -114,7 +115,8 @@ def test_cacl_function(duthosts, enum_rand_one_per_hwsku_hostname, localhost, cr duthost.file(path="/tmp/config_service_acls.sh", state="absent") # Ensure we can gather basic SNMP facts from the device once again. Should fail on timeout - get_snmp_facts(localhost, + get_snmp_facts(duthost, + localhost, host=dut_mgmt_ip, version="v2c", community=creds['snmp_rocommunity'], diff --git a/tests/common/helpers/snmp_helpers.py b/tests/common/helpers/snmp_helpers.py index f89b7b7ab49..c187e509f2b 100644 --- a/tests/common/helpers/snmp_helpers.py +++ b/tests/common/helpers/snmp_helpers.py @@ -14,16 +14,27 @@ global_snmp_facts = {} +def is_snmp_subagent_running(duthost): + cmd = "docker exec snmp supervisorctl status snmp-subagent" + output = duthost.shell(cmd) + if "RUNNING" in output["stdout"]: + logger.info("SNMP Sub-Agent is Running") + return True + logger.info("SNMP Sub-Agent is Not Running") + return False + + def _get_snmp_facts(localhost, host, version, community, is_dell, include_swap, module_ignore_errors): snmp_facts = localhost.snmp_facts(host=host, version=version, community=community, is_dell=is_dell, module_ignore_errors=module_ignore_errors, include_swap=include_swap) return snmp_facts -def _update_snmp_facts(localhost, host, version, community, is_dell, include_swap): +def _update_snmp_facts(localhost, host, version, community, is_dell, include_swap, duthost): global global_snmp_facts try: + snmp_subagent_running = is_snmp_subagent_running(duthost) global_snmp_facts = _get_snmp_facts(localhost, host, version, community, is_dell, include_swap, module_ignore_errors=False) except RunAnsibleModuleFail as e: @@ -31,10 +42,10 @@ def _update_snmp_facts(localhost, host, version, community, is_dell, include_swa global_snmp_facts = {} return False - return True + return snmp_subagent_running and True -def get_snmp_facts(localhost, host, version, community, is_dell=False, module_ignore_errors=False, +def get_snmp_facts(duthost, localhost, host, version, community, is_dell=False, module_ignore_errors=False, wait=False, include_swap=False, timeout=DEF_WAIT_TIMEOUT, interval=DEF_CHECK_INTERVAL): if not wait: return _get_snmp_facts(localhost, host, version, community, is_dell, include_swap, module_ignore_errors) @@ -42,7 +53,7 @@ def get_snmp_facts(localhost, host, version, community, is_dell=False, module_ig global global_snmp_facts pytest_assert(wait_until(timeout, interval, 0, _update_snmp_facts, localhost, host, version, - community, is_dell, include_swap), "Timeout waiting for SNMP facts") + community, is_dell, include_swap, duthost), "Timeout waiting for SNMP facts") return global_snmp_facts diff --git a/tests/mvrf/test_mgmtvrf.py b/tests/mvrf/test_mgmtvrf.py index 8a184579fc4..772e1755b0a 100644 --- a/tests/mvrf/test_mgmtvrf.py +++ b/tests/mvrf/test_mgmtvrf.py @@ -176,7 +176,7 @@ def test_ping(self, duthost): duthost.ping() def test_snmp_fact(self, localhost, duthost, creds): - get_snmp_facts(localhost, host=duthost.mgmt_ip, version="v2c", community=creds['snmp_rocommunity']) + get_snmp_facts(duthost, localhost, host=duthost.mgmt_ip, version="v2c", community=creds['snmp_rocommunity']) class TestMvrfOutbound(): diff --git a/tests/snmp/test_snmp_cpu.py b/tests/snmp/test_snmp_cpu.py index e03c34d57ec..101ad1f5352 100644 --- a/tests/snmp/test_snmp_cpu.py +++ b/tests/snmp/test_snmp_cpu.py @@ -39,7 +39,7 @@ def test_snmp_cpu(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_a # Gather facts with SNMP version 2 snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], is_dell=True, wait=True)['ansible_facts'] assert int(snmp_facts['ansible_ChStackUnitCpuUtil5sec']) @@ -53,7 +53,7 @@ def test_snmp_cpu(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_a # Gather facts with SNMP version 2 snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], is_dell=True, wait=True)['ansible_facts'] # Pull CPU utilization via shell diff --git a/tests/snmp/test_snmp_default_route.py b/tests/snmp/test_snmp_default_route.py index 1bb1e371e0a..63d0250a0b7 100644 --- a/tests/snmp/test_snmp_default_route.py +++ b/tests/snmp/test_snmp_default_route.py @@ -21,7 +21,7 @@ def test_snmp_default_route(duthosts, enum_rand_one_per_hwsku_frontend_hostname, hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] dut_result = duthost.shell(r'show ip route 0.0.0.0/0 | grep "\*"') diff --git a/tests/snmp/test_snmp_fdb.py b/tests/snmp/test_snmp_fdb.py index 22a09087d50..711b4bf6ebf 100644 --- a/tests/snmp/test_snmp_fdb.py +++ b/tests/snmp/test_snmp_fdb.py @@ -130,7 +130,7 @@ def test_snmp_fdb_send_tagged(ptfadapter, duthosts, rand_one_dut_hostname, hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] assert 'snmp_fdb' in snmp_facts assert 'snmp_interfaces' in snmp_facts diff --git a/tests/snmp/test_snmp_interfaces.py b/tests/snmp/test_snmp_interfaces.py index 956e13237d2..54a95066a22 100644 --- a/tests/snmp/test_snmp_interfaces.py +++ b/tests/snmp/test_snmp_interfaces.py @@ -168,7 +168,7 @@ def test_snmp_interfaces(localhost, creds_all_duts, duthosts, enum_rand_one_per_ config_facts = duthost.config_facts( host=duthost.hostname, source="persistent", namespace=namespace)['ansible_facts'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] snmp_ifnames = [v['name'] @@ -193,7 +193,7 @@ def test_snmp_mgmt_interface(localhost, creds_all_duts, duthosts, enum_rand_one_ duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] config_facts = duthost.config_facts( host=duthost.hostname, source="persistent")['ansible_facts'] @@ -227,7 +227,7 @@ def test_snmp_interfaces_mibs(duthosts, enum_rand_one_per_hwsku_hostname, localh hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] config_facts = duthost.config_facts( host=duthost.hostname, source="persistent", namespace=namespace)['ansible_facts'] diff --git a/tests/snmp/test_snmp_link_local.py b/tests/snmp/test_snmp_link_local.py index 9b395dda02a..4860eed5eb7 100644 --- a/tests/snmp/test_snmp_link_local.py +++ b/tests/snmp/test_snmp_link_local.py @@ -31,7 +31,7 @@ def test_snmp_link_local_ip(duthosts, hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] # Get link local IP of mamangement interface diff --git a/tests/snmp/test_snmp_lldp.py b/tests/snmp/test_snmp_lldp.py index 7b51fdf112b..dd43dd22aa7 100644 --- a/tests/snmp/test_snmp_lldp.py +++ b/tests/snmp/test_snmp_lldp.py @@ -43,7 +43,7 @@ def test_snmp_lldp(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_ duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] mg_facts = {} for asic_id in duthost.get_asic_ids(): diff --git a/tests/snmp/test_snmp_loopback.py b/tests/snmp/test_snmp_loopback.py index 2ebeb0c18d1..4be95c9fa56 100644 --- a/tests/snmp/test_snmp_loopback.py +++ b/tests/snmp/test_snmp_loopback.py @@ -23,7 +23,7 @@ def test_snmp_loopback(duthosts, enum_rand_one_per_hwsku_frontend_hostname, hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] config_facts = duthost.config_facts( host=duthost.hostname, source="persistent")['ansible_facts'] diff --git a/tests/snmp/test_snmp_memory.py b/tests/snmp/test_snmp_memory.py index 5e7397d8b93..298c9752d9b 100644 --- a/tests/snmp/test_snmp_memory.py +++ b/tests/snmp/test_snmp_memory.py @@ -88,7 +88,7 @@ def test_snmp_memory(duthosts, enum_rand_one_per_hwsku_hostname, localhost, cred # Allow the test to retry a few times before claiming failure. for _ in range(3): snmp_facts = get_snmp_facts( - localhost, host=host_ip, version="v2c", + duthost, localhost, host=host_ip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] facts = collect_memory(duthost) # net-snmp calculate cached memory as cached + sreclaimable @@ -175,7 +175,7 @@ def test_snmp_swap(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds_ "Swap is not on for this device, snmp does not support swap related queries when swap isn't on") snmp_facts = get_snmp_facts( - localhost, host=host_ip, version="v2c", include_swap=True, + duthost, localhost, host=host_ip, version="v2c", include_swap=True, community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] snmp_total_swap = snmp_facts['ansible_sysTotalSwap'] snmp_free_swap = snmp_facts['ansible_sysTotalFreeSwap'] diff --git a/tests/snmp/test_snmp_pfc_counters.py b/tests/snmp/test_snmp_pfc_counters.py index 184fa8fc543..c6fe4449ccc 100644 --- a/tests/snmp/test_snmp_pfc_counters.py +++ b/tests/snmp/test_snmp_pfc_counters.py @@ -14,7 +14,7 @@ def test_snmp_pfc_counters(duthosts, enum_rand_one_per_hwsku_frontend_hostname, duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] # Check PFC counters diff --git a/tests/snmp/test_snmp_phy_entity.py b/tests/snmp/test_snmp_phy_entity.py index dfc6490fe43..18421fbb693 100644 --- a/tests/snmp/test_snmp_phy_entity.py +++ b/tests/snmp/test_snmp_phy_entity.py @@ -209,7 +209,7 @@ def get_entity_and_sensor_mib(duthost, localhost, creds_all_duts): hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] entity_mib = {} sensor_mib = {} diff --git a/tests/snmp/test_snmp_psu.py b/tests/snmp/test_snmp_psu.py index d6ef9907fed..eb7492cc09f 100644 --- a/tests/snmp/test_snmp_psu.py +++ b/tests/snmp/test_snmp_psu.py @@ -20,7 +20,7 @@ def test_snmp_numpsu(duthosts, enum_supervisor_dut_hostname, localhost, creds_al duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] res = duthost.shell("psuutil numpsus", module_ignore_errors=True) @@ -47,7 +47,7 @@ def test_snmp_psu_status(duthosts, enum_supervisor_dut_hostname, localhost, cred hostip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=hostip, version="v2c", + duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] psus_on = 0 diff --git a/tests/snmp/test_snmp_queue.py b/tests/snmp/test_snmp_queue.py index 348e51b7ef5..e80b53c4b18 100644 --- a/tests/snmp/test_snmp_queue.py +++ b/tests/snmp/test_snmp_queue.py @@ -58,7 +58,7 @@ def test_snmp_queues(duthosts, enum_rand_one_per_hwsku_hostname, localhost, cred q_interfaces[intf[intf_idx]] = set() q_interfaces[intf[intf_idx]].add(intf[queue_idx]) - snmp_facts = get_snmp_facts(localhost, host=hostip, version="v2c", + snmp_facts = get_snmp_facts(duthost, localhost, host=hostip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] diff --git a/tests/snmp/test_snmp_v2mib.py b/tests/snmp/test_snmp_v2mib.py index c17d48b0964..0b0540733b9 100644 --- a/tests/snmp/test_snmp_v2mib.py +++ b/tests/snmp/test_snmp_v2mib.py @@ -19,7 +19,7 @@ def test_snmp_v2mib(duthosts, enum_rand_one_per_hwsku_hostname, localhost, creds host_ip = duthost.host.options['inventory_manager'].get_host( duthost.hostname).vars['ansible_host'] snmp_facts = get_snmp_facts( - localhost, host=host_ip, version="v2c", + duthost, localhost, host=host_ip, version="v2c", community=creds_all_duts[duthost.hostname]["snmp_rocommunity"], wait=True)['ansible_facts'] dut_facts = duthost.setup()['ansible_facts'] debian_ver = duthost.shell('cat /etc/debian_version')['stdout'] From fe49de0f2b49a385646399f8d0b3624c4eae6500 Mon Sep 17 00:00:00 2001 From: agadia-cisco Date: Tue, 29 Oct 2024 23:32:01 -0700 Subject: [PATCH 016/221] Configuring Community SNMP Credentials for SNMP TCs (#14926) Description of PR Summary: The PR contains changes to snmp/conftest.py with logic to configure snmp credentials stored in snmp.yml for every host before running any test script. Approach What is the motivation for this PR? If credentials in snmp.yml isn't configured, then the changes in PR configures them before running the tests and restores the original configuration after the TC execution. How did you do it? snmp/conftest.py will now copy the snmp.yml from DUT to UCS (if DUT has snmp.yml) & then it will configure the SNMP credentials for every host via sudo config snmp command. The logic it configures is same as in snmp_yml_to_configdb.py script; where it checks whether the credentials in yml are configured in config_db or not, if the keys are configured but the values are different / the keys are not configured - then it will configure them. Before the test script execution, SNMP is configured, once the execution completes, it reverts the configuration that existed before. How did you verify/test it? Run changes with 202405 image on a T0 setup without snmp credentials configured / with different credentials configured in image and snmp tests passed as expected in all scenarios. co-authorized by: jianquanye@microsoft.com --- tests/snmp/conftest.py | 84 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/tests/snmp/conftest.py b/tests/snmp/conftest.py index 930ecb35cb2..15d47cebd3c 100644 --- a/tests/snmp/conftest.py +++ b/tests/snmp/conftest.py @@ -1,13 +1,95 @@ import pytest from tests.common.utilities import wait_until +import shutil +import yaml + +from tests.common.gu_utils import create_checkpoint, rollback + +SETUP_ENV_CP = "test_setup_checkpoint" @pytest.fixture(scope="module", autouse=True) -def setup_check_snmp_ready(duthosts): +def setup_check_snmp_ready(duthosts, localhost): for duthost in duthosts: assert wait_until(300, 20, 0, duthost.is_service_fully_started, "snmp"), "SNMP service is not running" + # creating checkpoint before any configuration changes + create_checkpoint(duthost, SETUP_ENV_CP) + + snmp_config_path = "/etc/sonic/snmp.yml" + + # copy snmp.yml to ucs + output = duthost.shell("sudo find /etc/sonic -name 'snmp.yml'") + filename = output["stdout"].split("\n") + + if snmp_config_path in filename: + ret = duthost.fetch(src=snmp_config_path, dest=".") + ret_bin = ret.get("dest", None) + shutil.copyfile(ret_bin, "snmp/snmp.yml") + else: + assert False, f'{snmp_config_path} does not exist' + + # configure snmp for every host + full_snmp_comm_list = ['snmp_rocommunity', 'snmp_rocommunities', 'snmp_rwcommunity', 'snmp_rwcommunities'] + with open('./snmp/snmp.yml', 'r') as yaml_file: + yaml_snmp_info = yaml.load(yaml_file, Loader=yaml.FullLoader) + + # get redis output for SNMP_COMMUNITY & SNMP_LOCATION + snmp_comm_redis_keys = check_redis_output(duthost, 'SNMP_COMMUNITY') + snmp_comm_redis_vals = list(map(extract_redis_keys, snmp_comm_redis_keys)) + snmp_location_redis_keys = check_redis_output(duthost, 'SNMP|LOCATION') + snmp_location_redis_vals = list(map(extract_redis_keys, snmp_location_redis_keys)) + + for comm_type in full_snmp_comm_list: + if comm_type in yaml_snmp_info.keys(): + if comm_type.startswith('snmp_rocommunities'): + for community in yaml_snmp_info[comm_type]: + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'ro'") # set snmp cli + + elif comm_type.startswith('snmp_rocommunity'): + community = yaml_snmp_info[comm_type] + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'ro'") # set snmp cli + + elif comm_type.startswith('snmp_rwcommunities'): + for community in yaml_snmp_info[comm_type]: + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'rw'") # set snmp cli + + elif comm_type.startswith('snmp_rwcommunity'): + community = yaml_snmp_info[comm_type] + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'rw'") # set snmp cli + + yaml_snmp_location = yaml_snmp_info.get('snmp_location') + if yaml_snmp_location: + if 'LOCATION' not in snmp_location_redis_vals: + duthost.shell(f'sudo config snmp location add {yaml_snmp_location}') # set snmp cli + + yield + + # rollback configuration + rollback(duthost, SETUP_ENV_CP) + + # remove snmp files downloaded + local_command = "find ./snmp/ -type f -name 'snmp.yml' -exec rm -f {} +" + localhost.shell(local_command) + + +def extract_redis_keys(item): + return item.split('|')[1] + + +def check_redis_output(duthost, key): + snmp_redis_keys = duthost.shell(f"redis-cli -n 4 keys '{key}*'") + if snmp_redis_keys["stdout"] == "": + return [] + else: + snmp_redis_keys = snmp_redis_keys["stdout"].split("\n") + return snmp_redis_keys + @pytest.fixture(scope="module", autouse=True) def enable_queue_counterpoll_type(duthosts): From 5c52fd583b616e02219e2d586ed0fb7a409ff6aa Mon Sep 17 00:00:00 2001 From: dypet Date: Wed, 30 Oct 2024 01:29:15 -0600 Subject: [PATCH 017/221] Add Cisco Smartswitch hswku to select src/dst ports in qos_sai_base.py (#15034) * Add smartswitch hswku to check in qos_sai_base.py * Fix formatting for Flake8. * Fix indentation. --- tests/qos/qos_sai_base.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/qos/qos_sai_base.py b/tests/qos/qos_sai_base.py index 90dd5d17219..9f474d89276 100644 --- a/tests/qos/qos_sai_base.py +++ b/tests/qos/qos_sai_base.py @@ -781,7 +781,8 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids, dst_ srcPorts = [random.choice(src_port_ids)] else: srcPorts = [1] - if get_src_dst_asic_and_duts["src_asic"].sonichost.facts["hwsku"] == "Cisco-8101-O8C48": + if (get_src_dst_asic_and_duts["src_asic"].sonichost.facts["hwsku"] + in ["Cisco-8101-O8C48", "Cisco-8102-28FH-DPU-O-T1"]): srcPorts = [testPortIds[0][0].index(uplinkPortIds[0])] dstPorts = [testPortIds[0][0].index(x) for x in uplinkPortIds[1:4]] logging.debug("Test Port dst:{}, src:{}".format(dstPorts, srcPorts)) @@ -1027,8 +1028,9 @@ def dutConfig( # If the leaf router is using separated DSCP_TO_TC_MAP on uplink/downlink ports. # we also need to test them separately if (use_separated_upkink_dscp_tc_map or - get_src_dst_asic_and_duts["src_asic"].sonichost.facts["hwsku"] == - "Cisco-8101-O8C48"): + (get_src_dst_asic_and_duts["src_asic"] + .sonichost.facts["hwsku"] + in ["Cisco-8101-O8C48", "Cisco-8102-28FH-DPU-O-T1"])): neighName = src_mgFacts["minigraph_neighbors"].get(portName, {}).get("name", "").lower() if 't0' in neighName: downlinkPortIds.append(portIndex) From a2cb51d57314a0e208d878c002713817e06c9286 Mon Sep 17 00:00:00 2001 From: sanjair-git <114024719+sanjair-git@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:31:19 -0400 Subject: [PATCH 018/221] [T2-Chassis] - New tests for Reliable-TSA feature (#13290) * New tests for Reliable-TSA feature --- tests/bgp/bgp_helpers.py | 62 +- tests/bgp/route_checker.py | 2 +- tests/bgp/test_reliable_tsa.py | 1884 +++++++++++++++++++++ tests/bgp/test_startup_tsa_tsb_service.py | 535 +++--- tests/bgp/test_traffic_shift.py | 43 +- tests/bgp/test_traffic_shift_sup.py | 15 +- 6 files changed, 2331 insertions(+), 210 deletions(-) create mode 100644 tests/bgp/test_reliable_tsa.py diff --git a/tests/bgp/bgp_helpers.py b/tests/bgp/bgp_helpers.py index 72d408f2fb1..2eb7e391f61 100644 --- a/tests/bgp/bgp_helpers.py +++ b/tests/bgp/bgp_helpers.py @@ -13,10 +13,13 @@ import ipaddr as ipaddress from tests.common.helpers.assertions import pytest_require from tests.common.helpers.assertions import pytest_assert -from tests.common.helpers.constants import UPSTREAM_NEIGHBOR_MAP, DOWNSTREAM_NEIGHBOR_MAP, DEFAULT_NAMESPACE +from tests.common.helpers.constants import UPSTREAM_NEIGHBOR_MAP, DOWNSTREAM_NEIGHBOR_MAP, DEFAULT_NAMESPACE, \ + DEFAULT_ASIC_ID from tests.common.helpers.parallel import reset_ansible_local_tmp from tests.common.helpers.parallel import parallel_run from tests.common.utilities import wait_until +from tests.bgp.traffic_checker import get_traffic_shift_state +from tests.bgp.constants import TS_NORMAL BASE_DIR = os.path.dirname(os.path.realpath(__file__)) DUT_TMP_DIR = os.path.join('tmp', os.path.basename(BASE_DIR)) @@ -845,3 +848,60 @@ def fetch_and_delete_pcap_file(bgp_pcap, log_dir, duthost, request): duthost.fetch(src=bgp_pcap, dest=local_pcap_filename, flat=True) duthost.file(path=bgp_pcap, state="absent") return local_pcap_filename + + +def get_tsa_chassisdb_config(duthost): + """ + @summary: Returns the dut's CHASSIS_APP_DB value for BGP_DEVICE_GLOBAL.STATE.tsa_enabled flag + """ + tsa_conf = duthost.shell('sonic-db-cli CHASSIS_APP_DB HGET \'BGP_DEVICE_GLOBAL|STATE\' tsa_enabled')['stdout'] + return tsa_conf + + +def get_sup_cfggen_tsa_value(suphost): + """ + @summary: Returns the supervisor sonic-cfggen value for BGP_DEVICE_GLOBAL.STATE.tsa_enabled flag + """ + tsa_conf = suphost.shell('sonic-cfggen -d -v BGP_DEVICE_GLOBAL.STATE.tsa_enabled')['stdout'] + return tsa_conf + + +def verify_dut_configdb_tsa_value(duthost): + """ + @summary: Returns the line cards' asic CONFIG_DB value for BGP_DEVICE_GLOBAL.STATE.tsa_enabled flag + """ + tsa_config = list() + tsa_enabled = False + for asic_index in duthost.get_frontend_asic_ids(): + prefix = "-n asic{}".format(asic_index) if asic_index != DEFAULT_ASIC_ID else '' + output = duthost.shell('sonic-db-cli {} CONFIG_DB HGET \'BGP_DEVICE_GLOBAL|STATE\' \'tsa_enabled\''. + format(prefix))['stdout'] + tsa_config.append(output) + if 'true' in tsa_config: + tsa_enabled = True + + return tsa_enabled + + +def initial_tsa_check_before_and_after_test(duthosts): + """ + @summary: Common method to make sure the supervisor and line cards are in normal state before and after the test + """ + for duthost in duthosts: + if duthost.is_supervisor_node(): + # Initially make sure both supervisor and line cards are in BGP operational normal state + if get_tsa_chassisdb_config(duthost) != 'false' or get_sup_cfggen_tsa_value(duthost) != 'false': + duthost.shell('TSB') + duthost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(duthost), + "Supervisor {} tsa_enabled config is enabled".format(duthost.hostname)) + + for linecard in duthosts.frontend_nodes: + # Issue TSB on the line card before proceeding further + if verify_dut_configdb_tsa_value(linecard) is not False or get_tsa_chassisdb_config(linecard) != 'false' or \ + get_traffic_shift_state(linecard, cmd='TSC no-stats') != TS_NORMAL: + linecard.shell('TSB') + linecard.shell('sudo config save -y') + # Ensure that the DUT is not in maintenance already before start of the test + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state") diff --git a/tests/bgp/route_checker.py b/tests/bgp/route_checker.py index 9b0fdfb9808..ea0555839d4 100644 --- a/tests/bgp/route_checker.py +++ b/tests/bgp/route_checker.py @@ -2,7 +2,7 @@ import ipaddr as ipaddress import re import json -from bgp_helpers import parse_rib +from tests.bgp.bgp_helpers import parse_rib from tests.common.devices.eos import EosHost from tests.common.helpers.assertions import pytest_assert from tests.common.helpers.parallel import parallel_run diff --git a/tests/bgp/test_reliable_tsa.py b/tests/bgp/test_reliable_tsa.py new file mode 100644 index 00000000000..e956d6ef26a --- /dev/null +++ b/tests/bgp/test_reliable_tsa.py @@ -0,0 +1,1884 @@ +import logging +import pytest + +from tests.common import reboot, config_reload +from tests.common.reboot import wait_for_startup +from tests.common.helpers.assertions import pytest_assert +from tests.common.utilities import wait_until +from tests.common.platform.processes_utils import wait_critical_processes, _all_critical_processes_healthy +from tests.common.platform.interface_utils import check_interface_status_of_up_ports +from tests.bgp.bgp_helpers import get_tsa_chassisdb_config, get_sup_cfggen_tsa_value, verify_dut_configdb_tsa_value +from tests.bgp.traffic_checker import get_traffic_shift_state +from tests.bgp.route_checker import parse_routes_on_neighbors, check_and_log_routes_diff, \ + verify_current_routes_announced_to_neighs, verify_only_loopback_routes_are_announced_to_neighs +from tests.bgp.constants import TS_NORMAL, TS_MAINTENANCE +from tests.bgp.test_startup_tsa_tsb_service import get_tsa_tsb_service_uptime, get_tsa_tsb_service_status, \ + get_startup_tsb_timer, enable_disable_startup_tsa_tsb_service # noqa: F401 + +pytestmark = [ + pytest.mark.topology('t2') +] + +logger = logging.getLogger(__name__) + +CONTAINER_CHECK_INTERVAL_SECS = 2 +CONTAINER_STOP_THRESHOLD_SECS = 60 +CONTAINER_RESTART_THRESHOLD_SECS = 300 +PROGRAM_STATUS = "RUNNING" +BGP_CRIT_PROCESS = "bgpcfgd" +supported_tsa_configs = ['false', 'true'] + + +def nbrhosts_to_dut(duthost, nbrhosts): + """ + @summary: Fetch the neighbor hosts' details for duthost + @returns: dut_nbrhosts dict + """ + mg_facts = duthost.minigraph_facts(host=duthost.hostname)['ansible_facts'] + dut_nbrhosts = {} + for host in nbrhosts.keys(): + if host in mg_facts['minigraph_devices']: + new_nbrhost = {host: nbrhosts[host]} + dut_nbrhosts.update(new_nbrhost) + return dut_nbrhosts + + +@pytest.fixture +def enable_disable_bgp_autorestart_state(duthosts): + """ + @summary: enable/disable bgp feature autorestart state during OC run. + After test_pretest, autorestart status of bgp feature is disabled. This fixture + enables autorestart state of bgp before test start and disables once the test is done. + Args: + duthosts: Fixture returns a list of Ansible object DuT. + Returns: + None. + """ + # Enable autorestart status for bgp feature to overcome pretest changes + for duthost in duthosts.frontend_nodes: + feature_list, _ = duthost.get_feature_status() + bgp_autorestart_state = duthost.get_container_autorestart_states()['bgp'] + for feature, status in list(feature_list.items()): + if feature == 'bgp' and status == 'enabled' and bgp_autorestart_state == 'disabled': + duthost.shell("sudo config feature autorestart {} enabled".format(feature)) + break + yield + + # Disable autorestart status for bgp feature as in pretest + for duthost in duthosts.frontend_nodes: + feature_list, _ = duthost.get_feature_status() + bgp_autorestart_state = duthost.get_container_autorestart_states()['bgp'] + for feature, status in list(feature_list.items()): + if feature == 'bgp' and status == 'enabled' and bgp_autorestart_state == 'enabled': + duthost.shell("sudo config feature autorestart {} disabled".format(feature)) + break + + +def set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname): + """ + @summary: Common method to make sure the supervisor and line cards are in normal state before and after the test + """ + suphost = duthosts[enum_supervisor_dut_hostname] + # Initially make sure both supervisor and line cards are in BGP operational normal state + if get_tsa_chassisdb_config(suphost) != 'false' or get_sup_cfggen_tsa_value(suphost) != 'false': + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + for linecard in duthosts.frontend_nodes: + # Issue TSB on line card before proceeding further + if verify_dut_configdb_tsa_value(linecard) is not False or get_tsa_chassisdb_config(linecard) != 'false' or \ + get_traffic_shift_state(linecard, cmd='TSC no-stats') != TS_NORMAL: + linecard.shell('TSB') + linecard.shell('sudo config save -y') + # Ensure that the DUT is not in maintenance already before start of the test + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state") + + +def verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes): + """ + @summary: Verify all routes are announced to neighbors in TSB + """ + for linecard in duthosts.frontend_nodes: + # Wait until all routes are announced to neighbors + cur_v4_routes = {} + cur_v6_routes = {} + # Verify that all routes advertised to neighbor at the start of the test + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, linecard, dut_nbrhosts[linecard], + orig_v4_routes[linecard], cur_v4_routes, 4): + if not check_and_log_routes_diff(linecard, dut_nbrhosts[linecard], + orig_v4_routes[linecard], cur_v4_routes, 4): + pytest.fail("Not all ipv4 routes are announced to neighbors") + + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, linecard, dut_nbrhosts[linecard], + orig_v6_routes[linecard], cur_v6_routes, 6): + if not check_and_log_routes_diff(linecard, dut_nbrhosts[linecard], + orig_v6_routes[linecard], cur_v6_routes, 6): + pytest.fail("Not all ipv6 routes are announced to neighbors") + + +def kill_process_by_pid(duthost, container_name, program_name, program_pid): + """ + @summary: Kill a process in the specified container by its pid + """ + kill_cmd_result = duthost.shell("docker exec {} kill -SIGKILL {}".format(container_name, program_pid)) + + # Get the exit code of 'kill' command + exit_code = kill_cmd_result["rc"] + pytest_assert(exit_code == 0, "Failed to stop program '{}' before test".format(program_name)) + + logger.info("Program '{}' in container '{}' was stopped successfully" + .format(program_name, container_name)) + + +def get_program_info(duthost, container_name, program_name): + """ + @summary: Get program running status and its pid by analyzing the command + output of "docker exec supervisorctl status" + @return: Program running status and its pid + """ + program_status = None + program_pid = -1 + + program_list = duthost.shell("docker exec {} supervisorctl status". + format(container_name), module_ignore_errors=True) + for program_info in program_list["stdout_lines"]: + if program_info.find(program_name) != -1: + program_status = program_info.split()[1].strip() + if program_status == "RUNNING": + program_pid = int(program_info.split()[3].strip(',')) + break + + if program_pid != -1: + logger.info("Found program '{}' in the '{}' state with pid {}" + .format(program_name, program_status, program_pid)) + + return program_status, program_pid + + +def is_process_running(duthost, container_name, program_name): + """ + @summary: Determine whether a process under container is in the expected state (running/not running) + @returns: True if its running and false if its not + """ + global PROGRAM_STATUS + program_status, _ = get_program_info(duthost, container_name, program_name) + PROGRAM_STATUS = program_status + if program_status == "RUNNING": + return True + elif program_status in ["EXITED", "STOPPED", "STARTING"]: + return False + else: + pytest.fail("Failed to find program '{}' in container '{}'" + .format(program_name, container_name)) + + +def restart_bgp(duthost, container_name, service_name, program_name, program_pid): + """ + @summary: Kill a critical process in a container to verify whether the container + is stopped and restarted correctly + """ + global PROGRAM_STATUS + pytest_assert(wait_until(40, 3, 0, is_process_running, duthost, container_name, program_name), + "Program '{}' in container '{}' is in the '{}' state, expected 'RUNNING'" + .format(program_name, container_name, PROGRAM_STATUS)) + + kill_process_by_pid(duthost, container_name, program_name, program_pid) + logger.info("Waiting until container '{}' is stopped...".format(container_name)) + stopped = wait_until(CONTAINER_STOP_THRESHOLD_SECS, + CONTAINER_CHECK_INTERVAL_SECS, + 0, + check_container_state, duthost, container_name, False) + pytest_assert(stopped, "Failed to stop container '{}'".format(container_name)) + logger.info("Container '{}' was stopped".format(container_name)) + + logger.info("Waiting until container '{}' is restarted...".format(container_name)) + restarted = wait_until(CONTAINER_RESTART_THRESHOLD_SECS, + CONTAINER_CHECK_INTERVAL_SECS, + 0, + check_container_state, duthost, container_name, True) + if not restarted: + if is_hiting_start_limit(duthost, service_name): + clear_failed_flag_and_restart(duthost, service_name, container_name) + else: + pytest.fail("Failed to restart container '{}'".format(container_name)) + + logger.info("Container '{}' was restarted".format(container_name)) + + +def is_container_running(duthost, container_name): + """ + @summary: Decide whether the container is running or not + @return: Boolean value. True represents the container is running + """ + result = duthost.shell("docker inspect -f \{{\{{.State.Running\}}\}} {}".format(container_name)) # noqa: W605 + return result["stdout_lines"][0].strip() == "true" + + +def check_container_state(duthost, container_name, should_be_running): + """ + @summary: Determine whether a container is in the expected state (running/not running) + """ + is_running = is_container_running(duthost, container_name) + return is_running == should_be_running + + +def is_hiting_start_limit(duthost, service_name): + """ + @summary: Determine whether the service can not be restarted is due to + start-limit-hit or not + """ + service_status = duthost.shell("sudo systemctl status {}.service | grep 'Active'".format(service_name)) + for line in service_status["stdout_lines"]: + if "start-limit-hit" in line: + return True + + return False + + +def clear_failed_flag_and_restart(duthost, service_name, container_name): + """ + @summary: If a container hits the restart limitation, then we clear the failed flag and + restart it. + """ + logger.info("{} hits start limit and clear reset-failed flag".format(service_name)) + duthost.shell("sudo systemctl reset-failed {}.service".format(service_name)) + duthost.shell("sudo systemctl start {}.service".format(service_name)) + restarted = wait_until(300, 1, 0, check_container_state, duthost, container_name, True) + pytest_assert(restarted, "Failed to restart container '{}' after reset-failed was cleared".format(container_name)) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsa_act_when_sup_duts_on_tsb_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, nbrhosts, # noqa: F811 + traffic_shift_community, tbinfo): + """ + Test supervisor TSA action when supervisor and line cards are in TSB initially + Verify supervisor config state changes to TSA and Line card BGP TSA operational state changes to TSA from TSB + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Issue TSA from supervisor and verify line cards' BGP operational state changes to TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + for linecard in duthosts.frontend_nodes: + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsa_act_when_sup_on_tsb_duts_on_tsa_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSA action when supervisor is on TSB and line cards are in TSA initially + Verify supervisor config state changes to TSA and Line card BGP TSA operational state maintains TSA + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Convert line cards to BGP operational TSA state for the current test as initial config + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + + # Now Issue TSA from supervisor and make sure it changes from TSB->TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + for linecard in duthosts.frontend_nodes: + # Verify DUT continues to be in maintenance state even with supervisor TSA action + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard), + "DUT is not in maintenance state with supervisor TSA action") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsb_act_when_sup_on_tsa_duts_on_tsb_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSB action when supervisor is on TSA and line cards are in TSB configuration initially but with + BGP operational TSA states + Verify supervisor config state changes to TSB and Line card BGP TSA operational state changes to TSB from TSA + Make sure only loopback routes are advertised to neighbors during line cards' TSA state and all routes are + announced back to neighbors when the line cards are back to TSB. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Confirm all the line cards are in BGP operational TSA state due to supervisor TSA + for linecard in duthosts.frontend_nodes: + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Issue TSB on the supervisor + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + # Verify line cards change the state to TSB from TSA after supervisor TSB + for linecard in duthosts.frontend_nodes: + # Verify DUT changes to normal state with supervisor TSB action + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), + "DUT is not in normal state with supervisor TSB action") + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsb_act_when_sup_and_duts_on_tsa_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSB action when supervisor and line cards are in TSA configuration initially + Verify supervisor config state changes to TSB and Line card BGP TSA operational state is maintained + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + # Similarly keep line cards in TSA mode to start with as part of the test + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + + # Issue TSB on the supervisor + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + # Verify line cards maintains the BGP operational TSA state but with chassisdb tsa-enabled config as 'false' + # in sync with supervisor + for linecard in duthosts.frontend_nodes: + # Verify DUT continues to be in maintenance state even with supervisor TSB action + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsa_act_when_sup_duts_on_tsb_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSA action when supervisor and line cards are in TSB initially + Verify line card config state changes to TSA and BGP TSA operational state changes to TSA from TSB + Verify supervisor card continues to be in TSB + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Issue TSA from line card and verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Verify supervisor still has tsa_enabled 'false' config + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsa_act_when_sup_on_tsa_duts_on_tsb_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSA action when supervisor is on TSA and line cards are in TSB initially + Verify line card config state changes to TSA and BGP TSA operational state maintains its TSA state + Verify supervisor card continues to be in TSA config + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Confirm all the line cards are in BGP operational TSA state due to supervisor TSA + for linecard in duthosts.frontend_nodes: + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Verify line card config TSA enabled is still false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + + # Issue TSA from line card and verify line cards' BGP operational state continues to be in TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Verify supervisor still has tsa_enabled 'true' config + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsb_act_when_sup_on_tsb_duts_on_tsa_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSB action when supervisor is on TSB and line cards are in TSA initially + Verify line card config state changes to TSB and BGP TSA operational state changes to TSB from TSA + Verify supervisor card continues to be in TSB config + Make sure only loopback routes are advertised to neighbors during line cards' TSA state and all routes are + announced back to neighbors when the line cards are back to TSB. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSB mode to start with as part of the test + # And keep the line cards in TSA and verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Issue TSB from line card and verify line cards' BGP operational state changes to TSB + for linecard in duthosts.frontend_nodes: + linecard.shell('TSB') + linecard.shell('sudo config save -y') + # Verify line card config changed to tsa_enabled false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in normal state + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + # Make sure all routes are advertised back to neighbors after TSB on line cards + for linecard in duthosts.frontend_nodes: + # Wait until all routes are announced to neighbors + cur_v4_routes = {} + cur_v6_routes = {} + # Verify that all routes advertised to neighbor at the start of the test + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, linecard, + dut_nbrhosts[linecard], + orig_v4_routes[linecard], cur_v4_routes, 4): + if not check_and_log_routes_diff(linecard, dut_nbrhosts[linecard], + orig_v4_routes[linecard], cur_v4_routes, 4): + pytest.fail("Not all ipv4 routes are announced to neighbors") + + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, linecard, + dut_nbrhosts[linecard], + orig_v6_routes[linecard], cur_v6_routes, 6): + if not check_and_log_routes_diff(linecard, dut_nbrhosts[linecard], + orig_v6_routes[linecard], cur_v6_routes, 6): + pytest.fail("Not all ipv6 routes are announced to neighbors") + + finally: + # Bring back the supervisor and line cards to the normal state at the end of test + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsb_act_when_sup_and_duts_on_tsa_initially(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSB action when supervisor and line cards are in TSA configuration initially + Verify line card config state changes to TSB but the line card BGP TSA operational state is maintained + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Similarly keep line cards in TSA mode to start with as part of the test + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + + # Issue TSB from line card and verify line cards' BGP operational state maintained at TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSB') + linecard.shell('sudo config save -y') + # Verify line card config changed to tsa_enabled false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Verify supervisor still has tsa_enabled 'true' config + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsa_act_with_sup_reboot(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSA action when supervisor and line cards are in TSB initially + Verify supervisor config state changes to TSA and Line card BGP TSA operational state changes to TSA from TSB + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + Then, do 'config save' and reboot supervisor. + After reboot, make sure the BGP TSA operational states are same as before reboot. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + tsa_tsb_timer = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + up_bgp_neighbors = dict() + int_status_result, crit_process_check = dict(), dict() + for linecard in duthosts.frontend_nodes: + tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + int_status_result[linecard] = True + crit_process_check[linecard] = True + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Issue TSA from supervisor and verify line cards' BGP operational state changes to TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + for linecard in duthosts.frontend_nodes: + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Not verifying loopback routes here check since its been checked multiple times with previous test cases + + # Get a dut uptime before reboot + sup_uptime_before = suphost.get_up_time() + # Reboot supervisor and wait for startup_tsa_tsb service to start on line cards + logger.info("Cold reboot on supervisor node: %s", suphost.hostname) + reboot(suphost, localhost, wait=240) + logging.info("Wait until all critical processes are fully started") + wait_critical_processes(suphost) + + sup_uptime = suphost.get_up_time() + logger.info('DUT {} up since {}'.format(suphost.hostname, sup_uptime)) + rebooted = float(sup_uptime_before.strftime("%s")) != float(sup_uptime.strftime("%s")) + assert rebooted, "Device {} did not reboot".format(suphost.hostname) + # verify chassisdb config is same as before reboot + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + for linecard in duthosts.frontend_nodes: + wait_for_startup(linecard, localhost, delay=10, timeout=300) + + # Ensure startup_tsa_tsb service started on expected time since dut rebooted + dut_uptime = linecard.get_up_time() + logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) + service_uptime = get_tsa_tsb_service_uptime(linecard) + time_diff = (service_uptime - dut_uptime).total_seconds() + pytest_assert(int(time_diff) < 120, + "startup_tsa_tsb service started much later than the expected time after dut reboot") + + # Verify DUT is in the same maintenance state like before supervisor reboot + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + + logging.info("Wait until all critical processes are fully started") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") + + # Once all line cards are in maintenance state, proceed further + for linecard in duthosts.frontend_nodes: + # Verify startup_tsa_tsb service stopped after expected time + pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'exited'), + "startup_tsa_tsb service is not stopped even after configured timer expiry") + + # Ensure dut comes back to normal state after timer expiry + if not get_tsa_tsb_service_status(linecard, 'running'): + # Verify dut continues to be in TSA even after startup_tsa_tsb service is stopped + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state after startup_tsa_tsb service is stopped") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify line card config changed to TSB after startup-tsa-tsb service expiry + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + for linecard in duthosts.frontend_nodes: + # Make sure linecards are in Normal state, if not do config-reload on the dut + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats')): + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsa_act_when_duts_on_tsa_with_sup_config_reload(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSA action when supervisor is on TSB and line cards are in TSA initially + Verify supervisor config state changes to TSA and Line card BGP TSA operational state maintained at TSA + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + Then, do config_reload on the supervisor. + After config_relaod, make sure the BGP TSA operational states are same as before. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts, up_bgp_neighbors = dict(), dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Convert line cards to BGP operational TSA state for the current test as initial config + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + + # Now Issue TSA from supervisor and make sure it changes from TSB->TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + for linecard in duthosts.frontend_nodes: + # Verify DUT continues to be in maintenance state even with supervisor TSA action + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard), + "DUT is not in maintenance state with supervisor TSA action") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + + # Do config_reload on the supervisor and verify configs are same as before + config_reload(suphost, wait=300, safe_reload=True) + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Verify line cards traffic shift states are same as before config_reload + for linecard in duthosts.frontend_nodes: + # Verify DUT is in the same maintenance state like before supervisor config reload + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard), + "DUT is not in maintenance state after supervisor config reload") + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled chassisdb config is not enabled".format(linecard.hostname)) + # Before verifying loopback address, make sure IBGP neighbors are in established state + pytest_assert(wait_until(300, 20, 0, linecard.check_bgp_session_state_all_asics, + up_bgp_neighbors[linecard], "established")) + + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsa_act_with_reboot_when_sup_dut_on_tsb_init(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSA action when supervisor and line cards are in TSB initially + Verify line card config state changes to TSA and BGP TSA operational state changes to TSA from TSB + Verify supervisor card continues to be in TSB + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + Then, do 'config save' and reboot the line cards. + After reboot, make sure the BGP TSA operational states are same as before reboot on line cards. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + tsa_tsb_timer = dict() + dut_nbrhosts = dict() + up_bgp_neighbors = dict() + int_status_result, crit_process_check = dict(), dict() + for linecard in duthosts.frontend_nodes: + tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + int_status_result[linecard] = True + crit_process_check[linecard] = True + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Issue TSA from line card and verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + # Verify dut reboot scenario for one of the line card to make sure tsa config is in sync + for linecard in duthosts.frontend_nodes: + logger.info("Cold reboot on node: %s", linecard.hostname) + reboot(linecard, localhost, wait=240) + + for linecard in duthosts.frontend_nodes: + wait_for_startup(linecard, localhost, delay=10, timeout=300) + + # Ensure startup_tsa_tsb service started on expected time since dut rebooted + dut_uptime = linecard.get_up_time() + logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) + service_uptime = get_tsa_tsb_service_uptime(linecard) + time_diff = (service_uptime - dut_uptime).total_seconds() + pytest_assert(int(time_diff) < 120, + "startup_tsa_tsb service started much later than the expected time after dut reboot") + # Verify startup_tsa_tsb service is not started and in exited due to manual TSA + pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'exited'), + "startup_tsa_tsb service is in running state after dut reboot which is not expected") + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify line card config changed is still TSA enabled true after reboot + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + + # Make sure the ports, interfaces are UP and running after reboot + for linecard in duthosts.frontend_nodes: + logging.info("Wait until all critical processes are fully started") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") + + for linecard in duthosts.frontend_nodes: + # Verify only loopback routes are announced to neighbors when the linecards are in TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Verify supervisor still has tsa_enabled 'false' config + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + for linecard in duthosts.frontend_nodes: + # Make sure linecards are in Normal state, if not do config-reload on the dut to recover + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats')): + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsa_with_conf_reload_when_sup_on_tsa_dut_on_tsb_init(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811, E501 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSA action when supervisor is on TSA and line cards are in TSB initially + Verify line card config state changes to TSA and BGP TSA operational state maintains its TSA state + Verify supervisor card continues to be in TSA config + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + Then, do 'config save' and config_reload the line card + After config_reload, make sure the BGP TSA operational states are same as before config reload on line card. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Now Issue TSA from supervisor and make sure it changes from TSB->TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + # Verify line card BGP operational state changes to TSA + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled chassisdb config is not enabled".format(linecard.hostname)) + + # Verify dut config_reload scenario for one of the line card to make sure tsa config is in sync + for linecard in duthosts.frontend_nodes: + linecard.shell('sudo config save -y') + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state after config reload") + + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + break + + # Verify supervisor still has tsa_enabled 'true' config + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_user_init_tsa_on_dut_followed_by_sup_tsa(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test user initiated line card TSA action when supervisor and line cards are in TSB initially + Verify line card config state changes to TSA and BGP TSA operational state changes to TSA from TSB + Verify supervisor card continues to be in TSB + Then, issue TSA on supervisor card. + Verify supervisor and line card chassisdb config state changes to TSA and line card continues to be in + BGP operational TSA state. + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Issue TSA from line card and verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + # Issue TSA from supervisor and verify line cards' BGP operational state continues to be in TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Verify line cards' BGP operational state continues in mainternance state + for linecard in duthosts.frontend_nodes: + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify only loopback routes are announced with TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_user_init_tsa_on_dut_followed_by_sup_tsb(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test user initiated line card TSA action when supervisor and line cards are in TSB initially + Verify line card config state changes to TSA and BGP TSA operational state changes to TSA from TSB + Verify supervisor card continues to be in TSB + Then, issue TSB on supervisor card. + Verify supervisor and line card chassisdb config state changes to TSB and line card continues to be in + BGP operational TSA state. + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Issue TSA from line card and verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + # Issue TSB from supervisor and verify line cards' BGP operational state continues to be in TSA + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + # Verify line cards' BGP operational state continues in mainternance state + for linecard in duthosts.frontend_nodes: + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced with TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsa_when_startup_tsa_tsb_service_running(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSA action when startup-tsa-tsb service is running on line cards after reboot + Verify line card BGP operational state continues to be in TSA after the supervisor TSA action + Verify supervisor card changes to TSA from TSB + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + tsa_tsb_timer = dict() + up_bgp_neighbors = dict() + int_status_result, crit_process_check = dict(), dict() + for linecard in duthosts.frontend_nodes: + tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + int_status_result[linecard] = True + crit_process_check[linecard] = True + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Verify dut reboot scenario for line card to make sure tsa config is in sync + for linecard in duthosts.frontend_nodes: + logger.info("Cold reboot on node: %s", linecard.hostname) + reboot(linecard, localhost, wait=240) + wait_for_startup(linecard, localhost, delay=10, timeout=300) + + # Ensure startup_tsa_tsb service started on expected time since dut rebooted + dut_uptime = linecard.get_up_time() + logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) + service_uptime = get_tsa_tsb_service_uptime(linecard) + time_diff = (service_uptime - dut_uptime).total_seconds() + pytest_assert(int(time_diff) < 120, + "startup_tsa_tsb service started much later than the expected time after dut reboot") + # Verify startup_tsa_tsb service is started and running + pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'running'), + "startup_tsa_tsb service is not in running state after dut reboot") + # Now Issue TSA from supervisor and make sure it changes from TSB->TSA while the service is running + if get_tsa_tsb_service_status(linecard, 'running'): + # Now Issue TSA from supervisor and make sure it changes from TSB->TSA + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify line card config changed to tsa_enabled true during service run + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + + for linecard in duthosts.frontend_nodes: + logging.info("Wait until all critical processes are fully started") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") + + # Verify startup_tsa_tsb service stopped after expected time + pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'exited'), + "startup_tsa_tsb service is not stopped even after configured timer expiry") + + # Ensure dut is still in TSA even after startup-tsa-tsb timer expiry + if get_tsa_tsb_service_status(linecard, 'exited'): + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is in normal state after startup_tsa_tsb service is stopped") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify line card config changed to tsa_enabled false after timer expiry + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced to neighbors at this state + for linecard in duthosts.frontend_nodes: + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + for linecard in duthosts.frontend_nodes: + # Make sure linecards are in Normal state, if not do config-reload on the dut to recover + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats')): + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsb_when_startup_tsa_tsb_service_running(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811 + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSB action when startup-tsa-tsb service is running on line cards after reboot + Verify line card BGP operational state changes to normal from maintenance after supervisor TSB with timer expiry + Make sure only loopback routes are advertised to neighbors during line cards' TSA state and make sure all routes + are advertised back once the line cards are in normal state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + tsa_tsb_timer = dict() + up_bgp_neighbors = dict() + int_status_result, crit_process_check = True, True + for linecard in duthosts.frontend_nodes: + tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Verify dut reboot scenario for one of the line card to make sure tsa config is in sync + for linecard in duthosts.frontend_nodes: + logger.info("Cold reboot on node: %s", linecard.hostname) + reboot(linecard, localhost, wait=240) + wait_for_startup(linecard, localhost, delay=10, timeout=300) + + # Ensure startup_tsa_tsb service started on expected time since dut rebooted + dut_uptime = linecard.get_up_time() + logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) + service_uptime = get_tsa_tsb_service_uptime(linecard) + time_diff = (service_uptime - dut_uptime).total_seconds() + pytest_assert(int(time_diff) < 120, + "startup_tsa_tsb service started much later than the expected time after dut reboot") + # Verify startup_tsa_tsb service is started and running + pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'running'), + "startup_tsa_tsb service is not in running state after dut reboot") + # Now Issue TSB from supervisor and make sure it changes from TSA->TSB + if get_tsa_tsb_service_status(linecard, 'running'): + # Now Issue TSB from supervisor + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + + logging.info("Wait until all critical processes are fully started") + crit_process_check = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") + + # Verify startup_tsa_tsb service stopped after expected time + pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'exited'), + "startup_tsa_tsb service is not stopped even after configured timer expiry") + + # Ensure dut gets back to normal state after startup-tsa-tsb timer expiry + if get_tsa_tsb_service_status(linecard, 'exited'): + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state after startup_tsa_tsb service is stopped") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify line card config changed to tsa_enabled false after timer expiry + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + break + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + for linecard in duthosts.frontend_nodes: + # Make sure linecards are in Normal state, if not do config-reload on the dut to recover + if not (int_status_result and crit_process_check and + TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats')): + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsb_followed_by_dut_bgp_restart_when_sup_on_tsa_duts_on_tsb( + duthosts, localhost, enum_supervisor_dut_hostname, enable_disable_startup_tsa_tsb_service, # noqa: F811 + enable_disable_bgp_autorestart_state, nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSB action when supervisor is on TSA and line cards are in TSB configuration initially but with + BGP operational TSA states + Verify supervisor config state changes to TSB and Line card BGP TSA operational state changes to TSB from TSA + Restart bgp on the line cards and make sure BGP TSA operational state is maintained after docker restart + Make sure only loopback routes are advertised to neighbors during line cards' TSA state and all routes are + announced back to neighbors when the line cards are back to TSB. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Confirm all the line cards are in BGP operational TSA state due to supervisor TSA + for linecard in duthosts.frontend_nodes: + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Issue TSB on the supervisor + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + # Restart bgp on the line cards and check the status + for linecard in duthosts.frontend_nodes: + for asic in linecard.asics: + service_name = asic.get_service_name("bgp") + container_name = asic.get_docker_name("bgp") + logger.info("Restarting {} container on dut {}".format(container_name, linecard.hostname)) + process_status, program_pid = get_program_info(linecard, container_name, BGP_CRIT_PROCESS) + if process_status == "RUNNING": + restart_bgp(linecard, container_name, service_name, BGP_CRIT_PROCESS, program_pid) + + # Verify line cards continues to be in TSB state even after bgp restart + for linecard in duthosts.frontend_nodes: + # Verify DUT changes to normal state with supervisor TSB action + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state with supervisor TSB action") + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_sup_tsb_followed_by_dut_bgp_restart_when_sup_and_duts_on_tsa(duthosts, localhost, enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811, E501 + enable_disable_bgp_autorestart_state, + nbrhosts, traffic_shift_community, tbinfo): + """ + Test supervisor TSB action when supervisor and line cards are in TSA configuration initially + Verify supervisor config state changes to TSB and Line card BGP TSA operational state is maintained + Restart bgp on the line cards and make sure BGP TSA operational state is maintained after docker restart + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + # Similarly keep line cards in TSA mode to start with as part of the test + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + + # Issue TSB on the supervisor + suphost.shell('TSB') + suphost.shell('sudo config save -y') + pytest_assert('false' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is enabled".format(suphost.hostname)) + + # Restart bgp on the line cards and check the status + for linecard in duthosts.frontend_nodes: + for asic in linecard.asics: + service_name = asic.get_service_name("bgp") + container_name = asic.get_docker_name("bgp") + logger.info("Restarting {} container on dut {}".format(container_name, linecard.hostname)) + process_status, program_pid = get_program_info(linecard, container_name, BGP_CRIT_PROCESS) + if process_status == "RUNNING": + restart_bgp(linecard, container_name, service_name, BGP_CRIT_PROCESS, program_pid) + + # Verify line cards maintains the BGP operational TSA state but with chassisdb tsa-enabled config as 'false' + # in sync with supervisor + for linecard in duthosts.frontend_nodes: + # Verify DUT continues to be in maintenance state even with supervisor TSB action + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsb_followed_by_dut_bgp_restart_when_sup_on_tsb_duts_on_tsa(duthosts, localhost, + enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811, E501 + enable_disable_bgp_autorestart_state, + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSB action when supervisor is on TSB and line cards are in TSA initially + Verify line card config state changes to TSB and BGP TSA operational state changes to TSB from TSA + Restart bgp on the line cards and make sure BGP TSA operational state is maintained after docker restart + Verify supervisor card continues to be in TSB config + Make sure only loopback routes are advertised to neighbors during line cards' TSA state and all routes are + announced back to neighbors when the line cards are back to TSB. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + orig_v4_routes, orig_v6_routes = dict(), dict() + dut_nbrhosts = dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in the current TSB mode to start with as part of the test + # And keep the line cards in TSA and verify line cards' BGP operational state changes to TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + # Issue TSB from line card and verify line cards' BGP operational state changes to TSB + for linecard in duthosts.frontend_nodes: + linecard.shell('TSB') + linecard.shell('sudo config save -y') + # Verify line card config changed to tsa_enabled false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in normal state + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + # Restart bgp on the line cards and check the status + for linecard in duthosts.frontend_nodes: + for asic in linecard.asics: + service_name = asic.get_service_name("bgp") + container_name = asic.get_docker_name("bgp") + logger.info("Restarting {} container on dut {}".format(container_name, linecard.hostname)) + process_status, program_pid = get_program_info(linecard, container_name, BGP_CRIT_PROCESS) + if process_status == "RUNNING": + restart_bgp(linecard, container_name, service_name, BGP_CRIT_PROCESS, program_pid) + + # Verify line cards are in the same state as before docker restart + for linecard in duthosts.frontend_nodes: + # Verify line card config changed to tsa_enabled false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('false' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is enabled".format(linecard.hostname)) + + for linecard in duthosts.frontend_nodes: + # Wait until all routes are announced to neighbors + cur_v4_routes = {} + cur_v6_routes = {} + # Verify that all routes advertised to neighbor at the start of the test + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, linecard, + dut_nbrhosts[linecard], + orig_v4_routes[linecard], cur_v4_routes, 4): + if not check_and_log_routes_diff(linecard, dut_nbrhosts[linecard], + orig_v4_routes[linecard], cur_v4_routes, 4): + pytest.fail("Not all ipv4 routes are announced to neighbors") + + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, linecard, + dut_nbrhosts[linecard], + orig_v6_routes[linecard], cur_v6_routes, 6): + if not check_and_log_routes_diff(linecard, dut_nbrhosts[linecard], + orig_v6_routes[linecard], cur_v6_routes, 6): + pytest.fail("Not all ipv6 routes are announced to neighbors") + + finally: + # Bring back the supervisor and line cards to the normal state at the end of test + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + +@pytest.mark.disable_loganalyzer +def test_dut_tsb_followed_by_dut_bgp_restart_when_sup_and_duts_on_tsa(duthosts, localhost, + enum_supervisor_dut_hostname, + enable_disable_startup_tsa_tsb_service, # noqa: F811, E501 + enable_disable_bgp_autorestart_state, + nbrhosts, traffic_shift_community, tbinfo): + """ + Test line card TSB action when supervisor and line cards are in TSA configuration initially + Verify line card config state changes to TSB but the line card BGP TSA operational state is maintained + Restart bgp on the line cards and make sure BGP TSA operational state is continued after docker restart + Make sure only loopback routes are advertised to neighbors during line cards' TSA state. + """ + suphost = duthosts[enum_supervisor_dut_hostname] + if get_tsa_chassisdb_config(suphost) not in supported_tsa_configs: + pytest.skip("Reliable TSA feature is not supported in this image on dut {}".format(suphost.hostname)) + dut_nbrhosts = dict() + orig_v4_routes, orig_v6_routes = dict(), dict() + for linecard in duthosts.frontend_nodes: + dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) + # Initially make sure both supervisor and line cards are in BGP operational normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + try: + # Get the original routes present on the neighbors for each line card + for linecard in duthosts.frontend_nodes: + # Get all routes on neighbors + orig_v4_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 4) + orig_v6_routes[linecard] = parse_routes_on_neighbors(linecard, dut_nbrhosts[linecard], 6) + + # Keep supervisor in TSA mode to start with as part of the test + suphost.shell('TSA') + suphost.shell('sudo config save -y') + pytest_assert('true' == get_tsa_chassisdb_config(suphost), + "Supervisor {} tsa_enabled config is not enabled".format(suphost.hostname)) + + # Similarly keep line cards in TSA mode to start with as part of the test + for linecard in duthosts.frontend_nodes: + linecard.shell('TSA') + linecard.shell('sudo config save -y') + # Verify line card config changed to TSA enabled true + pytest_assert(verify_dut_configdb_tsa_value(linecard) is True, + "DUT {} tsa_enabled config is not enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + + # Issue TSB from line card and verify line cards' BGP operational state maintained at TSA + for linecard in duthosts.frontend_nodes: + linecard.shell('TSB') + linecard.shell('sudo config save -y') + # Verify line card config changed to tsa_enabled false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + + # Restart bgp on the line cards and check the status + for linecard in duthosts.frontend_nodes: + for asic in linecard.asics: + service_name = asic.get_service_name("bgp") + container_name = asic.get_docker_name("bgp") + logger.info("Restarting {} container on dut {}".format(container_name, linecard.hostname)) + process_status, program_pid = get_program_info(linecard, container_name, BGP_CRIT_PROCESS) + if process_status == "RUNNING": + restart_bgp(linecard, container_name, service_name, BGP_CRIT_PROCESS, program_pid) + + # Verify line cards are in the same state as before bgp restart + for linecard in duthosts.frontend_nodes: + # Verify line card config changed to tsa_enabled false + pytest_assert(verify_dut_configdb_tsa_value(linecard) is False, + "DUT {} tsa_enabled config is enabled".format(linecard.hostname)) + # Ensure that the DUT is in maintenance state + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state") + # Ensure line card chassisdb config is in sync with supervisor + pytest_assert('true' == get_tsa_chassisdb_config(linecard), + "{} tsa_enabled config is not enabled".format(linecard.hostname)) + # Verify only loopback routes are announced after TSA + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( + duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), + "Failed to verify routes on nbr in TSA") + + finally: + # Bring back the supervisor and line cards to the normal state + set_tsb_on_sup_duts_before_and_after_test(duthosts, enum_supervisor_dut_hostname) + + # Verify all routes are advertised back to neighbors when duts are in TSB + verify_route_on_neighbors_when_duts_on_tsb(duthosts, dut_nbrhosts, orig_v4_routes, orig_v6_routes) diff --git a/tests/bgp/test_startup_tsa_tsb_service.py b/tests/bgp/test_startup_tsa_tsb_service.py index 87c799f0dbb..2b3e779b328 100644 --- a/tests/bgp/test_startup_tsa_tsb_service.py +++ b/tests/bgp/test_startup_tsa_tsb_service.py @@ -5,14 +5,14 @@ from tests.common.reboot import get_reboot_cause, SONIC_SSH_PORT, SONIC_SSH_REGEX, wait_for_startup from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until -from tests.common.platform.processes_utils import wait_critical_processes +from tests.common.platform.processes_utils import wait_critical_processes, _all_critical_processes_healthy from tests.common.platform.interface_utils import check_interface_status_of_up_ports -from traffic_checker import get_traffic_shift_state, check_tsa_persistence_support -from route_checker import parse_routes_on_neighbors, check_and_log_routes_diff, \ +from tests.bgp.bgp_helpers import initial_tsa_check_before_and_after_test +from tests.bgp.traffic_checker import get_traffic_shift_state, check_tsa_persistence_support +from tests.bgp.route_checker import parse_routes_on_neighbors, check_and_log_routes_diff, \ verify_current_routes_announced_to_neighs, verify_only_loopback_routes_are_announced_to_neighs from tests.bgp.constants import TS_NORMAL, TS_MAINTENANCE - pytestmark = [ pytest.mark.topology('t2') ] @@ -87,8 +87,8 @@ def get_startup_tsb_timer(duthost): module_ignore_errors=True)['stdout'] timer = int(output.split('=', 2)[1].strip().encode('utf-8')) else: - logger.warn("{} file does not exist in the specified path on dut {}". - format(startup_tsa_tsb_file_path, duthost.hostname)) + logger.warning("{} file does not exist in the specified path on dut {}". + format(startup_tsa_tsb_file_path, duthost.hostname)) return timer @@ -175,15 +175,18 @@ def test_tsa_tsb_service_with_dut_cold_reboot(duthosts, localhost, enum_rand_one """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] tsa_tsb_timer = get_startup_tsb_timer(duthost) + int_status_result, crit_process_check = True, True if not tsa_tsb_timer: pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) dut_nbrhosts = nbrhosts_to_dut(duthost, nbrhosts) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") if not check_tsa_persistence_support(duthost): pytest.skip("TSA persistence not supported in the image") + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + try: # Get all routes on neighbors before doing reboot orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) @@ -214,9 +217,13 @@ def test_tsa_tsb_service_with_dut_cold_reboot(duthosts, localhost, enum_rand_one "DUT is not in maintenance state when startup_tsa_tsb service is running") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(duthost) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, duthost), - "Not all ports that are admin up on are operationally up") + crit_process_check = wait_until(600, 20, 0, _all_critical_processes_healthy, duthost) + int_status_result = wait_until(1200, 20, 0, check_interface_status_of_up_ports, duthost) + + # verify bgp sessions are established + pytest_assert( + wait_until(300, 10, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established"), + "All BGP sessions are not up, no point in continuing the test") pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, duthost, dut_nbrhosts, traffic_shift_community), "Failed to verify routes on nbr in TSA") @@ -246,10 +253,14 @@ def test_tsa_tsb_service_with_dut_cold_reboot(duthosts, localhost, enum_rand_one pytest.fail("Not all ipv6 routes are announced to neighbors") finally: - - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + # Verify DUT is in normal state after cold reboot scenario. + if not (int_status_result and crit_process_check and TS_NORMAL == get_traffic_shift_state(duthost)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}".format(int_status_result, crit_process_check, TS_NORMAL)) + logging.info("DUT is not in normal state after cold reboot, doing config-reload") + config_reload(duthost, safe_reload=True, check_intf_up_ports=True) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut") reboot_cause = get_reboot_cause(duthost) @@ -267,16 +278,19 @@ def test_tsa_tsb_service_with_dut_abnormal_reboot(duthosts, localhost, enum_rand """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] tsa_tsb_timer = get_startup_tsb_timer(duthost) + int_status_result, crit_process_check = True, True if not tsa_tsb_timer: pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) dut_nbrhosts = nbrhosts_to_dut(duthost, nbrhosts) dut_ip = duthost.mgmt_ip - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") if not check_tsa_persistence_support(duthost): pytest.skip("TSA persistence not supported in the image") + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + try: # Get all routes on neighbors before doing reboot orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) @@ -323,9 +337,13 @@ def test_tsa_tsb_service_with_dut_abnormal_reboot(duthosts, localhost, enum_rand "DUT is not in maintenance state when startup_tsa_tsb service is running") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(duthost) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, duthost), - "Not all ports that are admin up on are operationally up") + crit_process_check = wait_until(600, 20, 0, _all_critical_processes_healthy, duthost) + int_status_result = wait_until(1200, 20, 0, check_interface_status_of_up_ports, duthost) + + # verify bgp sessions are established + pytest_assert( + wait_until(300, 10, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established"), + "All BGP sessions are not up, no point in continuing the test") pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, duthost, dut_nbrhosts, traffic_shift_community), "Failed to verify routes on nbr in TSA") @@ -355,10 +373,14 @@ def test_tsa_tsb_service_with_dut_abnormal_reboot(duthosts, localhost, enum_rand pytest.fail("Not all ipv6 routes are announced to neighbors") finally: - - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + # Verify DUT is in normal state after abnormal reboot scenario. + if not (int_status_result and crit_process_check and TS_NORMAL == get_traffic_shift_state(duthost)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}".format(int_status_result, crit_process_check, TS_NORMAL)) + logging.info("DUT is not in normal state after abnormal reboot, doing config-reload") + config_reload(duthost, safe_reload=True, check_intf_up_ports=True) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut") reboot_cause = get_reboot_cause(duthost) @@ -377,17 +399,21 @@ def test_tsa_tsb_service_with_supervisor_cold_reboot(duthosts, localhost, enum_s suphost = duthosts[enum_supervisor_dut_hostname] tsa_tsb_timer = dict() dut_nbrhosts = dict() + up_bgp_neighbors = dict() orig_v4_routes, orig_v6_routes = dict(), dict() + int_status_result, crit_process_check = dict(), dict() for linecard in duthosts.frontend_nodes: tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + int_status_result[linecard] = True + crit_process_check[linecard] = True if not tsa_tsb_timer[linecard]: pytest.skip("startup_tsa_tsb.service is not supported on the duts under {}".format(suphost.hostname)) dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT is not in normal state") if not check_tsa_persistence_support(linecard): pytest.skip("TSA persistence not supported in the image") + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) try: for linecard in duthosts.frontend_nodes: @@ -424,9 +450,14 @@ def test_tsa_tsb_service_with_supervisor_cold_reboot(duthosts, localhost, enum_s "DUT is not in maintenance state when startup_tsa_tsb service is running") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(linecard) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, linecard), - "Not all ports that are admin up on are operationally up") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), @@ -461,10 +492,20 @@ def test_tsa_tsb_service_with_supervisor_cold_reboot(duthosts, localhost, enum_s pytest.fail("Not all ipv6 routes are announced to neighbors") finally: + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + # Make sure DUT is in normal state after supervisor cold reboot + for linecard in duthosts.frontend_nodes: + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}". + format(int_status_result[linecard], crit_process_check[linecard], TS_NORMAL)) + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + for linecard in duthosts.frontend_nodes: - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT {} is not in normal state".format(linecard)) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut {}".format(linecard)) reboot_cause = get_reboot_cause(linecard) @@ -490,17 +531,22 @@ def test_tsa_tsb_service_with_supervisor_abnormal_reboot(duthosts, localhost, en sup_ip = suphost.mgmt_ip tsa_tsb_timer = dict() dut_nbrhosts = dict() + up_bgp_neighbors = dict() orig_v4_routes, orig_v6_routes = dict(), dict() + int_status_result, crit_process_check = dict(), dict() for linecard in duthosts.frontend_nodes: tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + int_status_result[linecard] = True + crit_process_check[linecard] = True if not tsa_tsb_timer[linecard]: pytest.skip("startup_tsa_tsb.service is not supported on the duts under {}".format(suphost.hostname)) dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT is not in normal state") if not check_tsa_persistence_support(linecard): pytest.skip("TSA persistence not supported in the image") + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) try: for linecard in duthosts.frontend_nodes: @@ -549,14 +595,23 @@ def test_tsa_tsb_service_with_supervisor_abnormal_reboot(duthosts, localhost, en pytest_assert(int(time_diff) < 120, "startup_tsa_tsb service started much later than the expected time after dut reboot") + # Make sure BGP containers are running properly before verifying + pytest_assert(wait_until(90, 5, 0, check_tsc_command_error, linecard), + "TSC command still returns error even after startup_tsa_tsb service started") + # Verify DUT is in maintenance state. pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard), "DUT is not in maintenance state when startup_tsa_tsb service is running") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(linecard) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, linecard), - "Not all ports that are admin up on are operationally up") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), @@ -591,10 +646,20 @@ def test_tsa_tsb_service_with_supervisor_abnormal_reboot(duthosts, localhost, en pytest.fail("Not all ipv6 routes are announced to neighbors") finally: + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + # Make sure DUT is in normal state after supervisor abnormal reboot + for linecard in duthosts.frontend_nodes: + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}". + format(int_status_result[linecard], crit_process_check[linecard], TS_NORMAL)) + logging.info("DUT is not in normal state after SUP abnormal reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) + for linecard in duthosts.frontend_nodes: - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT {} is not in normal state".format(linecard)) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut {}".format(linecard)) reboot_cause = get_reboot_cause(linecard) @@ -623,12 +688,14 @@ def test_tsa_tsb_service_with_user_init_tsa(duthosts, localhost, enum_rand_one_p pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) dut_nbrhosts = nbrhosts_to_dut(duthost, nbrhosts) orig_v4_routes, orig_v6_routes = {}, {} - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") if not check_tsa_persistence_support(duthost): pytest.skip("TSA persistence not supported in the image") + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + try: # Get all routes on neighbors before doing reboot orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) @@ -664,9 +731,14 @@ def test_tsa_tsb_service_with_user_init_tsa(duthosts, localhost, enum_rand_one_p logging.info("Wait until all critical processes are fully started") wait_critical_processes(duthost) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, duthost), + pytest_assert(wait_until(1200, 20, 0, check_interface_status_of_up_ports, duthost), "Not all ports that are admin up on are operationally up") + # verify bgp sessions are established + pytest_assert( + wait_until(300, 10, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established"), + "All BGP sessions are not up, no point in continuing the test") + pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, duthost, dut_nbrhosts, traffic_shift_community), "Failed to verify routes on nbr in TSA") @@ -702,6 +774,8 @@ def test_tsa_tsb_service_with_user_init_tsa(duthosts, localhost, enum_rand_one_p reboot_cause = get_reboot_cause(duthost) pytest_assert(reboot_cause == COLD_REBOOT_CAUSE, "Reboot cause {} did not match the trigger {}".format(reboot_cause, COLD_REBOOT_CAUSE)) + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) @pytest.mark.disable_loganalyzer @@ -717,15 +791,18 @@ def test_user_init_tsa_while_service_run_on_dut(duthosts, localhost, enum_rand_o """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] tsa_tsb_timer = get_startup_tsb_timer(duthost) + int_status_result, crit_process_check = True, True if not tsa_tsb_timer: pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) dut_nbrhosts = nbrhosts_to_dut(duthost, nbrhosts) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") if not check_tsa_persistence_support(duthost): pytest.skip("TSA persistence not supported in the image") + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + try: # Get all routes on neighbors before doing reboot orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) @@ -768,9 +845,13 @@ def test_user_init_tsa_while_service_run_on_dut(duthosts, localhost, enum_rand_o "DUT is not in maintenance state with saved TSA config after reboot") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(duthost) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, duthost), - "Not all ports that are admin up on are operationally up") + crit_process_check = wait_until(600, 20, 0, _all_critical_processes_healthy, duthost) + int_status_result = wait_until(1200, 20, 0, check_interface_status_of_up_ports, duthost) + + # verify bgp sessions are established + pytest_assert( + wait_until(300, 10, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established"), + "All BGP sessions are not up, no point in continuing the test") pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, duthost, dut_nbrhosts, traffic_shift_community), @@ -785,8 +866,12 @@ def test_user_init_tsa_while_service_run_on_dut(duthosts, localhost, enum_rand_o duthost.shell("TSB") duthost.shell('sudo config save -y') - # Verify DUT comes back to normal state after TSB. - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), "DUT is not in normal state") + # Verify DUT is in normal state after cold reboot scenario. + if not (int_status_result and crit_process_check and TS_NORMAL == get_traffic_shift_state(duthost)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}".format(int_status_result, crit_process_check, TS_NORMAL)) + logging.info("DUT is not in normal state after cold reboot, doing config-reload") + config_reload(duthost, safe_reload=True, check_intf_up_ports=True) # Wait until all routes are announced to neighbors cur_v4_routes = {} cur_v6_routes = {} @@ -806,6 +891,8 @@ def test_user_init_tsa_while_service_run_on_dut(duthosts, localhost, enum_rand_o reboot_cause = get_reboot_cause(duthost) pytest_assert(reboot_cause == COLD_REBOOT_CAUSE, "Reboot cause {} did not match the trigger {}".format(reboot_cause, COLD_REBOOT_CAUSE)) + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) @pytest.mark.disable_loganalyzer @@ -821,14 +908,17 @@ def test_user_init_tsb_while_service_run_on_dut(duthosts, localhost, enum_rand_o """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] tsa_tsb_timer = get_startup_tsb_timer(duthost) + int_status_result, crit_process_check = True, True if not tsa_tsb_timer: pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") if not check_tsa_persistence_support(duthost): pytest.skip("TSA persistence not supported in the image") + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + try: # Get all routes on neighbors before doing reboot orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) @@ -872,6 +962,13 @@ def test_user_init_tsb_while_service_run_on_dut(duthosts, localhost, enum_rand_o # Make sure DUT continues to be in good state after TSB assert wait_until(300, 20, 2, duthost.critical_services_fully_started), \ "Not all critical services are fully started on {}".format(duthost.hostname) + crit_process_check = wait_until(600, 20, 0, _all_critical_processes_healthy, duthost) + int_status_result = wait_until(1200, 20, 0, check_interface_status_of_up_ports, duthost) + + # verify bgp sessions are established + pytest_assert( + wait_until(300, 10, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established"), + "All BGP sessions are not up, no point in continuing the test") # Wait until all routes are announced to neighbors cur_v4_routes = {} @@ -888,10 +985,14 @@ def test_user_init_tsb_while_service_run_on_dut(duthosts, localhost, enum_rand_o pytest.fail("Not all ipv6 routes are announced to neighbors") finally: - - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + # Verify DUT is in normal state after cold reboot scenario. + if not (int_status_result and crit_process_check and TS_NORMAL == get_traffic_shift_state(duthost)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}".format(int_status_result, crit_process_check, TS_NORMAL)) + logging.info("DUT is not in normal state after cold reboot, doing config-reload") + config_reload(duthost, safe_reload=True, check_intf_up_ports=True) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut") @@ -912,19 +1013,24 @@ def test_user_init_tsb_on_sup_while_service_run_on_dut(duthosts, localhost, Make sure TSA_TSB service is stopped and dut changes from maintenance mode to normal mode """ suphost = duthosts[enum_supervisor_dut_hostname] + int_status_result, crit_process_check = dict(), dict() tsa_tsb_timer = dict() dut_nbrhosts = dict() + up_bgp_neighbors = dict() orig_v4_routes, orig_v6_routes = dict(), dict() for linecard in duthosts.frontend_nodes: tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + int_status_result[linecard] = True + crit_process_check[linecard] = True if not tsa_tsb_timer[linecard]: pytest.skip("startup_tsa_tsb.service is not supported on the duts under {}".format(suphost.hostname)) dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT is not in normal state") if not check_tsa_persistence_support(linecard): pytest.skip("TSA persistence not supported in the image") + up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") + + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) try: for linecard in duthosts.frontend_nodes: @@ -961,29 +1067,38 @@ def test_user_init_tsb_on_sup_while_service_run_on_dut(duthosts, localhost, "DUT is not in maintenance state when startup_tsa_tsb service is running") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(linecard) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, linecard), - "Not all ports that are admin up on are operationally up") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 10, check_interface_status_of_up_ports, linecard) + + # verify bgp sessions are established + pytest_assert( + wait_until( + 300, 10, 0, linecard.check_bgp_session_state_all_asics, up_bgp_neighbors[linecard], "established"), + "All BGP sessions are not up, no point in continuing the test") pytest_assert(verify_only_loopback_routes_are_announced_to_neighs( duthosts, linecard, dut_nbrhosts[linecard], traffic_shift_community), "Failed to verify routes on nbr in TSA") - # Execute user initiated TSB from supervisor card - suphost.shell("TSB") + # Issue user initiated TSB on the supervisor + suphost.shell('TSB') for linecard in duthosts.frontend_nodes: - # Ensure dut comes back to normal state - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT is not in normal state after TSB command from supervisor") - - # Ensure startup_tsa_tsb service is in inactive state after user-initiated TSB on supervisor - pytest_assert(wait_until(60, 5, 0, get_tsa_tsb_service_status, linecard, 'inactive'), - "startup_tsa_tsb service is not in inactive state after user init TSB from supervisor") - - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, linecard), - "Not all ports that are admin up on are operationally up") + if get_tsa_tsb_service_status(linecard, 'running'): + # Verify DUT continues to be in maintenance state if the timer is running. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + else: + # Verify DUT continues came back to normal state after timer expiry. + pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard, cmd='TSC no-stats'), + "DUT is not in normal state when startup_tsa_tsb service is running") + + # Ensure startup_tsa_tsb service is in exited state after timer expiry + pytest_assert(wait_until(tsa_tsb_timer[linecard], 5, 0, get_tsa_tsb_service_status, linecard, 'exited'), + "startup_tsa_tsb service is not in exited state after user init TSB from supervisor") + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) + for linecard in duthosts.frontend_nodes: # Wait until all routes are announced to neighbors cur_v4_routes = {} cur_v6_routes = {} @@ -1001,13 +1116,18 @@ def test_user_init_tsb_on_sup_while_service_run_on_dut(duthosts, localhost, pytest.fail("Not all ipv6 routes are announced to neighbors") finally: + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + for linecard in duthosts.frontend_nodes: # Make sure linecards are in Normal state and save the config to proceed further - linecard.shell("TSB") - linecard.shell('sudo config save -y') - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT {} is not in normal state".format(linecard)) + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}". + format(int_status_result[linecard], crit_process_check[linecard], TS_NORMAL)) + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut {}".format(linecard)) reboot_cause = get_reboot_cause(linecard) @@ -1021,6 +1141,115 @@ def test_user_init_tsb_on_sup_while_service_run_on_dut(duthosts, localhost, "Reboot cause {} did not match the trigger {}".format(reboot_cause, COLD_REBOOT_CAUSE)) +@pytest.mark.disable_loganalyzer +def test_tsa_tsb_timer_efficiency(duthosts, localhost, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, + nbrhosts, traffic_shift_community, tbinfo): + """ + Test startup TSA_TSB service after DUT cold reboot + Verify the configured tsa_tsb_timer is sufficient for system to be stable + Verify this service configures TSA and starts a timer and configures TSB once the timer is expired + """ + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + tsa_tsb_timer = get_startup_tsb_timer(duthost) + int_status_result, crit_process_check = True, True + if not tsa_tsb_timer: + pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) + if not check_tsa_persistence_support(duthost): + pytest.skip("TSA persistence not supported in the image") + + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + + try: + # Get all routes on neighbors before doing reboot + orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) + orig_v6_routes = parse_routes_on_neighbors(duthost, nbrhosts, 6) + + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + + # Reboot dut and wait for startup_tsa_tsb service to start + logger.info("Cold reboot on node: %s", duthost.hostname) + reboot(duthost, localhost, wait=240) + + logger.info('Cold reboot finished on {}'.format(duthost.hostname)) + dut_uptime = duthost.get_up_time() + logger.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) + + # Ensure startup_tsa_tsb service is running after dut reboot + pytest_assert(wait_until(60, 5, 0, get_tsa_tsb_service_status, duthost, 'running'), + "startup_tsa_tsb service is not started after reboot") + + # Ensure startup_tsa_tsb service started on expected time since dut rebooted + dut_uptime = duthost.get_up_time() + logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) + service_uptime = get_tsa_tsb_service_uptime(duthost) + time_diff = (service_uptime - dut_uptime).total_seconds() + pytest_assert(int(time_diff) < 120, + "startup_tsa_tsb service started much later than the expected time after dut reboot") + + logging.info("Wait until all critical services are fully started") + pytest_assert(wait_until(300, 20, 2, duthost.critical_services_fully_started)), \ + "Not all critical services are fully started on {}".format(duthost.hostname) + + logging.info("Wait until all critical processes are fully started") + crit_process_check = wait_until(600, 20, 0, _all_critical_processes_healthy, duthost) + int_status_result = wait_until(1200, 20, 0, check_interface_status_of_up_ports, duthost) + + pytest_assert(wait_until(300, 10, 0, + duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established")) + + stability_check_time = datetime.datetime.now() + time_to_stabilize = (stability_check_time - service_uptime).total_seconds() + logging.info("Time taken for system stability : {}".format(time_to_stabilize)) + + # Verify DUT is in maintenance state. + pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(duthost), + "DUT is not in maintenance state when startup_tsa_tsb service is running") + + # Verify startup_tsa_tsb service stopped after expected time + pytest_assert(wait_until(tsa_tsb_timer, 20, 0, get_tsa_tsb_service_status, duthost, 'exited'), + "startup_tsa_tsb service is not stopped even after configured timer expiry") + + # Verify tsa_tsb_timer configured is sufficient + pytest_assert(time_to_stabilize < tsa_tsb_timer, + "Configured tsa_tsb_timer is not sufficient for the system to be stable") + + # Ensure dut comes back to normal state after timer expiry + if not get_tsa_tsb_service_status(duthost, 'running'): + # Verify TSB is configured on the dut after startup_tsa_tsb service is stopped + pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), + "DUT is not in normal state after startup_tsa_tsb service is stopped") + + # Wait until all routes are announced to neighbors + cur_v4_routes = {} + cur_v6_routes = {} + # Verify that all routes advertised to neighbor at the start of the test + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, duthost, nbrhosts, + orig_v4_routes, cur_v4_routes, 4): + if not check_and_log_routes_diff(duthost, nbrhosts, orig_v4_routes, cur_v4_routes, 4): + pytest.fail("Not all ipv4 routes are announced to neighbors") + + if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, duthost, nbrhosts, + orig_v6_routes, cur_v6_routes, 6): + if not check_and_log_routes_diff(duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): + pytest.fail("Not all ipv6 routes are announced to neighbors") + + finally: + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + # Verify DUT is in normal state after cold reboot scenario. + if not (int_status_result and crit_process_check and TS_NORMAL == get_traffic_shift_state(duthost)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}".format(int_status_result, crit_process_check, TS_NORMAL)) + logging.info("DUT is not in normal state after cold reboot, doing config-reload") + config_reload(duthost, safe_reload=True, check_intf_up_ports=True) + # Make sure the dut's reboot cause is as expected + logger.info("Check reboot cause of the dut") + reboot_cause = get_reboot_cause(duthost) + pytest_assert(reboot_cause == COLD_REBOOT_CAUSE, + "Reboot cause {} did not match the trigger {}".format(reboot_cause, COLD_REBOOT_CAUSE)) + + @pytest.mark.disable_loganalyzer def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, enum_supervisor_dut_hostname, ptfhost, nbrhosts, @@ -1034,9 +1263,12 @@ def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, tsa_tsb_timer = dict() dut_nbrhosts = dict() up_bgp_neighbors = dict() + int_status_result, crit_process_check = dict(), dict() for linecard in duthosts.frontend_nodes: up_bgp_neighbors[linecard] = linecard.get_bgp_neighbors_per_asic("established") tsa_tsb_timer[linecard] = get_startup_tsb_timer(linecard) + int_status_result[linecard] = True + crit_process_check[linecard] = True if not tsa_tsb_timer[linecard]: pytest.skip("startup_tsa_tsb.service is not supported on the duts under {}".format(suphost.hostname)) dut_nbrhosts[linecard] = nbrhosts_to_dut(linecard, nbrhosts) @@ -1045,7 +1277,8 @@ def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, "DUT is not in normal state") if not check_tsa_persistence_support(linecard): pytest.skip("TSA persistence not supported in the image") - + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) try: # Execute user initiated TSA from supervisor card suphost.shell("TSA") @@ -1084,9 +1317,8 @@ def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, "DUT is not in maintenance state when startup_tsa_tsb service is running") logging.info("Wait until all critical processes are fully started") - wait_critical_processes(linecard) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, linecard), - "Not all ports that are admin up on are operationally up") + crit_process_check[linecard] = wait_until(600, 20, 0, _all_critical_processes_healthy, linecard) + int_status_result[linecard] = wait_until(1200, 20, 0, check_interface_status_of_up_ports, linecard) # Verify BGP sessions are established pytest_assert( @@ -1114,16 +1346,18 @@ def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, "Failed to verify routes on nbr in TSA") finally: - # Make sure sup card is in normal state save save the config to proceed further - suphost.shell("TSB") - suphost.shell("sudo config save -y") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) + for linecard in duthosts.frontend_nodes: # Make sure linecards are in Normal state and save the config to proceed further - linecard.shell("TSB") - linecard.shell('sudo config save -y') - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(linecard), - "DUT {} is not in normal state".format(linecard)) + if not (int_status_result[linecard] and crit_process_check[linecard] and + TS_NORMAL == get_traffic_shift_state(linecard)): + logger.info("DUT's current interface status is {}, critical process check is {} " + "or traffic shift state is not {}". + format(int_status_result[linecard], crit_process_check[linecard], TS_NORMAL)) + logging.info("DUT is not in normal state after supervisor cold reboot, doing config-reload") + config_reload(linecard, safe_reload=True, check_intf_up_ports=True) # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut {}".format(linecard)) reboot_cause = get_reboot_cause(linecard) @@ -1135,108 +1369,3 @@ def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, reboot_cause = get_reboot_cause(suphost) pytest_assert(reboot_cause == COLD_REBOOT_CAUSE, "Reboot cause {} did not match the trigger {}".format(reboot_cause, COLD_REBOOT_CAUSE)) - - -@pytest.mark.disable_loganalyzer -def test_tsa_tsb_timer_efficiency(duthosts, localhost, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, - nbrhosts, traffic_shift_community, tbinfo): - """ - Test startup TSA_TSB service after DUT cold reboot - Verify the configured tsa_tsb_timer is sufficient for system to be stable - Verify this service configures TSA and starts a timer and configures TSB once the timer is expired - """ - duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] - tsa_tsb_timer = get_startup_tsb_timer(duthost) - if not tsa_tsb_timer: - pytest.skip("startup_tsa_tsb.service is not supported on the {}".format(duthost.hostname)) - # Ensure that the DUT is not in maintenance already before start of the test - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") - if not check_tsa_persistence_support(duthost): - pytest.skip("TSA persistence not supported in the image") - - try: - # Get all routes on neighbors before doing reboot - orig_v4_routes = parse_routes_on_neighbors(duthost, nbrhosts, 4) - orig_v6_routes = parse_routes_on_neighbors(duthost, nbrhosts, 6) - - up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") - - # Reboot dut and wait for startup_tsa_tsb service to start - logger.info("Cold reboot on node: %s", duthost.hostname) - reboot(duthost, localhost, wait=240) - - logger.info('Cold reboot finished on {}'.format(duthost.hostname)) - dut_uptime = duthost.get_up_time() - logger.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) - - # Ensure startup_tsa_tsb service is running after dut reboot - pytest_assert(wait_until(60, 5, 0, get_tsa_tsb_service_status, duthost, 'running'), - "startup_tsa_tsb service is not started after reboot") - - # Ensure startup_tsa_tsb service started on expected time since dut rebooted - dut_uptime = duthost.get_up_time() - logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) - service_uptime = get_tsa_tsb_service_uptime(duthost) - time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, - "startup_tsa_tsb service started much later than the expected time after dut reboot") - - logging.info("Wait until all critical services are fully started") - pytest_assert(wait_until(300, 20, 2, duthost.critical_services_fully_started)), \ - "Not all critical services are fully started on {}".format(duthost.hostname) - - logging.info("Wait until all critical processes are fully started") - wait_critical_processes(duthost) - pytest_assert(wait_until(600, 20, 0, check_interface_status_of_up_ports, duthost), - "Not all ports that are admin up on are operationally up") - - pytest_assert(wait_until(300, 10, 0, - duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established")) - - stability_check_time = datetime.datetime.now() - time_to_stabilize = (stability_check_time - service_uptime).total_seconds() - logging.info("Time taken for system stability : {}".format(time_to_stabilize)) - - # Verify DUT is in maintenance state. - pytest_assert(TS_MAINTENANCE == get_traffic_shift_state(duthost), - "DUT is not in maintenance state when startup_tsa_tsb service is running") - - # Verify startup_tsa_tsb service stopped after expected time - pytest_assert(wait_until(tsa_tsb_timer, 20, 0, get_tsa_tsb_service_status, duthost, 'exited'), - "startup_tsa_tsb service is not stopped even after configured timer expiry") - - # Verify tsa_tsb_timer configured is sufficient - pytest_assert(time_to_stabilize < tsa_tsb_timer, - "Configured tsa_tsb_timer is not sufficient for the system to be stable") - - # Ensure dut comes back to normal state after timer expiry - if not get_tsa_tsb_service_status(duthost, 'running'): - # Verify TSB is configured on the dut after startup_tsa_tsb service is stopped - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state after startup_tsa_tsb service is stopped") - - # Wait until all routes are announced to neighbors - cur_v4_routes = {} - cur_v6_routes = {} - # Verify that all routes advertised to neighbor at the start of the test - if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, duthost, nbrhosts, - orig_v4_routes, cur_v4_routes, 4): - if not check_and_log_routes_diff(duthost, nbrhosts, orig_v4_routes, cur_v4_routes, 4): - pytest.fail("Not all ipv4 routes are announced to neighbors") - - if not wait_until(300, 3, 0, verify_current_routes_announced_to_neighs, duthost, nbrhosts, - orig_v6_routes, cur_v6_routes, 6): - if not check_and_log_routes_diff(duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): - pytest.fail("Not all ipv6 routes are announced to neighbors") - - finally: - - # Verify DUT is in normal state. - pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), - "DUT is not in normal state") - # Make sure the dut's reboot cause is as expected - logger.info("Check reboot cause of the dut") - reboot_cause = get_reboot_cause(duthost) - pytest_assert(reboot_cause == COLD_REBOOT_CAUSE, - "Reboot cause {} did not match the trigger {}".format(reboot_cause, COLD_REBOOT_CAUSE)) diff --git a/tests/bgp/test_traffic_shift.py b/tests/bgp/test_traffic_shift.py index 2448b570632..28c9743107e 100644 --- a/tests/bgp/test_traffic_shift.py +++ b/tests/bgp/test_traffic_shift.py @@ -2,15 +2,17 @@ import re import pytest from tests.common.devices.eos import EosHost -from bgp_helpers import get_routes_not_announced_to_bgpmon, remove_bgp_neighbors, restore_bgp_neighbors +from tests.bgp.bgp_helpers import get_routes_not_announced_to_bgpmon, remove_bgp_neighbors, restore_bgp_neighbors, \ + initial_tsa_check_before_and_after_test from tests.common import config_reload from tests.common.helpers.assertions import pytest_assert from tests.common.helpers.constants import DEFAULT_ASIC_ID from tests.common.platform.processes_utils import wait_critical_processes from tests.common.utilities import wait_until -from route_checker import verify_only_loopback_routes_are_announced_to_neighs, parse_routes_on_neighbors, \ +from tests.bgp.route_checker import verify_only_loopback_routes_are_announced_to_neighs, parse_routes_on_neighbors, \ verify_current_routes_announced_to_neighs, check_and_log_routes_diff -from traffic_checker import get_traffic_shift_state, check_tsa_persistence_support, verify_traffic_shift_per_asic +from tests.bgp.traffic_checker import get_traffic_shift_state, check_tsa_persistence_support, \ + verify_traffic_shift_per_asic from tests.bgp.constants import TS_NORMAL, TS_MAINTENANCE, TS_NO_NEIGHBORS pytestmark = [ @@ -68,6 +70,9 @@ def test_TSA(duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, Verify all routes are announced to bgp monitor, and only loopback routes are announced to neighs """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + # Initially make sure both supervisor and line cards are in BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) try: # Issue TSA on DUT duthost.shell("TSA") @@ -89,6 +94,9 @@ def test_TSA(duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, finally: # Recover to Normal state duthost.shell("TSB") + # Bring back the supervisor and line cards to the BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) def test_TSB(duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, nbrhosts, bgpmon_setup_teardown, tbinfo): @@ -98,6 +106,9 @@ def test_TSB(duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, nbrho and all routes are announced to neighbors """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + # Initially make sure both supervisor and line cards are in BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) # Ensure that the DUT is not in maintenance already before start of the test pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), "DUT is not in normal state") @@ -131,9 +142,13 @@ def test_TSB(duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, nbrho if not check_and_log_routes_diff(duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): pytest.fail("Not all ipv6 routes are announced to neighbors") + # Bring back the supervisor and line cards to the BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) + def test_TSA_B_C_with_no_neighbors(duthosts, enum_rand_one_per_hwsku_frontend_hostname, - bgpmon_setup_teardown, nbrhosts, core_dump_and_config_check): + bgpmon_setup_teardown, nbrhosts, core_dump_and_config_check, tbinfo): """ Test TSA, TSB, TSC with no neighbors on ASIC0 in case of multi-asic and single-asic. """ @@ -141,6 +156,9 @@ def test_TSA_B_C_with_no_neighbors(duthosts, enum_rand_one_per_hwsku_frontend_ho bgp_neighbors = {} duts_data = core_dump_and_config_check asic_index = 0 if duthost.is_multi_asic else DEFAULT_ASIC_ID + # Initially make sure both supervisor and line cards are in BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) # Ensure that the DUT is not in maintenance already before start of the test pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), "DUT is not in normal state") @@ -193,6 +211,10 @@ def test_TSA_B_C_with_no_neighbors(duthosts, enum_rand_one_per_hwsku_frontend_ho if not check_and_log_routes_diff(duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): pytest.fail("Not all ipv6 routes are announced to neighbors") + # Bring back the supervisor and line cards to the BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) + @pytest.mark.disable_loganalyzer def test_TSA_TSB_with_config_reload(duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, nbrhosts, @@ -202,6 +224,9 @@ def test_TSA_TSB_with_config_reload(duthosts, enum_rand_one_per_hwsku_frontend_h Verify all routes are announced to bgp monitor, and only loopback routes are announced to neighs """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + # Initially make sure both supervisor and line cards are in BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) # Ensure that the DUT is not in maintenance already before start of the test pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), "DUT is not in normal state") @@ -255,6 +280,9 @@ def test_TSA_TSB_with_config_reload(duthosts, enum_rand_one_per_hwsku_frontend_h duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): if not check_and_log_routes_diff(duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): pytest.fail("Not all ipv6 routes are announced to neighbors") + # Bring back the supervisor and line cards to the BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) @pytest.mark.disable_loganalyzer @@ -266,6 +294,9 @@ def test_load_minigraph_with_traffic_shift_away(duthosts, enum_rand_one_per_hwsk Verify all routes are announced to bgp monitor, and only loopback routes are announced to neighs """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + # Initially make sure both supervisor and line cards are in BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) # Ensure that the DUT is not in maintenance already before start of the test pytest_assert(TS_NORMAL == get_traffic_shift_state(duthost), "DUT is not in normal state") @@ -316,3 +347,7 @@ def test_load_minigraph_with_traffic_shift_away(duthosts, enum_rand_one_per_hwsk duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): if not check_and_log_routes_diff(duthost, nbrhosts, orig_v6_routes, cur_v6_routes, 6): pytest.fail("Not all ipv6 routes are announced to neighbors") + + # Bring back the supervisor and line cards to the BGP operational normal state + if tbinfo['topo']['type'] == 't2': + initial_tsa_check_before_and_after_test(duthosts) diff --git a/tests/bgp/test_traffic_shift_sup.py b/tests/bgp/test_traffic_shift_sup.py index b93e680bf6d..e3c5922e596 100644 --- a/tests/bgp/test_traffic_shift_sup.py +++ b/tests/bgp/test_traffic_shift_sup.py @@ -2,8 +2,9 @@ import pytest from tests.common.helpers.assertions import pytest_assert from tests.common import config_reload -from traffic_checker import get_traffic_shift_state from tests.bgp.constants import TS_NORMAL, TS_MAINTENANCE +from tests.bgp.traffic_checker import get_traffic_shift_state +from tests.bgp.bgp_helpers import initial_tsa_check_before_and_after_test pytestmark = [ pytest.mark.topology('t2') @@ -46,6 +47,8 @@ def test_TSA(duthosts, enum_supervisor_dut_hostname): Test TSA Verify all linecards transition to maintenance state after TSA on supervisor """ + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) suphost = duthosts[enum_supervisor_dut_hostname] try: # Make sure LCs are in normal mode before tests starts @@ -55,6 +58,8 @@ def test_TSA(duthosts, enum_supervisor_dut_hostname): suphost.shell("TSA") # Verify DUT is in maintenance state. verify_traffic_shift_state_all_lcs(duthosts, TS_MAINTENANCE, "maintenance") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) except Exception as e: # Log exception logger.error("Exception caught in TSB test. Error message: {}".format(e)) @@ -68,6 +73,8 @@ def test_TSB(duthosts, enum_supervisor_dut_hostname): Test TSB Verify all linecards transition back to normal state from maintenance after TSB on supervisor """ + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) suphost = duthosts[enum_supervisor_dut_hostname] try: # Make sure LCs are in normal mode before tests starts @@ -81,6 +88,8 @@ def test_TSB(duthosts, enum_supervisor_dut_hostname): suphost.shell("TSB") # Verify DUT is in normal state verify_traffic_shift_state_all_lcs(duthosts, TS_NORMAL, "normal") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) except Exception as e: # Log exception logger.error("Exception caught in TSB test. Error message: {}".format(e)) @@ -93,6 +102,8 @@ def test_TSA_TSB_chassis_with_config_reload(duthosts, enum_supervisor_dut_hostna Verify all linecards remain in Maintenance state after TSA and config reload on supervisor Verify all linecards remain in Normal state after TSB and config reload on supervisor """ + # Initially make sure both supervisor and line cards are in BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) suphost = duthosts[enum_supervisor_dut_hostname] try: # Make sure LCs are in normal mode before tests starts @@ -120,3 +131,5 @@ def test_TSA_TSB_chassis_with_config_reload(duthosts, enum_supervisor_dut_hostna # Verify DUT is in normal state. verify_traffic_shift_state_all_lcs(duthosts, TS_NORMAL, "normal") + # Bring back the supervisor and line cards to the BGP operational normal state + initial_tsa_check_before_and_after_test(duthosts) From c24fef72ff0dd6b770c14c6b9539deaf826f2bf9 Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Thu, 31 Oct 2024 04:25:20 +0800 Subject: [PATCH 019/221] Update the logic of adding mux to the critical process list (#15142) Enhance the logic to cover the mock dualtor test on topology ptf32 There is no mux docker running but its metadata subtype is DualToR Change-Id: Ie076d4037c03e75240308d6eeb46244d2d137639 --- tests/common/devices/multi_asic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/common/devices/multi_asic.py b/tests/common/devices/multi_asic.py index 9660815b6c0..41d16d3884b 100644 --- a/tests/common/devices/multi_asic.py +++ b/tests/common/devices/multi_asic.py @@ -82,7 +82,8 @@ def critical_services_tracking_list(self): "DEVICE_METADATA" in config_facts and "localhost" in config_facts["DEVICE_METADATA"] and "subtype" in config_facts["DEVICE_METADATA"]["localhost"] and - config_facts["DEVICE_METADATA"]["localhost"]["subtype"] == "DualToR" + config_facts["DEVICE_METADATA"]["localhost"]["subtype"] == "DualToR" and + "mux" in config_facts["FEATURE"] and config_facts["FEATURE"]["mux"]["state"] == "enabled" ): service_list.append("mux") From c37452a4722a91a26d89d84c51d683ce60c59219 Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Thu, 31 Oct 2024 04:32:12 +0800 Subject: [PATCH 020/221] Add dualtor active active topology support for copp test (#15103) Add dualtor active active topology support for copp test Change-Id: I02914b2385d01fdec1bc2efa8ac2f54501099158 --- .../common/plugins/conditional_mark/tests_mark_conditions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 04dade44e36..9d453e62edd 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -228,7 +228,7 @@ copp/test_copp.py: skip: reason: "Topology not supported by COPP tests" conditions: - - "(topo_name not in ['ptf32', 'ptf64', 't0', 't0-64', 't0-52', 't0-116', 't1', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 'm0', 'm0-2vlan', 'mx'] and 't2' not in topo_type)" + - "(topo_name not in ['dualtor-aa', 'dualtor-aa-64-breakout', 'ptf32', 'ptf64', 't0', 't0-64', 't0-52', 't0-116', 't1', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 'm0', 'm0-2vlan', 'mx'] and 't2' not in topo_type)" copp/test_copp.py::TestCOPP::test_add_new_trap: skip: From a5af13fd998959f51ecf77ed57f7f1f08f93e28d Mon Sep 17 00:00:00 2001 From: "Nana@Nvidia" <78413612+nhe-NV@users.noreply.github.com> Date: Thu, 31 Oct 2024 04:52:38 +0800 Subject: [PATCH 021/221] Skip the bfd test case by the github issue (#14088) test_bfd_echo_mode failed due to the test issue: https://github.com/sonic-net/sonic-mgmt/issues/14087 --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 9d453e62edd..1d38d86e22c 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -84,6 +84,12 @@ bfd/test_bfd.py::test_bfd_basic: - "platform not in ['x86_64-mlnx_msn4600c-r0', 'x86_64-mlnx_msn4700-r0', 'x86_64-nvidia_sn5600-r0', 'x86_64-8102_64h_o-r0', 'x86_64-8101_32fh_o-r0']" - "release in ['201811', '201911']" +bfd/test_bfd.py::test_bfd_echo_mode: + skip: + reason: "https://github.com/sonic-net/sonic-mgmt/issues/14087" + conditions: + - "https://github.com/sonic-net/sonic-mgmt/issues/14087" + bfd/test_bfd.py::test_bfd_scale: skip: reason: "Test not supported for cisco as it doesnt support single hop BFD. From 001ee956ecad296d4af72a35e579e86ea1db0463 Mon Sep 17 00:00:00 2001 From: weguo-NV <154216071+weiguo-nvidia@users.noreply.github.com> Date: Thu, 31 Oct 2024 05:01:15 +0800 Subject: [PATCH 022/221] Update sflow cases to adapt T0-64 setup (#12655) --- tests/sflow/test_sflow.py | 198 ++++++++++++++++++++++++++------------ 1 file changed, 138 insertions(+), 60 deletions(-) diff --git a/tests/sflow/test_sflow.py b/tests/sflow/test_sflow.py index 6c0d65611ed..35b441a961a 100644 --- a/tests/sflow/test_sflow.py +++ b/tests/sflow/test_sflow.py @@ -18,6 +18,8 @@ from tests.common import config_reload from tests.common.utilities import wait_until +SFLOW_RATE_DEFAULT = 512 + pytestmark = [ pytest.mark.topology('t0', 'm0', 'mx') ] @@ -33,7 +35,7 @@ def setup(duthosts, rand_one_dut_hostname, ptfhost, tbinfo, config_sflow_feature feature_status, _ = duthost.get_feature_status() if 'sflow' not in feature_status or feature_status['sflow'] == 'disabled': - pytest.skip("sflow feature is not eanbled") + pytest.skip("sflow feature is not enabled") mg_facts = duthost.get_extended_minigraph_facts(tbinfo) var['router_mac'] = duthost.facts['router_mac'] @@ -55,13 +57,14 @@ def setup(duthosts, rand_one_dut_hostname, ptfhost, tbinfo, config_sflow_feature config_dut_ports(duthost, var['test_ports'][0:2], vlan=1000) for port_channel, interfaces in list(mg_facts['minigraph_portchannels'].items()): - port = interfaces['members'][0] - var['sflow_ports'][port] = {} - var['sflow_ports'][port]['ifindex'] = get_ifindex(duthost, port) - var['sflow_ports'][port]['port_index'] = get_port_index(duthost, port) - var['sflow_ports'][port]['ptf_indices'] = mg_facts['minigraph_ptf_indices'][interfaces['members'][0]] - var['sflow_ports'][port]['sample_rate'] = 512 + for port in interfaces['members']: + var['sflow_ports'][port] = {} + var['sflow_ports'][port]['ifindex'] = get_ifindex(duthost, port) + var['sflow_ports'][port]['port_index'] = get_port_index(duthost, port) + var['sflow_ports'][port]['ptf_indices'] = mg_facts['minigraph_ptf_indices'][port] + var['sflow_ports'][port]['sample_rate'] = SFLOW_RATE_DEFAULT var['portmap'] = json.dumps(var['sflow_ports']) + logger.info(f'var = {var}') udp_port = 6343 for i in range(0, 2, 1): @@ -109,6 +112,28 @@ def config_dut_ports(duthost, ports, vlan): config_reload(duthost, config_source='config_db', wait=120) time.sleep(5) +# ----------------------------------------------------------------------------------$ + + +def get_default_agent(duthost): + # get_default_agent function is used to get the agent ip selected by the hsflowd daemon. + # hsflowd.auto is the auto generated file by hsflowd daemon + hsflowd_autogen_file = '/etc/hsflowd.auto' + result = duthost.shell( + r"docker exec -i sflow sh -c 'test -f {} && echo exist'".format(hsflowd_autogen_file), + module_ignore_errors=True)['stdout'].strip() + if result != 'exist': + pytest.fail("{} file does not exist.".format(hsflowd_autogen_file)) + + selected_agent = duthost.shell( + "docker exec sflow grep -w 'agentIP' {} | cut -d '=' -f 2".format(hsflowd_autogen_file))['stdout'].strip() + if not selected_agent: + pytest.fail('agent variable not found in the hsflowd.auto file') + else: + logger.info('Selected hsflowd agent is : {}'.format(selected_agent)) + + return selected_agent + # ---------------------------------------------------------------------------------- @@ -174,7 +199,7 @@ def config_sflow_interfaces(duthost, intf, **kwargs): (kwargs['status'], intf)) if 'sample_rate' in kwargs: duthost.shell('config sflow interface sample-rate %s %s' % - (intf, kwargs['sample_rate'])) + (intf, str(kwargs['sample_rate']))) # ---------------------------------------------------------------------------------- @@ -209,7 +234,7 @@ def verify_show_sflow(duthost, status, **kwargs): collector), show_sflow), "Number of Sflow collectors should be %s" % len(collector) for col in collector: assert re.search(r"Name:\s+%s\s+IP addr:\s%s\s+UDP port:\s%s" % ( - var[col]['name'], var[col]['ip_addr'], var[col]['port']), show_sflow),\ + var[col]['name'], var[col]['ip_addr'], var[col]['port']), show_sflow), \ "col %s is not properly Configured" % col # ---------------------------------------------------------------------------------- @@ -234,6 +259,7 @@ def verify_sflow_interfaces(duthost, intf, status, sampling_rate): @pytest.fixture def partial_ptf_runner(request, ptfhost, tbinfo): def _partial_ptf_runner(**kwargs): + logger.info(f'The enabled sflow interface is: {kwargs}') params = {'testbed_type': tbinfo['topo']['name'], 'router_mac': var['router_mac'], 'dst_port': var['ptf_test_indices'][2], @@ -264,19 +290,63 @@ def sflowbase_config(duthosts, rand_one_dut_hostname): duthost.shell("config sflow polling-interval 20") for port in var['sflow_ports']: config_sflow_interfaces( - duthost, port, status='enable', sample_rate='512') + duthost, port, status='enable', sample_rate=SFLOW_RATE_DEFAULT) time.sleep(2) verify_show_sflow(duthost, status='up', collector=[ 'collector0', 'collector1']) for intf in var['sflow_ports']: - verify_sflow_interfaces(duthost, intf, 'up', 512) + verify_sflow_interfaces(duthost, intf, 'up', SFLOW_RATE_DEFAULT) + + +# ---------------------------------------------------------------------------------- + +@pytest.fixture +def selected_portchannel_members(duthost, tbinfo): + """ + Get the sflow interface + + Example: + { + 'PortChannel101': {'name': 'PortChannel101', 'members': ['Ethernet224', 'Ethernet228'], 'namespace': ''}, + 'PortChannel102': {'name': 'PortChannel102', 'members': ['Ethernet232', 'Ethernet236'], 'namespace': ''}, + 'PortChannel103': {'name': 'PortChannel103', 'members': ['Ethernet240', 'Ethernet244'], 'namespace': ''}, + 'PortChannel104': {'name': 'PortChannel104', 'members': ['Ethernet248', 'Ethernet252'], 'namespace': ''} + } + + Returns: + [['Ethernet224', 'Ethernet228'], + ['Ethernet232', 'Ethernet236'], + ['Ethernet240', 'Ethernet244'], + ['Ethernet248', 'Ethernet252']] + """ + mg_facts = duthost.get_extended_minigraph_facts(tbinfo) + portchannel_interfaces_list = [details['members'] for details in mg_facts["minigraph_portchannels"].values()] + if len(portchannel_interfaces_list) < 2: + pytest.skip("The test requires at least two portchannels with multiple members") + logger.info(f'The portchannel interface is: {portchannel_interfaces_list}') + + return portchannel_interfaces_list +@pytest.fixture +def restore_sflow_interface_status_and_rate(duthost, selected_portchannel_members): + + yield + + logger.info(f'The restored sflow interface is: {selected_portchannel_members}') + for sflow_intf_list in selected_portchannel_members: + for intf in sflow_intf_list: + config_sflow_interfaces(duthost, intf, status='enable', sample_rate=SFLOW_RATE_DEFAULT) + var['sflow_ports'][intf]['sample_rate'] = SFLOW_RATE_DEFAULT + + var['portmap'] = json.dumps(var['sflow_ports']) + # ---------------------------------------------------------------------------------- + class TestSflowCollector(): """ - Test Sflow with 2 collectors , adding or removibg collector and verify collector samples + Test Sflow with 2 collectors , adding or removing collector and verify collector samples """ def test_sflow_config(self, duthosts, rand_one_dut_hostname, partial_ptf_runner): @@ -288,10 +358,10 @@ def test_sflow_config(self, duthosts, rand_one_dut_hostname, partial_ptf_runner) duthost.command("config sflow interface disable all") for port in var['sflow_ports']: config_sflow_interfaces( - duthost, port, status='enable', sample_rate='512') + duthost, port, status='enable', sample_rate=SFLOW_RATE_DEFAULT) verify_show_sflow(duthost, status='up', collector=['collector0']) for intf in var['sflow_ports']: - verify_sflow_interfaces(duthost, intf, 'up', 512) + verify_sflow_interfaces(duthost, intf, 'up', SFLOW_RATE_DEFAULT) time.sleep(5) partial_ptf_runner( enabled_sflow_interfaces=list(var['sflow_ports'].keys()), @@ -347,7 +417,7 @@ def test_two_collectors(self, sflowbase_config, duthosts, rand_one_dut_hostname, "config sflow collector add collector2 192.168.0.5 ", module_ignore_errors=True) assert "Only 2 collectors can be configured, please delete one" in out['stdout'] - # remove first collector and check DUT sends samples to collector 2 woth non default port number (6344) + # remove first collector and check DUT sends samples to collector 2 with non default port number (6344) config_sflow_collector(duthost, 'collector0', 'del') verify_show_sflow(duthost, status='up', collector=['collector1']) time.sleep(10) @@ -381,7 +451,7 @@ def testDisablePolling(self, duthost, partial_ptf_runner): polling_int=0, active_collectors="['collector0','collector1']") - def testDifferntPollingInt(self, duthost, partial_ptf_runner): + def testDifferentPollingInt(self, duthost, partial_ptf_runner): duthost.shell("config sflow polling-interval 60") verify_show_sflow(duthost, status='up', polling_int=60) @@ -395,63 +465,70 @@ def testDifferntPollingInt(self, duthost, partial_ptf_runner): class TestSflowInterface(): """ Enable / Disable Sflow interfaces and check the samples are received only from the intended interface - Test interfaceswith different sampling rates + Test interfaces with different sampling rates """ - def testIntfRemoval(self, sflowbase_config, duthost, partial_ptf_runner): - sflow_int = sorted(var['sflow_ports'].keys()) - config_sflow_interfaces(duthost, sflow_int[0], status='disable') - config_sflow_interfaces(duthost, sflow_int[1], status='disable') + def testIntfRemoval(self, sflowbase_config, duthost, partial_ptf_runner, selected_portchannel_members, + restore_sflow_interface_status_and_rate): + disabled_sflow_intf_list = selected_portchannel_members[0] + enabled_sflow_intf_list = [intf for intf_list in selected_portchannel_members[1:] for intf in intf_list] - verify_sflow_interfaces(duthost, sflow_int[0], 'down', 512) - verify_sflow_interfaces(duthost, sflow_int[1], 'down', 512) - enabled_intf = sflow_int[2:] - for intf in enabled_intf: - verify_sflow_interfaces(duthost, intf, 'up', 512) + # Disable sflow for the interface in first portchannel + for intf in disabled_sflow_intf_list: + config_sflow_interfaces(duthost, intf, status='disable') + verify_sflow_interfaces(duthost, intf, 'down', SFLOW_RATE_DEFAULT) + + # Enable sflow for the interface in other portchannel + for intf in enabled_sflow_intf_list: + verify_sflow_interfaces(duthost, intf, 'up', SFLOW_RATE_DEFAULT) + + # Traffic test for the enabled sflow interfaces partial_ptf_runner( - enabled_sflow_interfaces=enabled_intf, + enabled_sflow_interfaces=enabled_sflow_intf_list, active_collectors="['collector0','collector1']") - def testIntfSamplingRate(self, sflowbase_config, duthost, ptfhost, partial_ptf_runner): + def testIntfSamplingRate(self, sflowbase_config, duthost, ptfhost, partial_ptf_runner, selected_portchannel_members, + restore_sflow_interface_status_and_rate): + first_portchannel_members = selected_portchannel_members[0] + second_portchannel_members = selected_portchannel_members[1] - # re-add ports with different sampling rate - sflow_int = sorted(var['sflow_ports'].keys()) - test_intf = sflow_int[0] - test_intf1 = sflow_int[1] - config_sflow_interfaces( - duthost, test_intf, status='enable', sample_rate=256) - config_sflow_interfaces(duthost, test_intf1, - status='enable', sample_rate=1024) + # Set sflow rate for interface in first portchannel + for intf in first_portchannel_members: + config_sflow_interfaces(duthost, intf, status='enable', sample_rate=256) + var['sflow_ports'][intf]['sample_rate'] = 256 + + # Set sflow rate for interface in second portchannel + for intf in second_portchannel_members: + config_sflow_interfaces(duthost, intf, status='enable', sample_rate=1024) + var['sflow_ports'][intf]['sample_rate'] = 1024 - var['sflow_ports'][test_intf]['sample_rate'] = 256 - var['sflow_ports'][test_intf1]['sample_rate'] = 1024 var['portmap'] = json.dumps(var['sflow_ports']) - for intf in sflow_int: - verify_sflow_interfaces( - duthost, intf, 'up', var['sflow_ports'][intf]['sample_rate']) + enabled_sflow_intf_list = [intf for intf_list in selected_portchannel_members for intf in intf_list] + for intf in enabled_sflow_intf_list: + verify_sflow_interfaces(duthost, intf, 'up', var['sflow_ports'][intf]['sample_rate']) + + # Traffic test for the enabled sflow interfaces ptfhost.copy(content=var['portmap'], dest="/tmp/sflow_ports.json") time.sleep(2) partial_ptf_runner( - enabled_sflow_interfaces=sflow_int, + enabled_sflow_interfaces=enabled_sflow_intf_list, active_collectors="['collector0','collector1']") - def testIntfChangeSamplingRate(self, sflowbase_config, duthost, partial_ptf_runner, ptfhost): + # Revert sflow rate for interface in first portchannel + for intf in first_portchannel_members: + config_sflow_interfaces(duthost, intf, status='enable', sample_rate=SFLOW_RATE_DEFAULT) + var['sflow_ports'][intf]['sample_rate'] = SFLOW_RATE_DEFAULT + + # Revert sflow rate for interface in second portchannel + for intf in second_portchannel_members: + config_sflow_interfaces(duthost, intf, status='enable', sample_rate=SFLOW_RATE_DEFAULT) + var['sflow_ports'][intf]['sample_rate'] = SFLOW_RATE_DEFAULT - sflow_int = sorted(var['sflow_ports'].keys()) - test_intf = sflow_int[0] - test_intf1 = sflow_int[1] - # revert the sampling rate to 512 on both ports - config_sflow_interfaces(duthost, test_intf, sample_rate=512) - config_sflow_interfaces(duthost, test_intf1, sample_rate=512) - var['sflow_ports'][test_intf]['sample_rate'] = 512 - var['sflow_ports'][test_intf1]['sample_rate'] = 512 + # Traffic test for the enabled sflow interfaces var['portmap'] = json.dumps(var['sflow_ports']) - for intf in sflow_int: - verify_sflow_interfaces( - duthost, intf, 'up', var['sflow_ports'][intf]['sample_rate']) ptfhost.copy(content=var['portmap'], dest="/tmp/sflow_ports.json") partial_ptf_runner( - enabled_sflow_interfaces=sflow_int, + enabled_sflow_interfaces=enabled_sflow_intf_list, active_collectors="['collector0','collector1']") # ------------------------------------------------------------------------------ @@ -461,7 +538,7 @@ def testIntfChangeSamplingRate(self, sflowbase_config, duthost, partial_ptf_runn class TestAgentId(): """ Add loopback0 ip as the agent id and check the samples are received with intended agent-id. - Remove agent-ip and check whether samples are received with previously cofigured agent ip. + Remove agent-ip and check whether samples are received with previously configured agent ip. Add eth0 ip as the agent ip and check the samples are received with intended agent-id. """ @@ -479,10 +556,11 @@ def testDelAgent(self, duthost, partial_ptf_runner): duthost.shell(" config sflow agent-id del") verify_show_sflow(duthost, status='up', agent_id='default') time.sleep(5) + agent_ip = get_default_agent(duthost) # Verify whether the samples are received with previously configured agent ip partial_ptf_runner( polling_int=20, - agent_id=var['mgmt_ip'], + agent_id=agent_ip, active_collectors="['collector0','collector1']") def testAddAgent(self, duthost, partial_ptf_runner): @@ -515,7 +593,7 @@ def testRebootSflowEnable(self, sflowbase_config, config_sflow_agent, duthost, var['sflow_ports'][intf]['ifindex'] = get_ifindex(duthost, intf) var['sflow_ports'][intf]['port_index'] = get_port_index( duthost, intf) - verify_sflow_interfaces(duthost, intf, 'up', 512) + verify_sflow_interfaces(duthost, intf, 'up', SFLOW_RATE_DEFAULT) var['portmap'] = json.dumps(var['sflow_ports']) ptfhost.copy(content=var['portmap'], dest="/tmp/sflow_ports.json") partial_ptf_runner( @@ -562,7 +640,7 @@ def testFastreboot(self, sflowbase_config, config_sflow_agent, duthost, localhos var['sflow_ports'][intf]['ifindex'] = get_ifindex(duthost, intf) var['sflow_ports'][intf]['port_index'] = get_port_index( duthost, intf) - verify_sflow_interfaces(duthost, intf, 'up', 512) + verify_sflow_interfaces(duthost, intf, 'up', SFLOW_RATE_DEFAULT) var['portmap'] = json.dumps(var['sflow_ports']) ptfhost.copy(content=var['portmap'], dest="/tmp/sflow_ports.json") partial_ptf_runner( @@ -584,7 +662,7 @@ def testWarmreboot(self, sflowbase_config, duthost, localhost, partial_ptf_runne var['sflow_ports'][intf]['ifindex'] = get_ifindex(duthost, intf) var['sflow_ports'][intf]['port_index'] = get_port_index( duthost, intf) - verify_sflow_interfaces(duthost, intf, 'up', 512) + verify_sflow_interfaces(duthost, intf, 'up', SFLOW_RATE_DEFAULT) var['portmap'] = json.dumps(var['sflow_ports']) ptfhost.copy(content=var['portmap'], dest="/tmp/sflow_ports.json") partial_ptf_runner( From 600b03ff7f636bf055b45870c17ba0df2e6eebcd Mon Sep 17 00:00:00 2001 From: Jibin Bao Date: Thu, 31 Oct 2024 05:01:57 +0800 Subject: [PATCH 023/221] Stabilize test_cacl cases (#14999) * Stabilize test_cacl_tc1_acl_table_suite when rollback_or_reload the config, we are not sure how long the iptable rule is ready, so use retry mechanism to check if the current iptable rule are equal to the original ones * update the retry time --- tests/generic_config_updater/test_cacl.py | 35 ++++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/tests/generic_config_updater/test_cacl.py b/tests/generic_config_updater/test_cacl.py index 2631db44598..39534ac00c2 100644 --- a/tests/generic_config_updater/test_cacl.py +++ b/tests/generic_config_updater/test_cacl.py @@ -7,6 +7,7 @@ from tests.common.gu_utils import apply_patch, expect_op_success, expect_res_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload +from tests.common.utilities import wait_until # Test on t0 topo to verify functionality and to choose predefined variable # admin@vlab-01:~$ show acl table @@ -73,19 +74,8 @@ def setup_env(duthosts, rand_one_dut_hostname): logger.info("Rolled back to original checkpoint") rollback_or_reload(duthost) - current_iptable_rules = get_iptable_rules(duthost) - logger.info("original iptable rules: {}, current iptable rules: {}".format( - original_iptable_rules, current_iptable_rules) - ) - iptable_rules_diff = [ - li for li in difflib.ndiff(original_iptable_rules, current_iptable_rules) if li[0] != ' ' - ] - logger.info("iptable_rules_diff {}".format(iptable_rules_diff)) - pytest_assert( - set(original_iptable_rules) == set(current_iptable_rules), - "iptable rules are not suppose to change after test. diff: {}".format( - iptable_rules_diff) - ) + pytest_assert(wait_until(5, 1, 0, check_original_and_current_iptable_rule, duthost, original_iptable_rules), + "The current iptable rules doesn't match the original one") current_cacl_tables = get_cacl_tables(duthost) logger.info("original cacl tables: {}, current cacl tables: {}".format( @@ -94,7 +84,7 @@ def setup_env(duthosts, rand_one_dut_hostname): cacl_tables_diff = [ li for li in difflib.ndiff(original_cacl_tables, current_cacl_tables) if li[0] != ' ' ] - logger.info("cacl_tables_diff {}".format(iptable_rules_diff)) + logger.info("cacl_tables_diff {}".format(cacl_tables_diff)) pytest_assert( set(original_cacl_tables) == set(current_cacl_tables), "cacl tables are not suppose to change after test. diff: {}".format( @@ -104,6 +94,23 @@ def setup_env(duthosts, rand_one_dut_hostname): delete_checkpoint(duthost) +def check_original_and_current_iptable_rule(duthost, original_iptable_rules): + current_iptable_rules = get_iptable_rules(duthost) + logger.info("original iptable rules: {}, current iptable rules: {}".format( + original_iptable_rules, current_iptable_rules) + ) + iptable_rules_diff = [ + li for li in difflib.ndiff(original_iptable_rules, current_iptable_rules) if li[0] != ' ' + ] + logger.info("iptable_rules_diff {}".format(iptable_rules_diff)) + + if set(original_iptable_rules) == set(current_iptable_rules): + return True + else: + logger.error(f"iptable rules are not suppose to change after test. diff: {iptable_rules_diff}") + return False + + def expect_acl_table_match(duthost, table_name, expected_content_list): """Check if acl table show as expected """ From 359ff0beba245832ec0d929006dd9c45b959eb28 Mon Sep 17 00:00:00 2001 From: Jibin Bao Date: Thu, 31 Oct 2024 05:03:00 +0800 Subject: [PATCH 024/221] Update qos sai tests (#14342) 1. update qos sai test for sn5400 according to the two PRs below a. https://github.com/sonic-net/sonic-mgmt/pull/9583 b. https://github.com/sonic-net/sonic-mgmt/pull/12848 2. To stabilize testQosSaiQSharedWatermark[single_asic-wm_q_shared_lossy], update margin from 4 to 5 for spc4 Change-Id: Ic3919a9123cd968fb9d89013687cf31791684208 --- tests/qos/files/mellanox/special_qos_config.yml | 1 + tests/qos/qos_sai_base.py | 4 +++- tests/saitests/py3/sai_qos_tests.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/qos/files/mellanox/special_qos_config.yml b/tests/qos/files/mellanox/special_qos_config.yml index 2f1668cf891..23581fb8230 100644 --- a/tests/qos/files/mellanox/special_qos_config.yml +++ b/tests/qos/files/mellanox/special_qos_config.yml @@ -33,5 +33,6 @@ qos_params: pkts_num_margin: 7 wm_pg_shared_lossy: packet_size: 600 + pkts_num_margin: 5 wm_q_shared_lossy: packet_size: 600 diff --git a/tests/qos/qos_sai_base.py b/tests/qos/qos_sai_base.py index 9f474d89276..2e1db2b4e46 100644 --- a/tests/qos/qos_sai_base.py +++ b/tests/qos/qos_sai_base.py @@ -352,7 +352,9 @@ def __getBufferProfile(self, request, dut_asic, os_version, table, port, priorit # Update profile static threshold value if profile threshold is dynamic if "dynamic_th" in list(bufferProfile.keys()): - if dut_asic.sonichost.facts['platform'] == "x86_64-nvidia_sn5600-r0": + platform_support_nvidia_new_algorithm_cal_buffer_thr = ["x86_64-nvidia_sn5600-r0", + "x86_64-nvidia_sn5400-r0"] + if dut_asic.sonichost.facts['platform'] in platform_support_nvidia_new_algorithm_cal_buffer_thr: self.__compute_buffer_threshold_for_nvidia_device(dut_asic, table, port, bufferProfile) else: self.__computeBufferThreshold(dut_asic, bufferProfile) diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index 779b48196de..86369ffff56 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -5113,7 +5113,7 @@ def runTest(self): if pkts_num_fill_min: assert (q_wm_res[queue] == 0) - elif 'cisco-8000' in asic_type or "SN5600" in hwsku: + elif 'cisco-8000' in asic_type or "SN5600" in hwsku or "SN5400" in hwsku: assert (q_wm_res[queue] <= (margin + 1) * cell_size) else: if platform_asic and platform_asic == "broadcom-dnx": From f0f80a4ced65ec098c9abe1c6b42d2f41de5a53d Mon Sep 17 00:00:00 2001 From: jingwenxie Date: Thu, 31 Oct 2024 09:22:54 +0800 Subject: [PATCH 025/221] Add GCU testcase for acl table&rule in one patch (#15215) ### Description of PR Summary: This test is to check the GCU function when ACL_TABLE and ACL_RULE in one patch ### Approach #### What is the motivation for this PR? There are PRDO scenarios that GCU will be used for ACL_TABLE&ACL_RULE modification in one patch. We add this test to gain confident. #### How did you do it? Add a test #### How did you verify/test it? Test on DUT --- tests/generic_config_updater/test_cacl.py | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/generic_config_updater/test_cacl.py b/tests/generic_config_updater/test_cacl.py index 39534ac00c2..6c4e3ec968d 100644 --- a/tests/generic_config_updater/test_cacl.py +++ b/tests/generic_config_updater/test_cacl.py @@ -673,6 +673,53 @@ def cacl_external_client_add_new_table(duthost): delete_tmpfile(duthost, tmpfile) +def cacl_tc3_acl_table_and_acl_rule(duthost): + """ Add acl table and acl rule in single patch for test + """ + json_patch = [ + { + "op": "add", + "path": "/ACL_TABLE/EXTERNAL_CLIENT_ACL", + "value": { + "type": "CTRLPLANE", + "stage": "ingress", + "policy_desc": "EXTERNAL_CLIENT_ACL", + "services": [ + "EXTERNAL_CLIENT" + ] + } + }, + { + "op": "add", + "path": "/ACL_RULE", + "value": { + "EXTERNAL_CLIENT_ACL|RULE_1": { + "PRIORITY": "9999", + "SRC_IP": "9.9.9.9/32", + "IP_PROTOCOL": "6", + "PACKET_ACTION": "DROP", + "L4_DST_PORT": "8081" + } + } + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + expected_table_content_list = ["EXTERNAL_CLIENT_ACL", "CTRLPLANE", "EXTERNAL_CLIENT", + "EXTERNAL_CLIENT_ACL", "ingress"] + expect_acl_table_match(duthost, "EXTERNAL_CLIENT_ACL", expected_table_content_list) + expected_rule_content_list = ["-A INPUT -s 9.9.9.9/32 -p tcp -m tcp --dport 8081 -j DROP"] + expect_res_success_acl_rule(duthost, expected_rule_content_list, []) + finally: + delete_tmpfile(duthost, tmpfile) + + @pytest.fixture(scope="module", params=["SSH", "NTP", "SNMP", "EXTERNAL_CLIENT"]) def cacl_protocol(request): # noqa F811 """ @@ -703,3 +750,7 @@ def test_cacl_tc2_acl_rule_test(cacl_protocol, rand_selected_dut): cacl_tc2_remove_table_before_rule(rand_selected_dut, cacl_protocol) cacl_tc2_remove_unexist_rule(rand_selected_dut, cacl_protocol) cacl_tc2_remove_rule(rand_selected_dut) + + +def test_cacl_tc3_acl_all(rand_selected_dut): + cacl_tc3_acl_table_and_acl_rule(rand_selected_dut) From 13920a3eda4f4f03a0415fa816285ffa5f2a24bd Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:11:49 +0800 Subject: [PATCH 026/221] [dualtor][mux_simulator] Fix mux simulator stuck (#15226) What is the motivation for this PR? Active-standby Dualtor is failing to talk to mux_simulator: # curl -v http://10.64.246.154:8082/mux/vms24-7/24 * Trying 10.64.246.154:8082... on the test server, TCP syn drops are reported increasing: # netstat -s | grep -i listen 1531500 times the listen queue of a socket overflowed 1531501 SYNs to LISTEN sockets dropped mux simulator sync queue is overflowing: # ss -lnt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 129 128 0.0.0.0:8082 0.0.0.0:* It appeared that mux_simulator is stuck in the recvfrom: # strace -p 21315 strace: Process 21315 attached recvfrom(6, and there is no existing TCP connection on the test server/DUT for fd 6. mux_simulator is blocking reading from an already closed TCP connection, so subsequent HTTP requests cannot be handled properly, which resulted in the TCP sync queue overflow. How did you do it? Enable mux_simulator to work in threaded mode. Set socket timeout to 60s, if a worker thread stucks in the recvfrom like this, this will ensure the work thread exits after 60s, so no resource leak. How did you verify/test it? Run mux_simulator with the change. Signed-off-by: Longxiang Lyu --- ansible/roles/vm_set/files/mux_simulator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ansible/roles/vm_set/files/mux_simulator.py b/ansible/roles/vm_set/files/mux_simulator.py index 81c74700785..db49c115974 100644 --- a/ansible/roles/vm_set/files/mux_simulator.py +++ b/ansible/roles/vm_set/files/mux_simulator.py @@ -8,6 +8,7 @@ import re import shlex import subprocess +import socket import sys import threading import traceback @@ -966,4 +967,5 @@ def log_message(vm_set): app.logger.info('Starting server on port {}'.format(sys.argv[1])) create_muxes(arg_vm_set) app.logger.info('####################### STARTING HTTP SERVER #######################') - app.run(host='0.0.0.0', port=http_port, threaded=False) + socket.setdefaulttimeout(60) + app.run(host='0.0.0.0', port=http_port, threaded=True) # nosemgrep From f2d6c053217c5cec8f1a6b0cf8eafd20a4729ac4 Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:13:03 +0800 Subject: [PATCH 027/221] Run mux simulator script per testbed (#15255) What is the motivation for this PR? As mux_simulator script differs between branches, let's copy mux_simulator per testbed. How did you do it? Use the port number as suffix. How did you verify/test it? Run on dualtor testbeds that share the same host server, ensure mux_simulators run with each owne script file. Signed-off-by: Longxiang Lyu --- ansible/roles/vm_set/tasks/control_mux_simulator.yml | 2 +- ansible/roles/vm_set/templates/mux-simulator.service.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible/roles/vm_set/tasks/control_mux_simulator.yml b/ansible/roles/vm_set/tasks/control_mux_simulator.yml index 4d888078e11..4e837c6895b 100644 --- a/ansible/roles/vm_set/tasks/control_mux_simulator.yml +++ b/ansible/roles/vm_set/tasks/control_mux_simulator.yml @@ -42,7 +42,7 @@ - name: Copy the mux simulator to test server copy: src: mux_simulator.py - dest: "{{ abs_root_path }}" + dest: "{{ abs_root_path }}/mux_simulator_{{ mux_simulator_port }}.py" mode: 0755 - name: Generate mux-simulator systemd service file diff --git a/ansible/roles/vm_set/templates/mux-simulator.service.j2 b/ansible/roles/vm_set/templates/mux-simulator.service.j2 index 575dcf19dfd..6f9b9bad621 100644 --- a/ansible/roles/vm_set/templates/mux-simulator.service.j2 +++ b/ansible/roles/vm_set/templates/mux-simulator.service.j2 @@ -3,4 +3,4 @@ Description=mux simulator After=network.target [Service] -ExecStart=/usr/bin/env {{python_command}} {{ abs_root_path }}/mux_simulator.py {{ mux_simulator_port }} {{ vm_set_name }} -v +ExecStart=/usr/bin/env {{python_command}} {{ abs_root_path }}/mux_simulator_{{ mux_simulator_port }}.py {{ mux_simulator_port }} {{ vm_set_name }} -v From a8dbb9f648a3a634919760c795a7ec10e6ee1296 Mon Sep 17 00:00:00 2001 From: vkjammala-arista <152394203+vkjammala-arista@users.noreply.github.com> Date: Thu, 31 Oct 2024 13:59:35 +0530 Subject: [PATCH 028/221] [sonic-mgmt] Remove incorrect quotes around issue url (#15204) PR#14912 has introduced single quotes around github issue url and this is causing conditional mark evaluation to fail. Thus conditional mark config is not honored and couple of tests are getting scheduled even though they are supposed to be skipped. --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 1d38d86e22c..166659033d0 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -161,7 +161,7 @@ bgp/test_bgp_slb.py::test_bgp_slb_neighbor_persistence_across_advanced_reboot: or over topologies which doesn't support slb." conditions_logical_operator: or conditions: - - "topo_name in ['dualtor', 'dualtor-56', 'dualtor-120', 'dualtor-aa', 'dualtor-aa-56'] and 'https://github.com/sonic-net/sonic-mgmt/issues/9201'" + - "topo_name in ['dualtor', 'dualtor-56', 'dualtor-120', 'dualtor-aa', 'dualtor-aa-56'] and https://github.com/sonic-net/sonic-mgmt/issues/9201" - "'backend' in topo_name or 'mgmttor' in topo_name" bgp/test_bgp_speaker.py: @@ -824,7 +824,7 @@ generic_config_updater/test_eth_interface.py::test_replace_fec: / generic_config_updater is not a supported feature for T2' conditions_logical_operator: "OR" conditions: - - "hwsku in ['Arista-7260CX3-D108C8', 'Arista-7260CX3-Q64', 'Mellanox-SN3800-D112C8'] and 'https://github.com/sonic-net/sonic-mgmt/issues/11237'" + - "hwsku in ['Arista-7260CX3-D108C8', 'Arista-7260CX3-Q64', 'Mellanox-SN3800-D112C8'] and https://github.com/sonic-net/sonic-mgmt/issues/11237" - "'t2' in topo_name" generic_config_updater/test_eth_interface.py::test_toggle_pfc_asym: From 4ca9c6d4a5a89c5ede55cf87679088691347116c Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Thu, 31 Oct 2024 19:55:16 +1100 Subject: [PATCH 029/221] feat: optimise log_rotate for modular chassis (#15296) Description of PR Summary: Fixes # (issue) 29752643 Approach What is the motivation for this PR? Currently log rotate for supervisor takes 1 to 2 minutes with a maximum of 2 minutes on pc/test_lag_2 Since log_rotate is now running on function fixture. With all test case running, this will add up. On recent nightly run, it added up to 2:03:58 hours which slows down the test to 2 hours. The reason for log rotating is documented in #2161 to save spaces on 7060 devices. This change for T2 device make sure that we only rotate for T2 at module level instead of functions. This will optimise the time from 2 hours to 2 minutes. Details of the stats can be seen here for pc/test_lag_2 { "analyzer_logrotate_time": { "total": "2:03:58.135243", "average": "0:01:01.984460", "max": "0:02:00.298079", "min": "0:00:57.740233", "number of runs": 120 }, "analyzer_add_marker_time": { "total": "0:07:09.586112", "average": "0:00:03.579884", "max": "0:00:07.686170", "min": "0:00:02.248445", "number of runs": 120 }, "analyze_logs_time": { "total": "0:18:48.677592", "average": "0:00:11.880817", "max": "0:00:17.943104", "min": "0:00:06.689129", "number of runs": 95 }, "total_time": "2:29:56.398947", "longest_analyzer_logrotate_time": { "line": 8467, "time": "0:02:00.298079" }, "longest_analyzer_add_marker_time": { "line": 10299, "time": "0:00:07.686170" }, "longest_analyze_logs_time": { "line": 47906, "time": "0:00:17.943104" } } Break down of analyzer_logrotate_time in details lc4-1 lc1-1 lc2-1 sup-1 /usr/sbin/logrotate -f /etc/logrotate.conf > /dev/null 2>&1 Start 22:08:46 22:08:46 22:08:46 22:08:47 End 22:09:02 22:09:02 22:09:07 22:10:43 sed -i 's/^#//g' /etc/cron.d/logrotate Start 22:09:02 22:09:02 22:09:07 22:10:43 End 22:09:03 22:09:03 22:09:07 22:10:44 systemctl start logrotate.timer Start 22:09:03 22:09:03 22:09:07 2:10:44 End 22:09:03 22:09:03 22:09:07 22:10:45 Complete everything around 22:10:45 everyone was waiting for sup-1 which goes from 22:08:44 -> 22:10:45 which is around 2 minutes. This is reasonable speed. The rest of the task start around 22:08:44 -> 22:09:03 which is 19 seconds. But we have to wait for supervisor to be done. co-authorized by: jianquanye@microsoft.com --- tests/common/plugins/loganalyzer/__init__.py | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/common/plugins/loganalyzer/__init__.py b/tests/common/plugins/loganalyzer/__init__.py index 7932bf28871..5723cc5dea5 100644 --- a/tests/common/plugins/loganalyzer/__init__.py +++ b/tests/common/plugins/loganalyzer/__init__.py @@ -45,8 +45,24 @@ def analyze_logs(analyzers, markers, node=None, results=None, fail_test=True, st dut_analyzer.analyze(markers[node.hostname], fail_test, store_la_logs=store_la_logs) +@pytest.fixture(scope="module") +def log_rotate_modular_chassis(duthosts, request): + # The process of logrotate will take up to 2 minutes each test for modular chassis. + # This will add-up as the number of tests we have. As a result for modular chassis we want to run logrotate + # as "module" scope instead of "function" scope. + if request.config.getoption("--disable_loganalyzer") or "disable_loganalyzer" in request.keywords: + return + + is_modular_chassis = duthosts[0].get_facts().get("modular_chassis") + + if not is_modular_chassis: + return + + parallel_run(analyzer_logrotate, [], {}, duthosts, timeout=120) + + @pytest.fixture(autouse=True) -def loganalyzer(duthosts, request): +def loganalyzer(duthosts, request, log_rotate_modular_chassis): if request.config.getoption("--disable_loganalyzer") or "disable_loganalyzer" in request.keywords: logging.info("Log analyzer is disabled") yield @@ -57,7 +73,11 @@ def loganalyzer(duthosts, request): store_la_logs = request.config.getoption("--store_la_logs") analyzers = {} should_rotate_log = request.config.getoption("--loganalyzer_rotate_logs") - if should_rotate_log: + is_modular_chassis = duthosts[0].get_facts().get("modular_chassis") + + # We make sure only run logrotate as "function" scope for non-modular chassis for optimisation purpose. + # For modular chassis please refer to "log_rotate_modular_chassis" fixture + if should_rotate_log and not is_modular_chassis: parallel_run(analyzer_logrotate, [], {}, duthosts, timeout=120) for duthost in duthosts: analyzer = LogAnalyzer(ansible_host=duthost, marker_prefix=request.node.name) From f0d731776a71d3ad45b0054efa50556750dd5f0e Mon Sep 17 00:00:00 2001 From: Yatish Koul <36380820+yatishkoul@users.noreply.github.com> Date: Thu, 31 Oct 2024 08:52:49 -0700 Subject: [PATCH 030/221] Fix for test_voq_ip_fwd (#15209) * Update test_voq_ipfwd.py --- tests/voq/test_voq_ipfwd.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/voq/test_voq_ipfwd.py b/tests/voq/test_voq_ipfwd.py index dee41e3fd52..fd7750b607c 100644 --- a/tests/voq/test_voq_ipfwd.py +++ b/tests/voq/test_voq_ipfwd.py @@ -579,9 +579,13 @@ def test_host_route_table_nbr_lb_addr(self, duthosts, enum_rand_one_per_hwsku_fr neighs = cfg_facts['BGP_NEIGHBOR'] # Remove the neighbor if BGP neighbor is of type RegionalHub + keys_to_remove = [] for k, v in neighs.items(): if v['name'] in dev_rh_neigh: - neighs.pop(k) + keys_to_remove.append(k) + + for k in keys_to_remove: + neighs.pop(k) for neighbor in neighs: local_ip = neighs[neighbor]['local_addr'] From 9a53416d4c1be02f21534a9dd2b592cb8223d696 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam <163894573+vvolam@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:12:07 -0700 Subject: [PATCH 031/221] Replace commas before converting to an integer (#15265) --- tests/platform_tests/test_intf_fec.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/platform_tests/test_intf_fec.py b/tests/platform_tests/test_intf_fec.py index 0b53c9db081..88b6fcdc557 100644 --- a/tests/platform_tests/test_intf_fec.py +++ b/tests/platform_tests/test_intf_fec.py @@ -130,9 +130,9 @@ def test_verify_fec_stats_counters(duthosts, enum_rand_one_per_hwsku_frontend_ho fec_symbol_err = intf.get('fec_symbol_err', '').lower() # Check if fec_corr, fec_uncorr, and fec_symbol_err are valid integers try: - fec_corr_int = int(fec_corr) - fec_uncorr_int = int(fec_uncorr) - fec_symbol_err_int = int(fec_symbol_err) + fec_corr_int = int(fec_corr.replace(',', '')) + fec_uncorr_int = int(fec_uncorr.replace(',', '')) + fec_symbol_err_int = int(fec_symbol_err.replace(',', '')) except ValueError: pytest.fail("FEC stat counters are not valid integers for interface {}, \ fec_corr: {} fec_uncorr: {} fec_symbol_err: {}" From 952ed8a31d2da70f92e88b3340f4b7fbe18403ea Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Fri, 1 Nov 2024 01:20:27 +0800 Subject: [PATCH 032/221] Increase the ready timeout for fast reboot test (#15143) Increase the ready timeout from 180 to 540 Change-Id: Ic07c4a2e2c504d78f4026af67d059a0884bbe5b7 --- ansible/roles/test/tasks/common_tasks/reboot_sonic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/test/tasks/common_tasks/reboot_sonic.yml b/ansible/roles/test/tasks/common_tasks/reboot_sonic.yml index b241d4b59ac..d520b4413b4 100644 --- a/ansible/roles/test/tasks/common_tasks/reboot_sonic.yml +++ b/ansible/roles/test/tasks/common_tasks/reboot_sonic.yml @@ -9,7 +9,7 @@ - name: set default value for sonic ready timeout set_fact: - ready_timeout: 180 + ready_timeout: 540 when: ready_timeout is not defined - fail: From aa018dfc2b8b0a395d6eb695ce0a34f2b9079c5d Mon Sep 17 00:00:00 2001 From: "Nana@Nvidia" <78413612+nhe-NV@users.noreply.github.com> Date: Fri, 1 Nov 2024 01:24:30 +0800 Subject: [PATCH 033/221] Add memory usage checker for the stress route test (#14240) --- tests/stress/test_stress_routes.py | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/stress/test_stress_routes.py b/tests/stress/test_stress_routes.py index 78ddbb6e094..ba984c12824 100644 --- a/tests/stress/test_stress_routes.py +++ b/tests/stress/test_stress_routes.py @@ -76,6 +76,10 @@ def test_announce_withdraw_route(duthosts, localhost, tbinfo, get_function_compl loop_times = LOOP_TIMES_LEVEL_MAP[normalized_level] + frr_demons_to_check = ['bgpd', 'zebra'] + start_time_frr_daemon_memory = get_frr_daemon_memory_usage(duthost, frr_demons_to_check) + logging.info(f"memory usage at start: {start_time_frr_daemon_memory}") + while loop_times > 0: announce_withdraw_routes(duthost, namespace, localhost, ptf_ip, topo_name) loop_times -= 1 @@ -89,3 +93,46 @@ def test_announce_withdraw_route(duthosts, localhost, tbinfo, get_function_compl "ipv4 route used after is not equal to it used before") pytest_assert(abs(ipv6_route_used_after - ipv6_route_used_before) < ALLOW_ROUTES_CHANGE_NUMS, "ipv6 route used after is not equal to it used before") + + end_time_frr_daemon_memory = get_frr_daemon_memory_usage(duthost, frr_demons_to_check) + logging.info(f"memory usage at end: {end_time_frr_daemon_memory}") + check_memory_usage_is_expected(duthost, frr_demons_to_check, start_time_frr_daemon_memory, + end_time_frr_daemon_memory) + + +def check_memory_usage_is_expected(duthost, frr_demons_to_check, start_time_frr_daemon_memory, + end_time_frr_daemon_memory): + + unsupported_branches = ['202012', '202205', '202211', '202305', '202311', "20405"] + if duthost.os_version in unsupported_branches or duthost.sonic_release in unsupported_branches: + logger.info("Only check the memory usage after the 202405") + return "" + incr_frr_daemon_memory_threshold_dict = { + "bgpd": 100, + "zebra": 200 + } # unit is MiB + for daemon in frr_demons_to_check: + logging.info(f"{daemon} memory usage at end: \n%s", end_time_frr_daemon_memory[daemon]) + + # Calculate diff in FRR daemon memory + incr_frr_daemon_memory = \ + float(end_time_frr_daemon_memory[daemon]) - float(start_time_frr_daemon_memory[daemon]) + logging.info(f"{daemon} absolute difference: %d", incr_frr_daemon_memory) + pytest_assert(incr_frr_daemon_memory < incr_frr_daemon_memory_threshold_dict[daemon], + f"The increase memory should not exceed than {incr_frr_daemon_memory_threshold_dict[daemon]} MiB") + + +def get_frr_daemon_memory_usage(duthost, daemon_list): + frr_daemon_memory_dict = {} + for daemon in daemon_list: + frr_daemon_memory_output = duthost.shell(f'vtysh -c "show memory {daemon}"')["stdout"] + logging.info(f"{daemon} memory status: \n%s", frr_daemon_memory_output) + output = duthost.shell(f'vtysh -c "show memory {daemon}" | grep "Free ordinary blocks"')["stdout"] + frr_daemon_memory = output.split()[-2] + unit = output.split()[-1] + if unit == "KiB": + frr_daemon_memory = frr_daemon_memory / 1000 + elif unit == "GiB": + frr_daemon_memory = frr_daemon_memory * 1000 + frr_daemon_memory_dict[daemon] = frr_daemon_memory + return frr_daemon_memory_dict From 15176b2589b7b5aa8678c5c69153bc47127cf893 Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Fri, 1 Nov 2024 01:24:50 +0800 Subject: [PATCH 034/221] Add port status check for config reload in function __dut_reload (#14915) Avoid following script failed due to port not recovered Change-Id: Id991980f4ce49c3bd6d1086f3df912575f1c3ac0 --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8a2cff90483..8e9e7ce2674 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2354,7 +2354,7 @@ def __dut_reload(duts_data, node=None, results=None): node.copy(src=asic_cfg_file, dest='/etc/sonic/config_db{}.json'.format(asic_index), verbose=False) os.remove(asic_cfg_file) - config_reload(node, wait_before_force_reload=300, safe_reload=True) + config_reload(node, wait_before_force_reload=300, safe_reload=True, check_intf_up_ports=True) def compare_running_config(pre_running_config, cur_running_config): From 5e28d5e4e7aab06d33a975f9ccd85e7cade84c9f Mon Sep 17 00:00:00 2001 From: mannytaheri <86314901+mannytaheri@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:29:59 -0400 Subject: [PATCH 035/221] Use lldp0/lldp1 instead of lldp, since container lldp was removed from the host (#13172) Use lldp0/lldp1 instead of lldp, since container lldp was removed from the host --- tests/lldp/test_lldp.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/lldp/test_lldp.py b/tests/lldp/test_lldp.py index 2f9fa91b216..eb3183b93f4 100644 --- a/tests/lldp/test_lldp.py +++ b/tests/lldp/test_lldp.py @@ -64,18 +64,19 @@ def test_lldp(duthosts, enum_rand_one_per_hwsku_frontend_hostname, localhost, def check_lldp_neighbor(duthost, localhost, eos, sonic, collect_techsupport_all_duts, - enum_frontend_asic_index, tbinfo, request): + enum_rand_one_frontend_asic_index, tbinfo, request): """ verify LLDP information on neighbors """ + asic = enum_rand_one_frontend_asic_index res = duthost.shell( - "docker exec -i lldp lldpcli show chassis | grep \"SysDescr:\" | sed -e 's/^\\s*SysDescr:\\s*//g'") + "docker exec -i lldp{} lldpcli show chassis | grep \"SysDescr:\" | sed -e 's/^\\s*SysDescr:\\s*//g'".format( + '' if asic is None else asic)) dut_system_description = res['stdout'] internal_port_list = get_dpu_npu_ports_from_hwsku(duthost) lldpctl_facts = duthost.lldpctl_facts( - asic_instance_id=enum_frontend_asic_index, + asic_instance_id=asic, skip_interface_pattern_list=["eth0", "Ethernet-BP", "Ethernet-IB"] + internal_port_list)['ansible_facts'] - config_facts = duthost.asic_instance(enum_frontend_asic_index).config_facts(host=duthost.hostname, - source="running")['ansible_facts'] + config_facts = duthost.asic_instance(asic).config_facts(host=duthost.hostname, source="running")['ansible_facts'] if not list(lldpctl_facts['lldpctl'].items()): pytest.fail("No LLDP neighbors received (lldpctl_facts are empty)") # We use the MAC of mgmt port to generate chassis ID as LLDPD dose. From 8e376b6122cc87dd9ff0efc1bfd89eb5185c3eb0 Mon Sep 17 00:00:00 2001 From: arista-nwolfe <94405414+arista-nwolfe@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:33:26 -0400 Subject: [PATCH 036/221] Multi-asic fixes for `lldp/test_lldp_syncd.py` (#15258) Various multi-asic fixes in lldp/test_lldp_syncd.py Fix helper functions db_instance, get_lldp_entry_keys, get_lldp_entry_content, get_lldpctl_output to query both namespaces test_lldp_entry_table_after_flap Ignore routeCheck log errors as this test flaps ports and churns routes ignore_expected_loganalyzer_exceptions Don't skip the test if it finds eth0 port, just continue Add namespace to config interface commands Increase delay from 5s to 10s as verify_lldp_entry was seeing the stale LLDP_ENTRY from before link flap and returning True test_lldp_entry_table_after_lldp_restart Query the per-namespace lldp docker when available test_lldp_entry_table_after_reboot wait until check_intf_up_ports=True when rebooting, otherwise the LLDP_ENTRY may flap when the ports come up --- tests/lldp/test_lldp_syncd.py | 76 ++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/tests/lldp/test_lldp_syncd.py b/tests/lldp/test_lldp_syncd.py index 941d0b2dbb1..7cce1ec3b14 100644 --- a/tests/lldp/test_lldp_syncd.py +++ b/tests/lldp/test_lldp_syncd.py @@ -17,23 +17,44 @@ ] +@pytest.fixture(scope="function") +def ignore_expected_loganalyzer_exceptions(duthosts, loganalyzer): + """Ignore expected failures logs during test execution.""" + if loganalyzer: + for duthost in duthosts: + loganalyzer[duthost.hostname].ignore_regex.extend( + [ + # Interface flaps in test_lldp_entry_table_after_flap can cause routeCheck to fail momentarily + r".*ERR.* 'routeCheck' status failed.*", + ] + ) + + @pytest.fixture(autouse="True") def db_instance(duthosts, enum_rand_one_per_hwsku_frontend_hostname): duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] - appl_db = SonicDbCli(duthost, APPL_DB) + appl_db = [] + for asic in duthost.asics: + appl_db.append(SonicDbCli(asic, APPL_DB)) # Cleanup code here return appl_db # Helper function to get the LLDP_ENTRY_TABLE keys -def get_lldp_entry_keys(db): - items = db.get_keys("LLDP_ENTRY_TABLE*") - return [key.split(":")[1] for key in items] +def get_lldp_entry_keys(dbs): + lldp_entries = [] + for db in dbs: + items = db.get_keys("LLDP_ENTRY_TABLE*") + lldp_entries.extend([key.split(":")[1] for key in items]) + return lldp_entries # Helper function to get LLDP_ENTRY_TABLE content -def get_lldp_entry_content(db, interface): - return db.hget_all("LLDP_ENTRY_TABLE:{}".format(interface)) +def get_lldp_entry_content(dbs, interface): + lldp_content = {} + for db in dbs: + lldp_content.update(db.hget_all("LLDP_ENTRY_TABLE:{}".format(interface))) + return lldp_content # Helper function to get lldptcl output @@ -46,8 +67,18 @@ def get_lldpctl_facts_output(duthost, enum_frontend_asic_index): def get_lldpctl_output(duthost): - result = duthost.shell("docker exec lldp /usr/sbin/lldpctl -f json")["stdout"] - return json.loads(result) + if duthost.is_multi_asic: + resultDict = {} + for asic in duthost.asics: + result = duthost.shell("docker exec lldp{} /usr/sbin/lldpctl -f json".format(asic.asic_index))["stdout"] + if not resultDict: + resultDict = json.loads(result) + else: + resultDict['lldp']['interface'].extend(json.loads(result)['lldp']['interface']) + else: + result = duthost.shell("docker exec lldp /usr/sbin/lldpctl -f json")["stdout"] + resultDict = json.loads(result) + return resultDict # Helper function to get show lldp table output @@ -193,7 +224,7 @@ def test_lldp_entry_table_content( # Test case 3: Verify LLDP_ENTRY_TABLE after interface flap def test_lldp_entry_table_after_flap( - duthosts, enum_rand_one_per_hwsku_frontend_hostname, db_instance + duthosts, enum_rand_one_per_hwsku_frontend_hostname, db_instance, ignore_expected_loganalyzer_exceptions ): duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] # Fetch interfaces from LLDP_ENTRY_TABLE @@ -203,11 +234,15 @@ def test_lldp_entry_table_after_flap( for interface in lldp_entry_keys: if interface == "eth0": - pytest.skip("Skipping test for eth0 interface") + # Skip test for 'eth0' interface + continue # Shutdown and startup the interface - duthost.shell("sudo config interface shutdown {}".format(interface)) - duthost.shell("sudo config interface startup {}".format(interface)) - result = wait_until(60, 2, 5, verify_lldp_entry, db_instance, interface) + asicStr = "" + if duthost.is_multi_asic: + asicStr = "-n {}".format(duthost.get_port_asic_instance(interface).get_asic_namespace()) + duthost.shell("sudo config interface {} shutdown {}".format(asicStr, interface)) + duthost.shell("sudo config interface {} startup {}".format(asicStr, interface)) + result = wait_until(60, 2, 10, verify_lldp_entry, db_instance, interface) pytest_assert( result, "After interface {} flap, no LLDP_ENTRY_TABLE entry for it.".format( @@ -250,16 +285,18 @@ def test_lldp_entry_table_after_lldp_restart( lldpctl_output = get_lldpctl_output(duthost) # Restart the LLDP service - duthost.shell("sudo systemctl restart lldp") + for asic in duthost.asics: + duthost.shell("sudo systemctl restart {}".format(asic.get_service_name('lldp'))) result = wait_until( 60, 2, 5, verify_lldp_table, duthost ) # Adjust based on LLDP service restart time pytest_assert(result, "no output for show lldp table after restarting lldp") - result = duthost.shell("sudo systemctl status lldp")["stdout"] - pytest_assert( - "active (running)" in result, - "LLDP service is not running", - ) + for asic in duthost.asics: + result = duthost.shell("sudo systemctl status {}".format(asic.get_service_name('lldp')))["stdout"] + pytest_assert( + "active (running)" in result, + "LLDP service is not running", + ) lldpctl_interfaces = lldpctl_output["lldp"]["interface"] assert_lldp_interfaces( lldp_entry_keys, show_lldp_table_int_list, lldpctl_interfaces @@ -296,6 +333,7 @@ def test_lldp_entry_table_after_reboot( reboot_helper=None, reboot_kwargs=None, safe_reboot=True, + check_intf_up_ports=True ) lldpctl_interfaces = lldpctl_output["lldp"]["interface"] assert_lldp_interfaces( From b426c628e97e91e6df4a6396684de0014ef43537 Mon Sep 17 00:00:00 2001 From: Chenyang Wang <49756587+cyw233@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:23:39 +1100 Subject: [PATCH 037/221] fix: handle EOFError for cache reading (#15298) Description of PR When parallel run is enabled, multiple processes may try to read/write the same cache file, so there will be a small chance that the file is being written by process 1 while process 2 is reading it, which will cause EOFError in process 2. In this case, we will retry reading the file in process 2. If we still get EOFError after some retry attempts, we will return NOTEXIST to overwrite the file. In the meantime, we should also optimize how we initialize the DUT hosts when parallel run is enabled to reduce the chance of having such cache read issue. Summary: Fixes # (issue) Microsoft ADO 30031372 Approach What is the motivation for this PR? To prevent EOFError when reading cache file when parallel run is enabled. How did you do it? Add retry mechanism and optimize how DUT hosts are initialized when parallel is enabled. How did you verify/test it? I ran the updated code and can confirm parallel run is still working as expected. co-authorized by: jianquanye@microsoft.com --- tests/common/cache/facts_cache.py | 30 ++++++++++++++++++++++---- tests/common/devices/duthosts.py | 35 ++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/tests/common/cache/facts_cache.py b/tests/common/cache/facts_cache.py index 07f35f29132..965f4a1a42a 100644 --- a/tests/common/cache/facts_cache.py +++ b/tests/common/cache/facts_cache.py @@ -6,6 +6,7 @@ import pickle import shutil import sys +import time from collections import defaultdict from threading import Lock @@ -67,6 +68,12 @@ def _check_usage(self): .format(total_size, SIZE_LIMIT, total_entries, ENTRY_LIMIT) raise Exception(msg) + def _read_facts_file(self, facts_file, z, k): + with open(facts_file, 'rb') as f: + self._cache[z][k] = pickle.load(f) + logger.debug('[Cache] Loaded cached facts "{}.{}" from {}'.format(z, k, facts_file)) + return self._cache[z][k] + def read(self, zone, key): """Read cached facts. @@ -85,14 +92,29 @@ def read(self, zone, key): else: facts_file = os.path.join(self._cache_location, '{}/{}.pickle'.format(zone, key)) try: - with open(facts_file, 'rb') as f: - self._cache[zone][key] = pickle.load(f) - logger.debug('[Cache] Loaded cached facts "{}.{}" from {}'.format(zone, key, facts_file)) - return self._cache[zone][key] + return self._read_facts_file(facts_file, zone, key) except (IOError, ValueError) as e: logger.info('[Cache] Load cache file "{}" failed with exception: {}' .format(os.path.abspath(facts_file), repr(e))) return self.NOTEXIST + except EOFError as eof_err: + # When parallel run is enabled, multiple processes may try to read/write the same cache file, + # so there will be a chance that the file is being written by process 1 while process 2 is reading + # it, which will cause EOFError in process 2. In this case, we will retry reading the file in + # process 2. If we still get EOFError after retrying, we will return NOTEXIST to overwrite the file. + retry_attempts = 3 + retry_interval = 5 + for attempt in range(retry_attempts): + time.sleep(retry_interval) + try: + return self._read_facts_file(facts_file, zone, key) + except EOFError: + logger.warning('[Cache] Retry {}/{} failed for file "{}"' + .format(attempt + 1, retry_attempts, facts_file)) + + logger.error('[Cache] Load cache file "{}" failed with exception: {}' + .format(facts_file, repr(eof_err))) + return self.NOTEXIST def write(self, zone, key, value): """Store facts to cache. diff --git a/tests/common/devices/duthosts.py b/tests/common/devices/duthosts.py index 3715cb35e76..88db8181c06 100644 --- a/tests/common/devices/duthosts.py +++ b/tests/common/devices/duthosts.py @@ -72,18 +72,29 @@ def __init__(self, ansible_adhoc, tbinfo, request, duts, target_hostname=None, i self.__initialize_nodes() def __initialize_nodes_for_parallel(self): - self._nodes_for_parallel_initial_checks = self._Nodes([ - MultiAsicSonicHost( - self.ansible_adhoc, - hostname, - self, - self.tbinfo['topo']['type'], - ) for hostname in self.tbinfo["duts"] - ]) - - self._nodes_for_parallel_tests = self._Nodes([ - node for node in self._nodes_for_parallel_initial_checks if node.hostname == self.target_hostname - ]) + if self.is_parallel_leader: + self._nodes_for_parallel_initial_checks = self._Nodes([ + MultiAsicSonicHost( + self.ansible_adhoc, + hostname, + self, + self.tbinfo['topo']['type'], + ) for hostname in self.tbinfo["duts"] + ]) + + self._nodes_for_parallel_tests = self._Nodes([ + node for node in self._nodes_for_parallel_initial_checks if node.hostname == self.target_hostname + ]) + else: + self._nodes_for_parallel_initial_checks = None + self._nodes_for_parallel_tests = self._Nodes([ + MultiAsicSonicHost( + self.ansible_adhoc, + self.target_hostname, + self, + self.tbinfo['topo']['type'], + ) + ]) self._nodes_for_parallel = ( self._nodes_for_parallel_initial_checks if self.is_parallel_leader else self._nodes_for_parallel_tests From 7d7b09da3e57a46029c0df83fbf95f22e57860b4 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:27:08 -0700 Subject: [PATCH 038/221] Move the common code from testcases to the fixtures. (#15099) Description of PR Summary: Snappi reboot testcases don't save the config before rebooting the DUT. This causes the DUT to loose all the config, and the test fails with "ARP is not resolved" errors. This PR addresses this issue by saving the config before any reboot. Also this PR moves the code that is reused in multiple tests to a common code. co-authorized by: jianquanye@microsoft.com --- tests/common/snappi_tests/qos_fixtures.py | 61 +++++ tests/common/snappi_tests/snappi_fixtures.py | 46 +++- tests/snappi_tests/files/helper.py | 94 +++++++- .../multidut/pfc/files/multidut_helper.py | 8 +- ...multidut_pfc_pause_lossless_with_snappi.py | 217 ++++-------------- tests/snappi_tests/test_multidut_snappi.py | 53 ++--- 6 files changed, 258 insertions(+), 221 deletions(-) diff --git a/tests/common/snappi_tests/qos_fixtures.py b/tests/common/snappi_tests/qos_fixtures.py index e85ab866487..b7aa795da02 100644 --- a/tests/common/snappi_tests/qos_fixtures.py +++ b/tests/common/snappi_tests/qos_fixtures.py @@ -1,4 +1,9 @@ import pytest +import time +import json +from tests.common.snappi_tests.common_helpers import \ + stop_pfcwd, disable_packet_aging, enable_packet_aging +from tests.common.utilities import get_running_config """ RDMA test cases may require variety of fixtures. This @@ -106,3 +111,59 @@ def lossy_prio_list(all_prio_list, lossless_prio_list): """ result = [x for x in all_prio_list if x not in lossless_prio_list] return result + + +# Introducing these functions, since the existing pfcwd-start function +# uses start-default. The start-default starts pfcwd only if the config +# is enabled by default. Since we need a definite way to start pfcwd, +# the following functions are introduced. +def get_pfcwd_config(duthost): + config = get_running_config(duthost) + if "PFC_WD" in config.keys(): + return config['PFC_WD'] + else: + all_configs = [] + output = duthost.shell("ip netns | awk '{print $1}'")['stdout'] + all_asic_list = output.split("\n") + all_asic_list.append(None) + for space in all_asic_list: + config = get_running_config(duthost, space) + if "PFC_WD" in config.keys(): + all_configs.append(config['PFC_WD']) + else: + all_configs.append({}) + return all_configs + + +def reapply_pfcwd(duthost, pfcwd_config): + timestamp = time.time() + file_prefix = f"{timestamp}_pfcwd" + if type(pfcwd_config) is dict: + duthost.copy(content=json.dumps({"PFC_WD": pfcwd_config}, indent=4), dest=file_prefix) + duthost.shell(f"config load {file_prefix} -y") + elif type(pfcwd_config) is list: + output = duthost.shell("ip netns | awk '{print $1}'")['stdout'] + all_asic_list = output.split("\n") + all_asic_list.append(None) + + all_files = [] + for index, config in enumerate(pfcwd_config): + filename = "{}_{}.json".format(file_prefix, all_asic_list[index]) + duthost.copy(content=json.dumps({"PFC_WD": config}, indent=4), dest=filename) + all_files.append(filename) + duthost.shell("config load {} -y".format(",".join(all_files))) + else: + raise RuntimeError(f"Script problem: Got an unsupported type of pfcwd_config:{pfcwd_config}") + + +@pytest.fixture(autouse=False) +def disable_pfcwd(duthosts): + pfcwd_value = {} + for duthost in duthosts: + pfcwd_value[duthost.hostname] = get_pfcwd_config(duthost) + stop_pfcwd(duthost) + disable_packet_aging(duthost) + yield + for duthost in duthosts: + reapply_pfcwd(duthost, pfcwd_value[duthost.hostname]) + enable_packet_aging(duthost) diff --git a/tests/common/snappi_tests/snappi_fixtures.py b/tests/common/snappi_tests/snappi_fixtures.py index 4bd8f0e80d1..6b268b3e409 100755 --- a/tests/common/snappi_tests/snappi_fixtures.py +++ b/tests/common/snappi_tests/snappi_fixtures.py @@ -19,6 +19,8 @@ from tests.snappi_tests.variables import dut_ip_start, snappi_ip_start, prefix_length, \ dut_ipv6_start, snappi_ipv6_start, v6_prefix_length, pfcQueueGroupSize, \ pfcQueueValueDict # noqa: F401 + + logger = logging.getLogger(__name__) @@ -552,7 +554,8 @@ def cvg_api(snappi_api_serv_ip, def snappi_dut_base_config(duthost_list, snappi_ports, - snappi_api): + snappi_api, + setup=True): """ Generate snappi API config and port config information for the testbed Args: @@ -613,18 +616,33 @@ def snappi_dut_base_config(duthost_list, port_config_list = [] + return (setup_dut_ports( + setup=setup, + duthost_list=duthost_list, + config=config, + port_config_list=port_config_list, + snappi_ports=new_snappi_ports)) + + +def setup_dut_ports( + setup, + duthost_list, + config, + port_config_list, + snappi_ports): + for index, duthost in enumerate(duthost_list): config_result = __vlan_intf_config(config=config, port_config_list=port_config_list, duthost=duthost, - snappi_ports=new_snappi_ports) + snappi_ports=snappi_ports) pytest_assert(config_result is True, 'Fail to configure Vlan interfaces') for index, duthost in enumerate(duthost_list): config_result = __portchannel_intf_config(config=config, port_config_list=port_config_list, duthost=duthost, - snappi_ports=new_snappi_ports) + snappi_ports=snappi_ports) pytest_assert(config_result is True, 'Fail to configure portchannel interfaces') if is_snappi_multidut(duthost_list): @@ -633,17 +651,18 @@ def snappi_dut_base_config(duthost_list, config=config, port_config_list=port_config_list, duthost=duthost, - snappi_ports=new_snappi_ports) + snappi_ports=snappi_ports, + setup=setup) pytest_assert(config_result is True, 'Fail to configure multidut L3 interfaces') else: for index, duthost in enumerate(duthost_list): config_result = __l3_intf_config(config=config, port_config_list=port_config_list, duthost=duthost, - snappi_ports=new_snappi_ports) + snappi_ports=snappi_ports) pytest_assert(config_result is True, 'Fail to configure L3 interfaces') - return config, port_config_list, new_snappi_ports + return config, port_config_list, snappi_ports @pytest.fixture(scope="function") @@ -772,7 +791,7 @@ def __intf_config(config, port_config_list, duthost, snappi_ports): return True -def __intf_config_multidut(config, port_config_list, duthost, snappi_ports): +def __intf_config_multidut(config, port_config_list, duthost, snappi_ports, setup=True): """ Configures interfaces of the DUT Args: @@ -780,6 +799,7 @@ def __intf_config_multidut(config, port_config_list, duthost, snappi_ports): port_config_list (list): list of Snappi port configuration information duthost (object): device under test snappi_ports (list): list of Snappi port information + setup: Setting up or teardown? True or False Returns: True if we successfully configure the interfaces or False """ @@ -797,17 +817,25 @@ def __intf_config_multidut(config, port_config_list, duthost, snappi_ports): port['peer_port'], dutIp, prefix_length)) + if setup: + cmd = "add" + else: + cmd = "remove" if port['asic_value'] is None: - duthost.command('sudo config interface ip add {} {}/{} \n' .format( + duthost.command('sudo config interface ip {} {} {}/{} \n' .format( + cmd, port['peer_port'], dutIp, prefix_length)) else: - duthost.command('sudo config interface -n {} ip add {} {}/{} \n' .format( + duthost.command('sudo config interface -n {} ip {} {} {}/{} \n' .format( port['asic_value'], + cmd, port['peer_port'], dutIp, prefix_length)) + if setup is False: + continue port['intf_config_changed'] = True device = config.devices.device(name='Device Port {}'.format(port_id))[-1] ethernet = device.ethernets.add() diff --git a/tests/snappi_tests/files/helper.py b/tests/snappi_tests/files/helper.py index f8a7f26900d..60be345f6d3 100644 --- a/tests/snappi_tests/files/helper.py +++ b/tests/snappi_tests/files/helper.py @@ -1,6 +1,17 @@ +import logging +import pytest from tests.common.broadcom_data import is_broadcom_device from tests.common.helpers.assertions import pytest_require from tests.common.cisco_data import is_cisco_device +from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED +from tests.common.config_reload import config_reload +from tests.common.reboot import reboot +from tests.common.helpers.parallel import parallel_run +from tests.common.utilities import wait_until +from tests.common.snappi_tests.snappi_fixtures import get_snappi_ports_for_rdma, \ + snappi_dut_base_config + +logger = logging.getLogger(__name__) def skip_warm_reboot(duthost, reboot_type): @@ -21,8 +32,10 @@ def skip_warm_reboot(duthost, reboot_type): reboot_case_supported = False elif is_broadcom_device(duthost) and asic_type in SKIP_LIST and "warm" in reboot_type: reboot_case_supported = False - pytest_require(reboot_case_supported, "Reboot type {} is not supported on {} switches". - format(reboot_type, duthost.facts['asic_type'])) + msg = "Reboot type {} is {} supported on {} switches".format( + reboot_type, "" if reboot_case_supported else "not", duthost.facts['asic_type']) + logger.info(msg) + pytest_require(reboot_case_supported, msg) def skip_ecn_tests(duthost): @@ -55,3 +68,80 @@ def skip_pfcwd_test(duthost, trigger_pfcwd): """ pytest_require(trigger_pfcwd is True or is_broadcom_device(duthost) is False, 'Skip trigger_pfcwd=False test cases for Broadcom devices') + + +@pytest.fixture(autouse=True, params=MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) +def multidut_port_info(request): + yield request.param + + +@pytest.fixture(autouse=True) +def setup_ports_and_dut( + duthosts, + snappi_api, + get_snappi_ports, + multidut_port_info, + number_of_tx_rx_ports): + for testbed_subtype, rdma_ports in multidut_port_info.items(): + tx_port_count, rx_port_count = number_of_tx_rx_ports + if len(get_snappi_ports) < tx_port_count + rx_port_count: + pytest.skip( + "Need Minimum of 2 ports defined in ansible/files/*links.csv" + " file, got:{}".format(len(get_snappi_ports))) + + if len(rdma_ports['tx_ports']) < tx_port_count: + pytest.skip( + "MULTIDUT_PORT_INFO doesn't have the required Tx ports defined for " + "testbed {}, subtype {} in variables.py".format( + MULTIDUT_TESTBED, testbed_subtype)) + + if len(rdma_ports['rx_ports']) < rx_port_count: + pytest.skip( + "MULTIDUT_PORT_INFO doesn't have the required Rx ports defined for " + "testbed {}, subtype {} in variables.py".format( + MULTIDUT_TESTBED, testbed_subtype)) + logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) + snappi_ports = get_snappi_ports_for_rdma( + get_snappi_ports, + rdma_ports, + tx_port_count, + rx_port_count, + MULTIDUT_TESTBED) + testbed_config, port_config_list, snappi_ports = snappi_dut_base_config( + duthosts, snappi_ports, snappi_api, setup=True) + + if len(port_config_list) < 2: + pytest.skip("This test requires at least 2 ports") + yield (testbed_config, port_config_list, snappi_ports) + + snappi_dut_base_config(duthosts, snappi_ports, snappi_api, setup=False) + + +@pytest.fixture(params=['warm', 'cold', 'fast']) +def reboot_duts(setup_ports_and_dut, localhost, request): + reboot_type = request.param + _, _, snappi_ports = setup_ports_and_dut + skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) + skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) + + def save_config_and_reboot(node, results=None): + logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, node.hostname)) + node.shell("mkdir /etc/sonic/orig_configs; mv /etc/sonic/config_db* /etc/sonic/orig_configs/") + node.shell("sudo config save -y") + reboot(node, localhost, reboot_type=reboot_type, safe_reboot=True) + logger.info("Wait until the system is stable") + wait_until(180, 20, 0, node.critical_services_fully_started) + + # Convert the list of duthosts into a list of tuples as required for parallel func. + args = set((snappi_ports[0]['duthost'], snappi_ports[1]['duthost'])) + parallel_run(save_config_and_reboot, {}, {}, list(args), timeout=900) + + yield + + def revert_config_and_reload(node, results=None): + node.shell("mv /etc/sonic/orig_configs/* /etc/sonic/ ; rmdir /etc/sonic/orig_configs; ") + config_reload(node, safe_reload=True) + + # parallel_run(revert_config_and_reload, {}, {}, list(args), timeout=900) + for duthost in args: + revert_config_and_reload(node=duthost) diff --git a/tests/snappi_tests/multidut/pfc/files/multidut_helper.py b/tests/snappi_tests/multidut/pfc/files/multidut_helper.py index 56507c4dadf..fbd84fbf08a 100644 --- a/tests/snappi_tests/multidut/pfc/files/multidut_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/multidut_helper.py @@ -6,7 +6,7 @@ fanout_graph_facts # noqa F401 from tests.common.snappi_tests.common_helpers import pfc_class_enable_vector,\ get_lossless_buffer_size, get_pg_dropped_packets,\ - stop_pfcwd, disable_packet_aging, sec_to_nanosec,\ + disable_packet_aging, enable_packet_aging, sec_to_nanosec,\ get_pfc_frame_count, packet_capture, config_capture_pkt,\ traffic_flow_mode, calc_pfc_pause_flow_rate # noqa F401 from tests.common.snappi_tests.port import select_ports, select_tx_port # noqa F401 @@ -91,10 +91,6 @@ def run_pfc_test(api, pytest_assert(testbed_config is not None, 'Fail to get L2/3 testbed config') - for duthost, asic in dut_asics_to_be_configured: - stop_pfcwd(duthost, asic) - disable_packet_aging(duthost) - global DATA_FLOW_DURATION_SEC global data_flow_delay_sec @@ -290,7 +286,7 @@ def run_pfc_test(api, verify_in_flight_buffer_pkts(duthost=egress_duthost, flow_metrics=in_flight_flow_metrics, snappi_extra_params=snappi_extra_params, - asic_value=rx_port['asic_value']) + asic_value=tx_port['asic_value']) else: # Verify zero pause frames are counted when the PFC class enable vector is not set verify_unset_cev_pause_frame_count(duthost=duthost, diff --git a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py index dac9e0348d6..a3e40541bb5 100644 --- a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py +++ b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py @@ -6,32 +6,36 @@ snappi_api, snappi_dut_base_config, get_snappi_ports_for_rdma, cleanup_config, get_snappi_ports_multi_dut, \ snappi_testbed_config, get_snappi_ports_single_dut, \ get_snappi_ports, is_snappi_multidut # noqa: F401 +from tests.snappi_tests.files.helper import multidut_port_info, setup_ports_and_dut, reboot_duts # noqa: F401 from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, all_prio_list, lossless_prio_list,\ - lossy_prio_list # noqa F401 -from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED + lossy_prio_list, disable_pfcwd # noqa F401 from tests.snappi_tests.multidut.pfc.files.multidut_helper import run_pfc_test -from tests.common.reboot import reboot -from tests.common.utilities import wait_until import logging from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.files.helper import skip_warm_reboot + + logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) +@pytest.fixture(autouse=True) +def number_of_tx_rx_ports(): + yield (1, 1) + + def test_pfc_pause_single_lossless_prio(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 - fanout_graph_facts_multidut, # noqa: F811 + fanout_graph_facts_multidut, # noqa: F811 duthosts, enum_dut_lossless_prio, - prio_dscp_map, # noqa: F811 - lossless_prio_list, # noqa: F811 - all_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info): + prio_dscp_map, # noqa: F811 + lossless_prio_list, # noqa: F811 + all_prio_list, # noqa: F811 + get_snappi_ports, # noqa: F811 + tbinfo, # noqa: F811 + disable_pfcwd, # noqa: F811 + setup_ports_and_dut): # noqa: F811 """ Test if PFC can pause a single lossless priority in multidut setup @@ -51,33 +55,8 @@ def test_pfc_pause_single_lossless_prio(snappi_api, # noqa: Returns: N/A """ - snappi_port_list = get_snappi_ports - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut _, lossless_prio = enum_dut_lossless_prio.split('|') lossless_prio = int(lossless_prio) @@ -103,20 +82,18 @@ def test_pfc_pause_single_lossless_prio(snappi_api, # noqa: prio_dscp_map=prio_dscp_map, test_traffic_pause=True, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) -def test_pfc_pause_multi_lossless_prio(snappi_api, # noqa: F811 - conn_graph_facts, # noqa: F811 - fanout_graph_facts_multidut, # noqa: F811 +def test_pfc_pause_multi_lossless_prio(snappi_api, # noqa: F811 + conn_graph_facts, # noqa: F811 + fanout_graph_facts_multidut, # noqa: F811 duthosts, prio_dscp_map, # noqa: F811 lossy_prio_list, # noqa: F811 - lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info): # noqa: F811 + lossless_prio_list, # noqa: F811 + get_snappi_ports, # noqa: F811 + tbinfo, + setup_ports_and_dut): # noqa: F811 """ Test if PFC can pause multiple lossless priorities in multidut setup @@ -134,31 +111,7 @@ def test_pfc_pause_multi_lossless_prio(snappi_api, # noqa: F811 Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut pause_prio_list = lossless_prio_list test_prio_list = lossless_prio_list @@ -180,25 +133,23 @@ def test_pfc_pause_multi_lossless_prio(snappi_api, # noqa: F811 prio_dscp_map=prio_dscp_map, test_traffic_pause=True, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) @pytest.mark.disable_loganalyzer -@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) -def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # noqa: F811 - conn_graph_facts, # noqa: F811 - fanout_graph_facts_multidut, # noqa: F811 +def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # noqa: F811 + conn_graph_facts, # noqa: F811 + fanout_graph_facts_multidut, # noqa: F811 duthosts, localhost, - enum_dut_lossless_prio_with_completeness_level, # noqa: F811 prio_dscp_map, # noqa: F811 lossless_prio_list, # noqa: F811 all_prio_list, # noqa: F811 - reboot_type, get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - multidut_port_info): + enum_dut_lossless_prio_with_completeness_level, # noqa: F811 + setup_ports_and_dut, # noqa: F811 + disable_pfcwd, # noqa: F811 + reboot_duts): # noqa: F811 """ Test if PFC can pause a single lossless priority even after various types of reboot in multidut setup @@ -210,41 +161,14 @@ def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # no localhost (pytest fixture): localhost handle all_prio_list (pytest fixture): list of all the priorities prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + lossless_prio_list (pytest fixture): list of all the lossless priorities enum_dut_lossless_prio_with_completeness_level (str): lossless priority to test, e.g., 's6100-1|3' - reboot_type (str): reboot type to be issued on the DUT tbinfo (pytest fixture): fixture provides information about testbed get_snappi_ports (pytest fixture): gets snappi ports and connected DUT port info and returns as a list Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - - skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) - skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut _, lossless_prio = enum_dut_lossless_prio_with_completeness_level.split('|') lossless_prio = int(lossless_prio) @@ -257,12 +181,6 @@ def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # no snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports - for duthost in set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]): - logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) - reboot(duthost, localhost, reboot_type=reboot_type, safe_reboot=True) - logger.info("Wait until the system is stable") - wait_until(180, 20, 0, duthost.critical_services_fully_started) - run_pfc_test(api=snappi_api, testbed_config=testbed_config, port_config_list=port_config_list, @@ -276,24 +194,21 @@ def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # no test_traffic_pause=True, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) - @pytest.mark.disable_loganalyzer -@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) -def test_pfc_pause_multi_lossless_prio_reboot(snappi_api, # noqa: F811 - conn_graph_facts, # noqa: F811 - fanout_graph_facts_multidut, # noqa: F811 +def test_pfc_pause_multi_lossless_prio_reboot(snappi_api, # noqa: F811 + conn_graph_facts, # noqa: F811 + fanout_graph_facts_multidut, # noqa: F811 duthosts, localhost, - prio_dscp_map, # noqa: F811 - lossy_prio_list, # noqa: F811 - lossless_prio_list, # noqa: F811 - reboot_type, - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info): + prio_dscp_map, # noqa: F811 + lossy_prio_list, # noqa: F811 + lossless_prio_list, # noqa: F811 + get_snappi_ports, # noqa: F811 + tbinfo, # noqa: F811 + setup_ports_and_dut, # noqa: F811 + disable_pfcwd, # noqa: F811 + reboot_duts): # noqa: F811 """ Test if PFC can pause multiple lossless priorities even after various types of reboot in multidut setup @@ -306,39 +221,13 @@ def test_pfc_pause_multi_lossless_prio_reboot(snappi_api, # noq prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). lossless_prio_list (pytest fixture): list of all the lossless priorities lossy_prio_list (pytest fixture): list of all the lossy priorities - reboot_type (str): reboot type to be issued on the DUT tbinfo (pytest fixture): fixture provides information about testbed get_snappi_ports (pytest fixture): gets snappi ports and connected DUT port info and returns as a list Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) - skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut + pause_prio_list = lossless_prio_list test_prio_list = lossless_prio_list bg_prio_list = lossy_prio_list @@ -347,12 +236,6 @@ def test_pfc_pause_multi_lossless_prio_reboot(snappi_api, # noq snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports - for duthost in set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]): - logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) - reboot(duthost, localhost, reboot_type=reboot_type, safe_reboot=True) - logger.info("Wait until the system is stable") - wait_until(180, 20, 0, duthost.critical_services_fully_started) - run_pfc_test(api=snappi_api, testbed_config=testbed_config, port_config_list=port_config_list, @@ -365,5 +248,3 @@ def test_pfc_pause_multi_lossless_prio_reboot(snappi_api, # noq prio_dscp_map=prio_dscp_map, test_traffic_pause=True, snappi_extra_params=snappi_extra_params) - - cleanup_config(duthosts, snappi_ports) diff --git a/tests/snappi_tests/test_multidut_snappi.py b/tests/snappi_tests/test_multidut_snappi.py index 84a6bde8c55..0fd2cc78272 100644 --- a/tests/snappi_tests/test_multidut_snappi.py +++ b/tests/snappi_tests/test_multidut_snappi.py @@ -2,15 +2,15 @@ import pytest import random import logging -from tests.common.helpers.assertions import pytest_assert, pytest_require +from tests.common.helpers.assertions import pytest_assert from tests.common.fixtures.conn_graph_facts import conn_graph_facts, fanout_graph_facts_multidut # noqa: F401 from tests.common.snappi_tests.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port, snappi_api, \ snappi_dut_base_config, get_snappi_ports, get_snappi_ports_for_rdma, cleanup_config, \ get_snappi_ports_multi_dut # noqa: F401 -from tests.common.snappi_tests.snappi_helpers import wait_for_arp from tests.common.snappi_tests.port import select_ports from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, lossless_prio_list # noqa: F401 -from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED +from tests.common.snappi_tests.snappi_helpers import wait_for_arp +from tests.snappi_tests.files.helper import multidut_port_info, setup_ports_and_dut # noqa: F401 logger = logging.getLogger(__name__) SNAPPI_POLL_DELAY_SEC = 2 @@ -90,17 +90,21 @@ def __gen_all_to_all_traffic(testbed_config, return testbed_config -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) +@pytest.fixture(autouse=True) +def number_of_tx_rx_ports(): + yield (1, 1) + + def test_snappi(request, duthosts, - snappi_api, # noqa: F811 - conn_graph_facts, # noqa: F811 - fanout_graph_facts_multidut, # noqa: F811 - lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info, - prio_dscp_map, # noqa: F811 + snappi_api, # noqa: F811 + conn_graph_facts, # noqa: F811 + fanout_graph_facts_multidut, # noqa: F811 + lossless_prio_list, # noqa: F811 + get_snappi_ports, # noqa: F811 + tbinfo, + prio_dscp_map, # noqa: F811 + setup_ports_and_dut # noqa: F811 ): """ @@ -117,34 +121,11 @@ def test_snappi(request, Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut lossless_prio = random.sample(lossless_prio_list, 1) lossless_prio = int(lossless_prio[0]) - pytest_require(len(port_config_list) >= 2, "This test requires at least 2 ports") - config = __gen_all_to_all_traffic(testbed_config=testbed_config, port_config_list=port_config_list, conn_data=conn_graph_facts, From b27ee7868daf5e7a32bb5c3aab7b84c3279cad9b Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:30:24 -0700 Subject: [PATCH 039/221] Adding fixes for the docker0 ipv6 issue. (#14917) Description of PR Summary: In qos-sai-base, there is a docker0 ipv6 checking function, which fails if the DUT has no ipv6 address. The failure signature is as below: 14:50:01 __init__._fixture_generator_decorator L0088 ERROR | IndexError('list index out of range') Traceback (most recent call last): File "/data/tests/common/plugins/log_section_start/__init__.py", line 84, in _fixture_generator_decorator res = next(it) File "/data/tests/qos/qos_sai_base.py", line 1824, in dut_disable_ipv6 duthost.shell("sudo ip -6 addr show dev docker0 | grep global" + " | awk '{print $2}'")[ IndexError: list index out of range Approach What is the motivation for this PR? The failure of the ipv6 disabling fixture. How did you do it? Check if the docker0 has ipv6 address or not. How did you verify/test it? Ran it on my TB: ----------------------------------------------------------------------------- live log sessionfinish ----------------------------------------------------------------------------- 07:42:47 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ============================================================================ short test summary info ============================================================================= PASSED qos/test_qos_sai.py::TestQosSai::testParameter[single_asic] PASSED qos/test_qos_sai.py::TestQosSai::testParameter[single_dut_multi_asic] PASSED qos/test_qos_sai.py::TestQosSai::testParameter[multi_dut_longlink_to_shortlink] PASSED qos/test_qos_sai.py::TestQosSai::testParameter[multi_dut_shortlink_to_shortlink] PASSED qos/test_qos_sai.py::TestQosSai::testParameter[multi_dut_shortlink_to_longlink] =================================================================== 5 passed, 1 warning in 5246.68s (1:27:26) ==================================================================== sonic@202405-qos-sonic-mgmt-prod:/data/tests$ co-authorized by: jianquanye@microsoft.com --- tests/qos/qos_sai_base.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/qos/qos_sai_base.py b/tests/qos/qos_sai_base.py index 2e1db2b4e46..1b2c5d92a66 100644 --- a/tests/qos/qos_sai_base.py +++ b/tests/qos/qos_sai_base.py @@ -1864,18 +1864,30 @@ def populateArpEntries( @pytest.fixture(scope='class', autouse=True) def dut_disable_ipv6(self, duthosts, get_src_dst_asic_and_duts, tbinfo, lower_tor_host, # noqa F811 swapSyncd_on_selected_duts): + all_docker0_ipv6_addrs = {} for duthost in get_src_dst_asic_and_duts['all_duts']: - docker0_ipv6_addr = \ - duthost.shell("sudo ip -6 addr show dev docker0 | grep global" + " | awk '{print $2}'")[ - "stdout_lines"][0] + try: + all_docker0_ipv6_addrs[duthost.hostname] = \ + duthost.shell("sudo ip -6 addr show dev docker0 | grep global" + " | awk '{print $2}'")[ + "stdout_lines"][0] + except IndexError: + logger.info( + "Couldnot get the ipv6 address for docker0 for the" + " host:{}".format(duthost.hostname)) + all_docker0_ipv6_addrs[duthost.hostname] = None + duthost.shell("sysctl -w net.ipv6.conf.all.disable_ipv6=1") yield for duthost in get_src_dst_asic_and_duts['all_duts']: duthost.shell("sysctl -w net.ipv6.conf.all.disable_ipv6=0") - logger.info("Adding docker0's IPv6 address since it was removed when disabing IPv6") - duthost.shell("ip -6 addr add {} dev docker0".format(docker0_ipv6_addr)) + if all_docker0_ipv6_addrs[duthost.hostname] is not None: + logger.info("Adding docker0's IPv6 address since it was removed when disabing IPv6") + duthost.shell("ip -6 addr add {} dev docker0".format(all_docker0_ipv6_addrs[duthost.hostname])) + + # TODO: parallelize this step.. Do we really need this ? + for duthost in get_src_dst_asic_and_duts['all_duts']: config_reload(duthost, config_source='config_db', safe_reload=True, check_intf_up_ports=True) @pytest.fixture(scope='class', autouse=True) From 391f38e4c217ba94bbab7babfd8eb0e8e4b80ea1 Mon Sep 17 00:00:00 2001 From: anamehra <54692434+anamehra@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:35:54 -0700 Subject: [PATCH 040/221] Add all running_golden_config files for multi-asics based on num_asic (#15315) Signed-off-by: anamehra anamehra@cisco.com Description of PR Fixes config reload -y for chassis sup by using num_asics to populate config db file list Summary: Fixes # (issue) Approach What is the motivation for this PR? During some tests, config is restored via config reload using runnin_golden config files. config reload -y expects all n+1 config files be provided as input but sonic-mgmt script only includes the config files for present asics. System had 10 asics but max asics could be 16. The command shows only 10+1(global) config db Before fix: tc/sonic/running_golden_config0.json,/etc/sonic/running_golden_config1.json,/etc/sonic/running_golden_config4.json,/etc/sonic/running_golden_config5.json,/etc/sonic/running_golden_config8.json,/etc/soo nic/running_golden_config9.json,/etc/sonic/running_golden_config10.json,/etc/sonic/running_golden_config11.json,/etc/sonic/running_golden_config12.json,/etc/sonic/running_golden_config13.json &>/dev/nn ull _uses_shell=True warn=False stdin_add_newline=True strip_empty_ends=True argv=None chdir=None creates=None removes=None stdin=None How did you do it? Use num_asics for the DUT host and populate the CLI args list with running_golden_config db file path for each possible asic, present or absent. How did you verify/test it? RUn sonic-mgmt tests suits After fix: Config reload on RP with max 16 asics, 10 resent: 2024 Oct 30 20:45:56.831628 sfd-t2-sup INFO python[3758349]: ansible-ansible.legacy.command Invoked with executable=/bin/bash _raw_params=config reload -y -f -l /etc/sonic/running_golden_config.json,// etc/sonic/running_golden_config0.json,/etc/sonic/running_golden_config1.json,/etc/sonic/running_golden_config2.json,/etc/sonic/running_golden_config3.json,/etc/sonic/running_golden_config4.json,/etc/ss onic/running_golden_config5.json,/etc/sonic/running_golden_config6.json,/etc/sonic/running_golden_config7.json,/etc/sonic/running_golden_config8.json,/etc/sonic/running_golden_config9.json,/etc/sonic// running_golden_config10.json,/etc/sonic/running_golden_config11.json,/etc/sonic/running_golden_config12.json,/etc/sonic/running_golden_config13.json,/etc/sonic/running_golden_config14.json,/etc/sonic// running_golden_config15.json &>/dev/null _uses_shell=True warn=False stdin_add_newline=True strip_empty_ends=True argv=None chdir=None creates=None removes=None stdin=None 2024 Oct 30 20:46:01.770294 sfd-t2-sup NOTICE CCmisApi: 'reload' executing with command: config reload -y -f -l /etc/sonic/running_golden_config.json,/etc/sonic/running_golden_config0.json,/etc/sonic// running_golden_config1.json,/etc/sonic/running_golden_config2.json,/etc/sonic/running_golden_config3.json,/etc/sonic/running_golden_config4.json,/etc/sonic/running_golden_config5.json,/etc/sonic/runnii ng_golden_config6.json,/etc/sonic/running_golden_config7.json,/etc/sonic/running_golden_config8.json,/etc/sonic/running_golden_config9.json,/etc/sonic/running_golden_config10.json,/etc/sonic/running_gg olden_config11.json,/etc/sonic/running_golden_config12.json,/etc/sonic/running_golden_config13.json,/etc/sonic/running_golden_config14.json,/etc/sonic/running_golden_config15.json Config reload on LC with 3 asics: 2024 Oct 30 20:45:53.282867 sfd-t2-lc0 INFO python[86920]: ansible-ansible.legacy.command Invoked with executable=/bin/bash _raw_params=config reload -y -f -l /etc/sonic/running_golden_confii g.json,/etc/sonic/running_golden_config0.json,/etc/sonic/running_golden_config1.json,/etc/sonic/running_golden_config2.json &>/dev/null _uses_shell=True warn=False stdin_add_newline=True strr ip_empty_ends=True argv=None chdir=None creates=None removes=None stdin=None 2024 Oct 30 20:45:54.919206 sfd-t2-lc0 NOTICE CCmisApi: 'reload' executing with command: config reload -y -f -l /etc/sonic/running_golden_config.json,/etc/sonic/running_golden_config0.json,// etc/sonic/running_golden_config1.json,/etc/sonic/running_golden_config2.json 2024 Oct 30 20:45:54.919305 sfd-t2-lc0 NOTICE CCmisApi: 'reload' stopping services... Any platform specific information? Chassis Supervisor Signed-off-by: anamehra anamehra@cisco.com --- tests/common/config_reload.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/config_reload.py b/tests/common/config_reload.py index 1fc41582c2a..ae43156288f 100644 --- a/tests/common/config_reload.py +++ b/tests/common/config_reload.py @@ -183,8 +183,8 @@ def _config_reload_cmd_wrapper(cmd, executable): elif config_source == 'running_golden_config': golden_path = '/etc/sonic/running_golden_config.json' if sonic_host.is_multi_asic: - for asic in sonic_host.asics: - golden_path = f'{golden_path},/etc/sonic/running_golden_config{asic.asic_index}.json' # noqa: E231 + for asic in range(sonic_host.num_asics()): + golden_path = f'{golden_path},/etc/sonic/running_golden_config{asic}.json' # noqa: E231 cmd = f'config reload -y -l {golden_path} &>/dev/null' if config_force_option_supported(sonic_host): cmd = f'config reload -y -f -l {golden_path} &>/dev/null' From 3b0a3c4d824c886a651dc0547e0d165f76df55d8 Mon Sep 17 00:00:00 2001 From: Ryangwaite Date: Fri, 1 Nov 2024 15:35:11 +1100 Subject: [PATCH 041/221] Capture before warm-reboot device logs (#14980) What is the motivation for this PR? Have experienced issues in the reboot tests and were unable to diagnose due to a lack of information in the warm-reboot sequence. How did you do it? Copied across the logs that were already preserved on the device across reboots. How did you verify/test it? Tested internally on A->B and multl-hop upgrade scenarios. --- tests/common/fixtures/advanced_reboot.py | 11 +++++++++++ tests/common/platform/device_utils.py | 2 ++ 2 files changed, 13 insertions(+) diff --git a/tests/common/fixtures/advanced_reboot.py b/tests/common/fixtures/advanced_reboot.py index eeb94e60fe2..74b4d4827b7 100644 --- a/tests/common/fixtures/advanced_reboot.py +++ b/tests/common/fixtures/advanced_reboot.py @@ -435,6 +435,11 @@ def __fetchTestLogs(self, rebootOper=None): os.makedirs(log_dir) log_dir = log_dir + "/" + # Create a sub-directory to store the logs before the reboot happened + log_dir_before_reboot = os.path.join(log_dir, "before_reboot/") + if not os.path.exists(log_dir_before_reboot): + os.makedirs(log_dir_before_reboot) + if "warm" in self.rebootType: # normalize "warm-reboot -f", "warm-reboot -c" to "warm-reboot" for report collection reboot_file_prefix = "warm-reboot" @@ -481,6 +486,12 @@ def __fetchTestLogs(self, rebootOper=None): {'src': syslogFile, 'dest': log_dir, 'flat': True}, {'src': sairedisRec, 'dest': log_dir, 'flat': True}, {'src': swssRec, 'dest': log_dir, 'flat': True}, + # Logs from before reboot + {'src': '/host/syslog.99', 'dest': log_dir_before_reboot, 'flat': True, 'fail_on_missing': False}, + {'src': '/host/sairedis.rec.99', 'dest': log_dir_before_reboot, 'flat': True, + 'fail_on_missing': False}, + {'src': '/host/swss.rec.99', 'dest': log_dir_before_reboot, 'flat': True, 'fail_on_missing': False}, + {'src': '/host/bgpd.log.99', 'dest': log_dir_before_reboot, 'flat': True, 'fail_on_missing': False}, ], } for host, logs in list(logFiles.items()): diff --git a/tests/common/platform/device_utils.py b/tests/common/platform/device_utils.py index b56d5811092..6676b2f6afa 100644 --- a/tests/common/platform/device_utils.py +++ b/tests/common/platform/device_utils.py @@ -800,6 +800,7 @@ def pre_reboot_analysis(): base_os_version.append(get_current_sonic_version(duthost)) bgpd_log = bgpd_log_handler(preboot=True) if platform in LOGS_ON_TMPFS_PLATFORMS or (len(logs_in_tmpfs) > 0 and logs_in_tmpfs[0] is True): + logger.info("Inserting step to back up logs to /host/ before reboot") # For small disk devices, /var/log in mounted in tmpfs. # Hence, after reboot the preboot logs are lost. # For log_analyzer to work, it needs logs from the shutdown path @@ -822,6 +823,7 @@ def pre_reboot_analysis(): def post_reboot_analysis(marker, event_counters=None, reboot_oper=None, log_dir=None): bgpd_log_handler() if platform in LOGS_ON_TMPFS_PLATFORMS or (len(logs_in_tmpfs) > 0 and logs_in_tmpfs[0] is True): + logger.info("Restoring log backup from /host/ after reboot") restore_backup = "mv /host/syslog.99 /var/log/; " +\ "mv /host/sairedis.rec.99 /var/log/swss/; " +\ "mv /host/swss.rec.99 /var/log/swss/; " +\ From f63d2c1eeb603bb71906290a943599ca81db404d Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Fri, 1 Nov 2024 20:34:29 +1100 Subject: [PATCH 042/221] chore: address test gap in test_mgmt_ipv6 (#15137) Description of PR Summary: Fixing test gap on test_mgmt_ipv6 Fixes # (issue) 28836766 Approach What is the motivation for this PR? Currently test_mgmt_ipv6 is having the following skipped tests: SKIPPED [2] ip/test_mgmt_ipv6_only.py:122: DUT has no default route, skiped SKIPPED [1] ip/test_mgmt_ipv6_only.py:192: Skipping test as no Ethernet0 frontpanel port on supervisor "DUT has no default route, skiped" was because the ipv6 default gateway becomes stale from not using it. Solution: adding a ping and check if it's still reachable after ping "Skipping test as no Ethernet0 frontpanel port on supervisor" was because the test is meant to be for supervisor: Solution: only use the enumerate of frontend nodes. This is to avoid in the future someone else need to investigate why this one is skipped. We should only call the fixture we want to test. Signed-off-by: Austin Pham --- tests/common/helpers/syslog_helpers.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/common/helpers/syslog_helpers.py b/tests/common/helpers/syslog_helpers.py index d5d7351525b..2dd3ce0cae9 100644 --- a/tests/common/helpers/syslog_helpers.py +++ b/tests/common/helpers/syslog_helpers.py @@ -23,6 +23,10 @@ def check_default_route(rand_selected_dut): if result == 0: neigh_ip = duthost.shell( "ip route show default table default | cut -d ' ' -f 3", module_ignore_errors=True)['stdout'] + + # We ping here to make sure that the neigh_ip is not stale before checking for reachability + duthost.shell("ping -c 1 {}".format(neigh_ip), module_ignore_errors=True) + result = duthost.shell( "ip -4 neigh show {} | grep REACHABLE".format(neigh_ip), module_ignore_errors=True)['rc'] if result == 0: @@ -31,6 +35,10 @@ def check_default_route(rand_selected_dut): if result == 0: neigh_ip = duthost.shell( "ip -6 route show default table default | cut -d ' ' -f 3", module_ignore_errors=True)['stdout'] + + # We ping here to make sure that the neigh_ip is not stale before checking for reachability + duthost.shell("ping -c 1 {}".format(neigh_ip), module_ignore_errors=True) + result = duthost.shell( "ip -6 neigh show {} | grep REACHABLE".format(neigh_ip), module_ignore_errors=True)['rc'] if result == 0: From e4ad13a90450c930d272b13a8b1e49a66284b036 Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:32:49 +0800 Subject: [PATCH 043/221] Fix fixture not found issue (#15317) --- tests/pfc_asym/test_pfc_asym.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/pfc_asym/test_pfc_asym.py b/tests/pfc_asym/test_pfc_asym.py index 15930df026c..dba740d7c30 100755 --- a/tests/pfc_asym/test_pfc_asym.py +++ b/tests/pfc_asym/test_pfc_asym.py @@ -1,4 +1,5 @@ from tests.ptf_runner import ptf_runner +from tests.common.fixtures.pfc_asym import setup # noqa F401 import pytest pytestmark = [ @@ -11,7 +12,7 @@ def prepare_syncdrpc(swapSyncd): pass -def test_pfc_asym_off_tx_pfc(ptfhost, setup, pfc_storm_runner): +def test_pfc_asym_off_tx_pfc(ptfhost, setup, pfc_storm_runner): # noqa F811 """ @summary: Asymmetric PFC is disabled. Verify that DUT generates PFC frames only on lossless priorities when asymmetric PFC is disabled @@ -29,7 +30,7 @@ def test_pfc_asym_off_tx_pfc(ptfhost, setup, pfc_storm_runner): log_file="/tmp/pfc_asym.PfcAsymOffOnTxTest.log") -def test_pfc_asym_off_rx_pause_frames(ptfhost, setup, pfc_storm_runner): +def test_pfc_asym_off_rx_pause_frames(ptfhost, setup, pfc_storm_runner): # noqa F811 """ @summary: Asymmetric PFC is disabled. Verify that while receiving PFC frames DUT drops packets only for lossless priorities (RX and Tx queue buffers are full) @@ -48,7 +49,7 @@ def test_pfc_asym_off_rx_pause_frames(ptfhost, setup, pfc_storm_runner): log_file="/tmp/pfc_asym.PfcAsymOffRxTest.log") -def test_pfc_asym_on_tx_pfc(ptfhost, setup, enable_pfc_asym, pfc_storm_runner): +def test_pfc_asym_on_tx_pfc(ptfhost, setup, enable_pfc_asym, pfc_storm_runner): # noqa F811 """ @summary: Asymmetric PFC is enabled. Verify that DUT generates PFC frames only on lossless priorities when asymmetric PFC is enabled @@ -67,7 +68,7 @@ def test_pfc_asym_on_tx_pfc(ptfhost, setup, enable_pfc_asym, pfc_storm_runner): log_file="/tmp/pfc_asym.PfcAsymOffOnTxTest.log") -def test_pfc_asym_on_handle_pfc_all_prio(ptfhost, setup, enable_pfc_asym, pfc_storm_runner): +def test_pfc_asym_on_handle_pfc_all_prio(ptfhost, setup, enable_pfc_asym, pfc_storm_runner): # noqa F811 """ @summary: Asymmetric PFC is enabled. Verify that while receiving PFC frames DUT handle PFC frames on all priorities when asymetric mode is enabled From ce052ec30e84fc5f6ae90bf0c41ac20f43a7d73a Mon Sep 17 00:00:00 2001 From: sanjair-git <114024719+sanjair-git@users.noreply.github.com> Date: Sat, 2 Nov 2024 21:24:41 -0400 Subject: [PATCH 044/221] T2 Chassis - BGP FIB Suppress Pending Testplan (#12633) This T2 Chassis test plan for BGP FIB suppress pending feature is an extension of the BGP Suppress FIB Pending Test Plan added for T1 DUT at plan --- ...ppress-FIB-Pending-test-plan-T2-Chassis.md | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 docs/testplan/BGP-Suppress-FIB-Pending-test-plan-T2-Chassis.md diff --git a/docs/testplan/BGP-Suppress-FIB-Pending-test-plan-T2-Chassis.md b/docs/testplan/BGP-Suppress-FIB-Pending-test-plan-T2-Chassis.md new file mode 100644 index 00000000000..20546de4519 --- /dev/null +++ b/docs/testplan/BGP-Suppress-FIB-Pending-test-plan-T2-Chassis.md @@ -0,0 +1,242 @@ +- [T2-Chassis: BGP Suppress FIB Pending Test Plan](#t2-chassis--bgp-suppress-fib-pending-test-plan) + * [Related documents](#related-documents) + * [Overview](#overview) + + [Scope](#scope) + + [Scale / Performance](#scale---performance) + + [Related **DUT** CLI commands](#related---dut---cli-commands) + + [Supported Topology](#supported-topology) + * [Test cases](#test-cases) + + [Test case # 1 - BGPv4 route suppress test](#test-case---1---bgpv4-route-suppress-test) + + [Test case # 2 - BGPv6 route suppress test](#test-case---2---bgpv6-route-suppress-test) + + [Test case # 3 - Test BGP route without suppress](#test-case---3---test-bgp-route-without-suppress) + + [Test case # 4 - Test BGP route suppress under negative operation](#test-case---4---test-bgp-route-suppress-under-negative-operation) + + [Test case # 5 - Test BGP route suppress in credit loops scenario](#test-case---5---test-bgp-route-suppress-in-credit-loops-scenario) + + [Test case # 6 - Test BGP route suppress under stress](#test-case---6---test-bgp-route-suppress-under-stress) + + [Test case # 7 - Test BGP route suppress performance](#test-case---7---test-bgp-route-suppress-performance) + + +# T2-Chassis: BGP Suppress FIB Pending Test Plan + +## Related documents + +| **Document Name** | **Link** | +|-------------------|----------| +| BGP Suppress FIB Pending HLD | [https://github.com/stepanblyschak/SONiC/blob/bgp-suppress-fib-pending/doc/BGP/BGP-supress-fib-pending.md]| +| T1 - BGP Suppress FIB Pending| [https://github.com/sonic-net/sonic-mgmt/blob/master/docs/testplan/BGP-Suppress-FIB-Pending-test-plan.md]| + +## Overview + +This test plan is an extension of the __BGP Suppress FIB Pending Test Plan__ added for T1 DUT at [https://github.com/sonic-net/sonic-mgmt/blob/master/docs/testplan/BGP-Suppress-FIB-Pending-test-plan.md]. + +As of today, SONiC BGP advertises learnt prefixes regardless of whether these prefixes were successfully programmed into ASIC. +While route programming failure is followed by orchagent crash and all services restart, even for successfully created routes there is a short period of time when the peer will be black holing traffic. + +### Scope + +The test is to verify the mechanism that allows BGP not to advertise routes that haven't been installed into ASIC yet. + + +### Scale / Performance + +No scale/performance test involved in this test plan + +### Related **DUT** CLI commands +Command to enable the feature: +``` +admin@sonic:~$ sudo config suppress-fib-pending enabled +``` +Command to disable the feature: +``` +admin@sonic:~$ sudo config suppress-fib-pending disabled +``` +Note: Issue raised for the above command not working on multi-asic environment globally, https://github.com/sonic-net/sonic-buildimage/issues/19022 . Currently it works only as specific asic commands. + +### Supported Topology +The tests will be supported on t1 as well as on t2 topo. + + +## Test cases + +As part of test changes for T2, to be consistent with existing T1 test cases, we will choose DUT which is connected to downstream T1 neighbors. This is because, on the other line card connected to upstream neighbors, it is not possible to verify traffic not being sent to the neighbor advertising the prefix since there is already a default route pointing to it. + +### Test case # 1 - BGPv4 route suppress test +1. Enable BGP suppress-fib-pending function on all DUTs in multi-dut scenario. +2. Save configuration and do config reload on DUTs. +3. Suspend orchagent process on both asics to simulate a delay on downstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +4. Announce BGP ipv4 prefixes to downstream DUT from one of T1 peer using exabgp. +5. Make sure announced BGP routes are in __queued__ state in the downstream DUT routing table for the specific asic. +6. Verify the routes are not announced via __IBGP__ or __EBGP__ to any of the peers. +7. Send traffic matching the prefixes from one of T3 peer. +8. Verify packets are not forwarded to any T1 peers of downstream line cards. And also make sure packets are forwarded to other T3 peers because of default route. +9. Suspend orchagent process on both asics to simulate a delay on upstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +10. Restore orchagent process on both asics of the downstream dut, +``` +kill -SIGCONT $(pidof orchagent) +``` +11. Make sure announced BGP routes are __not__ in __queued__ state in the downstream DUT routing table. +12. Make sure the routes are programmed in FIB by checking offloaded flag value in the downstream DUT routing table. +13. Make sure announced BGP routes are in __queued__ state in the upstream DUT routing table for the specific asic. +14. Verify the routes are not announced via __IBGP__ or __EBGP__ to any of the T3 peers. +15. Restore orchagent process on both asics of the upstream dut, +``` +kill -SIGCONT $(pidof orchagent) +``` +16. Make sure announced BGP routes are __not__ in __queued__ state in the upstream DUT routing table. +17. Make sure the routes are programmed in FIB by checking offloaded flag value in the upstream DUT routing table. +18. Verify the routes are announced to all T3 peer neighbors on the upstream DUT. +19. Send traffic matching the prefixes from one of T3 peer and verify packets are forwarded to expected T1 peer only. + +### Test case # 2 - BGPv6 route suppress test +1. Enable BGP suppress-fib-pending function on all DUTs in multi-dut scenario. +2. Save configuration and do config reload on DUTs. +3. Suspend orchagent process on both asics to simulate a delay on downstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +4. Announce BGP ipv6 prefixes to downstream DUT from one of T1 peer using exabgp. +5. Make sure announced BGP routes are in __queued__ state in the downstream DUT routing table for the specific asic. +6. Verify the routes are not announced via __IBGP__ or __EBGP__ to any of the peers. +7. Send traffic matching the prefixes from one of T3 peer. +8. Verify packets are not forwarded to any T1 peers of downstream line cards. And also make sure packets are forwarded to other T3 peers because of default route. +9. Suspend orchagent process on both asics to simulate a delay on upstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +10. Restore orchagent process on both asics of the downstream dut, +``` +kill -SIGCONT $(pidof orchagent) +``` +11. Make sure announced BGP routes are __not__ in __queued__ state in the downstream DUT routing table. +12. Make sure the routes are programmed in FIB by checking offloaded flag value in the downstream DUT routing table. +13. Make sure announced BGP routes are in __queued__ state in the upstream DUT routing table for the specific asic. +14. Verify the routes are not announced via __IBGP__ or __EBGP__ to any of the T3 peers. +15. Restore orchagent process on both asics of the upstream dut, +``` +kill -SIGCONT $(pidof orchagent) +``` +16. Make sure announced BGP routes are __not__ in __queued__ state in the upstream DUT routing table. +17. Make sure the routes are programmed in FIB by checking offloaded flag value in the upstream DUT routing table. +18. Verify the routes are announced to all T3 peer neighbors on the upstream DUT. +19. Send traffic matching the prefixes from one of T3 peer and verify packets are forwarded to expected T1 peer only. + +### Test case # 3 - Test BGP route without suppress + +1. Disable BGP suppress-fib-pending function at both upstream and downstream DUT(Default configuration). +2. Suspend orchagent process on both asics to simulate a delay on both upstream and downstream DUTs. +``` +kill -SIGSTOP $(pidof orchagent) +``` +3. Announce BGP prefixes to DUT from one of T1 peer using exabgp. +4. Make sure announced BGP routes are __not__ in __queued__ state on both DUT's routing table. +5. Verify the routes are announced via __IBGP__ and __EBGP__ to all T3 peer neighbors on the upstream DUT. +6. Send traffic matching the prefixes from one of T3 peer. +7. Verify packets are not forwarded to any T1 peers of downstream line cards. And also make sure packets are forwarded to other T3 peers because of default route. +8. Restore orchagent process on both asics for both DUTs, +``` +kill -SIGCONT $(pidof orchagent) +``` +9. Make sure the routes are programmed in FIB by checking offloaded flag in the upstream and downstream DUT routing table. +10. Send traffic matching the prefixes from one of T3 peer and verify packets are forwarded to expected T1 peer only. + +### Test case # 4 - Test BGP route suppress under negative operation + +1. Enable BGP suppress-fib-pending function on all DUTs in multi-dut scenario. +2. Save configuration and do config reload on DUTs. +3. Suspend orchagent process on both asics to simulate a delay on downstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +4. Announce BGP prefixes to downstream DUT from one of T1 peer using exabgp. +5. Execute BGP session restart by restarting all BGP sessions on the downstream DUT. +6. Verify BGP neighborships are re-established. +7. Make sure announced BGP routes are in __queued__ state in the downstream DUT routing table +8. Verify the routes are not announced via __IBGP__ or __EBGP__ to any of the peers. +9. Configure static route with nexthop as downstream DUT and then redistribute to BGP. +10. Verify the redistributed routes are in the DUT routing table. +11. Verify the static routes are announced via __IBGP__ and __EBGP__ to all T3 peer neighbors on the upstream DUT. +12. Send traffic matching the initial prefixes from one of T3 peer . +13. Verify packets with intial prefixes are not forwarded to any T1 peers of downstream line cards. And also make sure packets are forwarded to other T3 peers because of default route. +14. Then, send traffic matching the static route prefix from one of the T3 peer. +15. Make sure traffic with static route prefix are forwarded via downstream DUT as expected. +16. Suspend orchagent process on both asics to simulate a delay on upstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +17. Restore orchagent process on both asics of the downstream dut, +``` +kill -SIGCONT $(pidof orchagent) +``` +18. Make sure announced BGP routes are __not__ in __queued__ state in the downstream DUT routing table. +19. Make sure the routes are programmed in FIB by checking offloaded flag value in the downstream DUT routing table. +20. Make sure announced BGP routes are in __queued__ state in the upstream DUT routing table for the specific asic. +21. Verify the routes are not announced via __IBGP__ or __EBGP__ to any of the T3 peers. +22. Restore orchagent process on both asics of the upstream dut, +``` +kill -SIGCONT $(pidof orchagent) +``` +23. Make sure announced BGP routes are __not__ in __queued__ state in the upstream DUT routing table. +24. Make sure the routes are programmed in FIB by checking offloaded flag value in the upstream DUT routing table. +25. Verify the routes are announced to all T3 peer neighbors on the upstream DUT. +26. Send traffic matching the prefixes from one of T3 peer and verify packets are forwarded to expected T1 peer only. + +### Test case # 5 - Test BGP route suppress in credit loops scenario + +1. Disable BGP suppress-fib-pending function at both upstream and downstream DUT(Default configuration). +2. Suspend orchagent process on both asics to simulate a delay on the downstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +3. Announce BGP prefixes to downstream DUT from one of T1 peer using exabgp. +4. Verify the routes are announced via __IBGP__ and __EBGP__ to all T3 peer neighbors on the upstream DUT. +5. Send traffic matching the prefixes from the T3 peer and verify packets are forwarded back to the same T3 peer. +6. Enable BGP suppress-fib-pending function on the downstream DUT. +7. Restore orchagent process on both asics on the downstream DUT now, +``` +kill -SIGCONT $(pidof orchagent) +``` +8. Make sure the routes are programmed in FIB by checking offloaded flag in the downstream DUT routing table. +9. Send traffic matching the prefixes from one of T3 peer and verify packets are forwarded to expected T1 peer only. + +### Test case # 6 - Test BGP route suppress under stress + +1. Do BGP route flap 5 times - Announce/Withdraw BGP prefixes from one of T1 peer using exabgp. +2. Disable BGP suppress-fib-pending function on both upstream and downstream DUT +3. Send traffic matching the prefixes in the BGP route flap from one of T3 peer and verify packets are forwarded back to the same T3 peer. +4. Suspend orchagent process to simulate a delay on both asics of the downstream DUT. +``` +kill -SIGSTOP $(pidof orchagent) +``` +5. Announce 33K BGP prefixes to DUT from T1 peer by exabgp +6. Verify the routes are announced via __IBGP__ and __EBGP__ to all T3 peer neighbors on the upstream DUT. +7. Send traffic matching the prefixes in the BGP route flap from one of T3 VM and verify packets are forwarded back to the same T3 VM. +8. Enable BGP suppress-fib-pending function at downstream DUT. +9. Restore orchagent process on both asics on the downstream DUT now, +``` +kill -SIGCONT $(pidof orchagent) +``` +10. Verify the routes are programmed in FIB by checking offloaded flag in the downstream DUT routing table +11. Send traffic matching the prefixes from one of T3 peer and verify packets are forwarded to expected T1 peer only. + + +### Test case # 7 - Test BGP route suppress performance + +1. Enable BGP suppress-fib-pending function on upstream and downstream DUTs. +2. Start tcpdump capture at the ingress and egress ports of both the DUTs. +3. Announce 33K BGP prefixes to downstream DUT from T1 VM by exabgp +4. Verify the routes are announced via __IBGP__ and __EBGP__ to all T3 peer neighbors on the upstream DUT. +5. Withdraw 33K BGP prefixes to DUT from the same T1 VM using exabgp +6. Verify the BGP routes are withdrawn from all T3 VM peer neighbors. +7. Stop tcpdump capture on both the DUTs' ingress and egress ports. +8. Calculate the average and middle route processing time for each of the ipv4 and ipv6 route prefixes announced and withdrawn. +9. Verify the average as well as middle route process time are under the threshold processing time ~ 3 seconds(T2 Chassis) for each route. +``` +Note: +Average route processing time (announced or withdrawn) = Sum of total processing time taken for each route (announced or withdrawn) / Total number of routes (announced or withdrawn) +Middle route processing time (announced or withdrawn) = Middle data value(time) in the sorted list of all route processing times data set (either announced or withdrawn) +``` From 5c5068d778846b7b12411a1221be312397543fa2 Mon Sep 17 00:00:00 2001 From: Dashuai Zhang <164845223+sdszhang@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:21:29 +1100 Subject: [PATCH 045/221] Add cEOS neighbor support for bgp/test_4-byte_asn_community.py (#15268) Description of PR Summary: Add cEOS neighbor support for test_4-byte_asn_community.py. Current test case only support SONiC neighbors. this PR will improve coverage with more neighbor type. Future works to improve, not in this PR: implement SONiC specific BGP operations in class SonicBGPRouter. and change the current command check method to using class method for BGP configuration/verification. Approach What is the motivation for this PR? Improve test coverage by adding cEOS support to the test case. How did you do it? Defined a base class for common BGP operations. class BGPRouter(ABC):, and implemented platfor specific BGP operations for cEOS neighbors. How did you verify/test it? bgp/test_4-byte_asn_community.py::test_4_byte_asn_community[vlab-01-None] PASSED [100%] co-authorized by: jianquanye@microsoft.com --- tests/bgp/templates/bgp_id.template | 2 +- tests/bgp/test_4-byte_asn_community.py | 336 ++++++++++++++++++++++++- tests/common/devices/multi_asic.py | 2 + tests/common/devices/sonic_asic.py | 2 + 4 files changed, 335 insertions(+), 7 deletions(-) diff --git a/tests/bgp/templates/bgp_id.template b/tests/bgp/templates/bgp_id.template index 09228b80969..c36b3973cfc 100644 --- a/tests/bgp/templates/bgp_id.template +++ b/tests/bgp/templates/bgp_id.template @@ -1,4 +1,4 @@ Value router_id (\d+.\d+.\d+.\d+) Start - ^BGP router identifier\s+${router_id} + ^(asic\d:\s+){0,1}BGP router identifier\s+${router_id} diff --git a/tests/bgp/test_4-byte_asn_community.py b/tests/bgp/test_4-byte_asn_community.py index 67ca0d37025..d58e2a60805 100644 --- a/tests/bgp/test_4-byte_asn_community.py +++ b/tests/bgp/test_4-byte_asn_community.py @@ -12,7 +12,11 @@ import pytest import time import textfsm +import re from tests.common.config_reload import config_reload +from tests.common.helpers.assertions import pytest_assert +from tests.common.utilities import wait_until +from abc import ABC, abstractmethod logger = logging.getLogger(__name__) dut_4byte_asn = 400003 @@ -25,11 +29,259 @@ ] +class BGPRouter(ABC): + def __init__(self, host, asn): + self.host = host + self.asn = asn + self.saved_bgp_config = None + + def __str__(self): + return f"{self.host} {self.asn}" + + @abstractmethod + def get_router_id(self): + pass + + @abstractmethod + def get_current_bgp_asn(self): + pass + + @abstractmethod + def save_bgp_config(self): + pass + + @abstractmethod + def remove_bgp_config(self, asn=None): + pass + + @abstractmethod + def restore_bgp_config(self, asn_to_be_removed): + pass + + @abstractmethod + def get_bgp_config(self): + pass + + @abstractmethod + def get_originated_ipv4_networks(self): + pass + + @abstractmethod + def get_originated_ipv6_networks(self): + pass + + +class SonicBGPRouter(BGPRouter): + def __init__(self, host, asn): + super().__init__(host, asn) + self.os_type = 'sonic' + + def get_router_id(self): + # TODO: Add SONiC implementation + pass + + def get_current_bgp_asn(self): + # TODO: Add SONiC implementation + pass + + def save_bgp_config(self): + # TODO: Add SONiC implementation + pass + + def remove_bgp_config(self, asn=None): + # TODO: Add SONiC implementation + pass + + def restore_bgp_config(self, asn_to_be_removed): + # TODO: Add SONiC implementation + pass + + def get_bgp_config(self): + # TODO: Add SONiC implementation + pass + + def get_originated_ipv4_networks(self): + # TODO: Add SONiC implementation + pass + + def get_originated_ipv6_networks(self): + # TODO: Add SONiC implementation + pass + + +class EosBGPRouter(BGPRouter): + def __init__(self, host, asn): + super().__init__(host, asn) + self.os_type = 'eos' + + def get_router_id(self): + neigh_ip_bgp_sum = self.get_command_output("show ip bgp summary") + neigh_ip_bgp_sum = neigh_ip_bgp_sum.split("\n") + # Use regular expression to find the router identifier + match = re.search(r'Router identifier (\d+\.\d+\.\d+\.\d+)', neigh_ip_bgp_sum[1]) + if match: + router_id = match.group(1) + else: + pytest_assert(router_id is not None, f"Failed to get BGP ID {self.host}") + return router_id + + def get_current_bgp_asn(self): + current_bgp_asn = self.get_command_output("show run section bgp | sec router bgp") + match = re.search(r'router bgp (\d+)', current_bgp_asn) + if match: + current_asn = match.group(1) + else: + pytest_assert(current_asn is not None, f"Failed to get BGP ASN {self.host}") + return current_asn + + def save_bgp_config(self): + self.saved_bgp_config = self.get_command_output("show run section bgp") + + def remove_bgp_config(self, asn=None): + if asn is None: + asn = self.get_current_bgp_asn() + self.host.eos_config( + lines=["no router bgp {}".format(asn)]) + + def restore_bgp_config(self, asn_to_be_removed): + self.remove_bgp_config(asn=asn_to_be_removed) + self.host.eos_config(lines=list(self.saved_bgp_config.split("\n"))) + + def get_bgp_config(self): + current_bgp_config = self.get_command_output("show run section bgp") + return current_bgp_config + + def get_originated_ipv4_networks(self): + ipv4_af_output = self.get_command_output("show run section bgp | sec address-family ipv4") + match = re.search(r'network (\d+\.\d+\.\d+\.\d+/\d+)', ipv4_af_output) + if match: + self_ipv4_network = match.group(1) + else: + pytest_assert(self_ipv4_network is not None, f"Failed to get IPv4 network {self.host}") + return self_ipv4_network + + def get_originated_ipv6_networks(self): + ipv6_af_network = self.get_command_output("show run section bgp | sec address-family ipv6") + match = re.search(r'network ([a-fA-F0-9:]+/\d+)', ipv6_af_network) + if match: + self_ipv6_network = match.group(1) + else: + pytest_assert(self_ipv6_network is not None, f"Failed to get IPv6 network {self.host}") + return self_ipv6_network + + def get_command_output(self, command): + return self.host.eos_command(commands=[command])['stdout'][0] + + +def check_bgp_neighbor(duthost, bgp_neighbors): + """ + Validate all the bgp neighbors are established + """ + pytest_assert( + wait_until(300, 10, 0, duthost.check_bgp_session_state, bgp_neighbors), + "bgp sessions {} are not up".format(bgp_neighbors) + ) + + +def setup_ceos(tbinfo, nbrhosts, duthosts, enum_frontend_dut_hostname, enum_rand_one_frontend_asic_index, request): + duthost = duthosts[enum_frontend_dut_hostname] + asic_index = enum_rand_one_frontend_asic_index + + if duthost.is_multi_asic: + cli_options = " -n " + str(asic_index) + else: + cli_options = '' + + dut_asn = tbinfo['topo']['properties']['configuration_properties']['common']['dut_asn'] + + neighbors = dict() + bgp_facts = duthost.bgp_facts(instance_id=asic_index)['ansible_facts'] + ceosNeighbors = [v['description'] for v in bgp_facts['bgp_neighbors'].values() + if 'asic' not in v['description'].lower()] + if not ceosNeighbors: + pytest.skip("No ceos neighbors found") + neigh = ceosNeighbors[0] + logger.debug("Neighbor is: {}".format(neigh)) + neigh_asn = dict() + + # verify sessions are established and gather neighbor information + for k, v in bgp_facts['bgp_neighbors'].items(): + # skip internal neighbors to other 'asic' namespaces + if 'asic' not in v['description'].lower(): + if v['description'] == neigh: + if v['ip_version'] == 4: + neigh_ip_v4 = k + peer_group_v4 = v['peer group'] + elif v['ip_version'] == 6: + neigh_ip_v6 = k + peer_group_v6 = v['peer group'] + assert v['state'] == 'established' + neigh_asn[v['description']] = v['remote AS'] + neighbors[v['description']] = nbrhosts[v['description']]["host"] + + neigh_cli_options = '' + + dut_ip_v4 = tbinfo['topo']['properties']['configuration'][neigh]['bgp']['peers'][dut_asn][0] + dut_ip_v6 = tbinfo['topo']['properties']['configuration'][neigh]['bgp']['peers'][dut_asn][1] + + dut_ip_bgp_sum = duthost.shell('show ip bgp summary')['stdout'] + + bgp_neigh = EosBGPRouter(nbrhosts[neigh]["host"], neigh_asn[neigh]) + neigh_bgp_id = bgp_neigh.get_router_id() + with open(bgp_id_textfsm) as template: + fsm = textfsm.TextFSM(template) + dut_bgp_id = fsm.ParseText(dut_ip_bgp_sum)[0][0] + + dut_ipv4_network = duthost.shell("show run bgp | grep 'ip prefix-list'")['stdout'].split()[6] + dut_ipv6_network = duthost.shell("show run bgp | grep 'ipv6 prefix-list'")['stdout'].split()[6] + neigh_ipv4_network = bgp_neigh.get_originated_ipv4_networks() + neigh_ipv6_network = bgp_neigh.get_originated_ipv6_networks() + + setup_info = { + 'bgp_neigh': bgp_neigh, + 'duthost': duthost, + 'neighhost': neighbors[neigh], + 'neigh': neigh, + 'dut_asn': dut_asn, + 'neigh_asn': neigh_asn[neigh], + 'asn_dict': neigh_asn, + 'neighbors': neighbors, + 'cli_options': cli_options, + 'neigh_cli_options': neigh_cli_options, + 'dut_ip_v4': dut_ip_v4, + 'dut_ip_v6': dut_ip_v6, + 'neigh_ip_v4': neigh_ip_v4, + 'neigh_ip_v6': neigh_ip_v6, + 'peer_group_v4': peer_group_v4, + 'peer_group_v6': peer_group_v6, + 'asic_index': asic_index, + 'dut_bgp_id': dut_bgp_id, + 'neigh_bgp_id': neigh_bgp_id, + 'dut_ipv4_network': dut_ipv4_network, + 'dut_ipv6_network': dut_ipv6_network, + 'neigh_ipv4_network': neigh_ipv4_network, + 'neigh_ipv6_network': neigh_ipv6_network, + } + + logger.debug("DUT BGP Config: {}".format(duthost.shell("show run bgp", module_ignore_errors=True)['stdout'])) + logger.debug("Neighbor BGP Config: {}".format(bgp_neigh.get_bgp_config())) + logger.debug('Setup_info: {}'.format(setup_info)) + bgp_neigh.save_bgp_config() + + yield setup_info + + bgp_neigh.restore_bgp_config(asn_to_be_removed=neighbor_4byte_asn) + # restore config to original state + config_reload(duthost, safe_reload=True, wait_for_bgp=True) + + @pytest.fixture(scope='module') def setup(tbinfo, nbrhosts, duthosts, enum_frontend_dut_hostname, enum_rand_one_frontend_asic_index, request): # verify neighbors are type sonic and skip if not if request.config.getoption("neighbor_type") != "sonic": - pytest.skip("Neighbor type must be sonic") + yield from setup_ceos(tbinfo, nbrhosts, duthosts, enum_frontend_dut_hostname, + enum_rand_one_frontend_asic_index, request) + return duthost = duthosts[enum_frontend_dut_hostname] asic_index = enum_rand_one_frontend_asic_index @@ -82,6 +334,7 @@ def setup(tbinfo, nbrhosts, duthosts, enum_frontend_dut_hostname, enum_rand_one_ neigh_ipv6_network = nbrhosts[neigh]["host"].shell("show run bgp | grep 'ipv6 prefix-list'")['stdout'].split()[6] setup_info = { + 'bgp_neigh': SonicBGPRouter(neighbors[neigh], neigh_asn[neigh]), 'duthost': duthost, 'neighhost': neighbors[neigh], 'neigh': neigh, @@ -124,11 +377,14 @@ def setup(tbinfo, nbrhosts, duthosts, enum_frontend_dut_hostname, enum_rand_one_ assert v['state'] == 'established' -def test_4_byte_asn_community(setup): +def config_dut_4_byte_asn_dut(setup): # configure BGP with 4-byte ASN using the standard T2 config and existing route-maps on DUT + # as route-map names varies dependin on the topology, used ALLOW_ANY route-map to + # allow all routes as we only have two neighbors. cmd = 'vtysh{} \ -c "config" \ -c "no router bgp {}" \ + -c "route-map ALLOW_ANY permit 10" \ -c "router bgp {}" \ -c "bgp router-id {}" \ -c "bgp log-neighbor-changes" \ @@ -150,16 +406,16 @@ def test_4_byte_asn_community(setup): -c "address-family ipv4 unicast" \ -c "network {}" \ -c "neighbor {} soft-reconfiguration inbound" \ - -c "neighbor {} route-map FROM_BGP_PEER_V4 in" \ - -c "neighbor {} route-map TO_BGP_PEER_V4 out" \ + -c "neighbor {} route-map ALLOW_ANY in" \ + -c "neighbor {} route-map ALLOW_ANY out" \ -c "neighbor {} activate" \ -c "maximum-paths 64" \ -c "exit-address-family" \ -c "address-family ipv6 unicast" \ -c "network {}" \ -c "neighbor {} soft-reconfiguration inbound" \ - -c "neighbor {} route-map FROM_BGP_PEER_V6 in" \ - -c "neighbor {} route-map TO_BGP_PEER_V6 out" \ + -c "neighbor {} route-map ALLOW_ANY in" \ + -c "neighbor {} route-map ALLOW_ANY out" \ -c "neighbor {} activate" \ -c "maximum-paths 64" \ -c "exit-address-family" \ @@ -173,6 +429,10 @@ def test_4_byte_asn_community(setup): setup['peer_group_v6'], setup['neigh_ip_v6']) logger.debug(setup['duthost'].shell(cmd, module_ignore_errors=True)) + +def run_bgp_4_byte_asn_community_sonic(setup): + config_dut_4_byte_asn_dut(setup) + # configure BGP with 4-byte ASN using the standard T2 config and existing route-maps on neighbor device cmd = 'vtysh{}\ -c "config" \ @@ -243,3 +503,67 @@ def test_4_byte_asn_community(setup): assert str(dut_4byte_asn) in str(output.split('\n')[9].split()[5]) output = setup['neighhost'].shell("show ipv6 bgp neighbors {} routes".format(setup['dut_ip_v6'].lower()))['stdout'] assert str(dut_4byte_asn) in str(output.split('\n')[9].split()[5]) + + +def run_bgp_4_byte_asn_community_eos(setup): + config_dut_4_byte_asn_dut(setup) + + bgp_neigh = setup['bgp_neigh'] + bgp_neigh.remove_bgp_config() + # configure BGP with 4-byte ASN using the standard T2 config and existing route-maps on neighbor device + cmd = [ + "router bgp {}".format(neighbor_4byte_asn), + "router-id {}".format(setup['neigh_bgp_id']), + "neighbor {} remote-as {}".format(setup['dut_ip_v4'], dut_4byte_asn), + "neighbor {} description {}".format(setup['dut_ip_v4'], 'DUT'), + "neighbor {} maximum-routes 0".format(setup['dut_ip_v4']), + "neighbor {} remote-as {}".format(setup['dut_ip_v6'], dut_4byte_asn), + "neighbor {} description {}".format(setup['dut_ip_v6'], 'DUT'), + "neighbor {} maximum-routes 0".format(setup['dut_ip_v6']), + "!", + "address-family ipv4", + "neighbor {} activate".format(setup['dut_ip_v4']), + "network {}".format(setup['neigh_ipv4_network']), + "!", + "address-family ipv6", + "neighbor {} activate".format(setup['dut_ip_v6']), + "network {}".format(setup['neigh_ipv6_network']) + ] + + logger.debug(bgp_neigh.host.eos_config(lines=cmd)) + + logger.debug("DUT BGP Config: {}".format(setup['duthost'].shell("show run bgp")['stdout'])) + logger.debug("Neighbor BGP Config: {}".format(bgp_neigh.get_bgp_config())) + + time.sleep(60) + check_bgp_neighbor(setup['duthost'], [setup['neigh_ip_v4'], setup['neigh_ip_v6']]) + + output = setup['duthost'].shell("show ip bgp summary | grep {}".format(setup['neigh_ip_v4']))['stdout'] + assert str(neighbor_4byte_asn) in output.split()[2] + output = setup['duthost'].shell("show ipv6 bgp summary | grep {}".format(setup['neigh_ip_v6'].lower()))['stdout'] + assert str(neighbor_4byte_asn) in output.split()[2] + output = setup['duthost'].shell("show ip bgp neighbors {} routes".format(setup['neigh_ip_v4']))['stdout'] + assert str(neighbor_4byte_asn) in str(output.split('\n')[9]) + output = setup['duthost'].shell("show ipv6 bgp neighbors {} routes".format(setup['neigh_ip_v6'].lower()))['stdout'] + # show ipv6 bgp neighbors routes may split into two lines, hence checking both lines + # Network Next Hop Metric LocPrf Weight Path + # *> 2064:100::1d/128 fe80::4059:38ff:feaa:82db + # 0 400001 i + assert (str(neighbor_4byte_asn) in str(output.split('\n')[9]) or + str(neighbor_4byte_asn) in str(output.split('\n')[10])) + + output = bgp_neigh.get_command_output("show ip bgp summary | include {}".format(setup['dut_ip_v4'])) + assert str(dut_4byte_asn) in output.split()[3] + output = bgp_neigh.get_command_output("show ipv6 bgp summary | include {}".format(setup['dut_ip_v6'].lower())) + assert str(dut_4byte_asn) in output.split()[3] + output = bgp_neigh.get_command_output("show ip bgp neighbors {} routes".format(setup['dut_ip_v4'])) + assert str(dut_4byte_asn) in str(output.split('\n')[-1]) + output = bgp_neigh.get_command_output("show ipv6 bgp peers {} routes".format(setup['dut_ip_v6'].lower())) + assert str(dut_4byte_asn) in str(output.split('\n')[-1]) or str(dut_4byte_asn) in str(output.split('\n')[-2]) + + +def test_4_byte_asn_community(setup): + if setup['bgp_neigh'].os_type == 'eos': + run_bgp_4_byte_asn_community_eos(setup) + else: + run_bgp_4_byte_asn_community_sonic(setup) diff --git a/tests/common/devices/multi_asic.py b/tests/common/devices/multi_asic.py index 41d16d3884b..df1eaf1b7b7 100644 --- a/tests/common/devices/multi_asic.py +++ b/tests/common/devices/multi_asic.py @@ -572,6 +572,8 @@ def check_bgp_session_state(self, neigh_ips, state="established"): if v['state'] == state: if k.lower() in neigh_ips: neigh_ok.append(k) + logging.info("bgp neighbors to be checked for the state: {}".format( + [ip for ip in neigh_ips if ip not in neigh_ok])) logging.info("bgp neighbors that match the state: {}".format(neigh_ok)) if len(neigh_ips) == len(neigh_ok): diff --git a/tests/common/devices/sonic_asic.py b/tests/common/devices/sonic_asic.py index f30809ca07c..7f8ff9c1190 100644 --- a/tests/common/devices/sonic_asic.py +++ b/tests/common/devices/sonic_asic.py @@ -685,6 +685,8 @@ def check_bgp_session_state(self, neigh_ips, state="established"): if k.lower() in neigh_ips: neigh_ok.append(k) logging.info("bgp neighbors that match the state: {} on namespace {}".format(neigh_ok, self.namespace)) + logging.info("bgp neighbors to be checked on the state: {} on namespace {}".format( + [ip for ip in neigh_ips if ip not in neigh_ok], self.namespace)) if len(neigh_ips) == len(neigh_ok): return True From b2f130f06909df73a1fc1c7d7015d2856a85b27f Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Sun, 3 Nov 2024 16:32:02 -0800 Subject: [PATCH 046/221] [arp_update] Verify that kernel/APPL_DB MAC mismatch is corrected (#14662) What is the motivation for this PR? It is possible for kernel neighbor information to fall out of sync with the APPL_DB neighbor table. How did you do it? Manually change the APPL_DB neighbor table entry, then verify that the arp_update script is able to flush the out of sync neighbor. --- tests/arp/test_arp_update.py | 77 ++++++++++++++++++++++++++ tests/common/fixtures/ptfhost_utils.py | 57 +++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 tests/arp/test_arp_update.py diff --git a/tests/arp/test_arp_update.py b/tests/arp/test_arp_update.py new file mode 100644 index 00000000000..95906707552 --- /dev/null +++ b/tests/arp/test_arp_update.py @@ -0,0 +1,77 @@ +# Test cases to validate functionality of the arp_update script + +import logging +import pytest + +from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa: F401 +from tests.common.fixtures.ptfhost_utils import setup_vlan_arp_responder # noqa: F401 +from tests.common.helpers.assertions import pytest_assert as pt_assert +from tests.common.utilities import wait_until + +logger = logging.getLogger(__name__) + +pytestmark = [ + pytest.mark.topology("t0") +] + + +@pytest.fixture +def setup(rand_selected_dut): + cmds = [ + "docker exec swss supervisorctl stop arp_update", + "ip neigh flush all" + ] + rand_selected_dut.shell_cmds(cmds) + yield + cmds[0] = "docker exec swss supervisorctl start arp_update" + # rand_selected_dut.shell_cmds(cmds) + + +def neighbor_learned(dut, target_ip): + neigh_output = dut.shell(f"ip neigh show {target_ip}")['stdout'].strip() + logger.info(f"DUT neighbor entry: {neigh_output}") + return neigh_output and ("REACHABLE" in neigh_output or "STALE" in neigh_output) + + +def ip_version_string(version): + return f"ipv{version}" + + +@pytest.mark.parametrize("ip_version", [4, 6], ids=ip_version_string) +def test_kernel_asic_mac_mismatch( + toggle_all_simulator_ports_to_rand_selected_tor, # noqa: F811 + rand_selected_dut, ip_version, setup_vlan_arp_responder # noqa: F811 +): + vlan_name, ipv4_base, ipv6_base = setup_vlan_arp_responder + if ip_version == 4: + target_ip = ipv4_base.ip + 2 + else: + target_ip = ipv6_base.ip + 2 + + rand_selected_dut.shell(f"ping -c1 -W1 {target_ip}; true") + + wait_until(10, 1, 0, neighbor_learned, rand_selected_dut, target_ip) + + neighbor_info = rand_selected_dut.shell(f"ip neigh show {target_ip}")["stdout"].split() + pt_assert(neighbor_info[2] == vlan_name) + + asic_db_mac = rand_selected_dut.shell( + f"sonic-db-cli APPL_DB hget 'NEIGH_TABLE:{vlan_name}:{target_ip}' 'neigh'" + )['stdout'] + pt_assert(neighbor_info[4].lower() == asic_db_mac.lower()) + + logger.info(f"Neighbor {target_ip} has been learned, APPL_DB and kernel are in sync") + + logger.info("Manually setting APPL_DB MAC address") + rand_selected_dut.shell( + f"sonic-db-cli APPL_DB hset 'NEIGH_TABLE:{vlan_name}:{target_ip}' 'neigh' '00:00:00:00:00:00'" + ) + asic_db_mac = rand_selected_dut.shell( + f"sonic-db-cli APPL_DB hget 'NEIGH_TABLE:{vlan_name}:{target_ip}' 'neigh'" + )['stdout'] + pt_assert(neighbor_info[4].lower() != asic_db_mac.lower()) + logger.info("APPL_DB and kernel are out of sync (expected)") + + rand_selected_dut.shell("docker exec swss supervisorctl start arp_update") + + wait_until(10, 1, 0, lambda dut, ip: not neighbor_learned(dut, ip), rand_selected_dut, target_ip) diff --git a/tests/common/fixtures/ptfhost_utils.py b/tests/common/fixtures/ptfhost_utils.py index 35e7803cd71..642cd521e74 100644 --- a/tests/common/fixtures/ptfhost_utils.py +++ b/tests/common/fixtures/ptfhost_utils.py @@ -179,6 +179,63 @@ def copy_arp_responder_py(ptfhost): ptfhost.file(path=os.path.join(OPT_DIR, ARP_RESPONDER_PY), state="absent") +@pytest.fixture(scope="module", autouse=True) +def setup_vlan_arp_responder(ptfhost, rand_selected_dut, tbinfo): + arp_responder_cfg = {} + config_facts = rand_selected_dut.config_facts( + host=rand_selected_dut.hostname, source="running" + )['ansible_facts'] + vlan_intf_config = config_facts['VLAN_INTERFACE'] + for vlan, attrs in vlan_intf_config.items(): + for val in attrs: + try: + ip = ip_interface(val) + if ip.version == 4: + ipv4_base = ip + else: + ipv6_base = ip + except ValueError: + continue + break + vlan_members = list(config_facts['VLAN_MEMBER'][vlan].keys()) + + dut_to_ptf_port_map = rand_selected_dut.get_extended_minigraph_facts( + tbinfo + )['minigraph_ptf_indices'] + + for port in vlan_members: + ptf_index = dut_to_ptf_port_map[port] + ip_offset = ptf_index + 1 # Add one since PTF indices start at 0 + arp_responder_cfg['eth{}'.format(ptf_index)] = [ + str(ipv4_base.ip + ip_offset), str(ipv6_base.ip + ip_offset) + ] + + CFG_FILE = '/tmp/arp_responder_vlan.json' + with open(CFG_FILE, 'w') as file: + json.dump(arp_responder_cfg, file) + ptfhost.copy(src=CFG_FILE, dest=CFG_FILE) + + extra_vars = { + 'arp_responder_args': '--conf {}'.format(CFG_FILE) + } + + ptfhost.host.options['variable_manager'].extra_vars.update(extra_vars) + ptfhost.template(src='templates/arp_responder.conf.j2', + dest='/etc/supervisor/conf.d/arp_responder.conf') + ptfhost.copy(src=os.path.join(SCRIPTS_SRC_DIR, ARP_RESPONDER_PY), + dest=OPT_DIR) + + ptfhost.command('supervisorctl reread') + ptfhost.command('supervisorctl update') + + logger.info("Start arp_responder") + ptfhost.command('supervisorctl start arp_responder') + + yield vlan, ipv4_base, ipv6_base + + ptfhost.command('supervisorctl stop arp_responder') + + def _ptf_portmap_file(duthost, ptfhost, tbinfo): """ Prepare and copys port map file to PTF host From 1eecddc475eb75180934abc0b87aadfa7e92bcd4 Mon Sep 17 00:00:00 2001 From: siqbal1986 Date: Sun, 3 Nov 2024 16:34:17 -0800 Subject: [PATCH 047/221] [TestGap] New tests to cover VNET route advertisement. (#14666) What is the motivation for this PR? How did you do it? Create the BGP profile Create a VNET routes. check neighbor bgp routes to verify the advertisements. The following tests are performed for Both V4 and V6 routes. Step Goal Expected results Create a tunnel route and advertise the tunnel route to all neighbor without community id BGP ALL BGP neighbors can recieve the advertised BGP routes Create a tunnel route and advertise the tunnel route to all neighbor with community id BGP ALL BGP neighbors can recieve the advertised BGP routes with community id Update a tunnel route and advertise the tunnel route to all neighbor with new community id BGP ALL BGP neighbors can recieve the advertised BGP routes with new community id Create a tunnel route and advertise the tunnel route to all neighbor with BGP profile, but create the profile later BGP ALL BGP neighbors can recieve the advertised BGP routes without community id first, after the profile table created, the community id would be added and all BGP neighbors can recieve this update and associate the community id with the route Delete a tunnel route BGP ALL BGP neighbors can remove the previously advertised BGP routes Create 400 tunnel routes and advertise all tunnel routes to all neighbor with community id BGP scale ALL BGP neighbors can recieve 400 advertised BGP routes with community id and record the time Updat BGP_PROFILE_TABLE with new community id for 400 tunnel routes and advertise all tunnel routes to all neighbor with new community id BGP scale ALL BGP neighbors can recieve 400 advertised BGP routes with new community id and record the time How did you verify/test it? image Any platform specific information? These scale tests are set to un with 400 routes. Altough I have ran these tests with 4k routes without any problem, but that takes the test run time to around 40 minutes. Supported testbed topology if it's a new test case? T1 Cisco, T1 Mlnx, VS --- tests/common/devices/eos.py | 9 + tests/common/vxlan_ecmp_utils.py | 34 +- tests/vxlan/test_vxlan_route_advertisement.py | 461 ++++++++++++++++++ 3 files changed, 492 insertions(+), 12 deletions(-) create mode 100644 tests/vxlan/test_vxlan_route_advertisement.py diff --git a/tests/common/devices/eos.py b/tests/common/devices/eos.py index c9a615a4074..35f28ab3e85 100644 --- a/tests/common/devices/eos.py +++ b/tests/common/devices/eos.py @@ -313,6 +313,15 @@ def get_route(self, prefix): 'output': 'json' }])['stdout'][0] + def run_command_json(self, cmd): + return self.eos_command(commands=[{ + 'command': '{}'.format(cmd), + 'output': 'json' + }])['stdout'][0] + + def run_command(self, cmd): + return self.eos_command(commands=[cmd]) + def run_command_list(self, cmd): return self.eos_command(commands=cmd) diff --git a/tests/common/vxlan_ecmp_utils.py b/tests/common/vxlan_ecmp_utils.py index fd5f0ef8bd5..6aa8620ebdc 100644 --- a/tests/common/vxlan_ecmp_utils.py +++ b/tests/common/vxlan_ecmp_utils.py @@ -297,7 +297,8 @@ def create_vnets( vnet_count=1, scope=None, vni_base=10000, - vnet_name_prefix="Vnet"): + vnet_name_prefix="Vnet", + advertise_prefix='false'): ''' Create the required number of vnets. duthost : AnsibleHost data structure of the DUT. @@ -322,8 +323,9 @@ def create_vnets( "vxlan_tunnel": "{}", {}"vni": "{}", "peer_list": "", + "advertise_prefix": "{}", "overlay_dmac" : "{}" - }}'''.format(name, tunnel_name, scope_entry, vni, self.OVERLAY_DMAC)) + }}'''.format(name, tunnel_name, scope_entry, vni, advertise_prefix, self.OVERLAY_DMAC)) full_config = '{\n"VNET": {' + ",\n".join(config_list) + '\n}\n}' @@ -526,7 +528,8 @@ def create_and_apply_config(self, mask, nhs, op, - bfd=False): + bfd=False, + profile=""): ''' Create a single destinatoin->endpoint list mapping, and configure it in the DUT. @@ -538,12 +541,12 @@ def create_and_apply_config(self, op : Operation to be done : SET or DEL. ''' - config = self.create_single_route(vnet, dest, mask, nhs, op, bfd=bfd) + config = self.create_single_route(vnet, dest, mask, nhs, op, bfd=bfd, profile=profile) str_config = '[\n' + config + '\n]' self.apply_config_in_swss(duthost, str_config, op + "_vnet_route") @classmethod - def create_single_route(cls, vnet, dest, mask, nhs, op, bfd=False): + def create_single_route(cls, vnet, dest, mask, nhs, op, bfd=False, profile=""): ''' Create a single route entry for vnet, for the given dest, through the endpoints:nhs, op:SET/DEL @@ -552,18 +555,20 @@ def create_single_route(cls, vnet, dest, mask, nhs, op, bfd=False): config = '''{{ "VNET_ROUTE_TUNNEL_TABLE:{}:{}/{}": {{ "endpoint": "{}", - "endpoint_monitor": "{}" + "endpoint_monitor": "{}", + "profile" : "{}" }}, "OP": "{}" - }}'''.format(vnet, dest, mask, ",".join(nhs), ",".join(nhs), op) + }}'''.format(vnet, dest, mask, ",".join(nhs), ",".join(nhs), profile, op) else: config = '''{{ "VNET_ROUTE_TUNNEL_TABLE:{}:{}/{}": {{ - "endpoint": "{}" + "endpoint": "{}", + "profile" : "{}" }}, "OP": "{}" - }}'''.format(vnet, dest, mask, ",".join(nhs), op) + }}'''.format(vnet, dest, mask, ",".join(nhs), profile, op) return config @@ -592,7 +597,9 @@ def set_routes_in_dut(self, dest_to_nh_map, dest_af, op, - bfd=False): + bfd=False, + mask="", + profile=""): ''' Configure Vnet routes in the DUT. duthost : AnsibleHost structure for the DUT. @@ -602,16 +609,19 @@ def set_routes_in_dut(self, op : Operation to be done: SET or DEL. bfd : Enable BFD or not (True/False). ''' + if mask == "": + mask = self.HOST_MASK[dest_af] config_list = [] for vnet in dest_to_nh_map: for dest in dest_to_nh_map[vnet]: config_list.append(self.create_single_route( vnet, dest, - self.HOST_MASK[dest_af], + mask, dest_to_nh_map[vnet][dest], op, - bfd=bfd)) + bfd=bfd, + profile=profile)) full_config = '[' + "\n,".join(config_list) + '\n]' self.apply_config_in_swss(duthost, full_config, op+"_routes") diff --git a/tests/vxlan/test_vxlan_route_advertisement.py b/tests/vxlan/test_vxlan_route_advertisement.py new file mode 100644 index 00000000000..51babda62c7 --- /dev/null +++ b/tests/vxlan/test_vxlan_route_advertisement.py @@ -0,0 +1,461 @@ +#! /usr/bin/env python3 +''' + These tests check the Vxlan ecmp Route advertisement. Further details are + provided with each test. +''' + +import time +import logging +import pytest +from tests.common.helpers.assertions import pytest_assert as py_assert +from tests.common.vxlan_ecmp_utils import Ecmp_Utils + +Logger = logging.getLogger(__name__) +ecmp_utils = Ecmp_Utils() +WAIT_TIME = 2 +WAIT_TIME_EXTRA = 5 + +# This is the list of encapsulations that will be tested in this script. +SUPPORTED_ENCAP_TYPES = ['v4_in_v4', 'v6_in_v4'] +DESTINATION_PREFIX = 150 +NEXTHOP_PREFIX = 100 +pytestmark = [ + # This script supports any T1 topology: t1, t1-64-lag, t1-56-lag, t1-lag. + pytest.mark.topology("t1", "vs") +] + + +@pytest.fixture( + name="encap_type", + scope="module", + params=SUPPORTED_ENCAP_TYPES) +def fixture_encap_type(request): + ''' + This fixture forces the script to perform one encap_type at a time. + So this script doesn't support multiple encap types at the same. + ''' + return request.param + + +@pytest.fixture(autouse=True) +def _ignore_route_sync_errlogs(duthosts, rand_one_dut_hostname, loganalyzer): + """Ignore expected failures logs during test execution.""" + if loganalyzer: + IgnoreRegex = [ + ".*Unaccounted_ROUTE_ENTRY_TABLE_entries.*", + ".*missed_in_asic_db_routes.*", + ".*Look at reported mismatches above.*", + ".*Unaccounted_ROUTE_ENTRY_TABLE_entries.*", + ".*'vnetRouteCheck' status failed.*", + ".*Vnet Route Mismatch reported.*", + ".*_M_construct null not valid.*", + ] + # Ignore in KVM test + KVMIgnoreRegex = [ + ".*doTask: Logic error: basic_string: construction from null is not valid.*", + ] + duthost = duthosts[rand_one_dut_hostname] + loganalyzer[rand_one_dut_hostname].ignore_regex.extend(IgnoreRegex) + if duthost.facts["asic_type"] == "vs": + loganalyzer[rand_one_dut_hostname].ignore_regex.extend(KVMIgnoreRegex) + return + + +@pytest.fixture(name="setUp", scope="module") +def fixture_setUp(duthosts, + request, + rand_one_dut_hostname, + minigraph_facts, + tbinfo, + nbrhosts, + encap_type): + ''' + Setup for the entire script. + The basic steps in VxLAN configs are: + 1. Configure VxLAN tunnel. + 2. Configure Vnet and its VNI. + + The testcases are focused on the "configure routes" step. They add, + delete, modify, the routes while testing the advertisement. + ''' + data = {} + nbrnames = list(nbrhosts.keys()) + data['t2'] = [] + for name in nbrnames: + if 'T2' in name: + data['t2'].append(nbrhosts[name]) + + asic_type = duthosts[rand_one_dut_hostname].facts["asic_type"] + if asic_type not in ["cisco-8000", "mellanox", "vs"]: + raise RuntimeError("Pls update this script for your platform.") + + # Should I keep the temporary files copied to DUT? + ecmp_utils.Constants['KEEP_TEMP_FILES'] = \ + request.config.option.keep_temp_files + + # Is debugging going on, or is it a production run? If it is a + # production run, use time-stamped file names for temp files. + ecmp_utils.Constants['DEBUG'] = request.config.option.debug_enabled + + # The host id in the ip addresses for DUT. It can be anything, + # but helps to keep as a single number that is easy to identify + # as DUT. + ecmp_utils.Constants['DUT_HOSTID'] = request.config.option.dut_hostid + + Logger.info("Constants to be used in the script:%s", ecmp_utils.Constants) + + data['tbinfo'] = tbinfo + data['duthost'] = duthosts[rand_one_dut_hostname] + data['minigraph_facts'] = \ + data['duthost'].get_extended_minigraph_facts(tbinfo) + data['dut_mac'] = data['duthost'].facts['router_mac'] + time.sleep(WAIT_TIME) + + ecmp_utils.configure_vxlan_switch( + data['duthost'], + vxlan_port=4789, + dutmac=data['dut_mac']) + data['active_routes'] = {} + + outer_layer_version = ecmp_utils.get_outer_layer_version(encap_type) + encap_type_data = {} + # To store the names of the tunnels, for every outer layer version. + tunnel_names = {} + # To track the vnets for every outer_layer_version. + vnet_af_map = {} + outer_layer_version = ecmp_utils.get_outer_layer_version(encap_type) + try: + tunnel_names[outer_layer_version] + except KeyError: + tunnel_names[outer_layer_version] = ecmp_utils.create_vxlan_tunnel( + data['duthost'], + minigraph_data=minigraph_facts, + af=outer_layer_version) + + payload_version = ecmp_utils.get_payload_version(encap_type) + encap_type = "{}_in_{}".format(payload_version, outer_layer_version) + + try: + encap_type_data['vnet_vni_map'] = vnet_af_map[outer_layer_version] + except KeyError: + vnet_af_map[outer_layer_version] = ecmp_utils.create_vnets( + data['duthost'], + tunnel_name=tunnel_names[outer_layer_version], + vnet_count=1, # default scope can take only one vnet. + vnet_name_prefix="Vnet_" + encap_type, + scope="default", + vni_base=10000, + advertise_prefix='true') + encap_type_data['vnet_vni_map'] = vnet_af_map[outer_layer_version] + data[encap_type] = encap_type_data + + yield data + + # Cleanup code. + if encap_type == 'v4_in_v4': + prefix_mask = 24 + prefix_type = 'v4' + else: + prefix_mask = 64 + prefix_type = 'v6' + if 'active_routes' in data: + ecmp_utils.set_routes_in_dut(data['duthost'], + data['active_routes'], + prefix_type, + 'DEL', + bfd=False, + mask=prefix_mask) + + # This script's setup code re-uses same vnets for v4inv4 and v6inv4. + # There will be same vnet in multiple encap types. + # So remove vnets *after* removing the routes first. + for vnet in list(data[encap_type]['vnet_vni_map'].keys()): + data['duthost'].shell("redis-cli -n 4 del \"VNET|{}\"".format(vnet)) + + time.sleep(5) + for tunnel in list(tunnel_names.values()): + data['duthost'].shell( + "redis-cli -n 4 del \"VXLAN_TUNNEL|{}\"".format(tunnel)) + time.sleep(1) + + +class Test_VxLAN_route_Advertisement(): + + ''' + Class for all the Vxlan tunnel cases where primary and secondary next hops are configured. + ''' + def create_bgp_profile(self, name, community): + # sonic-db-cli APPL_DB HSET "BGP_PROFILE_TABLE:FROM_SDN_SLB_ROUTES" "community_id" "1234:1235" + self.duthost.shell("sonic-db-cli APPL_DB HSET 'BGP_PROFILE_TABLE:{}' 'community_id' '{}'" + .format(name, community)) + + def remove_bgp_profile(self, name): + # sonic-db-cli APPL_DB DEL "BGP_PROFILE_TABLE:FROM_SDN_SLB_ROUTES" + self.duthost.shell("sonic-db-cli APPL_DB DEL 'BGP_PROFILE_TABLE:{}' " + .format(name)) + + def gnenrate_vnet_routes(self, encap_type, num_routes): + # We are not aiming to test the vnet route functionality so we shall stick to 4 nexthops for all prefixes. + nexthops = ['202.1.1.1', '202.1.1.2', '202.1.1.3', '202.1.1.4'] + if num_routes > 4000: + py_assert("Routes more than 4000 are not suppored.") + routes = {} + vnet = list(self.vxlan_test_setup[encap_type]['vnet_vni_map'].keys())[0] + routes[vnet] = {} + count = 0 + if self.prefix_type == 'v4': + for i in range(1, 250): + for j in range(2, 250): + key = f"99.{i}.{j}.0" + routes[vnet][key] = nexthops.copy() + count = count + 1 + if count >= num_routes: + return routes + else: + for i in range(1, 250): + for j in range(2, 250): + key = f"dc4a:{i}:{j}::" + routes[vnet][key] = nexthops.copy() + count = count + 1 + if count >= num_routes: + return routes + + return routes + + def add_unmonitored_vnet_route(self, routes, profile): + if self.prefix_type == 'v4': + prefix_mask = 24 + else: + prefix_mask = 64 + self.vxlan_test_setup['active_routes'] = routes.copy() + ecmp_utils.set_routes_in_dut(self.duthost, + routes, + self.prefix_type, + 'SET', + bfd=False, + mask=prefix_mask, + profile=profile) + + def remove_unmonitored_vnet_route(self, routes): + if self.prefix_type == 'v4': + prefix_mask = 24 + else: + prefix_mask = 64 + del self.vxlan_test_setup['active_routes'] + ecmp_utils.set_routes_in_dut(self.duthost, + routes, + self.prefix_type, + 'DEL', + bfd=False, + mask=prefix_mask) + + def verify_nighbor_has_routes(self, routes, community=""): + if self.prefix_type == 'v4': + prefix_mask = 24 + else: + prefix_mask = 64 + for vnet in routes: + for prefix in routes[vnet]: + route = f'{prefix}/{prefix_mask}' + for t2device in self.vxlan_test_setup['t2']: + result = t2device['host'].get_route(route) + py_assert(route in result['vrfs']['default']['bgpRouteEntries'], + "Route not propogated to the T2") + if community != "": + py_assert(community in str(result), "community not propogated.") + return + + def verify_nighbor_doesnt_have_routes(self, routes, community=""): + if self.prefix_type == 'v4': + prefix_mask = 24 + else: + prefix_mask = 64 + for vnet in routes: + for prefix in routes[vnet]: + route = f'{prefix}/{prefix_mask}' + for t2device in self.vxlan_test_setup['t2']: + result = t2device['host'].get_route(route) + py_assert(route not in result['vrfs']['default']['bgpRouteEntries'], + "Route not propogated to the T2") + if community != "": + py_assert(community not in str(result), "community is still getting propogated.") + return + + def verify_nighbor_has_routes_scale(self, routes, community=""): + if self.prefix_type == 'v4': + prefix_mask = 24 + cmd = "show ip bgp " + cmty = "community " + community if community != "" else "" + grepdata = " | grep ' 99.'" + else: + prefix_mask = 64 + cmd = "show ipv6 bgp " + cmty = "match community " + community if community != "" else "" + grepdata = " | grep ' dc4a:'" + cmd = cmd + cmty + grepdata + + retry_count = 4 + for t2device in self.vxlan_test_setup['t2']: + result = t2device['host'].run_command(cmd) + while len(result['stdout'][0]) == 0 and retry_count > 0: + time.sleep(10) + result = self.vxlan_test_setup['t2']['host'].run_command(cmd) + retry_count = retry_count - 1 + if len(result['stdout'][0]) == 0: + py_assert(False, "Routes not propogated to the T2.") + + for vnet in routes: + for prefix in routes[vnet]: + route = f'{prefix}/{prefix_mask}' + if route not in result['stdout'][0]: + py_assert(False, "Route not propogated to the T2.{route} with community{community} not found.") + return + + def verify_nighbor_doesnt_have_routes_scale(self, routes, community=""): + if self.prefix_type == 'v4': + prefix_mask = 24 + cmd = "show ip bgp " + grepdata = " | grep ' 99.'" + else: + prefix_mask = 64 + cmd = "show ipv6 bgp " + grepdata = " | grep ' dc4a:'" + if community != "": + cmd = cmd + "community " + community + cmd = cmd + grepdata + for t2device in self.vxlan_test_setup['t2']: + result = t2device['host'].run_command(cmd) + for vnet in routes: + for prefix in routes[vnet]: + route = f'{prefix}/{prefix_mask}' + if route in result['stdout'][0]: + py_assert(False, "Route ot propogated to the T2 which is unexpected.") + + return + + def test_basic_route_advertisement(self, setUp, encap_type, duthost): # noqa F811 + ''' + Create a tunnel route and advertise the tunnel route to all neighbor without community id + Result: All BGP neighbors can recieve the advertised BGP routes + ''' + self.vxlan_test_setup = setUp + self.duthost = duthost + if encap_type == 'v4_in_v4': + self.prefix_type = 'v4' + else: + self.prefix_type = 'v6' + routes = self.gnenrate_vnet_routes(encap_type, 1) + self.add_unmonitored_vnet_route(routes, "") + time.sleep(WAIT_TIME) + self.verify_nighbor_has_routes(routes, "") + self.remove_unmonitored_vnet_route(routes) + time.sleep(WAIT_TIME) + self.verify_nighbor_doesnt_have_routes(routes, "") + return + + def test_basic_route_advertisement_with_community(self, setUp, encap_type, duthost): # noqa F811 + ''' + Create a tunnel route and advertise the tunnel route to all neighbor with community id. + Result: All BGP neighbors can recieve the advertised BGP routes with community id + ''' + self.vxlan_test_setup = setUp + self.duthost = duthost + if encap_type == 'v4_in_v4': + self.prefix_type = 'v4' + else: + self.prefix_type = 'v6' + + self.create_bgp_profile("FROM_SDN_SLB_ROUTES", "1234:4321") + routes = self.gnenrate_vnet_routes(encap_type, 1) + self.add_unmonitored_vnet_route(routes, "FROM_SDN_SLB_ROUTES") + time.sleep(WAIT_TIME) + self.verify_nighbor_has_routes(routes, "1234:4321") + self.remove_unmonitored_vnet_route(routes) + time.sleep(WAIT_TIME) + self.verify_nighbor_doesnt_have_routes(routes, "1234:4321") + self.remove_bgp_profile("FROM_SDN_SLB_ROUTES") + return + + def test_basic_route_advertisement_with_community_change(self, setUp, encap_type, duthost): # noqa F811 + ''' + Update a tunnel route and advertise the tunnel route to all neighbor with new community id. + Result: All BGP neighbors can recieve the advertised BGP routes with new community id + ''' + self.vxlan_test_setup = setUp + self.duthost = duthost + if encap_type == 'v4_in_v4': + self.prefix_type = 'v4' + else: + self.prefix_type = 'v6' + self.create_bgp_profile("FROM_SDN_SLB_ROUTES", "1234:4321") + routes = self.gnenrate_vnet_routes(encap_type, 1) + self.add_unmonitored_vnet_route(routes, "FROM_SDN_SLB_ROUTES") + time.sleep(WAIT_TIME) + self.verify_nighbor_has_routes(routes, "1234:4321") + self.create_bgp_profile("FROM_SDN_SLB_ROUTES", "9999:8888") + time.sleep(WAIT_TIME_EXTRA) + self.verify_nighbor_has_routes(routes, "9999:8888") + self.remove_unmonitored_vnet_route(routes) + time.sleep(WAIT_TIME) + self.verify_nighbor_doesnt_have_routes(routes, "9999:8888") + self.remove_bgp_profile("FROM_SDN_SLB_ROUTES") + return + + def test_route_advertisement_without_and_with_community(self, setUp, encap_type, duthost): # noqa F811 + ''' + Create a tunnel route and advertise the tunnel route to all neighbor with BGP profile, + but create the profile later + Result: All BGP neighbors can recieve the advertised BGP routes without community id first, + after the profile table created, the community id would be added and all BGP neighbors can + recieve this update and associate the community id with the route + ''' + self.vxlan_test_setup = setUp + self.duthost = duthost + if encap_type == 'v4_in_v4': + self.prefix_type = 'v4' + else: + self.prefix_type = 'v6' + routes = self.gnenrate_vnet_routes(encap_type, 1) + self.add_unmonitored_vnet_route(routes, "FROM_SDN_SLB_ROUTES") + time.sleep(WAIT_TIME) + self.verify_nighbor_doesnt_have_routes(routes, "") + self.create_bgp_profile("FROM_SDN_SLB_ROUTES", "9999:8888") + time.sleep(WAIT_TIME_EXTRA) + self.verify_nighbor_has_routes(routes, "9999:8888") + self.remove_unmonitored_vnet_route(routes) + time.sleep(WAIT_TIME_EXTRA) + self.verify_nighbor_doesnt_have_routes(routes, "9999:8888") + self.remove_bgp_profile("FROM_SDN_SLB_ROUTES") + return + + def test_scale_route_advertisement_with_community(self, setUp, encap_type, duthost): # noqa F811 + ''' + Create 4k tunnel routes and advertise all tunnel routes to all neighbor with community id. + Result: All BGP neighbors can recieve 4k advertised BGP routes with community id and record the time. + 2nd part: + Update BGP_PROFILE_TABLE with new community id for 4k tunnel routes and advertise all tunnel routes. + Result: All BGP neighbors can recieve 4k advertised BGP routes with new community id and record the time + ''' + self.vxlan_test_setup = setUp + self.duthost = duthost + if encap_type == 'v4_in_v4': + self.prefix_type = 'v4' + else: + self.prefix_type = 'v6' + + # Part 1 + routes = self.gnenrate_vnet_routes(encap_type, 4000) + self.create_bgp_profile("FROM_SDN_SLB_ROUTES", "9999:8888") + self.add_unmonitored_vnet_route(routes, "FROM_SDN_SLB_ROUTES") + self.verify_nighbor_has_routes_scale(routes, "9999:8888") + + # Part 2 + self.create_bgp_profile("FROM_SDN_SLB_ROUTES", "1234:4321") + time.sleep(WAIT_TIME_EXTRA*20) + self.verify_nighbor_has_routes_scale(routes, "1234:4321") + self.remove_unmonitored_vnet_route(routes) + time.sleep(WAIT_TIME) + self.verify_nighbor_doesnt_have_routes_scale(routes, "") + + self.remove_bgp_profile("FROM_SDN_SLB_ROUTES") + return From fd01a32f565fae2850b023eb53726d75c0ec87d9 Mon Sep 17 00:00:00 2001 From: Janet Cui Date: Mon, 4 Nov 2024 12:00:51 +1100 Subject: [PATCH 048/221] Add topo t1-isolated-d224u8 (#15168) Add a new T1 topology with 224 VMs simulating downstream T0 neighbors and 8 VMs simulating upstream T2 neighbors. Signed-off-by: Janetxxx --- ansible/vars/topo_t1-isolated-d224u8.yaml | 5356 +++++++++++++++++++++ ansible/veos | 1 + docs/testbed/README.testbed.Overview.md | 7 + 3 files changed, 5364 insertions(+) create mode 100644 ansible/vars/topo_t1-isolated-d224u8.yaml diff --git a/ansible/vars/topo_t1-isolated-d224u8.yaml b/ansible/vars/topo_t1-isolated-d224u8.yaml new file mode 100644 index 00000000000..5f97f7fd713 --- /dev/null +++ b/ansible/vars/topo_t1-isolated-d224u8.yaml @@ -0,0 +1,5356 @@ +topology: + VMs: + ARISTA01T0: + vlans: + - 0 + vm_offset: 0 + ARISTA02T0: + vlans: + - 1 + vm_offset: 1 + ARISTA03T0: + vlans: + - 2 + vm_offset: 2 + ARISTA04T0: + vlans: + - 3 + vm_offset: 3 + ARISTA05T0: + vlans: + - 4 + vm_offset: 4 + ARISTA06T0: + vlans: + - 5 + vm_offset: 5 + ARISTA07T0: + vlans: + - 6 + vm_offset: 6 + ARISTA08T0: + vlans: + - 7 + vm_offset: 7 + ARISTA09T0: + vlans: + - 8 + vm_offset: 8 + ARISTA10T0: + vlans: + - 9 + vm_offset: 9 + ARISTA11T0: + vlans: + - 10 + vm_offset: 10 + ARISTA12T0: + vlans: + - 11 + vm_offset: 11 + ARISTA13T0: + vlans: + - 12 + vm_offset: 12 + ARISTA14T0: + vlans: + - 13 + vm_offset: 13 + ARISTA15T0: + vlans: + - 14 + vm_offset: 14 + ARISTA16T0: + vlans: + - 15 + vm_offset: 15 + ARISTA17T0: + vlans: + - 16 + vm_offset: 16 + ARISTA18T0: + vlans: + - 17 + vm_offset: 17 + ARISTA19T0: + vlans: + - 18 + vm_offset: 18 + ARISTA20T0: + vlans: + - 19 + vm_offset: 19 + ARISTA21T0: + vlans: + - 20 + vm_offset: 20 + ARISTA22T0: + vlans: + - 21 + vm_offset: 21 + ARISTA23T0: + vlans: + - 22 + vm_offset: 22 + ARISTA24T0: + vlans: + - 23 + vm_offset: 23 + ARISTA25T0: + vlans: + - 24 + vm_offset: 24 + ARISTA26T0: + vlans: + - 25 + vm_offset: 25 + ARISTA27T0: + vlans: + - 26 + vm_offset: 26 + ARISTA28T0: + vlans: + - 27 + vm_offset: 27 + ARISTA29T0: + vlans: + - 28 + vm_offset: 28 + ARISTA30T0: + vlans: + - 29 + vm_offset: 29 + ARISTA31T0: + vlans: + - 30 + vm_offset: 30 + ARISTA32T0: + vlans: + - 31 + vm_offset: 31 + ARISTA33T0: + vlans: + - 32 + vm_offset: 32 + ARISTA34T0: + vlans: + - 33 + vm_offset: 33 + ARISTA35T0: + vlans: + - 34 + vm_offset: 34 + ARISTA36T0: + vlans: + - 35 + vm_offset: 35 + ARISTA37T0: + vlans: + - 36 + vm_offset: 36 + ARISTA38T0: + vlans: + - 37 + vm_offset: 37 + ARISTA39T0: + vlans: + - 38 + vm_offset: 38 + ARISTA40T0: + vlans: + - 39 + vm_offset: 39 + ARISTA41T0: + vlans: + - 40 + vm_offset: 40 + ARISTA42T0: + vlans: + - 41 + vm_offset: 41 + ARISTA43T0: + vlans: + - 42 + vm_offset: 42 + ARISTA44T0: + vlans: + - 43 + vm_offset: 43 + ARISTA45T0: + vlans: + - 44 + vm_offset: 44 + ARISTA46T0: + vlans: + - 45 + vm_offset: 45 + ARISTA47T0: + vlans: + - 46 + vm_offset: 46 + ARISTA48T0: + vlans: + - 47 + vm_offset: 47 + ARISTA49T2: + vlans: + - 48 + vm_offset: 48 + ARISTA50T2: + vlans: + - 49 + vm_offset: 49 + ARISTA51T0: + vlans: + - 56 + vm_offset: 50 + ARISTA52T0: + vlans: + - 57 + vm_offset: 51 + ARISTA53T0: + vlans: + - 58 + vm_offset: 52 + ARISTA54T0: + vlans: + - 59 + vm_offset: 53 + ARISTA55T0: + vlans: + - 60 + vm_offset: 54 + ARISTA56T0: + vlans: + - 61 + vm_offset: 55 + ARISTA57T0: + vlans: + - 62 + vm_offset: 56 + ARISTA58T0: + vlans: + - 63 + vm_offset: 57 + ARISTA59T2: + vlans: + - 64 + vm_offset: 58 + ARISTA60T2: + vlans: + - 65 + vm_offset: 59 + ARISTA61T0: + vlans: + - 72 + vm_offset: 60 + ARISTA62T0: + vlans: + - 73 + vm_offset: 61 + ARISTA63T0: + vlans: + - 74 + vm_offset: 62 + ARISTA64T0: + vlans: + - 75 + vm_offset: 63 + ARISTA65T0: + vlans: + - 76 + vm_offset: 64 + ARISTA66T0: + vlans: + - 77 + vm_offset: 65 + ARISTA67T0: + vlans: + - 78 + vm_offset: 66 + ARISTA68T0: + vlans: + - 79 + vm_offset: 67 + ARISTA69T0: + vlans: + - 80 + vm_offset: 68 + ARISTA70T0: + vlans: + - 81 + vm_offset: 69 + ARISTA71T0: + vlans: + - 82 + vm_offset: 70 + ARISTA72T0: + vlans: + - 83 + vm_offset: 71 + ARISTA73T0: + vlans: + - 84 + vm_offset: 72 + ARISTA74T0: + vlans: + - 85 + vm_offset: 73 + ARISTA75T0: + vlans: + - 86 + vm_offset: 74 + ARISTA76T0: + vlans: + - 87 + vm_offset: 75 + ARISTA77T0: + vlans: + - 88 + vm_offset: 76 + ARISTA78T0: + vlans: + - 89 + vm_offset: 77 + ARISTA79T0: + vlans: + - 90 + vm_offset: 78 + ARISTA80T0: + vlans: + - 91 + vm_offset: 79 + ARISTA81T0: + vlans: + - 92 + vm_offset: 80 + ARISTA82T0: + vlans: + - 93 + vm_offset: 81 + ARISTA83T0: + vlans: + - 94 + vm_offset: 82 + ARISTA84T0: + vlans: + - 95 + vm_offset: 83 + ARISTA85T0: + vlans: + - 96 + vm_offset: 84 + ARISTA86T0: + vlans: + - 97 + vm_offset: 85 + ARISTA87T0: + vlans: + - 98 + vm_offset: 86 + ARISTA88T0: + vlans: + - 99 + vm_offset: 87 + ARISTA89T0: + vlans: + - 100 + vm_offset: 88 + ARISTA90T0: + vlans: + - 101 + vm_offset: 89 + ARISTA91T0: + vlans: + - 102 + vm_offset: 90 + ARISTA92T0: + vlans: + - 103 + vm_offset: 91 + ARISTA93T0: + vlans: + - 104 + vm_offset: 92 + ARISTA94T0: + vlans: + - 105 + vm_offset: 93 + ARISTA95T0: + vlans: + - 106 + vm_offset: 94 + ARISTA96T0: + vlans: + - 107 + vm_offset: 95 + ARISTA97T0: + vlans: + - 108 + vm_offset: 96 + ARISTA98T0: + vlans: + - 109 + vm_offset: 97 + ARISTA99T0: + vlans: + - 110 + vm_offset: 98 + ARISTA100T0: + vlans: + - 111 + vm_offset: 99 + ARISTA101T0: + vlans: + - 112 + vm_offset: 100 + ARISTA102T0: + vlans: + - 113 + vm_offset: 101 + ARISTA103T0: + vlans: + - 114 + vm_offset: 102 + ARISTA104T0: + vlans: + - 115 + vm_offset: 103 + ARISTA105T0: + vlans: + - 116 + vm_offset: 104 + ARISTA106T0: + vlans: + - 117 + vm_offset: 105 + ARISTA107T0: + vlans: + - 118 + vm_offset: 106 + ARISTA108T0: + vlans: + - 119 + vm_offset: 107 + ARISTA109T0: + vlans: + - 120 + vm_offset: 108 + ARISTA110T0: + vlans: + - 121 + vm_offset: 109 + ARISTA111T0: + vlans: + - 122 + vm_offset: 110 + ARISTA112T0: + vlans: + - 123 + vm_offset: 111 + ARISTA113T0: + vlans: + - 124 + vm_offset: 112 + ARISTA114T0: + vlans: + - 125 + vm_offset: 113 + ARISTA115T0: + vlans: + - 126 + vm_offset: 114 + ARISTA116T0: + vlans: + - 127 + vm_offset: 115 + ARISTA117T0: + vlans: + - 128 + vm_offset: 116 + ARISTA118T0: + vlans: + - 129 + vm_offset: 117 + ARISTA119T0: + vlans: + - 130 + vm_offset: 118 + ARISTA120T0: + vlans: + - 131 + vm_offset: 119 + ARISTA121T0: + vlans: + - 132 + vm_offset: 120 + ARISTA122T0: + vlans: + - 133 + vm_offset: 121 + ARISTA123T0: + vlans: + - 134 + vm_offset: 122 + ARISTA124T0: + vlans: + - 135 + vm_offset: 123 + ARISTA125T0: + vlans: + - 136 + vm_offset: 124 + ARISTA126T0: + vlans: + - 137 + vm_offset: 125 + ARISTA127T0: + vlans: + - 138 + vm_offset: 126 + ARISTA128T0: + vlans: + - 139 + vm_offset: 127 + ARISTA129T0: + vlans: + - 140 + vm_offset: 128 + ARISTA130T0: + vlans: + - 141 + vm_offset: 129 + ARISTA131T0: + vlans: + - 142 + vm_offset: 130 + ARISTA132T0: + vlans: + - 143 + vm_offset: 131 + ARISTA133T0: + vlans: + - 144 + vm_offset: 132 + ARISTA134T0: + vlans: + - 145 + vm_offset: 133 + ARISTA135T0: + vlans: + - 146 + vm_offset: 134 + ARISTA136T0: + vlans: + - 147 + vm_offset: 135 + ARISTA137T0: + vlans: + - 148 + vm_offset: 136 + ARISTA138T0: + vlans: + - 149 + vm_offset: 137 + ARISTA139T0: + vlans: + - 150 + vm_offset: 138 + ARISTA140T0: + vlans: + - 151 + vm_offset: 139 + ARISTA141T0: + vlans: + - 152 + vm_offset: 140 + ARISTA142T0: + vlans: + - 153 + vm_offset: 141 + ARISTA143T0: + vlans: + - 154 + vm_offset: 142 + ARISTA144T0: + vlans: + - 155 + vm_offset: 143 + ARISTA145T0: + vlans: + - 156 + vm_offset: 144 + ARISTA146T0: + vlans: + - 157 + vm_offset: 145 + ARISTA147T0: + vlans: + - 158 + vm_offset: 146 + ARISTA148T0: + vlans: + - 159 + vm_offset: 147 + ARISTA149T0: + vlans: + - 160 + vm_offset: 148 + ARISTA150T0: + vlans: + - 161 + vm_offset: 149 + ARISTA151T0: + vlans: + - 162 + vm_offset: 150 + ARISTA152T0: + vlans: + - 163 + vm_offset: 151 + ARISTA153T0: + vlans: + - 164 + vm_offset: 152 + ARISTA154T0: + vlans: + - 165 + vm_offset: 153 + ARISTA155T0: + vlans: + - 166 + vm_offset: 154 + ARISTA156T0: + vlans: + - 167 + vm_offset: 155 + ARISTA157T0: + vlans: + - 168 + vm_offset: 156 + ARISTA158T0: + vlans: + - 169 + vm_offset: 157 + ARISTA159T0: + vlans: + - 170 + vm_offset: 158 + ARISTA160T0: + vlans: + - 171 + vm_offset: 159 + ARISTA161T0: + vlans: + - 172 + vm_offset: 160 + ARISTA162T0: + vlans: + - 173 + vm_offset: 161 + ARISTA163T0: + vlans: + - 174 + vm_offset: 162 + ARISTA164T0: + vlans: + - 175 + vm_offset: 163 + ARISTA165T2: + vlans: + - 176 + vm_offset: 164 + ARISTA166T2: + vlans: + - 177 + vm_offset: 165 + ARISTA167T0: + vlans: + - 184 + vm_offset: 166 + ARISTA168T0: + vlans: + - 185 + vm_offset: 167 + ARISTA169T0: + vlans: + - 186 + vm_offset: 168 + ARISTA170T0: + vlans: + - 187 + vm_offset: 169 + ARISTA171T0: + vlans: + - 188 + vm_offset: 170 + ARISTA172T0: + vlans: + - 189 + vm_offset: 171 + ARISTA173T0: + vlans: + - 190 + vm_offset: 172 + ARISTA174T0: + vlans: + - 191 + vm_offset: 173 + ARISTA175T2: + vlans: + - 192 + vm_offset: 174 + ARISTA176T2: + vlans: + - 193 + vm_offset: 175 + ARISTA177T0: + vlans: + - 200 + vm_offset: 176 + ARISTA178T0: + vlans: + - 201 + vm_offset: 177 + ARISTA179T0: + vlans: + - 202 + vm_offset: 178 + ARISTA180T0: + vlans: + - 203 + vm_offset: 179 + ARISTA181T0: + vlans: + - 204 + vm_offset: 180 + ARISTA182T0: + vlans: + - 205 + vm_offset: 181 + ARISTA183T0: + vlans: + - 206 + vm_offset: 182 + ARISTA184T0: + vlans: + - 207 + vm_offset: 183 + ARISTA185T0: + vlans: + - 208 + vm_offset: 184 + ARISTA186T0: + vlans: + - 209 + vm_offset: 185 + ARISTA187T0: + vlans: + - 210 + vm_offset: 186 + ARISTA188T0: + vlans: + - 211 + vm_offset: 187 + ARISTA189T0: + vlans: + - 212 + vm_offset: 188 + ARISTA190T0: + vlans: + - 213 + vm_offset: 189 + ARISTA191T0: + vlans: + - 214 + vm_offset: 190 + ARISTA192T0: + vlans: + - 215 + vm_offset: 191 + ARISTA193T0: + vlans: + - 216 + vm_offset: 192 + ARISTA194T0: + vlans: + - 217 + vm_offset: 193 + ARISTA195T0: + vlans: + - 218 + vm_offset: 194 + ARISTA196T0: + vlans: + - 219 + vm_offset: 195 + ARISTA197T0: + vlans: + - 220 + vm_offset: 196 + ARISTA198T0: + vlans: + - 221 + vm_offset: 197 + ARISTA199T0: + vlans: + - 222 + vm_offset: 198 + ARISTA200T0: + vlans: + - 223 + vm_offset: 199 + ARISTA201T0: + vlans: + - 224 + vm_offset: 200 + ARISTA202T0: + vlans: + - 225 + vm_offset: 201 + ARISTA203T0: + vlans: + - 226 + vm_offset: 202 + ARISTA204T0: + vlans: + - 227 + vm_offset: 203 + ARISTA205T0: + vlans: + - 228 + vm_offset: 204 + ARISTA206T0: + vlans: + - 229 + vm_offset: 205 + ARISTA207T0: + vlans: + - 230 + vm_offset: 206 + ARISTA208T0: + vlans: + - 231 + vm_offset: 207 + ARISTA209T0: + vlans: + - 232 + vm_offset: 208 + ARISTA210T0: + vlans: + - 233 + vm_offset: 209 + ARISTA211T0: + vlans: + - 234 + vm_offset: 210 + ARISTA212T0: + vlans: + - 235 + vm_offset: 211 + ARISTA213T0: + vlans: + - 236 + vm_offset: 212 + ARISTA214T0: + vlans: + - 237 + vm_offset: 213 + ARISTA215T0: + vlans: + - 238 + vm_offset: 214 + ARISTA216T0: + vlans: + - 239 + vm_offset: 215 + ARISTA217T0: + vlans: + - 240 + vm_offset: 216 + ARISTA218T0: + vlans: + - 241 + vm_offset: 217 + ARISTA219T0: + vlans: + - 242 + vm_offset: 218 + ARISTA220T0: + vlans: + - 243 + vm_offset: 219 + ARISTA221T0: + vlans: + - 244 + vm_offset: 220 + ARISTA222T0: + vlans: + - 245 + vm_offset: 221 + ARISTA223T0: + vlans: + - 246 + vm_offset: 222 + ARISTA224T0: + vlans: + - 247 + vm_offset: 223 + ARISTA225T0: + vlans: + - 248 + vm_offset: 224 + ARISTA226T0: + vlans: + - 249 + vm_offset: 225 + ARISTA227T0: + vlans: + - 250 + vm_offset: 226 + ARISTA228T0: + vlans: + - 251 + vm_offset: 227 + ARISTA229T0: + vlans: + - 252 + vm_offset: 228 + ARISTA230T0: + vlans: + - 253 + vm_offset: 229 + ARISTA231T0: + vlans: + - 254 + vm_offset: 230 + ARISTA232T0: + vlans: + - 255 + vm_offset: 231 + +configuration_properties: + common: + dut_asn: 65100 + dut_type: LeafRouter + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine: + swrole: spine + tor: + swrole: tor + +configuration: + ARISTA01T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.0 + - fc00::1 + interfaces: + Loopback0: + ipv4: 100.1.0.1/32 + ipv6: 2064:100::1/128 + Ethernet1: + ipv4: 10.0.0.1/31 + ipv6: fc00::2/126 + bp_interfaces: + ipv4: 10.10.246.2/24 + ipv6: fc0a::2/64 + ARISTA02T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.2 + - fc00::5 + interfaces: + Loopback0: + ipv4: 100.1.0.2/32 + ipv6: 2064:100::2/128 + Ethernet1: + ipv4: 10.0.0.3/31 + ipv6: fc00::6/126 + bp_interfaces: + ipv4: 10.10.246.3/24 + ipv6: fc0a::3/64 + ARISTA03T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.4 + - fc00::9 + interfaces: + Loopback0: + ipv4: 100.1.0.3/32 + ipv6: 2064:100::3/128 + Ethernet1: + ipv4: 10.0.0.5/31 + ipv6: fc00::a/126 + bp_interfaces: + ipv4: 10.10.246.4/24 + ipv6: fc0a::4/64 + ARISTA04T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.6 + - fc00::d + interfaces: + Loopback0: + ipv4: 100.1.0.4/32 + ipv6: 2064:100::4/128 + Ethernet1: + ipv4: 10.0.0.7/31 + ipv6: fc00::e/126 + bp_interfaces: + ipv4: 10.10.246.5/24 + ipv6: fc0a::5/64 + ARISTA05T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.8 + - fc00::11 + interfaces: + Loopback0: + ipv4: 100.1.0.5/32 + ipv6: 2064:100::5/128 + Ethernet1: + ipv4: 10.0.0.9/31 + ipv6: fc00::12/126 + bp_interfaces: + ipv4: 10.10.246.6/24 + ipv6: fc0a::6/64 + ARISTA06T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.10 + - fc00::15 + interfaces: + Loopback0: + ipv4: 100.1.0.6/32 + ipv6: 2064:100::6/128 + Ethernet1: + ipv4: 10.0.0.11/31 + ipv6: fc00::16/126 + bp_interfaces: + ipv4: 10.10.246.7/24 + ipv6: fc0a::7/64 + ARISTA07T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.12 + - fc00::19 + interfaces: + Loopback0: + ipv4: 100.1.0.7/32 + ipv6: 2064:100::7/128 + Ethernet1: + ipv4: 10.0.0.13/31 + ipv6: fc00::1a/126 + bp_interfaces: + ipv4: 10.10.246.8/24 + ipv6: fc0a::8/64 + ARISTA08T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.14 + - fc00::1d + interfaces: + Loopback0: + ipv4: 100.1.0.8/32 + ipv6: 2064:100::8/128 + Ethernet1: + ipv4: 10.0.0.15/31 + ipv6: fc00::1e/126 + bp_interfaces: + ipv4: 10.10.246.9/24 + ipv6: fc0a::9/64 + ARISTA09T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.16 + - fc00::21 + interfaces: + Loopback0: + ipv4: 100.1.0.9/32 + ipv6: 2064:100::9/128 + Ethernet1: + ipv4: 10.0.0.17/31 + ipv6: fc00::22/126 + bp_interfaces: + ipv4: 10.10.246.10/24 + ipv6: fc0a::a/64 + ARISTA10T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.18 + - fc00::25 + interfaces: + Loopback0: + ipv4: 100.1.0.10/32 + ipv6: 2064:100::a/128 + Ethernet1: + ipv4: 10.0.0.19/31 + ipv6: fc00::26/126 + bp_interfaces: + ipv4: 10.10.246.11/24 + ipv6: fc0a::b/64 + ARISTA11T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.20 + - fc00::29 + interfaces: + Loopback0: + ipv4: 100.1.0.11/32 + ipv6: 2064:100::b/128 + Ethernet1: + ipv4: 10.0.0.21/31 + ipv6: fc00::2a/126 + bp_interfaces: + ipv4: 10.10.246.12/24 + ipv6: fc0a::c/64 + ARISTA12T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.22 + - fc00::2d + interfaces: + Loopback0: + ipv4: 100.1.0.12/32 + ipv6: 2064:100::c/128 + Ethernet1: + ipv4: 10.0.0.23/31 + ipv6: fc00::2e/126 + bp_interfaces: + ipv4: 10.10.246.13/24 + ipv6: fc0a::d/64 + ARISTA13T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.24 + - fc00::31 + interfaces: + Loopback0: + ipv4: 100.1.0.13/32 + ipv6: 2064:100::d/128 + Ethernet1: + ipv4: 10.0.0.25/31 + ipv6: fc00::32/126 + bp_interfaces: + ipv4: 10.10.246.14/24 + ipv6: fc0a::e/64 + ARISTA14T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.26 + - fc00::35 + interfaces: + Loopback0: + ipv4: 100.1.0.14/32 + ipv6: 2064:100::e/128 + Ethernet1: + ipv4: 10.0.0.27/31 + ipv6: fc00::36/126 + bp_interfaces: + ipv4: 10.10.246.15/24 + ipv6: fc0a::f/64 + ARISTA15T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.28 + - fc00::39 + interfaces: + Loopback0: + ipv4: 100.1.0.15/32 + ipv6: 2064:100::f/128 + Ethernet1: + ipv4: 10.0.0.29/31 + ipv6: fc00::3a/126 + bp_interfaces: + ipv4: 10.10.246.16/24 + ipv6: fc0a::10/64 + ARISTA16T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.30 + - fc00::3d + interfaces: + Loopback0: + ipv4: 100.1.0.16/32 + ipv6: 2064:100::10/128 + Ethernet1: + ipv4: 10.0.0.31/31 + ipv6: fc00::3e/126 + bp_interfaces: + ipv4: 10.10.246.17/24 + ipv6: fc0a::11/64 + ARISTA17T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.32 + - fc00::41 + interfaces: + Loopback0: + ipv4: 100.1.0.17/32 + ipv6: 2064:100::11/128 + Ethernet1: + ipv4: 10.0.0.33/31 + ipv6: fc00::42/126 + bp_interfaces: + ipv4: 10.10.246.18/24 + ipv6: fc0a::12/64 + ARISTA18T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.34 + - fc00::45 + interfaces: + Loopback0: + ipv4: 100.1.0.18/32 + ipv6: 2064:100::12/128 + Ethernet1: + ipv4: 10.0.0.35/31 + ipv6: fc00::46/126 + bp_interfaces: + ipv4: 10.10.246.19/24 + ipv6: fc0a::13/64 + ARISTA19T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.36 + - fc00::49 + interfaces: + Loopback0: + ipv4: 100.1.0.19/32 + ipv6: 2064:100::13/128 + Ethernet1: + ipv4: 10.0.0.37/31 + ipv6: fc00::4a/126 + bp_interfaces: + ipv4: 10.10.246.20/24 + ipv6: fc0a::14/64 + ARISTA20T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.38 + - fc00::4d + interfaces: + Loopback0: + ipv4: 100.1.0.20/32 + ipv6: 2064:100::14/128 + Ethernet1: + ipv4: 10.0.0.39/31 + ipv6: fc00::4e/126 + bp_interfaces: + ipv4: 10.10.246.21/24 + ipv6: fc0a::15/64 + ARISTA21T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.40 + - fc00::51 + interfaces: + Loopback0: + ipv4: 100.1.0.21/32 + ipv6: 2064:100::15/128 + Ethernet1: + ipv4: 10.0.0.41/31 + ipv6: fc00::52/126 + bp_interfaces: + ipv4: 10.10.246.22/24 + ipv6: fc0a::16/64 + ARISTA22T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.42 + - fc00::55 + interfaces: + Loopback0: + ipv4: 100.1.0.22/32 + ipv6: 2064:100::16/128 + Ethernet1: + ipv4: 10.0.0.43/31 + ipv6: fc00::56/126 + bp_interfaces: + ipv4: 10.10.246.23/24 + ipv6: fc0a::17/64 + ARISTA23T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.44 + - fc00::59 + interfaces: + Loopback0: + ipv4: 100.1.0.23/32 + ipv6: 2064:100::17/128 + Ethernet1: + ipv4: 10.0.0.45/31 + ipv6: fc00::5a/126 + bp_interfaces: + ipv4: 10.10.246.24/24 + ipv6: fc0a::18/64 + ARISTA24T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.46 + - fc00::5d + interfaces: + Loopback0: + ipv4: 100.1.0.24/32 + ipv6: 2064:100::18/128 + Ethernet1: + ipv4: 10.0.0.47/31 + ipv6: fc00::5e/126 + bp_interfaces: + ipv4: 10.10.246.25/24 + ipv6: fc0a::19/64 + ARISTA25T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.48 + - fc00::61 + interfaces: + Loopback0: + ipv4: 100.1.0.25/32 + ipv6: 2064:100::19/128 + Ethernet1: + ipv4: 10.0.0.49/31 + ipv6: fc00::62/126 + bp_interfaces: + ipv4: 10.10.246.26/24 + ipv6: fc0a::1a/64 + ARISTA26T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.50 + - fc00::65 + interfaces: + Loopback0: + ipv4: 100.1.0.26/32 + ipv6: 2064:100::1a/128 + Ethernet1: + ipv4: 10.0.0.51/31 + ipv6: fc00::66/126 + bp_interfaces: + ipv4: 10.10.246.27/24 + ipv6: fc0a::1b/64 + ARISTA27T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.52 + - fc00::69 + interfaces: + Loopback0: + ipv4: 100.1.0.27/32 + ipv6: 2064:100::1b/128 + Ethernet1: + ipv4: 10.0.0.53/31 + ipv6: fc00::6a/126 + bp_interfaces: + ipv4: 10.10.246.28/24 + ipv6: fc0a::1c/64 + ARISTA28T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.54 + - fc00::6d + interfaces: + Loopback0: + ipv4: 100.1.0.28/32 + ipv6: 2064:100::1c/128 + Ethernet1: + ipv4: 10.0.0.55/31 + ipv6: fc00::6e/126 + bp_interfaces: + ipv4: 10.10.246.29/24 + ipv6: fc0a::1d/64 + ARISTA29T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.56 + - fc00::71 + interfaces: + Loopback0: + ipv4: 100.1.0.29/32 + ipv6: 2064:100::1d/128 + Ethernet1: + ipv4: 10.0.0.57/31 + ipv6: fc00::72/126 + bp_interfaces: + ipv4: 10.10.246.30/24 + ipv6: fc0a::1e/64 + ARISTA30T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.58 + - fc00::75 + interfaces: + Loopback0: + ipv4: 100.1.0.30/32 + ipv6: 2064:100::1e/128 + Ethernet1: + ipv4: 10.0.0.59/31 + ipv6: fc00::76/126 + bp_interfaces: + ipv4: 10.10.246.31/24 + ipv6: fc0a::1f/64 + ARISTA31T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.60 + - fc00::79 + interfaces: + Loopback0: + ipv4: 100.1.0.31/32 + ipv6: 2064:100::1f/128 + Ethernet1: + ipv4: 10.0.0.61/31 + ipv6: fc00::7a/126 + bp_interfaces: + ipv4: 10.10.246.32/24 + ipv6: fc0a::20/64 + ARISTA32T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.62 + - fc00::7d + interfaces: + Loopback0: + ipv4: 100.1.0.32/32 + ipv6: 2064:100::20/128 + Ethernet1: + ipv4: 10.0.0.63/31 + ipv6: fc00::7e/126 + bp_interfaces: + ipv4: 10.10.246.33/24 + ipv6: fc0a::21/64 + ARISTA33T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.64 + - fc00::81 + interfaces: + Loopback0: + ipv4: 100.1.0.33/32 + ipv6: 2064:100::21/128 + Ethernet1: + ipv4: 10.0.0.65/31 + ipv6: fc00::82/126 + bp_interfaces: + ipv4: 10.10.246.34/24 + ipv6: fc0a::22/64 + ARISTA34T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.66 + - fc00::85 + interfaces: + Loopback0: + ipv4: 100.1.0.34/32 + ipv6: 2064:100::22/128 + Ethernet1: + ipv4: 10.0.0.67/31 + ipv6: fc00::86/126 + bp_interfaces: + ipv4: 10.10.246.35/24 + ipv6: fc0a::23/64 + ARISTA35T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.68 + - fc00::89 + interfaces: + Loopback0: + ipv4: 100.1.0.35/32 + ipv6: 2064:100::23/128 + Ethernet1: + ipv4: 10.0.0.69/31 + ipv6: fc00::8a/126 + bp_interfaces: + ipv4: 10.10.246.36/24 + ipv6: fc0a::24/64 + ARISTA36T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.70 + - fc00::8d + interfaces: + Loopback0: + ipv4: 100.1.0.36/32 + ipv6: 2064:100::24/128 + Ethernet1: + ipv4: 10.0.0.71/31 + ipv6: fc00::8e/126 + bp_interfaces: + ipv4: 10.10.246.37/24 + ipv6: fc0a::25/64 + ARISTA37T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.72 + - fc00::91 + interfaces: + Loopback0: + ipv4: 100.1.0.37/32 + ipv6: 2064:100::25/128 + Ethernet1: + ipv4: 10.0.0.73/31 + ipv6: fc00::92/126 + bp_interfaces: + ipv4: 10.10.246.38/24 + ipv6: fc0a::26/64 + ARISTA38T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.74 + - fc00::95 + interfaces: + Loopback0: + ipv4: 100.1.0.38/32 + ipv6: 2064:100::26/128 + Ethernet1: + ipv4: 10.0.0.75/31 + ipv6: fc00::96/126 + bp_interfaces: + ipv4: 10.10.246.39/24 + ipv6: fc0a::27/64 + ARISTA39T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.76 + - fc00::99 + interfaces: + Loopback0: + ipv4: 100.1.0.39/32 + ipv6: 2064:100::27/128 + Ethernet1: + ipv4: 10.0.0.77/31 + ipv6: fc00::9a/126 + bp_interfaces: + ipv4: 10.10.246.40/24 + ipv6: fc0a::28/64 + ARISTA40T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.78 + - fc00::9d + interfaces: + Loopback0: + ipv4: 100.1.0.40/32 + ipv6: 2064:100::28/128 + Ethernet1: + ipv4: 10.0.0.79/31 + ipv6: fc00::9e/126 + bp_interfaces: + ipv4: 10.10.246.41/24 + ipv6: fc0a::29/64 + ARISTA41T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.80 + - fc00::a1 + interfaces: + Loopback0: + ipv4: 100.1.0.41/32 + ipv6: 2064:100::29/128 + Ethernet1: + ipv4: 10.0.0.81/31 + ipv6: fc00::a2/126 + bp_interfaces: + ipv4: 10.10.246.42/24 + ipv6: fc0a::2a/64 + ARISTA42T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.82 + - fc00::a5 + interfaces: + Loopback0: + ipv4: 100.1.0.42/32 + ipv6: 2064:100::2a/128 + Ethernet1: + ipv4: 10.0.0.83/31 + ipv6: fc00::a6/126 + bp_interfaces: + ipv4: 10.10.246.43/24 + ipv6: fc0a::2b/64 + ARISTA43T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.84 + - fc00::a9 + interfaces: + Loopback0: + ipv4: 100.1.0.43/32 + ipv6: 2064:100::2b/128 + Ethernet1: + ipv4: 10.0.0.85/31 + ipv6: fc00::aa/126 + bp_interfaces: + ipv4: 10.10.246.44/24 + ipv6: fc0a::2c/64 + ARISTA44T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.86 + - fc00::ad + interfaces: + Loopback0: + ipv4: 100.1.0.44/32 + ipv6: 2064:100::2c/128 + Ethernet1: + ipv4: 10.0.0.87/31 + ipv6: fc00::ae/126 + bp_interfaces: + ipv4: 10.10.246.45/24 + ipv6: fc0a::2d/64 + ARISTA45T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.88 + - fc00::b1 + interfaces: + Loopback0: + ipv4: 100.1.0.45/32 + ipv6: 2064:100::2d/128 + Ethernet1: + ipv4: 10.0.0.89/31 + ipv6: fc00::b2/126 + bp_interfaces: + ipv4: 10.10.246.46/24 + ipv6: fc0a::2e/64 + ARISTA46T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.90 + - fc00::b5 + interfaces: + Loopback0: + ipv4: 100.1.0.46/32 + ipv6: 2064:100::2e/128 + Ethernet1: + ipv4: 10.0.0.91/31 + ipv6: fc00::b6/126 + bp_interfaces: + ipv4: 10.10.246.47/24 + ipv6: fc0a::2f/64 + ARISTA47T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.92 + - fc00::b9 + interfaces: + Loopback0: + ipv4: 100.1.0.47/32 + ipv6: 2064:100::2f/128 + Ethernet1: + ipv4: 10.0.0.93/31 + ipv6: fc00::ba/126 + bp_interfaces: + ipv4: 10.10.246.48/24 + ipv6: fc0a::30/64 + ARISTA48T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.94 + - fc00::bd + interfaces: + Loopback0: + ipv4: 100.1.0.48/32 + ipv6: 2064:100::30/128 + Ethernet1: + ipv4: 10.0.0.95/31 + ipv6: fc00::be/126 + bp_interfaces: + ipv4: 10.10.246.49/24 + ipv6: fc0a::31/64 + ARISTA49T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.96 + - fc00::c1 + interfaces: + Loopback0: + ipv4: 100.1.0.49/32 + ipv6: 2064:100::31/128 + Ethernet1: + ipv4: 10.0.0.97/31 + ipv6: fc00::c2/126 + bp_interfaces: + ipv4: 10.10.246.50/24 + ipv6: fc0a::32/64 + ARISTA50T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.98 + - fc00::c5 + interfaces: + Loopback0: + ipv4: 100.1.0.50/32 + ipv6: 2064:100::32/128 + Ethernet1: + ipv4: 10.0.0.99/31 + ipv6: fc00::c6/126 + bp_interfaces: + ipv4: 10.10.246.51/24 + ipv6: fc0a::33/64 + ARISTA51T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.112 + - fc00::e1 + interfaces: + Loopback0: + ipv4: 100.1.0.57/32 + ipv6: 2064:100::39/128 + Ethernet1: + ipv4: 10.0.0.113/31 + ipv6: fc00::e2/126 + bp_interfaces: + ipv4: 10.10.246.52/24 + ipv6: fc0a::34/64 + ARISTA52T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.114 + - fc00::e5 + interfaces: + Loopback0: + ipv4: 100.1.0.58/32 + ipv6: 2064:100::3a/128 + Ethernet1: + ipv4: 10.0.0.115/31 + ipv6: fc00::e6/126 + bp_interfaces: + ipv4: 10.10.246.53/24 + ipv6: fc0a::35/64 + ARISTA53T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.116 + - fc00::e9 + interfaces: + Loopback0: + ipv4: 100.1.0.59/32 + ipv6: 2064:100::3b/128 + Ethernet1: + ipv4: 10.0.0.117/31 + ipv6: fc00::ea/126 + bp_interfaces: + ipv4: 10.10.246.54/24 + ipv6: fc0a::36/64 + ARISTA54T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.118 + - fc00::ed + interfaces: + Loopback0: + ipv4: 100.1.0.60/32 + ipv6: 2064:100::3c/128 + Ethernet1: + ipv4: 10.0.0.119/31 + ipv6: fc00::ee/126 + bp_interfaces: + ipv4: 10.10.246.55/24 + ipv6: fc0a::37/64 + ARISTA55T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.120 + - fc00::f1 + interfaces: + Loopback0: + ipv4: 100.1.0.61/32 + ipv6: 2064:100::3d/128 + Ethernet1: + ipv4: 10.0.0.121/31 + ipv6: fc00::f2/126 + bp_interfaces: + ipv4: 10.10.246.56/24 + ipv6: fc0a::38/64 + ARISTA56T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.122 + - fc00::f5 + interfaces: + Loopback0: + ipv4: 100.1.0.62/32 + ipv6: 2064:100::3e/128 + Ethernet1: + ipv4: 10.0.0.123/31 + ipv6: fc00::f6/126 + bp_interfaces: + ipv4: 10.10.246.57/24 + ipv6: fc0a::39/64 + ARISTA57T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.124 + - fc00::f9 + interfaces: + Loopback0: + ipv4: 100.1.0.63/32 + ipv6: 2064:100::3f/128 + Ethernet1: + ipv4: 10.0.0.125/31 + ipv6: fc00::fa/126 + bp_interfaces: + ipv4: 10.10.246.58/24 + ipv6: fc0a::3a/64 + ARISTA58T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.126 + - fc00::fd + interfaces: + Loopback0: + ipv4: 100.1.0.64/32 + ipv6: 2064:100::40/128 + Ethernet1: + ipv4: 10.0.0.127/31 + ipv6: fc00::fe/126 + bp_interfaces: + ipv4: 10.10.246.59/24 + ipv6: fc0a::3b/64 + ARISTA59T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.128 + - fc00::101 + interfaces: + Loopback0: + ipv4: 100.1.0.65/32 + ipv6: 2064:100::41/128 + Ethernet1: + ipv4: 10.0.0.129/31 + ipv6: fc00::102/126 + bp_interfaces: + ipv4: 10.10.246.60/24 + ipv6: fc0a::3c/64 + ARISTA60T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.130 + - fc00::105 + interfaces: + Loopback0: + ipv4: 100.1.0.66/32 + ipv6: 2064:100::42/128 + Ethernet1: + ipv4: 10.0.0.131/31 + ipv6: fc00::106/126 + bp_interfaces: + ipv4: 10.10.246.61/24 + ipv6: fc0a::3d/64 + ARISTA61T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.144 + - fc00::121 + interfaces: + Loopback0: + ipv4: 100.1.0.73/32 + ipv6: 2064:100::49/128 + Ethernet1: + ipv4: 10.0.0.145/31 + ipv6: fc00::122/126 + bp_interfaces: + ipv4: 10.10.246.62/24 + ipv6: fc0a::3e/64 + ARISTA62T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.146 + - fc00::125 + interfaces: + Loopback0: + ipv4: 100.1.0.74/32 + ipv6: 2064:100::4a/128 + Ethernet1: + ipv4: 10.0.0.147/31 + ipv6: fc00::126/126 + bp_interfaces: + ipv4: 10.10.246.63/24 + ipv6: fc0a::3f/64 + ARISTA63T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.148 + - fc00::129 + interfaces: + Loopback0: + ipv4: 100.1.0.75/32 + ipv6: 2064:100::4b/128 + Ethernet1: + ipv4: 10.0.0.149/31 + ipv6: fc00::12a/126 + bp_interfaces: + ipv4: 10.10.246.64/24 + ipv6: fc0a::40/64 + ARISTA64T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.150 + - fc00::12d + interfaces: + Loopback0: + ipv4: 100.1.0.76/32 + ipv6: 2064:100::4c/128 + Ethernet1: + ipv4: 10.0.0.151/31 + ipv6: fc00::12e/126 + bp_interfaces: + ipv4: 10.10.246.65/24 + ipv6: fc0a::41/64 + ARISTA65T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.152 + - fc00::131 + interfaces: + Loopback0: + ipv4: 100.1.0.77/32 + ipv6: 2064:100::4d/128 + Ethernet1: + ipv4: 10.0.0.153/31 + ipv6: fc00::132/126 + bp_interfaces: + ipv4: 10.10.246.66/24 + ipv6: fc0a::42/64 + ARISTA66T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.154 + - fc00::135 + interfaces: + Loopback0: + ipv4: 100.1.0.78/32 + ipv6: 2064:100::4e/128 + Ethernet1: + ipv4: 10.0.0.155/31 + ipv6: fc00::136/126 + bp_interfaces: + ipv4: 10.10.246.67/24 + ipv6: fc0a::43/64 + ARISTA67T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.156 + - fc00::139 + interfaces: + Loopback0: + ipv4: 100.1.0.79/32 + ipv6: 2064:100::4f/128 + Ethernet1: + ipv4: 10.0.0.157/31 + ipv6: fc00::13a/126 + bp_interfaces: + ipv4: 10.10.246.68/24 + ipv6: fc0a::44/64 + ARISTA68T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.158 + - fc00::13d + interfaces: + Loopback0: + ipv4: 100.1.0.80/32 + ipv6: 2064:100::50/128 + Ethernet1: + ipv4: 10.0.0.159/31 + ipv6: fc00::13e/126 + bp_interfaces: + ipv4: 10.10.246.69/24 + ipv6: fc0a::45/64 + ARISTA69T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.160 + - fc00::141 + interfaces: + Loopback0: + ipv4: 100.1.0.81/32 + ipv6: 2064:100::51/128 + Ethernet1: + ipv4: 10.0.0.161/31 + ipv6: fc00::142/126 + bp_interfaces: + ipv4: 10.10.246.70/24 + ipv6: fc0a::46/64 + ARISTA70T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.162 + - fc00::145 + interfaces: + Loopback0: + ipv4: 100.1.0.82/32 + ipv6: 2064:100::52/128 + Ethernet1: + ipv4: 10.0.0.163/31 + ipv6: fc00::146/126 + bp_interfaces: + ipv4: 10.10.246.71/24 + ipv6: fc0a::47/64 + ARISTA71T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.164 + - fc00::149 + interfaces: + Loopback0: + ipv4: 100.1.0.83/32 + ipv6: 2064:100::53/128 + Ethernet1: + ipv4: 10.0.0.165/31 + ipv6: fc00::14a/126 + bp_interfaces: + ipv4: 10.10.246.72/24 + ipv6: fc0a::48/64 + ARISTA72T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.166 + - fc00::14d + interfaces: + Loopback0: + ipv4: 100.1.0.84/32 + ipv6: 2064:100::54/128 + Ethernet1: + ipv4: 10.0.0.167/31 + ipv6: fc00::14e/126 + bp_interfaces: + ipv4: 10.10.246.73/24 + ipv6: fc0a::49/64 + ARISTA73T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.168 + - fc00::151 + interfaces: + Loopback0: + ipv4: 100.1.0.85/32 + ipv6: 2064:100::55/128 + Ethernet1: + ipv4: 10.0.0.169/31 + ipv6: fc00::152/126 + bp_interfaces: + ipv4: 10.10.246.74/24 + ipv6: fc0a::4a/64 + ARISTA74T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.170 + - fc00::155 + interfaces: + Loopback0: + ipv4: 100.1.0.86/32 + ipv6: 2064:100::56/128 + Ethernet1: + ipv4: 10.0.0.171/31 + ipv6: fc00::156/126 + bp_interfaces: + ipv4: 10.10.246.75/24 + ipv6: fc0a::4b/64 + ARISTA75T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.172 + - fc00::159 + interfaces: + Loopback0: + ipv4: 100.1.0.87/32 + ipv6: 2064:100::57/128 + Ethernet1: + ipv4: 10.0.0.173/31 + ipv6: fc00::15a/126 + bp_interfaces: + ipv4: 10.10.246.76/24 + ipv6: fc0a::4c/64 + ARISTA76T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.174 + - fc00::15d + interfaces: + Loopback0: + ipv4: 100.1.0.88/32 + ipv6: 2064:100::58/128 + Ethernet1: + ipv4: 10.0.0.175/31 + ipv6: fc00::15e/126 + bp_interfaces: + ipv4: 10.10.246.77/24 + ipv6: fc0a::4d/64 + ARISTA77T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.176 + - fc00::161 + interfaces: + Loopback0: + ipv4: 100.1.0.89/32 + ipv6: 2064:100::59/128 + Ethernet1: + ipv4: 10.0.0.177/31 + ipv6: fc00::162/126 + bp_interfaces: + ipv4: 10.10.246.78/24 + ipv6: fc0a::4e/64 + ARISTA78T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.178 + - fc00::165 + interfaces: + Loopback0: + ipv4: 100.1.0.90/32 + ipv6: 2064:100::5a/128 + Ethernet1: + ipv4: 10.0.0.179/31 + ipv6: fc00::166/126 + bp_interfaces: + ipv4: 10.10.246.79/24 + ipv6: fc0a::4f/64 + ARISTA79T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.180 + - fc00::169 + interfaces: + Loopback0: + ipv4: 100.1.0.91/32 + ipv6: 2064:100::5b/128 + Ethernet1: + ipv4: 10.0.0.181/31 + ipv6: fc00::16a/126 + bp_interfaces: + ipv4: 10.10.246.80/24 + ipv6: fc0a::50/64 + ARISTA80T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.182 + - fc00::16d + interfaces: + Loopback0: + ipv4: 100.1.0.92/32 + ipv6: 2064:100::5c/128 + Ethernet1: + ipv4: 10.0.0.183/31 + ipv6: fc00::16e/126 + bp_interfaces: + ipv4: 10.10.246.81/24 + ipv6: fc0a::51/64 + ARISTA81T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.184 + - fc00::171 + interfaces: + Loopback0: + ipv4: 100.1.0.93/32 + ipv6: 2064:100::5d/128 + Ethernet1: + ipv4: 10.0.0.185/31 + ipv6: fc00::172/126 + bp_interfaces: + ipv4: 10.10.246.82/24 + ipv6: fc0a::52/64 + ARISTA82T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.186 + - fc00::175 + interfaces: + Loopback0: + ipv4: 100.1.0.94/32 + ipv6: 2064:100::5e/128 + Ethernet1: + ipv4: 10.0.0.187/31 + ipv6: fc00::176/126 + bp_interfaces: + ipv4: 10.10.246.83/24 + ipv6: fc0a::53/64 + ARISTA83T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.188 + - fc00::179 + interfaces: + Loopback0: + ipv4: 100.1.0.95/32 + ipv6: 2064:100::5f/128 + Ethernet1: + ipv4: 10.0.0.189/31 + ipv6: fc00::17a/126 + bp_interfaces: + ipv4: 10.10.246.84/24 + ipv6: fc0a::54/64 + ARISTA84T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.190 + - fc00::17d + interfaces: + Loopback0: + ipv4: 100.1.0.96/32 + ipv6: 2064:100::60/128 + Ethernet1: + ipv4: 10.0.0.191/31 + ipv6: fc00::17e/126 + bp_interfaces: + ipv4: 10.10.246.85/24 + ipv6: fc0a::55/64 + ARISTA85T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.192 + - fc00::181 + interfaces: + Loopback0: + ipv4: 100.1.0.97/32 + ipv6: 2064:100::61/128 + Ethernet1: + ipv4: 10.0.0.193/31 + ipv6: fc00::182/126 + bp_interfaces: + ipv4: 10.10.246.86/24 + ipv6: fc0a::56/64 + ARISTA86T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.194 + - fc00::185 + interfaces: + Loopback0: + ipv4: 100.1.0.98/32 + ipv6: 2064:100::62/128 + Ethernet1: + ipv4: 10.0.0.195/31 + ipv6: fc00::186/126 + bp_interfaces: + ipv4: 10.10.246.87/24 + ipv6: fc0a::57/64 + ARISTA87T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.196 + - fc00::189 + interfaces: + Loopback0: + ipv4: 100.1.0.99/32 + ipv6: 2064:100::63/128 + Ethernet1: + ipv4: 10.0.0.197/31 + ipv6: fc00::18a/126 + bp_interfaces: + ipv4: 10.10.246.88/24 + ipv6: fc0a::58/64 + ARISTA88T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.198 + - fc00::18d + interfaces: + Loopback0: + ipv4: 100.1.0.100/32 + ipv6: 2064:100::64/128 + Ethernet1: + ipv4: 10.0.0.199/31 + ipv6: fc00::18e/126 + bp_interfaces: + ipv4: 10.10.246.89/24 + ipv6: fc0a::59/64 + ARISTA89T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.200 + - fc00::191 + interfaces: + Loopback0: + ipv4: 100.1.0.101/32 + ipv6: 2064:100::65/128 + Ethernet1: + ipv4: 10.0.0.201/31 + ipv6: fc00::192/126 + bp_interfaces: + ipv4: 10.10.246.90/24 + ipv6: fc0a::5a/64 + ARISTA90T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.202 + - fc00::195 + interfaces: + Loopback0: + ipv4: 100.1.0.102/32 + ipv6: 2064:100::66/128 + Ethernet1: + ipv4: 10.0.0.203/31 + ipv6: fc00::196/126 + bp_interfaces: + ipv4: 10.10.246.91/24 + ipv6: fc0a::5b/64 + ARISTA91T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.204 + - fc00::199 + interfaces: + Loopback0: + ipv4: 100.1.0.103/32 + ipv6: 2064:100::67/128 + Ethernet1: + ipv4: 10.0.0.205/31 + ipv6: fc00::19a/126 + bp_interfaces: + ipv4: 10.10.246.92/24 + ipv6: fc0a::5c/64 + ARISTA92T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.206 + - fc00::19d + interfaces: + Loopback0: + ipv4: 100.1.0.104/32 + ipv6: 2064:100::68/128 + Ethernet1: + ipv4: 10.0.0.207/31 + ipv6: fc00::19e/126 + bp_interfaces: + ipv4: 10.10.246.93/24 + ipv6: fc0a::5d/64 + ARISTA93T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.208 + - fc00::1a1 + interfaces: + Loopback0: + ipv4: 100.1.0.105/32 + ipv6: 2064:100::69/128 + Ethernet1: + ipv4: 10.0.0.209/31 + ipv6: fc00::1a2/126 + bp_interfaces: + ipv4: 10.10.246.94/24 + ipv6: fc0a::5e/64 + ARISTA94T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.210 + - fc00::1a5 + interfaces: + Loopback0: + ipv4: 100.1.0.106/32 + ipv6: 2064:100::6a/128 + Ethernet1: + ipv4: 10.0.0.211/31 + ipv6: fc00::1a6/126 + bp_interfaces: + ipv4: 10.10.246.95/24 + ipv6: fc0a::5f/64 + ARISTA95T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.212 + - fc00::1a9 + interfaces: + Loopback0: + ipv4: 100.1.0.107/32 + ipv6: 2064:100::6b/128 + Ethernet1: + ipv4: 10.0.0.213/31 + ipv6: fc00::1aa/126 + bp_interfaces: + ipv4: 10.10.246.96/24 + ipv6: fc0a::60/64 + ARISTA96T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.214 + - fc00::1ad + interfaces: + Loopback0: + ipv4: 100.1.0.108/32 + ipv6: 2064:100::6c/128 + Ethernet1: + ipv4: 10.0.0.215/31 + ipv6: fc00::1ae/126 + bp_interfaces: + ipv4: 10.10.246.97/24 + ipv6: fc0a::61/64 + ARISTA97T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.216 + - fc00::1b1 + interfaces: + Loopback0: + ipv4: 100.1.0.109/32 + ipv6: 2064:100::6d/128 + Ethernet1: + ipv4: 10.0.0.217/31 + ipv6: fc00::1b2/126 + bp_interfaces: + ipv4: 10.10.246.98/24 + ipv6: fc0a::62/64 + ARISTA98T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.218 + - fc00::1b5 + interfaces: + Loopback0: + ipv4: 100.1.0.110/32 + ipv6: 2064:100::6e/128 + Ethernet1: + ipv4: 10.0.0.219/31 + ipv6: fc00::1b6/126 + bp_interfaces: + ipv4: 10.10.246.99/24 + ipv6: fc0a::63/64 + ARISTA99T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.220 + - fc00::1b9 + interfaces: + Loopback0: + ipv4: 100.1.0.111/32 + ipv6: 2064:100::6f/128 + Ethernet1: + ipv4: 10.0.0.221/31 + ipv6: fc00::1ba/126 + bp_interfaces: + ipv4: 10.10.246.100/24 + ipv6: fc0a::64/64 + ARISTA100T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.222 + - fc00::1bd + interfaces: + Loopback0: + ipv4: 100.1.0.112/32 + ipv6: 2064:100::70/128 + Ethernet1: + ipv4: 10.0.0.223/31 + ipv6: fc00::1be/126 + bp_interfaces: + ipv4: 10.10.246.101/24 + ipv6: fc0a::65/64 + ARISTA101T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.224 + - fc00::1c1 + interfaces: + Loopback0: + ipv4: 100.1.0.113/32 + ipv6: 2064:100::71/128 + Ethernet1: + ipv4: 10.0.0.225/31 + ipv6: fc00::1c2/126 + bp_interfaces: + ipv4: 10.10.246.102/24 + ipv6: fc0a::66/64 + ARISTA102T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.226 + - fc00::1c5 + interfaces: + Loopback0: + ipv4: 100.1.0.114/32 + ipv6: 2064:100::72/128 + Ethernet1: + ipv4: 10.0.0.227/31 + ipv6: fc00::1c6/126 + bp_interfaces: + ipv4: 10.10.246.103/24 + ipv6: fc0a::67/64 + ARISTA103T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.228 + - fc00::1c9 + interfaces: + Loopback0: + ipv4: 100.1.0.115/32 + ipv6: 2064:100::73/128 + Ethernet1: + ipv4: 10.0.0.229/31 + ipv6: fc00::1ca/126 + bp_interfaces: + ipv4: 10.10.246.104/24 + ipv6: fc0a::68/64 + ARISTA104T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.230 + - fc00::1cd + interfaces: + Loopback0: + ipv4: 100.1.0.116/32 + ipv6: 2064:100::74/128 + Ethernet1: + ipv4: 10.0.0.231/31 + ipv6: fc00::1ce/126 + bp_interfaces: + ipv4: 10.10.246.105/24 + ipv6: fc0a::69/64 + ARISTA105T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.232 + - fc00::1d1 + interfaces: + Loopback0: + ipv4: 100.1.0.117/32 + ipv6: 2064:100::75/128 + Ethernet1: + ipv4: 10.0.0.233/31 + ipv6: fc00::1d2/126 + bp_interfaces: + ipv4: 10.10.246.106/24 + ipv6: fc0a::6a/64 + ARISTA106T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.234 + - fc00::1d5 + interfaces: + Loopback0: + ipv4: 100.1.0.118/32 + ipv6: 2064:100::76/128 + Ethernet1: + ipv4: 10.0.0.235/31 + ipv6: fc00::1d6/126 + bp_interfaces: + ipv4: 10.10.246.107/24 + ipv6: fc0a::6b/64 + ARISTA107T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.236 + - fc00::1d9 + interfaces: + Loopback0: + ipv4: 100.1.0.119/32 + ipv6: 2064:100::77/128 + Ethernet1: + ipv4: 10.0.0.237/31 + ipv6: fc00::1da/126 + bp_interfaces: + ipv4: 10.10.246.108/24 + ipv6: fc0a::6c/64 + ARISTA108T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.238 + - fc00::1dd + interfaces: + Loopback0: + ipv4: 100.1.0.120/32 + ipv6: 2064:100::78/128 + Ethernet1: + ipv4: 10.0.0.239/31 + ipv6: fc00::1de/126 + bp_interfaces: + ipv4: 10.10.246.109/24 + ipv6: fc0a::6d/64 + ARISTA109T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.240 + - fc00::1e1 + interfaces: + Loopback0: + ipv4: 100.1.0.121/32 + ipv6: 2064:100::79/128 + Ethernet1: + ipv4: 10.0.0.241/31 + ipv6: fc00::1e2/126 + bp_interfaces: + ipv4: 10.10.246.110/24 + ipv6: fc0a::6e/64 + ARISTA110T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.242 + - fc00::1e5 + interfaces: + Loopback0: + ipv4: 100.1.0.122/32 + ipv6: 2064:100::7a/128 + Ethernet1: + ipv4: 10.0.0.243/31 + ipv6: fc00::1e6/126 + bp_interfaces: + ipv4: 10.10.246.111/24 + ipv6: fc0a::6f/64 + ARISTA111T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.244 + - fc00::1e9 + interfaces: + Loopback0: + ipv4: 100.1.0.123/32 + ipv6: 2064:100::7b/128 + Ethernet1: + ipv4: 10.0.0.245/31 + ipv6: fc00::1ea/126 + bp_interfaces: + ipv4: 10.10.246.112/24 + ipv6: fc0a::70/64 + ARISTA112T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.246 + - fc00::1ed + interfaces: + Loopback0: + ipv4: 100.1.0.124/32 + ipv6: 2064:100::7c/128 + Ethernet1: + ipv4: 10.0.0.247/31 + ipv6: fc00::1ee/126 + bp_interfaces: + ipv4: 10.10.246.113/24 + ipv6: fc0a::71/64 + ARISTA113T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.248 + - fc00::1f1 + interfaces: + Loopback0: + ipv4: 100.1.0.125/32 + ipv6: 2064:100::7d/128 + Ethernet1: + ipv4: 10.0.0.249/31 + ipv6: fc00::1f2/126 + bp_interfaces: + ipv4: 10.10.246.114/24 + ipv6: fc0a::72/64 + ARISTA114T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.250 + - fc00::1f5 + interfaces: + Loopback0: + ipv4: 100.1.0.126/32 + ipv6: 2064:100::7e/128 + Ethernet1: + ipv4: 10.0.0.251/31 + ipv6: fc00::1f6/126 + bp_interfaces: + ipv4: 10.10.246.115/24 + ipv6: fc0a::73/64 + ARISTA115T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.252 + - fc00::1f9 + interfaces: + Loopback0: + ipv4: 100.1.0.127/32 + ipv6: 2064:100::7f/128 + Ethernet1: + ipv4: 10.0.0.253/31 + ipv6: fc00::1fa/126 + bp_interfaces: + ipv4: 10.10.246.116/24 + ipv6: fc0a::74/64 + ARISTA116T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.254 + - fc00::1fd + interfaces: + Loopback0: + ipv4: 100.1.0.128/32 + ipv6: 2064:100::80/128 + Ethernet1: + ipv4: 10.0.0.255/31 + ipv6: fc00::1fe/126 + bp_interfaces: + ipv4: 10.10.246.117/24 + ipv6: fc0a::75/64 + ARISTA117T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.0 + - fc00::201 + interfaces: + Loopback0: + ipv4: 100.1.0.129/32 + ipv6: 2064:100::81/128 + Ethernet1: + ipv4: 10.0.1.1/31 + ipv6: fc00::202/126 + bp_interfaces: + ipv4: 10.10.246.118/24 + ipv6: fc0a::76/64 + ARISTA118T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.2 + - fc00::205 + interfaces: + Loopback0: + ipv4: 100.1.0.130/32 + ipv6: 2064:100::82/128 + Ethernet1: + ipv4: 10.0.1.3/31 + ipv6: fc00::206/126 + bp_interfaces: + ipv4: 10.10.246.119/24 + ipv6: fc0a::77/64 + ARISTA119T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.4 + - fc00::209 + interfaces: + Loopback0: + ipv4: 100.1.0.131/32 + ipv6: 2064:100::83/128 + Ethernet1: + ipv4: 10.0.1.5/31 + ipv6: fc00::20a/126 + bp_interfaces: + ipv4: 10.10.246.120/24 + ipv6: fc0a::78/64 + ARISTA120T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.6 + - fc00::20d + interfaces: + Loopback0: + ipv4: 100.1.0.132/32 + ipv6: 2064:100::84/128 + Ethernet1: + ipv4: 10.0.1.7/31 + ipv6: fc00::20e/126 + bp_interfaces: + ipv4: 10.10.246.121/24 + ipv6: fc0a::79/64 + ARISTA121T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.8 + - fc00::211 + interfaces: + Loopback0: + ipv4: 100.1.0.133/32 + ipv6: 2064:100::85/128 + Ethernet1: + ipv4: 10.0.1.9/31 + ipv6: fc00::212/126 + bp_interfaces: + ipv4: 10.10.246.122/24 + ipv6: fc0a::7a/64 + ARISTA122T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.10 + - fc00::215 + interfaces: + Loopback0: + ipv4: 100.1.0.134/32 + ipv6: 2064:100::86/128 + Ethernet1: + ipv4: 10.0.1.11/31 + ipv6: fc00::216/126 + bp_interfaces: + ipv4: 10.10.246.123/24 + ipv6: fc0a::7b/64 + ARISTA123T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.12 + - fc00::219 + interfaces: + Loopback0: + ipv4: 100.1.0.135/32 + ipv6: 2064:100::87/128 + Ethernet1: + ipv4: 10.0.1.13/31 + ipv6: fc00::21a/126 + bp_interfaces: + ipv4: 10.10.246.124/24 + ipv6: fc0a::7c/64 + ARISTA124T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.14 + - fc00::21d + interfaces: + Loopback0: + ipv4: 100.1.0.136/32 + ipv6: 2064:100::88/128 + Ethernet1: + ipv4: 10.0.1.15/31 + ipv6: fc00::21e/126 + bp_interfaces: + ipv4: 10.10.246.125/24 + ipv6: fc0a::7d/64 + ARISTA125T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.16 + - fc00::221 + interfaces: + Loopback0: + ipv4: 100.1.0.137/32 + ipv6: 2064:100::89/128 + Ethernet1: + ipv4: 10.0.1.17/31 + ipv6: fc00::222/126 + bp_interfaces: + ipv4: 10.10.246.126/24 + ipv6: fc0a::7e/64 + ARISTA126T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.18 + - fc00::225 + interfaces: + Loopback0: + ipv4: 100.1.0.138/32 + ipv6: 2064:100::8a/128 + Ethernet1: + ipv4: 10.0.1.19/31 + ipv6: fc00::226/126 + bp_interfaces: + ipv4: 10.10.246.127/24 + ipv6: fc0a::7f/64 + ARISTA127T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.20 + - fc00::229 + interfaces: + Loopback0: + ipv4: 100.1.0.139/32 + ipv6: 2064:100::8b/128 + Ethernet1: + ipv4: 10.0.1.21/31 + ipv6: fc00::22a/126 + bp_interfaces: + ipv4: 10.10.246.128/24 + ipv6: fc0a::80/64 + ARISTA128T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.22 + - fc00::22d + interfaces: + Loopback0: + ipv4: 100.1.0.140/32 + ipv6: 2064:100::8c/128 + Ethernet1: + ipv4: 10.0.1.23/31 + ipv6: fc00::22e/126 + bp_interfaces: + ipv4: 10.10.246.129/24 + ipv6: fc0a::81/64 + ARISTA129T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.24 + - fc00::231 + interfaces: + Loopback0: + ipv4: 100.1.0.141/32 + ipv6: 2064:100::8d/128 + Ethernet1: + ipv4: 10.0.1.25/31 + ipv6: fc00::232/126 + bp_interfaces: + ipv4: 10.10.246.130/24 + ipv6: fc0a::82/64 + ARISTA130T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.26 + - fc00::235 + interfaces: + Loopback0: + ipv4: 100.1.0.142/32 + ipv6: 2064:100::8e/128 + Ethernet1: + ipv4: 10.0.1.27/31 + ipv6: fc00::236/126 + bp_interfaces: + ipv4: 10.10.246.131/24 + ipv6: fc0a::83/64 + ARISTA131T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.28 + - fc00::239 + interfaces: + Loopback0: + ipv4: 100.1.0.143/32 + ipv6: 2064:100::8f/128 + Ethernet1: + ipv4: 10.0.1.29/31 + ipv6: fc00::23a/126 + bp_interfaces: + ipv4: 10.10.246.132/24 + ipv6: fc0a::84/64 + ARISTA132T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.30 + - fc00::23d + interfaces: + Loopback0: + ipv4: 100.1.0.144/32 + ipv6: 2064:100::90/128 + Ethernet1: + ipv4: 10.0.1.31/31 + ipv6: fc00::23e/126 + bp_interfaces: + ipv4: 10.10.246.133/24 + ipv6: fc0a::85/64 + ARISTA133T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.32 + - fc00::241 + interfaces: + Loopback0: + ipv4: 100.1.0.145/32 + ipv6: 2064:100::91/128 + Ethernet1: + ipv4: 10.0.1.33/31 + ipv6: fc00::242/126 + bp_interfaces: + ipv4: 10.10.246.134/24 + ipv6: fc0a::86/64 + ARISTA134T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.34 + - fc00::245 + interfaces: + Loopback0: + ipv4: 100.1.0.146/32 + ipv6: 2064:100::92/128 + Ethernet1: + ipv4: 10.0.1.35/31 + ipv6: fc00::246/126 + bp_interfaces: + ipv4: 10.10.246.135/24 + ipv6: fc0a::87/64 + ARISTA135T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.36 + - fc00::249 + interfaces: + Loopback0: + ipv4: 100.1.0.147/32 + ipv6: 2064:100::93/128 + Ethernet1: + ipv4: 10.0.1.37/31 + ipv6: fc00::24a/126 + bp_interfaces: + ipv4: 10.10.246.136/24 + ipv6: fc0a::88/64 + ARISTA136T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.38 + - fc00::24d + interfaces: + Loopback0: + ipv4: 100.1.0.148/32 + ipv6: 2064:100::94/128 + Ethernet1: + ipv4: 10.0.1.39/31 + ipv6: fc00::24e/126 + bp_interfaces: + ipv4: 10.10.246.137/24 + ipv6: fc0a::89/64 + ARISTA137T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.40 + - fc00::251 + interfaces: + Loopback0: + ipv4: 100.1.0.149/32 + ipv6: 2064:100::95/128 + Ethernet1: + ipv4: 10.0.1.41/31 + ipv6: fc00::252/126 + bp_interfaces: + ipv4: 10.10.246.138/24 + ipv6: fc0a::8a/64 + ARISTA138T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.42 + - fc00::255 + interfaces: + Loopback0: + ipv4: 100.1.0.150/32 + ipv6: 2064:100::96/128 + Ethernet1: + ipv4: 10.0.1.43/31 + ipv6: fc00::256/126 + bp_interfaces: + ipv4: 10.10.246.139/24 + ipv6: fc0a::8b/64 + ARISTA139T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.44 + - fc00::259 + interfaces: + Loopback0: + ipv4: 100.1.0.151/32 + ipv6: 2064:100::97/128 + Ethernet1: + ipv4: 10.0.1.45/31 + ipv6: fc00::25a/126 + bp_interfaces: + ipv4: 10.10.246.140/24 + ipv6: fc0a::8c/64 + ARISTA140T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.46 + - fc00::25d + interfaces: + Loopback0: + ipv4: 100.1.0.152/32 + ipv6: 2064:100::98/128 + Ethernet1: + ipv4: 10.0.1.47/31 + ipv6: fc00::25e/126 + bp_interfaces: + ipv4: 10.10.246.141/24 + ipv6: fc0a::8d/64 + ARISTA141T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.48 + - fc00::261 + interfaces: + Loopback0: + ipv4: 100.1.0.153/32 + ipv6: 2064:100::99/128 + Ethernet1: + ipv4: 10.0.1.49/31 + ipv6: fc00::262/126 + bp_interfaces: + ipv4: 10.10.246.142/24 + ipv6: fc0a::8e/64 + ARISTA142T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.50 + - fc00::265 + interfaces: + Loopback0: + ipv4: 100.1.0.154/32 + ipv6: 2064:100::9a/128 + Ethernet1: + ipv4: 10.0.1.51/31 + ipv6: fc00::266/126 + bp_interfaces: + ipv4: 10.10.246.143/24 + ipv6: fc0a::8f/64 + ARISTA143T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.52 + - fc00::269 + interfaces: + Loopback0: + ipv4: 100.1.0.155/32 + ipv6: 2064:100::9b/128 + Ethernet1: + ipv4: 10.0.1.53/31 + ipv6: fc00::26a/126 + bp_interfaces: + ipv4: 10.10.246.144/24 + ipv6: fc0a::90/64 + ARISTA144T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.54 + - fc00::26d + interfaces: + Loopback0: + ipv4: 100.1.0.156/32 + ipv6: 2064:100::9c/128 + Ethernet1: + ipv4: 10.0.1.55/31 + ipv6: fc00::26e/126 + bp_interfaces: + ipv4: 10.10.246.145/24 + ipv6: fc0a::91/64 + ARISTA145T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.56 + - fc00::271 + interfaces: + Loopback0: + ipv4: 100.1.0.157/32 + ipv6: 2064:100::9d/128 + Ethernet1: + ipv4: 10.0.1.57/31 + ipv6: fc00::272/126 + bp_interfaces: + ipv4: 10.10.246.146/24 + ipv6: fc0a::92/64 + ARISTA146T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.58 + - fc00::275 + interfaces: + Loopback0: + ipv4: 100.1.0.158/32 + ipv6: 2064:100::9e/128 + Ethernet1: + ipv4: 10.0.1.59/31 + ipv6: fc00::276/126 + bp_interfaces: + ipv4: 10.10.246.147/24 + ipv6: fc0a::93/64 + ARISTA147T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.60 + - fc00::279 + interfaces: + Loopback0: + ipv4: 100.1.0.159/32 + ipv6: 2064:100::9f/128 + Ethernet1: + ipv4: 10.0.1.61/31 + ipv6: fc00::27a/126 + bp_interfaces: + ipv4: 10.10.246.148/24 + ipv6: fc0a::94/64 + ARISTA148T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.62 + - fc00::27d + interfaces: + Loopback0: + ipv4: 100.1.0.160/32 + ipv6: 2064:100::a0/128 + Ethernet1: + ipv4: 10.0.1.63/31 + ipv6: fc00::27e/126 + bp_interfaces: + ipv4: 10.10.246.149/24 + ipv6: fc0a::95/64 + ARISTA149T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.64 + - fc00::281 + interfaces: + Loopback0: + ipv4: 100.1.0.161/32 + ipv6: 2064:100::a1/128 + Ethernet1: + ipv4: 10.0.1.65/31 + ipv6: fc00::282/126 + bp_interfaces: + ipv4: 10.10.246.150/24 + ipv6: fc0a::96/64 + ARISTA150T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.66 + - fc00::285 + interfaces: + Loopback0: + ipv4: 100.1.0.162/32 + ipv6: 2064:100::a2/128 + Ethernet1: + ipv4: 10.0.1.67/31 + ipv6: fc00::286/126 + bp_interfaces: + ipv4: 10.10.246.151/24 + ipv6: fc0a::97/64 + ARISTA151T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.68 + - fc00::289 + interfaces: + Loopback0: + ipv4: 100.1.0.163/32 + ipv6: 2064:100::a3/128 + Ethernet1: + ipv4: 10.0.1.69/31 + ipv6: fc00::28a/126 + bp_interfaces: + ipv4: 10.10.246.152/24 + ipv6: fc0a::98/64 + ARISTA152T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.70 + - fc00::28d + interfaces: + Loopback0: + ipv4: 100.1.0.164/32 + ipv6: 2064:100::a4/128 + Ethernet1: + ipv4: 10.0.1.71/31 + ipv6: fc00::28e/126 + bp_interfaces: + ipv4: 10.10.246.153/24 + ipv6: fc0a::99/64 + ARISTA153T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.72 + - fc00::291 + interfaces: + Loopback0: + ipv4: 100.1.0.165/32 + ipv6: 2064:100::a5/128 + Ethernet1: + ipv4: 10.0.1.73/31 + ipv6: fc00::292/126 + bp_interfaces: + ipv4: 10.10.246.154/24 + ipv6: fc0a::9a/64 + ARISTA154T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.74 + - fc00::295 + interfaces: + Loopback0: + ipv4: 100.1.0.166/32 + ipv6: 2064:100::a6/128 + Ethernet1: + ipv4: 10.0.1.75/31 + ipv6: fc00::296/126 + bp_interfaces: + ipv4: 10.10.246.155/24 + ipv6: fc0a::9b/64 + ARISTA155T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.76 + - fc00::299 + interfaces: + Loopback0: + ipv4: 100.1.0.167/32 + ipv6: 2064:100::a7/128 + Ethernet1: + ipv4: 10.0.1.77/31 + ipv6: fc00::29a/126 + bp_interfaces: + ipv4: 10.10.246.156/24 + ipv6: fc0a::9c/64 + ARISTA156T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.78 + - fc00::29d + interfaces: + Loopback0: + ipv4: 100.1.0.168/32 + ipv6: 2064:100::a8/128 + Ethernet1: + ipv4: 10.0.1.79/31 + ipv6: fc00::29e/126 + bp_interfaces: + ipv4: 10.10.246.157/24 + ipv6: fc0a::9d/64 + ARISTA157T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.80 + - fc00::2a1 + interfaces: + Loopback0: + ipv4: 100.1.0.169/32 + ipv6: 2064:100::a9/128 + Ethernet1: + ipv4: 10.0.1.81/31 + ipv6: fc00::2a2/126 + bp_interfaces: + ipv4: 10.10.246.158/24 + ipv6: fc0a::9e/64 + ARISTA158T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.82 + - fc00::2a5 + interfaces: + Loopback0: + ipv4: 100.1.0.170/32 + ipv6: 2064:100::aa/128 + Ethernet1: + ipv4: 10.0.1.83/31 + ipv6: fc00::2a6/126 + bp_interfaces: + ipv4: 10.10.246.159/24 + ipv6: fc0a::9f/64 + ARISTA159T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.84 + - fc00::2a9 + interfaces: + Loopback0: + ipv4: 100.1.0.171/32 + ipv6: 2064:100::ab/128 + Ethernet1: + ipv4: 10.0.1.85/31 + ipv6: fc00::2aa/126 + bp_interfaces: + ipv4: 10.10.246.160/24 + ipv6: fc0a::a0/64 + ARISTA160T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.86 + - fc00::2ad + interfaces: + Loopback0: + ipv4: 100.1.0.172/32 + ipv6: 2064:100::ac/128 + Ethernet1: + ipv4: 10.0.1.87/31 + ipv6: fc00::2ae/126 + bp_interfaces: + ipv4: 10.10.246.161/24 + ipv6: fc0a::a1/64 + ARISTA161T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.88 + - fc00::2b1 + interfaces: + Loopback0: + ipv4: 100.1.0.173/32 + ipv6: 2064:100::ad/128 + Ethernet1: + ipv4: 10.0.1.89/31 + ipv6: fc00::2b2/126 + bp_interfaces: + ipv4: 10.10.246.162/24 + ipv6: fc0a::a2/64 + ARISTA162T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.90 + - fc00::2b5 + interfaces: + Loopback0: + ipv4: 100.1.0.174/32 + ipv6: 2064:100::ae/128 + Ethernet1: + ipv4: 10.0.1.91/31 + ipv6: fc00::2b6/126 + bp_interfaces: + ipv4: 10.10.246.163/24 + ipv6: fc0a::a3/64 + ARISTA163T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.92 + - fc00::2b9 + interfaces: + Loopback0: + ipv4: 100.1.0.175/32 + ipv6: 2064:100::af/128 + Ethernet1: + ipv4: 10.0.1.93/31 + ipv6: fc00::2ba/126 + bp_interfaces: + ipv4: 10.10.246.164/24 + ipv6: fc0a::a4/64 + ARISTA164T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.94 + - fc00::2bd + interfaces: + Loopback0: + ipv4: 100.1.0.176/32 + ipv6: 2064:100::b0/128 + Ethernet1: + ipv4: 10.0.1.95/31 + ipv6: fc00::2be/126 + bp_interfaces: + ipv4: 10.10.246.165/24 + ipv6: fc0a::a5/64 + ARISTA165T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.1.96 + - fc00::2c1 + interfaces: + Loopback0: + ipv4: 100.1.0.177/32 + ipv6: 2064:100::b1/128 + Ethernet1: + ipv4: 10.0.1.97/31 + ipv6: fc00::2c2/126 + bp_interfaces: + ipv4: 10.10.246.166/24 + ipv6: fc0a::a6/64 + ARISTA166T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.1.98 + - fc00::2c5 + interfaces: + Loopback0: + ipv4: 100.1.0.178/32 + ipv6: 2064:100::b2/128 + Ethernet1: + ipv4: 10.0.1.99/31 + ipv6: fc00::2c6/126 + bp_interfaces: + ipv4: 10.10.246.167/24 + ipv6: fc0a::a7/64 + ARISTA167T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.112 + - fc00::2e1 + interfaces: + Loopback0: + ipv4: 100.1.0.185/32 + ipv6: 2064:100::b9/128 + Ethernet1: + ipv4: 10.0.1.113/31 + ipv6: fc00::2e2/126 + bp_interfaces: + ipv4: 10.10.246.168/24 + ipv6: fc0a::a8/64 + ARISTA168T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.114 + - fc00::2e5 + interfaces: + Loopback0: + ipv4: 100.1.0.186/32 + ipv6: 2064:100::ba/128 + Ethernet1: + ipv4: 10.0.1.115/31 + ipv6: fc00::2e6/126 + bp_interfaces: + ipv4: 10.10.246.169/24 + ipv6: fc0a::a9/64 + ARISTA169T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.116 + - fc00::2e9 + interfaces: + Loopback0: + ipv4: 100.1.0.187/32 + ipv6: 2064:100::bb/128 + Ethernet1: + ipv4: 10.0.1.117/31 + ipv6: fc00::2ea/126 + bp_interfaces: + ipv4: 10.10.246.170/24 + ipv6: fc0a::aa/64 + ARISTA170T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.118 + - fc00::2ed + interfaces: + Loopback0: + ipv4: 100.1.0.188/32 + ipv6: 2064:100::bc/128 + Ethernet1: + ipv4: 10.0.1.119/31 + ipv6: fc00::2ee/126 + bp_interfaces: + ipv4: 10.10.246.171/24 + ipv6: fc0a::ab/64 + ARISTA171T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.120 + - fc00::2f1 + interfaces: + Loopback0: + ipv4: 100.1.0.189/32 + ipv6: 2064:100::bd/128 + Ethernet1: + ipv4: 10.0.1.121/31 + ipv6: fc00::2f2/126 + bp_interfaces: + ipv4: 10.10.246.172/24 + ipv6: fc0a::ac/64 + ARISTA172T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.122 + - fc00::2f5 + interfaces: + Loopback0: + ipv4: 100.1.0.190/32 + ipv6: 2064:100::be/128 + Ethernet1: + ipv4: 10.0.1.123/31 + ipv6: fc00::2f6/126 + bp_interfaces: + ipv4: 10.10.246.173/24 + ipv6: fc0a::ad/64 + ARISTA173T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.124 + - fc00::2f9 + interfaces: + Loopback0: + ipv4: 100.1.0.191/32 + ipv6: 2064:100::bf/128 + Ethernet1: + ipv4: 10.0.1.125/31 + ipv6: fc00::2fa/126 + bp_interfaces: + ipv4: 10.10.246.174/24 + ipv6: fc0a::ae/64 + ARISTA174T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.126 + - fc00::2fd + interfaces: + Loopback0: + ipv4: 100.1.0.192/32 + ipv6: 2064:100::c0/128 + Ethernet1: + ipv4: 10.0.1.127/31 + ipv6: fc00::2fe/126 + bp_interfaces: + ipv4: 10.10.246.175/24 + ipv6: fc0a::af/64 + ARISTA175T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.1.128 + - fc00::301 + interfaces: + Loopback0: + ipv4: 100.1.0.193/32 + ipv6: 2064:100::c1/128 + Ethernet1: + ipv4: 10.0.1.129/31 + ipv6: fc00::302/126 + bp_interfaces: + ipv4: 10.10.246.176/24 + ipv6: fc0a::b0/64 + ARISTA176T2: + properties: + - common + bgp: + asn: 65200 + peers: + 65100: + - 10.0.1.130 + - fc00::305 + interfaces: + Loopback0: + ipv4: 100.1.0.194/32 + ipv6: 2064:100::c2/128 + Ethernet1: + ipv4: 10.0.1.131/31 + ipv6: fc00::306/126 + bp_interfaces: + ipv4: 10.10.246.177/24 + ipv6: fc0a::b1/64 + ARISTA177T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.144 + - fc00::321 + interfaces: + Loopback0: + ipv4: 100.1.0.201/32 + ipv6: 2064:100::c9/128 + Ethernet1: + ipv4: 10.0.1.145/31 + ipv6: fc00::322/126 + bp_interfaces: + ipv4: 10.10.246.178/24 + ipv6: fc0a::b2/64 + ARISTA178T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.146 + - fc00::325 + interfaces: + Loopback0: + ipv4: 100.1.0.202/32 + ipv6: 2064:100::ca/128 + Ethernet1: + ipv4: 10.0.1.147/31 + ipv6: fc00::326/126 + bp_interfaces: + ipv4: 10.10.246.179/24 + ipv6: fc0a::b3/64 + ARISTA179T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.148 + - fc00::329 + interfaces: + Loopback0: + ipv4: 100.1.0.203/32 + ipv6: 2064:100::cb/128 + Ethernet1: + ipv4: 10.0.1.149/31 + ipv6: fc00::32a/126 + bp_interfaces: + ipv4: 10.10.246.180/24 + ipv6: fc0a::b4/64 + ARISTA180T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.150 + - fc00::32d + interfaces: + Loopback0: + ipv4: 100.1.0.204/32 + ipv6: 2064:100::cc/128 + Ethernet1: + ipv4: 10.0.1.151/31 + ipv6: fc00::32e/126 + bp_interfaces: + ipv4: 10.10.246.181/24 + ipv6: fc0a::b5/64 + ARISTA181T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.152 + - fc00::331 + interfaces: + Loopback0: + ipv4: 100.1.0.205/32 + ipv6: 2064:100::cd/128 + Ethernet1: + ipv4: 10.0.1.153/31 + ipv6: fc00::332/126 + bp_interfaces: + ipv4: 10.10.246.182/24 + ipv6: fc0a::b6/64 + ARISTA182T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.154 + - fc00::335 + interfaces: + Loopback0: + ipv4: 100.1.0.206/32 + ipv6: 2064:100::ce/128 + Ethernet1: + ipv4: 10.0.1.155/31 + ipv6: fc00::336/126 + bp_interfaces: + ipv4: 10.10.246.183/24 + ipv6: fc0a::b7/64 + ARISTA183T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.156 + - fc00::339 + interfaces: + Loopback0: + ipv4: 100.1.0.207/32 + ipv6: 2064:100::cf/128 + Ethernet1: + ipv4: 10.0.1.157/31 + ipv6: fc00::33a/126 + bp_interfaces: + ipv4: 10.10.246.184/24 + ipv6: fc0a::b8/64 + ARISTA184T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.158 + - fc00::33d + interfaces: + Loopback0: + ipv4: 100.1.0.208/32 + ipv6: 2064:100::d0/128 + Ethernet1: + ipv4: 10.0.1.159/31 + ipv6: fc00::33e/126 + bp_interfaces: + ipv4: 10.10.246.185/24 + ipv6: fc0a::b9/64 + ARISTA185T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.160 + - fc00::341 + interfaces: + Loopback0: + ipv4: 100.1.0.209/32 + ipv6: 2064:100::d1/128 + Ethernet1: + ipv4: 10.0.1.161/31 + ipv6: fc00::342/126 + bp_interfaces: + ipv4: 10.10.246.186/24 + ipv6: fc0a::ba/64 + ARISTA186T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.162 + - fc00::345 + interfaces: + Loopback0: + ipv4: 100.1.0.210/32 + ipv6: 2064:100::d2/128 + Ethernet1: + ipv4: 10.0.1.163/31 + ipv6: fc00::346/126 + bp_interfaces: + ipv4: 10.10.246.187/24 + ipv6: fc0a::bb/64 + ARISTA187T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.164 + - fc00::349 + interfaces: + Loopback0: + ipv4: 100.1.0.211/32 + ipv6: 2064:100::d3/128 + Ethernet1: + ipv4: 10.0.1.165/31 + ipv6: fc00::34a/126 + bp_interfaces: + ipv4: 10.10.246.188/24 + ipv6: fc0a::bc/64 + ARISTA188T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.166 + - fc00::34d + interfaces: + Loopback0: + ipv4: 100.1.0.212/32 + ipv6: 2064:100::d4/128 + Ethernet1: + ipv4: 10.0.1.167/31 + ipv6: fc00::34e/126 + bp_interfaces: + ipv4: 10.10.246.189/24 + ipv6: fc0a::bd/64 + ARISTA189T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.168 + - fc00::351 + interfaces: + Loopback0: + ipv4: 100.1.0.213/32 + ipv6: 2064:100::d5/128 + Ethernet1: + ipv4: 10.0.1.169/31 + ipv6: fc00::352/126 + bp_interfaces: + ipv4: 10.10.246.190/24 + ipv6: fc0a::be/64 + ARISTA190T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.170 + - fc00::355 + interfaces: + Loopback0: + ipv4: 100.1.0.214/32 + ipv6: 2064:100::d6/128 + Ethernet1: + ipv4: 10.0.1.171/31 + ipv6: fc00::356/126 + bp_interfaces: + ipv4: 10.10.246.191/24 + ipv6: fc0a::bf/64 + ARISTA191T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.172 + - fc00::359 + interfaces: + Loopback0: + ipv4: 100.1.0.215/32 + ipv6: 2064:100::d7/128 + Ethernet1: + ipv4: 10.0.1.173/31 + ipv6: fc00::35a/126 + bp_interfaces: + ipv4: 10.10.246.192/24 + ipv6: fc0a::c0/64 + ARISTA192T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.174 + - fc00::35d + interfaces: + Loopback0: + ipv4: 100.1.0.216/32 + ipv6: 2064:100::d8/128 + Ethernet1: + ipv4: 10.0.1.175/31 + ipv6: fc00::35e/126 + bp_interfaces: + ipv4: 10.10.246.193/24 + ipv6: fc0a::c1/64 + ARISTA193T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.176 + - fc00::361 + interfaces: + Loopback0: + ipv4: 100.1.0.217/32 + ipv6: 2064:100::d9/128 + Ethernet1: + ipv4: 10.0.1.177/31 + ipv6: fc00::362/126 + bp_interfaces: + ipv4: 10.10.246.194/24 + ipv6: fc0a::c2/64 + ARISTA194T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.178 + - fc00::365 + interfaces: + Loopback0: + ipv4: 100.1.0.218/32 + ipv6: 2064:100::da/128 + Ethernet1: + ipv4: 10.0.1.179/31 + ipv6: fc00::366/126 + bp_interfaces: + ipv4: 10.10.246.195/24 + ipv6: fc0a::c3/64 + ARISTA195T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.180 + - fc00::369 + interfaces: + Loopback0: + ipv4: 100.1.0.219/32 + ipv6: 2064:100::db/128 + Ethernet1: + ipv4: 10.0.1.181/31 + ipv6: fc00::36a/126 + bp_interfaces: + ipv4: 10.10.246.196/24 + ipv6: fc0a::c4/64 + ARISTA196T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.182 + - fc00::36d + interfaces: + Loopback0: + ipv4: 100.1.0.220/32 + ipv6: 2064:100::dc/128 + Ethernet1: + ipv4: 10.0.1.183/31 + ipv6: fc00::36e/126 + bp_interfaces: + ipv4: 10.10.246.197/24 + ipv6: fc0a::c5/64 + ARISTA197T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.184 + - fc00::371 + interfaces: + Loopback0: + ipv4: 100.1.0.221/32 + ipv6: 2064:100::dd/128 + Ethernet1: + ipv4: 10.0.1.185/31 + ipv6: fc00::372/126 + bp_interfaces: + ipv4: 10.10.246.198/24 + ipv6: fc0a::c6/64 + ARISTA198T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.186 + - fc00::375 + interfaces: + Loopback0: + ipv4: 100.1.0.222/32 + ipv6: 2064:100::de/128 + Ethernet1: + ipv4: 10.0.1.187/31 + ipv6: fc00::376/126 + bp_interfaces: + ipv4: 10.10.246.199/24 + ipv6: fc0a::c7/64 + ARISTA199T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.188 + - fc00::379 + interfaces: + Loopback0: + ipv4: 100.1.0.223/32 + ipv6: 2064:100::df/128 + Ethernet1: + ipv4: 10.0.1.189/31 + ipv6: fc00::37a/126 + bp_interfaces: + ipv4: 10.10.246.200/24 + ipv6: fc0a::c8/64 + ARISTA200T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.190 + - fc00::37d + interfaces: + Loopback0: + ipv4: 100.1.0.224/32 + ipv6: 2064:100::e0/128 + Ethernet1: + ipv4: 10.0.1.191/31 + ipv6: fc00::37e/126 + bp_interfaces: + ipv4: 10.10.246.201/24 + ipv6: fc0a::c9/64 + ARISTA201T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.192 + - fc00::381 + interfaces: + Loopback0: + ipv4: 100.1.0.225/32 + ipv6: 2064:100::e1/128 + Ethernet1: + ipv4: 10.0.1.193/31 + ipv6: fc00::382/126 + bp_interfaces: + ipv4: 10.10.246.202/24 + ipv6: fc0a::ca/64 + ARISTA202T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.194 + - fc00::385 + interfaces: + Loopback0: + ipv4: 100.1.0.226/32 + ipv6: 2064:100::e2/128 + Ethernet1: + ipv4: 10.0.1.195/31 + ipv6: fc00::386/126 + bp_interfaces: + ipv4: 10.10.246.203/24 + ipv6: fc0a::cb/64 + ARISTA203T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.196 + - fc00::389 + interfaces: + Loopback0: + ipv4: 100.1.0.227/32 + ipv6: 2064:100::e3/128 + Ethernet1: + ipv4: 10.0.1.197/31 + ipv6: fc00::38a/126 + bp_interfaces: + ipv4: 10.10.246.204/24 + ipv6: fc0a::cc/64 + ARISTA204T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.198 + - fc00::38d + interfaces: + Loopback0: + ipv4: 100.1.0.228/32 + ipv6: 2064:100::e4/128 + Ethernet1: + ipv4: 10.0.1.199/31 + ipv6: fc00::38e/126 + bp_interfaces: + ipv4: 10.10.246.205/24 + ipv6: fc0a::cd/64 + ARISTA205T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.200 + - fc00::391 + interfaces: + Loopback0: + ipv4: 100.1.0.229/32 + ipv6: 2064:100::e5/128 + Ethernet1: + ipv4: 10.0.1.201/31 + ipv6: fc00::392/126 + bp_interfaces: + ipv4: 10.10.246.206/24 + ipv6: fc0a::ce/64 + ARISTA206T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.202 + - fc00::395 + interfaces: + Loopback0: + ipv4: 100.1.0.230/32 + ipv6: 2064:100::e6/128 + Ethernet1: + ipv4: 10.0.1.203/31 + ipv6: fc00::396/126 + bp_interfaces: + ipv4: 10.10.246.207/24 + ipv6: fc0a::cf/64 + ARISTA207T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.204 + - fc00::399 + interfaces: + Loopback0: + ipv4: 100.1.0.231/32 + ipv6: 2064:100::e7/128 + Ethernet1: + ipv4: 10.0.1.205/31 + ipv6: fc00::39a/126 + bp_interfaces: + ipv4: 10.10.246.208/24 + ipv6: fc0a::d0/64 + ARISTA208T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.206 + - fc00::39d + interfaces: + Loopback0: + ipv4: 100.1.0.232/32 + ipv6: 2064:100::e8/128 + Ethernet1: + ipv4: 10.0.1.207/31 + ipv6: fc00::39e/126 + bp_interfaces: + ipv4: 10.10.246.209/24 + ipv6: fc0a::d1/64 + ARISTA209T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.208 + - fc00::3a1 + interfaces: + Loopback0: + ipv4: 100.1.0.233/32 + ipv6: 2064:100::e9/128 + Ethernet1: + ipv4: 10.0.1.209/31 + ipv6: fc00::3a2/126 + bp_interfaces: + ipv4: 10.10.246.210/24 + ipv6: fc0a::d2/64 + ARISTA210T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.210 + - fc00::3a5 + interfaces: + Loopback0: + ipv4: 100.1.0.234/32 + ipv6: 2064:100::ea/128 + Ethernet1: + ipv4: 10.0.1.211/31 + ipv6: fc00::3a6/126 + bp_interfaces: + ipv4: 10.10.246.211/24 + ipv6: fc0a::d3/64 + ARISTA211T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.212 + - fc00::3a9 + interfaces: + Loopback0: + ipv4: 100.1.0.235/32 + ipv6: 2064:100::eb/128 + Ethernet1: + ipv4: 10.0.1.213/31 + ipv6: fc00::3aa/126 + bp_interfaces: + ipv4: 10.10.246.212/24 + ipv6: fc0a::d4/64 + ARISTA212T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.214 + - fc00::3ad + interfaces: + Loopback0: + ipv4: 100.1.0.236/32 + ipv6: 2064:100::ec/128 + Ethernet1: + ipv4: 10.0.1.215/31 + ipv6: fc00::3ae/126 + bp_interfaces: + ipv4: 10.10.246.213/24 + ipv6: fc0a::d5/64 + ARISTA213T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.216 + - fc00::3b1 + interfaces: + Loopback0: + ipv4: 100.1.0.237/32 + ipv6: 2064:100::ed/128 + Ethernet1: + ipv4: 10.0.1.217/31 + ipv6: fc00::3b2/126 + bp_interfaces: + ipv4: 10.10.246.214/24 + ipv6: fc0a::d6/64 + ARISTA214T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.218 + - fc00::3b5 + interfaces: + Loopback0: + ipv4: 100.1.0.238/32 + ipv6: 2064:100::ee/128 + Ethernet1: + ipv4: 10.0.1.219/31 + ipv6: fc00::3b6/126 + bp_interfaces: + ipv4: 10.10.246.215/24 + ipv6: fc0a::d7/64 + ARISTA215T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.220 + - fc00::3b9 + interfaces: + Loopback0: + ipv4: 100.1.0.239/32 + ipv6: 2064:100::ef/128 + Ethernet1: + ipv4: 10.0.1.221/31 + ipv6: fc00::3ba/126 + bp_interfaces: + ipv4: 10.10.246.216/24 + ipv6: fc0a::d8/64 + ARISTA216T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.222 + - fc00::3bd + interfaces: + Loopback0: + ipv4: 100.1.0.240/32 + ipv6: 2064:100::f0/128 + Ethernet1: + ipv4: 10.0.1.223/31 + ipv6: fc00::3be/126 + bp_interfaces: + ipv4: 10.10.246.217/24 + ipv6: fc0a::d9/64 + ARISTA217T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.224 + - fc00::3c1 + interfaces: + Loopback0: + ipv4: 100.1.0.241/32 + ipv6: 2064:100::f1/128 + Ethernet1: + ipv4: 10.0.1.225/31 + ipv6: fc00::3c2/126 + bp_interfaces: + ipv4: 10.10.246.218/24 + ipv6: fc0a::da/64 + ARISTA218T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.226 + - fc00::3c5 + interfaces: + Loopback0: + ipv4: 100.1.0.242/32 + ipv6: 2064:100::f2/128 + Ethernet1: + ipv4: 10.0.1.227/31 + ipv6: fc00::3c6/126 + bp_interfaces: + ipv4: 10.10.246.219/24 + ipv6: fc0a::db/64 + ARISTA219T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.228 + - fc00::3c9 + interfaces: + Loopback0: + ipv4: 100.1.0.243/32 + ipv6: 2064:100::f3/128 + Ethernet1: + ipv4: 10.0.1.229/31 + ipv6: fc00::3ca/126 + bp_interfaces: + ipv4: 10.10.246.220/24 + ipv6: fc0a::dc/64 + ARISTA220T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.230 + - fc00::3cd + interfaces: + Loopback0: + ipv4: 100.1.0.244/32 + ipv6: 2064:100::f4/128 + Ethernet1: + ipv4: 10.0.1.231/31 + ipv6: fc00::3ce/126 + bp_interfaces: + ipv4: 10.10.246.221/24 + ipv6: fc0a::dd/64 + ARISTA221T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.232 + - fc00::3d1 + interfaces: + Loopback0: + ipv4: 100.1.0.245/32 + ipv6: 2064:100::f5/128 + Ethernet1: + ipv4: 10.0.1.233/31 + ipv6: fc00::3d2/126 + bp_interfaces: + ipv4: 10.10.246.222/24 + ipv6: fc0a::de/64 + ARISTA222T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.234 + - fc00::3d5 + interfaces: + Loopback0: + ipv4: 100.1.0.246/32 + ipv6: 2064:100::f6/128 + Ethernet1: + ipv4: 10.0.1.235/31 + ipv6: fc00::3d6/126 + bp_interfaces: + ipv4: 10.10.246.223/24 + ipv6: fc0a::df/64 + ARISTA223T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.236 + - fc00::3d9 + interfaces: + Loopback0: + ipv4: 100.1.0.247/32 + ipv6: 2064:100::f7/128 + Ethernet1: + ipv4: 10.0.1.237/31 + ipv6: fc00::3da/126 + bp_interfaces: + ipv4: 10.10.246.224/24 + ipv6: fc0a::e0/64 + ARISTA224T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.238 + - fc00::3dd + interfaces: + Loopback0: + ipv4: 100.1.0.248/32 + ipv6: 2064:100::f8/128 + Ethernet1: + ipv4: 10.0.1.239/31 + ipv6: fc00::3de/126 + bp_interfaces: + ipv4: 10.10.246.225/24 + ipv6: fc0a::e1/64 + ARISTA225T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.240 + - fc00::3e1 + interfaces: + Loopback0: + ipv4: 100.1.0.249/32 + ipv6: 2064:100::f9/128 + Ethernet1: + ipv4: 10.0.1.241/31 + ipv6: fc00::3e2/126 + bp_interfaces: + ipv4: 10.10.246.226/24 + ipv6: fc0a::e2/64 + ARISTA226T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.242 + - fc00::3e5 + interfaces: + Loopback0: + ipv4: 100.1.0.250/32 + ipv6: 2064:100::fa/128 + Ethernet1: + ipv4: 10.0.1.243/31 + ipv6: fc00::3e6/126 + bp_interfaces: + ipv4: 10.10.246.227/24 + ipv6: fc0a::e3/64 + ARISTA227T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.244 + - fc00::3e9 + interfaces: + Loopback0: + ipv4: 100.1.0.251/32 + ipv6: 2064:100::fb/128 + Ethernet1: + ipv4: 10.0.1.245/31 + ipv6: fc00::3ea/126 + bp_interfaces: + ipv4: 10.10.246.228/24 + ipv6: fc0a::e4/64 + ARISTA228T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.246 + - fc00::3ed + interfaces: + Loopback0: + ipv4: 100.1.0.252/32 + ipv6: 2064:100::fc/128 + Ethernet1: + ipv4: 10.0.1.247/31 + ipv6: fc00::3ee/126 + bp_interfaces: + ipv4: 10.10.246.229/24 + ipv6: fc0a::e5/64 + ARISTA229T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.248 + - fc00::3f1 + interfaces: + Loopback0: + ipv4: 100.1.0.253/32 + ipv6: 2064:100::fd/128 + Ethernet1: + ipv4: 10.0.1.249/31 + ipv6: fc00::3f2/126 + bp_interfaces: + ipv4: 10.10.246.230/24 + ipv6: fc0a::e6/64 + ARISTA230T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.250 + - fc00::3f5 + interfaces: + Loopback0: + ipv4: 100.1.0.254/32 + ipv6: 2064:100::fe/128 + Ethernet1: + ipv4: 10.0.1.251/31 + ipv6: fc00::3f6/126 + bp_interfaces: + ipv4: 10.10.246.231/24 + ipv6: fc0a::e7/64 + ARISTA231T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.252 + - fc00::3f9 + interfaces: + Loopback0: + ipv4: 100.1.0.255/32 + ipv6: 2064:100::ff/128 + Ethernet1: + ipv4: 10.0.1.253/31 + ipv6: fc00::3fa/126 + bp_interfaces: + ipv4: 10.10.246.232/24 + ipv6: fc0a::e8/64 + ARISTA232T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.1.254 + - fc00::3fd + interfaces: + Loopback0: + ipv4: 100.1.1.0/32 + ipv6: 2064:100::100/128 + Ethernet1: + ipv4: 10.0.1.255/31 + ipv6: fc00::3fe/126 + bp_interfaces: + ipv4: 10.10.246.233/24 + ipv6: fc0a::e9/64 diff --git a/ansible/veos b/ansible/veos index 7e49327d99e..6d545542b13 100644 --- a/ansible/veos +++ b/ansible/veos @@ -21,6 +21,7 @@ all: - t1-64-lag - t1-64-lag-clet - t1-backend + - t1-isolated-d224u8 - t0 - t0-16 - t0-56 diff --git a/docs/testbed/README.testbed.Overview.md b/docs/testbed/README.testbed.Overview.md index fcbf3e95932..2dc6666480d 100644 --- a/docs/testbed/README.testbed.Overview.md +++ b/docs/testbed/README.testbed.Overview.md @@ -142,6 +142,13 @@ Like the T0 type topology, the T1 type topology also has variations: * 16 of the ports are connected to 8 VMs simulating upstream T2 neighbors. Each VM has 2 links connected. The connection to each upstream T2 is configured as a port-channel with 2 links. * 16 of the ports are connected to another 16 VMs simulating downstream T0 neighbors. No port-channel is configured for the links between DUT and T0 neighbors. +#### Variation t1-isolated-d224u8 + +* The DUT has 232 ports. +* Requires 232 VMs. +* 8 of the ports are connected to 8 VMs simulating upstream T2 neighbors. No port-channel is configured for the links between DUT and T2 neighbors. +* 224 of the ports are connected to 224 VMs simulating downstream T0 neighbors. No port-channel is configured for the links between DUT and T0 neighbors. + ### T2 type topology The T2 type topology is to simulate a SONiC DUT running as a T2 device. For a T2 device, in most case it is a chassis with multiple line cards and a supervisor card. For this type of topology, a set of DUT ports on some line cards are connected to VMs simulating upstream T3 neighbors. Another set of DUT ports on some line cards are connected to VMs simulating downstream T1 neighbors. From 3e8b015c9dee716011f81c0aa914d1fa96a88be6 Mon Sep 17 00:00:00 2001 From: Eddie Ruan <119699263+eddieruan-alibaba@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:29:17 +0800 Subject: [PATCH 049/221] Add test cases and infra changes for phoenixwing ptf test (#13785) What is the motivation for this PR? This changes are used for phoenix wing initiative, to provide 1. 5-node testbed for running existing test cases in sonic-mgmt 2. 7-node testbed for running srv6 test cases. The difference for this testbed is to use Cisco's ngdp as dataplane simulation. This type of vsonic would allow us to simulate both control plane and data plane in virtual testing environment. How did you do it? Based on Test doc #13645 How did you verify/test it? Both sanity test cases are running daily for phoenix wing. Any platform specific information? cisco-8101-p4-32x100-vs Supported testbed topology if it's a new test case? 5-node and 7-node testbed listed in testplan #13645. Documentation #13645 --- ansible/config_sonic_basedon_testbed.yml | 65 ++- ansible/group_vars/all/creds.yml | 1 + ansible/group_vars/all/labinfo.json | 6 + ansible/group_vars/sonic/variables | 2 +- ansible/lab | 11 + ansible/library/topo_facts.py | 5 + ansible/module_utils/port_utils.py | 4 + ansible/roles/sonic/handlers/main.yml | 2 +- ansible/roles/sonic/tasks/vsonic.yml | 121 +++-- .../roles/vm_set/library/sonic_kickstart.py | 6 +- ansible/roles/vm_set/library/vm_topology.py | 128 +++++ ansible/roles/vm_set/tasks/main.yml | 6 +- ansible/roles/vm_set/tasks/start.yml | 7 + ansible/roles/vm_set/tasks/start_vm.yml | 22 +- ansible/roles/vm_set/templates/sonic.xml.j2 | 9 + .../roles/vm_set/templates/sonic_vm.xml.j2 | 8 + .../vars/configdb_jsons/7nodes_cisco/P1.json | 430 ++++++++++++++++ .../vars/configdb_jsons/7nodes_cisco/P2.json | 416 ++++++++++++++++ .../vars/configdb_jsons/7nodes_cisco/P3.json | 435 ++++++++++++++++ .../vars/configdb_jsons/7nodes_cisco/P4.json | 416 ++++++++++++++++ .../vars/configdb_jsons/7nodes_cisco/PE1.json | 464 ++++++++++++++++++ .../vars/configdb_jsons/7nodes_cisco/PE2.json | 464 ++++++++++++++++++ .../vars/configdb_jsons/7nodes_cisco/PE3.json | 463 +++++++++++++++++ ansible/vars/init_cfg_profiles.yml | 7 + ansible/vars/topo_ciscovs-5nodes.yml | 211 ++++++++ ansible/vars/topo_ciscovs-7nodes.yml | 220 +++++++++ ansible/veos_vtb | 14 +- ansible/vtestbed.csv | 2 + ansible/vtestbed.yaml | 30 ++ tests/common/testbed.py | 6 +- tests/srv6/srv6_utils.py | 103 ++++ tests/srv6/test_srv6_basic_sanity.py | 128 +++++ 32 files changed, 4154 insertions(+), 58 deletions(-) create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/P1.json create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/P2.json create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/P3.json create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/P4.json create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/PE1.json create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/PE2.json create mode 100644 ansible/vars/configdb_jsons/7nodes_cisco/PE3.json create mode 100644 ansible/vars/init_cfg_profiles.yml create mode 100644 ansible/vars/topo_ciscovs-5nodes.yml create mode 100644 ansible/vars/topo_ciscovs-7nodes.yml create mode 100755 tests/srv6/srv6_utils.py create mode 100644 tests/srv6/test_srv6_basic_sanity.py diff --git a/ansible/config_sonic_basedon_testbed.yml b/ansible/config_sonic_basedon_testbed.yml index 0ea25ed16a1..dd7636751b3 100644 --- a/ansible/config_sonic_basedon_testbed.yml +++ b/ansible/config_sonic_basedon_testbed.yml @@ -422,10 +422,14 @@ - debug: msg="use_ptf_tacacs_server {{ use_ptf_tacacs_server }}" - block: + - name: Load variables from topology file for topo_{{ topo }}.yml + include_vars: "vars/topo_{{ topo }}.yml" + - name: saved original minigraph file in SONiC DUT(ignore errors when file does not exist) shell: mv /etc/sonic/minigraph.xml /etc/sonic/minigraph.xml.orig become: true ignore_errors: true + when: init_cfg_profile is not defined - name: Update TACACS server address to PTF IP set_fact: @@ -438,6 +442,29 @@ template: src=templates/minigraph_template.j2 dest=/etc/sonic/minigraph.xml become: true + when: init_cfg_profile is not defined + + - block: + - name: Load variables from vars/init_cfg_profiles.yml + include_vars: "vars/init_cfg_profiles.yml" + - name: set cfg_profile to {{ init_cfg_profile }} + set_fact: + cfg_profile: "{{ init_cfg_profile }}" + - name: Set actual configuration value based on cfg_profile key + set_fact: + actual_config: "{{ lookup('vars', cfg_profile) }}" + - name: Debug actual configuration value + debug: + msg: "The actual configuration value is: {{ actual_config }}" + - name: Copy over config_db.json from file system for {{ cfg_profile }} + copy : + src: "{{ actual_config }}" + dest: /tmp/config_db.json + when: cfg_profile is defined + - name: Overwrite config_db.json + shell: cat /tmp/config_db.json > /etc/sonic/config_db.json + become: yes + when: init_cfg_profile is defined - name: Test if configlet script exist stat: @@ -509,6 +536,7 @@ regexp: '^snmp_rocommunity:' line: 'snmp_rocommunity: {{ snmp_rocommunity }}' become: true + when: init_cfg_profile is not defined - name: docker status shell: docker ps @@ -555,18 +583,33 @@ port_index_map: "{{ port_index_map | default({}) }}" become: true - - name: execute cli "config load_minigraph --override_config -y" to apply new minigraph - become: true - shell: config load_minigraph --override_config -y - register: load_minigraph_result - failed_when: - - load_minigraph_result.rc != 0 - - "'no such option: --override_config' not in load_minigraph_result.stderr" + - name: Use minigraph case + block: + - name: execute cli "config load_minigraph --override_config -y" to apply new minigraph + become: true + shell: config load_minigraph --override_config -y + register: load_minigraph_result + failed_when: + - load_minigraph_result.rc != 0 + - "'no such option: --override_config' not in load_minigraph_result.stderr" - - name: execute cli "config load_minigraph -y" to apply new minigraph - become: true - shell: config load_minigraph -y - when: "'no such option: --override_config' in load_minigraph_result.stderr" + - name: execute cli "config load_minigraph -y" to apply new minigraph + become: true + shell: config load_minigraph -y + when: "'no such option: --override_config' in load_minigraph_result.stderr" + + - name: remove DSCP_TO_TC_MAP for {{ hwsku }}. Some platform doesn't support this configuration + become: true + shell: redis-cli -n 4 del "DSCP_TO_TC_MAP|AZURE" + when: + - hwsku is defined + - hwsku == 'cisco-8101-p4-32x100-vs' + when: init_cfg_profile is not defined + + - name: SONiC config reload to pick up config_db.json + command: config reload -y + become: yes + when: init_cfg_profile is defined - name: Wait for switch to become reachable again become: false diff --git a/ansible/group_vars/all/creds.yml b/ansible/group_vars/all/creds.yml index 9032331dfce..c5f9bd7201d 100644 --- a/ansible/group_vars/all/creds.yml +++ b/ansible/group_vars/all/creds.yml @@ -17,6 +17,7 @@ sonic_login: "admin" sonic_default_passwords: - "YourPaSsWoRd" - "password" + - "admin" sonic_password: "password" k8s_master_login: "ubuntu" diff --git a/ansible/group_vars/all/labinfo.json b/ansible/group_vars/all/labinfo.json index 04b8f5065ab..ac7c503e679 100644 --- a/ansible/group_vars/all/labinfo.json +++ b/ansible/group_vars/all/labinfo.json @@ -9,6 +9,7 @@ "Arista-7170-64C": "Arista", "Arista-VM": "Arista", "Nexus-3064-NX": "Nexus", + "cisco-8101-p4-32x100-vs" : "Cisco", "Force10-S6100": "Force10", "Force10-S6000": "Force10" }, @@ -23,6 +24,11 @@ "passwd": ["password", "123456"], "enable": ["", null] }, + "Cisco": { + "user": "admin", + "passwd": ["admin"], + "enable": ["admin"] + }, "Force10": { "user": "admin", "passwd": ["password"], diff --git a/ansible/group_vars/sonic/variables b/ansible/group_vars/sonic/variables index 1f192263d10..2d2ec3f80d3 100644 --- a/ansible/group_vars/sonic/variables +++ b/ansible/group_vars/sonic/variables @@ -33,7 +33,7 @@ barefoot_hwskus: [ "montara", "mavericks", "Arista-7170-64C", "newport", "Arista marvell_hwskus: [ "et6448m" ] innovium_tl7_hwskus: ["Wistron_sw_to3200k_32x100" , "Wistron_sw_to3200k"] -cisco_hwskus: ["Cisco-8102-C64", "Cisco-8111-O32", "Cisco-8111-O64", "Cisco-8122-O64", "Cisco-8800-LC-48H-C48"] +cisco_hwskus: ["Cisco-8102-C64", "Cisco-8111-O32", "Cisco-8111-O64", "Cisco-8122-O64", "Cisco-8800-LC-48H-C48", "cisco-8101-p4-32x100-vs"] cisco-8000_gb_hwskus: ["Cisco-8102-C64", "Cisco-88-LC0-36FH-M-O36", "Cisco-8101-O8C48", "Cisco-8101-O32", "Cisco-88-LC0-36FH-O36"] cisco-8000_gr_hwskus: ["Cisco-8111-O32", "Cisco-8111-O64"] cisco-8000_gr2_hwskus: ["Cisco-8122-O64"] diff --git a/ansible/lab b/ansible/lab index 17096c265c9..7308519349a 100644 --- a/ansible/lab +++ b/ansible/lab @@ -15,6 +15,7 @@ all: sonic_multi_asic_2: sonic_msft_sup: sonic_msft_lc_100G: + sonic_cisco_vs: fanout: hosts: str-7260-10: @@ -223,3 +224,13 @@ sonic_msft_lc_100G: loopback4096_ip: [3.3.3.7/32,3.3.3.8/32] loopback4096_ipv6: [2603:10e2:400::7/128,2603:10e2:400::8/128] ansible_host: 2.2.2.5 + +sonic_cisco_vs: + vars: + hwsku: cisco-8101-p4-32x100-vs + iface_speed: 100000 + hosts: + vlab-c-01: + hwsku: cisco-8101-p4-32x100-vs + ansible_host: 10.250.0.125 + ansible_hostv6: fec0::ffff:afa:13 diff --git a/ansible/library/topo_facts.py b/ansible/library/topo_facts.py index b6d8ffb3555..96b806d8bfc 100644 --- a/ansible/library/topo_facts.py +++ b/ansible/library/topo_facts.py @@ -171,6 +171,11 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs vmconfig[vm]['peer_ipv6'][dut_index] = ipv6_addr.upper() vmconfig[vm]['ipv6mask'][dut_index] = ipv6_mask vmconfig[vm]['ip_intf'][dut_index] = intf + + # Configuration is provided via init_cfg_profile, no need to go through the topo file + if "init_cfg_profile" in topo_definition['configuration'][vm]: + continue + # bgp vmconfig[vm]['bgp_asn'] = topo_definition['configuration'][vm]['bgp']['asn'] dut_asn = topo_definition['configuration_properties']['common']['dut_asn'] diff --git a/ansible/module_utils/port_utils.py b/ansible/module_utils/port_utils.py index f684cb19d52..8df35ca1d8c 100644 --- a/ansible/module_utils/port_utils.py +++ b/ansible/module_utils/port_utils.py @@ -429,6 +429,10 @@ def get_port_alias_to_name_map(hwsku, asic_name=None): elif hwsku == "Arista-7060DX5-32": for i in range(1, 33): port_alias_to_name_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 8) + elif hwsku == "cisco-8101-p4-32x100-vs": + # this device simulates 32 ports, with 4 as the step for port naming. + for i in range(0, 32, 4): + port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % i else: if "Arista-7800" in hwsku: assert False, "Please add port_alias_to_name_map for new modular SKU %s." % hwsku diff --git a/ansible/roles/sonic/handlers/main.yml b/ansible/roles/sonic/handlers/main.yml index a063302918e..0942db0d982 100755 --- a/ansible/roles/sonic/handlers/main.yml +++ b/ansible/roles/sonic/handlers/main.yml @@ -2,7 +2,7 @@ # This is also the case for handlers using listen. - name: SONiC update config db - command: config reload -y + command: config reload -y -f become: yes listen: "Update config db" diff --git a/ansible/roles/sonic/tasks/vsonic.yml b/ansible/roles/sonic/tasks/vsonic.yml index 0a1e8303411..99b5dd38023 100644 --- a/ansible/roles/sonic/tasks/vsonic.yml +++ b/ansible/roles/sonic/tasks/vsonic.yml @@ -9,47 +9,96 @@ - name: Set SONiC backplane port name set_fact: bp_ifname="Ethernet{{ fp_num.stdout|int + 1 }}" + when: '"hwsku" not in configuration[hostname]' + +- name: Set SONiC backplane port name for cisco-8101-p4-32x100-vs + set_fact: bp_ifname="Ethernet{{ fp_num.stdout|int *4 }}" + when: '"hwsku" in configuration[hostname] and configuration[hostname]["hwsku"]=="cisco-8101-p4-32x100-vs"' - set_fact: mgmt_ip: "{{ ansible_host }}/{{ mgmt_prefixlen }}" mgmt_gw: "{{ vm_mgmt_gw | default(mgmt_gw) }}" -- name: create mgmt config - template: src="configdb-mgmt.j2" - dest=config-mgmt.json - when: hostname in configuration - -- name: create device metadata config - shell: > - sonic-cfggen -H -k Force10-S6000 --preset empty - | jq '.DEVICE_METADATA.localhost.hostname="{{ hostname }}"' - | jq '.DEVICE_METADATA.localhost.bgp_asn="{{ configuration[hostname]['bgp']['asn'] }}"' - | jq '.DEVICE_METADATA.localhost.deployment_id="1"' - > config-metadata.json - when: hostname in configuration - -- name: create interface config - shell: > - sonic-cfggen -p /usr/share/sonic/device/x86_64-kvm_x86_64-r0/SONiC-VM/port_config.ini -k SONiC-VM --print-data - | jq '.PORT[].admin_status |= "up"' - > config-port.json - when: hostname in configuration - -- name: create topo config - template: src="configdb.j2" - dest=config-topo.json - when: hostname in configuration - -- name: create config db json - shell: | - set -e - sonic-cfggen -j config-mgmt.json -j config-metadata.json -j config-port.json -j config-topo.json --print-data > /etc/sonic/config_db.json - rm -f config-mgmt.json config-metadata.json config-port.json config-topo.json - become: yes - when: hostname in configuration - notify: - - Update config db - - wait for SONiC update config db to finish +- name: create config via mininet config + block: + - name: create mgmt config + template: src="configdb-mgmt.j2" + dest=config-mgmt.json + + - name: create device metadata config for {{ configuration[hostname]['hwsku'] }} + shell: > + sonic-cfggen -H -k {{ configuration[hostname]['hwsku'] }} --preset empty + | jq '.DEVICE_METADATA.localhost.hostname="{{ hostname }}"' + | jq '.DEVICE_METADATA.localhost.bgp_asn="{{ configuration[hostname]['bgp']['asn'] }}"' + | jq '.DEVICE_METADATA.localhost.deployment_id="1"' + > config-metadata.json + when: '"hwsku" in configuration[hostname]' + + - name: create device metadata config + shell: > + sonic-cfggen -H -k Force10-S6000 --preset empty + | jq '.DEVICE_METADATA.localhost.hostname="{{ hostname }}"' + | jq '.DEVICE_METADATA.localhost.bgp_asn="{{ configuration[hostname]['bgp']['asn'] }}"' + | jq '.DEVICE_METADATA.localhost.deployment_id="1"' + > config-metadata.json + when: '"hwsku" not in configuration[hostname]' + + - name: create interface config for {{ configuration[hostname]['hwsku'] }} + shell: > + sonic-cfggen -p /usr/share/sonic/device/x86_64-kvm_x86_64-r0/{{ configuration[hostname]['hwsku'] }}/port_config.ini -k {{ configuration[hostname]['hwsku'] }} --print-data + | jq '.PORT[].admin_status |= "up"' + > config-port.json + when: '"hwsku" in configuration[hostname]' + + - name: create interface config + shell: > + sonic-cfggen -p /usr/share/sonic/device/x86_64-kvm_x86_64-r0/SONiC-VM/port_config.ini -k SONiC-VM --print-data + | jq '.PORT[].admin_status |= "up"' + > config-port.json + when: '"hwsku" not in configuration[hostname]' + + - name: create topo config + template: src="configdb.j2" + dest=config-topo.json + + - name: create config db json + shell: | + set -e + sonic-cfggen -j config-mgmt.json -j config-metadata.json -j config-port.json -j config-topo.json --print-data > /etc/sonic/config_db.json + rm -f config-mgmt.json config-metadata.json config-port.json config-topo.json + become: yes + notify: + - Update config db + - wait for SONiC update config db to finish + when: hostname in configuration and "init_cfg_profile" not in configuration[hostname] + +- name: Update config via provided json + block: + - name: Get playbook directory + debug: + msg: "The playbook dir {{ playbook_dir }}" + - name: Load variables from vars/init_cfg_profiles.yml + include_vars: "vars/init_cfg_profiles.yml" + - name: set cfg_profile to {{ configuration[hostname].init_cfg_profile }} + set_fact: + cfg_profile: "{{ configuration[hostname].init_cfg_profile }}" + - name: Set actual configuration value based on cfg_profile key + set_fact: + actual_config: "{{ lookup('vars', cfg_profile) }}" + - name: Debug actual configuration value + debug: + msg: "The actual configuration value is: {{ actual_config }}" + - name: Copy over config_db.json from file system + copy : + src: "{{ playbook_dir }}/{{ actual_config }}" + dest: /tmp/config_db.json + - name: Overwrite config_db.json + shell: cat /tmp/config_db.json > /etc/sonic/config_db.json + become: yes + notify: + - Update config db + - wait for SONiC update config db to finish + when: hostname in configuration and configuration[hostname]['init_cfg_profile'] is defined - name: Load PTF image block: diff --git a/ansible/roles/vm_set/library/sonic_kickstart.py b/ansible/roles/vm_set/library/sonic_kickstart.py index e4c4920916a..7570a633575 100644 --- a/ansible/roles/vm_set/library/sonic_kickstart.py +++ b/ansible/roles/vm_set/library/sonic_kickstart.py @@ -56,9 +56,9 @@ def login(self, user, passwords): break for password in passwords: - index = self.pair(user, [r'assword:', r'\$']) + index = self.pair(user, [r'assword:', r'\$', r'\#']) if index == 0: - index = self.pair(password, [r'login:', r'\$']) + index = self.pair(password, [r'login:', r'\$', r'\#']) if index == 1: break @@ -73,7 +73,7 @@ def configure(self, seq): else: (action, wait_for, timeout) = cmd self.pair(action, wait_for, timeout) - self.pair('exit', [r'\$']) + self.pair('exit', [r'\$', r'\#']) return diff --git a/ansible/roles/vm_set/library/vm_topology.py b/ansible/roles/vm_set/library/vm_topology.py index dd78d673d44..80ae1f69cd4 100644 --- a/ansible/roles/vm_set/library/vm_topology.py +++ b/ansible/roles/vm_set/library/vm_topology.py @@ -253,6 +253,16 @@ def init(self, vm_set_name, vm_base, duts_fp_ports, duts_name, ptf_exists=True, raise Exception("Wrong vlans parameter for hostname %s, vm %s. Too many vlans. Maximum is %d" % (hostname, vmname, len(vm_bridges))) + self.VM_LINKs = {} + if 'VM_LINKs' in self.topo: + for k, v in self.topo['VM_LINKs'].items(): + self.VM_LINKs[k] = v + + self.OVS_LINKs = {} + if 'OVS_LINKs' in self.topo: + for k, v in self.topo['OVS_LINKs'].items(): + self.OVS_LINKs[k] = v + self._is_multi_duts = True if len(self.duts_name) > 1 else False # For now distinguish a cable topology since it does not contain any vms and there are two ToR's self._is_cable = True if len( @@ -473,6 +483,15 @@ def add_injected_fp_ports_to_docker(self): else: self.add_veth_if_to_docker(ext_if, int_if) + def add_injected_VM_ports_to_docker(self): + for k, attr in self.OVS_LINKs.items(): + vlans = attr['vlans'][:] + for vlan in vlans: + (_, _, ptf_index) = VMTopology.parse_vm_vlan_port(vlan) + int_if = PTF_FP_IFACE_TEMPLATE % ptf_index + injected_iface = adaptive_name(INJECTED_INTERFACES_TEMPLATE, self.vm_set_name, ptf_index) + self.add_veth_if_to_docker(injected_iface, int_if) + def add_mgmt_port_to_docker(self, mgmt_bridge, mgmt_ip, mgmt_gw, mgmt_ipv6_addr=None, mgmt_gw_v6=None, extra_mgmt_ip_addr=None, api_server_pid=None): @@ -863,6 +882,38 @@ def bind_fp_ports(self, disconnect_vm=False): self.bind_vs_dut_ports( VS_CHASSIS_MIDPLANE_BRIDGE_NAME, self.topo['DUT']['vs_chassis']['midplane_port']) + for k, attr in self.VM_LINKs.items(): + logging.info("Create VM links for {} : {}".format(k, attr)) + br_name = "br_{}".format(k.lower()) + port1 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['start_vm_offset']], + attr['start_vm_port_idx'] + ) + port2 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['end_vm_offset']], + attr['end_vm_port_idx'] + ) + + self.bind_vm_link(br_name, port1, port2) + + for k, attr in self.OVS_LINKs.items(): + logging.info("Create OVS links for {} : {}".format(k, attr)) + br_name = "br_{}".format(k.lower()) + port1 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['start_vm_offset']], + attr['start_vm_port_idx'] + ) + port2 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['end_vm_offset']], + attr['end_vm_port_idx'] + ) + self.create_ovs_bridge(br_name, 9000) + vlans = attr['vlans'] + for vlan in vlans: + (_, _, ptf_index) = VMTopology.parse_vm_vlan_port(vlan) + injected_iface = adaptive_name(INJECTED_INTERFACES_TEMPLATE, self.vm_set_name, ptf_index) + self.bind_ovs_ports(br_name, port1, injected_iface, port2, disconnect_vm) + def unbind_fp_ports(self): logging.info("=== unbind front panel ports ===") for attr in self.VMs.values(): @@ -885,6 +936,74 @@ def unbind_fp_ports(self): self.destroy_ovs_bridge(VS_CHASSIS_INBAND_BRIDGE_NAME) self.destroy_ovs_bridge(VS_CHASSIS_MIDPLANE_BRIDGE_NAME) + for k, attr in self.VM_LINKs.items(): + logging.info("Remove VM links for {} : {}".format(k, attr)) + br_name = "br_{}".format(k.lower()) + port1 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['start_vm_offset']], + attr['start_vm_port_idx'] + ) + port2 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['end_vm_offset']], + attr['end_vm_port_idx'] + ) + if "use_ovs" in attr and attr["use_ovs"] == 1: + self.unbind_ovs_port(br_name, port1) + self.unbind_ovs_port(br_name, port2) + self.destroy_ovs_bridge(br_name) + else: + self.unbind_vm_link(br_name, port1, port2) + + for k, attr in self.OVS_LINKs.items(): + logging.info("Remove OVS links for {} : {}".format(k, attr)) + br_name = "br_{}".format(k.lower()) + port1 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['start_vm_offset']], + attr['start_vm_port_idx'] + ) + port2 = OVS_FP_TAP_TEMPLATE % ( + self.vm_names[self.vm_base_index + attr['end_vm_offset']], + attr['end_vm_port_idx'] + ) + self.create_ovs_bridge(br_name, 9000) + vlans = attr['vlans'] + for vlan in vlans: + (_, _, ptf_index) = VMTopology.parse_vm_vlan_port(vlan) + injected_iface = adaptive_name(INJECTED_INTERFACES_TEMPLATE, self.vm_set_name, ptf_index) + self.unbind_ovs_ports(br_name, port1) + self.unbind_ovs_ports(br_name, port2) + self.unbind_ovs_ports(br_name, injected_iface) + + def unbind_vm_link(self, br_name, port1, port2): + _, if_to_br = VMTopology.brctl_show() + if port1 in if_to_br: + VMTopology.cmd("brctl delif %s %s" % (br_name, port1)) + if port2 in if_to_br: + VMTopology.cmd("brctl delif %s %s" % (br_name, port2)) + VMTopology.cmd('brctl delbr %s' % br_name) + + def bind_vm_link(self, br_name, port1, port2): + if VMTopology.intf_not_exists(br_name): + VMTopology.cmd('brctl addbr %s' % br_name) + VMTopology.iface_up(br_name) + + # Remove port from ovs bridge + br = VMTopology.get_ovs_bridge_by_port(port1) + if br is not None: + VMTopology.cmd('ovs-vsctl del-port %s %s' % (br, port1)) + + br = VMTopology.get_ovs_bridge_by_port(port2) + if br is not None: + VMTopology.cmd('ovs-vsctl del-port %s %s' % (br, port2)) + + m_to_ifs, _ = VMTopology.brctl_show() + if port1 not in m_to_ifs[br_name]: + VMTopology.cmd("brctl addif %s %s" % (br_name, port1)) + if port2 not in m_to_ifs[br_name]: + VMTopology.cmd("brctl addif %s %s" % (br_name, port2)) + VMTopology.iface_up(port1) + VMTopology.iface_up(port2) + def bind_vm_backplane(self): if VMTopology.intf_not_exists(self.bp_bridge): @@ -955,6 +1074,10 @@ def bind_ovs_ports(self, br_name, dut_iface, injected_iface, vm_iface, disconnec if br is not None and br != br_name: VMTopology.cmd('ovs-vsctl del-port %s %s' % (br, dut_iface)) + br = VMTopology.get_ovs_bridge_by_port(vm_iface) + if br is not None and br != br_name: + VMTopology.cmd('ovs-vsctl del-port %s %s' % (br, vm_iface)) + ports = VMTopology.get_ovs_br_ports(br_name) if injected_iface not in ports: VMTopology.cmd('ovs-vsctl add-port %s %s' % @@ -963,6 +1086,9 @@ def bind_ovs_ports(self, br_name, dut_iface, injected_iface, vm_iface, disconnec if dut_iface not in ports: VMTopology.cmd('ovs-vsctl add-port %s %s' % (br_name, dut_iface)) + if vm_iface not in ports: + VMTopology.cmd('ovs-vsctl add-port %s %s' % (br_name, vm_iface)) + bindings = VMTopology.get_ovs_port_bindings(br_name, [dut_iface]) dut_iface_id = bindings[dut_iface] injected_iface_id = bindings[injected_iface] @@ -1856,6 +1982,7 @@ def main(): if vms_exists: net.add_injected_fp_ports_to_docker() + net.add_injected_VM_ports_to_docker() net.bind_fp_ports() net.bind_vm_backplane() net.add_bp_port_to_docker(ptf_bp_ip_addr, ptf_bp_ipv6_addr) @@ -2001,6 +2128,7 @@ def main(): if vms_exists: net.unbind_fp_ports() net.add_injected_fp_ports_to_docker() + net.add_injected_VM_ports_to_docker() net.bind_fp_ports() net.bind_vm_backplane() net.add_bp_port_to_docker(ptf_bp_ip_addr, ptf_bp_ipv6_addr) diff --git a/ansible/roles/vm_set/tasks/main.yml b/ansible/roles/vm_set/tasks/main.yml index 69bbae918ef..b21e94d2fa9 100644 --- a/ansible/roles/vm_set/tasks/main.yml +++ b/ansible/roles/vm_set/tasks/main.yml @@ -17,10 +17,14 @@ # Need latest ubuntu 4.10 kernel to fix a openvswitch bug # https://bugs.launchpad.net/ubuntu/+source/kernel-package/+bug/1685742 +- name: Pick package_installation from env + set_fact: + package_installation: "{{ lookup('env', 'PACKAGE_INSTALLATION') | default(omit) }}" + - name: Set the default variable package_installation set_fact: package_installation: true - when: package_installation is not defined + when: package_installation is not defined or package_installation == '' - name: get host distribution shell: grep ^NAME /etc/os-release | awk -F '=' '{print $2}' | tr -d '"' diff --git a/ansible/roles/vm_set/tasks/start.yml b/ansible/roles/vm_set/tasks/start.yml index 4fe94b6feb2..bcfa7b4184d 100644 --- a/ansible/roles/vm_set/tasks/start.yml +++ b/ansible/roles/vm_set/tasks/start.yml @@ -7,6 +7,13 @@ include_vars: "vars/topo_{{ topo }}.yml" when: topo is defined +- name: Pick provided max num of fp + set_fact: + max_fp_num: "{{ max_fp_num_provided }}" + when: max_fp_num_provided is defined + +- debug: msg="max_fp_num {{ max_fp_num }}" + - name: Filter VMs for specified topology set_fact: VM_hosts={{ VM_hosts | filter_vm_targets(topology['VMs'], VM_base) | sort }} when: topology['VMs'] is defined and VM_base is defined diff --git a/ansible/roles/vm_set/tasks/start_vm.yml b/ansible/roles/vm_set/tasks/start_vm.yml index c7f40ef5c1f..ff680a85bce 100644 --- a/ansible/roles/vm_set/tasks/start_vm.yml +++ b/ansible/roles/vm_set/tasks/start_vm.yml @@ -33,8 +33,26 @@ respin_vms: [] when: respin_vms is not defined +- set_fact: + hwsku: "" + hname: "" + +- name: Find current server group + set_fact: current_server={{ group_names | extract_by_prefix('server_') }} + +- name: Extract VM names from the inventory + set_fact: VM_list={{ groups[current_server] | filter_by_prefix('VM') | sort }} + +- name: Generate hostname for target VM + set_fact: hname={{ VM_list | extract_hostname(topology['VMs'], VM_base, hostname) }} + when: topology['VMs'] is defined + +- set_fact: + hwsku: "{{ configuration[hname].hwsku }}" + when: configuration is defined and hname in configuration and configuration[hname]['hwsku'] is defined + - name: Device debug output - debug: msg="hostname = {{ hostname }} vm_type = {{ vm_type }} serial port = {{ serial_port }} ip = {{ mgmt_ip_address }}" + debug: msg="hostname = {{ hostname }} host internal name = {{ hname }} sonic_password = {{ sonic_password }} vm_type = {{ vm_type }} serial port = {{ serial_port }} ip = {{ mgmt_ip_address }} hwsku = {{ hwsku }}" - name: Check destination file existance stat: path={{ disk_image }} @@ -44,7 +62,7 @@ copy: src={{ src_disk_image }} dest={{ disk_image }} remote_src=True when: not file_stat.stat.exists -- name: Define vm {{ vm_name }} +- name: Define vm {{ vm_name }}, hwsku {{ hwsku }} virt: name={{ vm_name }} command=define xml="{{ lookup('template', 'templates/{{ vm_xml_template }}') }}" diff --git a/ansible/roles/vm_set/templates/sonic.xml.j2 b/ansible/roles/vm_set/templates/sonic.xml.j2 index db7a3e42662..ebedbfc3260 100644 --- a/ansible/roles/vm_set/templates/sonic.xml.j2 +++ b/ansible/roles/vm_set/templates/sonic.xml.j2 @@ -14,6 +14,14 @@ +{% elif hwsku == 'cisco-8101-p4-32x100-vs' %} + 8 + 8 + 6 + + + + {% else %} 4 4 @@ -23,6 +31,7 @@ {% endif %} + /machine diff --git a/ansible/roles/vm_set/templates/sonic_vm.xml.j2 b/ansible/roles/vm_set/templates/sonic_vm.xml.j2 index 7eff57b29fd..e200266b7b3 100644 --- a/ansible/roles/vm_set/templates/sonic_vm.xml.j2 +++ b/ansible/roles/vm_set/templates/sonic_vm.xml.j2 @@ -1,8 +1,16 @@ {{ vm_name }} + +{% if hwsku == 'cisco-8101-p4-32x100-vs' %} + 8 + 8 + 6 +{% else %} 4 4 2 +{% endif %} + /machine diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/P1.json b/ansible/vars/configdb_jsons/7nodes_cisco/P1.json new file mode 100644 index 00000000000..64088672776 --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/P1.json @@ -0,0 +1,430 @@ +{ + "BGP_GLOBALS": { + "default" : { + "local_asn" : "65100", + "router_id" : "100.1.0.35", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + } + }, + "BGP_NEIGHBOR_AF" : { + "default|fc00::72|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc00::76|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc00::7e|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc00::81|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc01::85|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "default|fc00::72": { + "admin_status": "true", + "local_asn" : "65100", + "min_adv_interval": "0", + "local_addr" :"fc00::71", + "asn": "64600", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "PE1" + }, + "default|fc00::76": { + "admin_status": "true", + "local_asn" : "65100", + "min_adv_interval": "0", + "local_addr" :"fc00::75", + "asn": "64601", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "PE2" + }, + "default|fc00::7e": { + "admin_status": "true", + "local_asn" : "65100", + "min_adv_interval": "0", + "local_addr" :"fc00::7d", + "asn": "65101", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P3" + }, + "default|fc00::81": { + "admin_status": "true", + "local_asn" : "65100", + "min_adv_interval": "0", + "local_addr" :"fc00::82", + "asn": "65102", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P2" + }, + "default|fc01::85": { + "admin_status": "true", + "local_asn" : "65100", + "min_adv_interval": "0", + "local_addr" :"fc01::86", + "asn": "65103", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P4" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "65100", + "hostname": "P1", + "mac": "52:54:00:00:00:4e", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "nexthop_group" : "enabled", + "frr_mgmt_framework_config": "true", + "docker_routing_config_mode": "unified", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet112": {}, + "Ethernet112|fc00::71/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet116": {}, + "Ethernet116|fc00::75/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet124": {}, + "Ethernet124|fc00::7d/126": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet64": {}, + "Ethernet64|fc00::82/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet68": {}, + "Ethernet68|fc01::86/126 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.35/32": {}, + "Loopback0|2064:700::23/128": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.125/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/P2.json b/ansible/vars/configdb_jsons/7nodes_cisco/P2.json new file mode 100644 index 00000000000..0f266ef4ef3 --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/P2.json @@ -0,0 +1,416 @@ +{ + "BGP_GLOBALS": { + "default" : { + "local_asn" : "65102", + "router_id" : "100.1.0.33", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + } + }, + "BGP_NEIGHBOR_AF" : { + "default|fc00::82|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc09::2|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc08::1|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc07::1|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "default|fc00::82": { + "admin_status": "true", + "local_asn" : "65102", + "min_adv_interval": "0", + "local_addr" :"fc00::81", + "asn": "65100", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P1" + }, + "default|fc09::2": { + "admin_status": "true", + "local_asn" : "65102", + "min_adv_interval": "0", + "local_addr" :"fc09::1", + "asn": "65101", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P3" + }, + "default|fc08::1": { + "admin_status": "true", + "local_asn" : "65102", + "min_adv_interval": "0", + "local_addr" :"fc08::2", + "asn": "64602", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "PE3" + }, + "default|fc07::1": { + "admin_status": "true", + "local_asn" : "65102", + "min_adv_interval": "0", + "local_addr" :"fc07::2", + "asn": "65103", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P4" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "65102", + "hostname": "P2", + "mac": "52:54:00:df:3c:6e", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "nexthop_group" : "enabled", + "frr_mgmt_framework_config": "true", + "docker_routing_config_mode": "unified", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet0": {}, + "Ethernet0|fc00::81/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet4": {}, + "Ethernet4|fc09::1/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet8": {}, + "Ethernet8|fc07::2/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet12": {}, + "Ethernet12|fc08::2/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet124": { + }, + "Ethernet124|fc0a::33/120 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.33/32": {}, + "Loopback0|2064:500::21/128": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.55/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/P3.json b/ansible/vars/configdb_jsons/7nodes_cisco/P3.json new file mode 100644 index 00000000000..f36e6c5b0df --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/P3.json @@ -0,0 +1,435 @@ +{ + "BGP_GLOBALS": { + "default" : { + "local_asn" : "65101", + "router_id" : "100.1.0.33", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + } + }, + "BGP_NEIGHBOR_AF" : { + "default|fc00::7d|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc02::1|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc03::1|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc04::1|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc09::1|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "default|fc00::7d": { + "admin_status": "true", + "local_asn" : "65101", + "min_adv_interval": "0", + "local_addr" :"fc00::7e", + "asn": "65100", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P1" + }, + "default|fc02::1": { + "admin_status": "true", + "local_asn" : "65101", + "min_adv_interval": "0", + "local_addr" :"fc02::2", + "asn": "64600", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "PE1" + }, + "default|fc03::1": { + "admin_status": "true", + "local_asn" : "65101", + "min_adv_interval": "0", + "local_addr" :"fc03::2", + "asn": "64601", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "PE2" + }, + "default|fc04::1": { + "admin_status": "true", + "local_asn" : "65101", + "min_adv_interval": "0", + "local_addr" :"fc04::2", + "asn": "65103", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P4" + }, + "default|fc09::1": { + "admin_status": "true", + "local_asn" : "65101", + "min_adv_interval": "0", + "local_addr" :"fc09::2", + "asn": "65102", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P2" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "65101", + "hostname": "P3", + "mac": "52:54:00:df:2c:6e", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "nexthop_group" : "enabled", + "frr_mgmt_framework_config": "true", + "docker_routing_config_mode": "unified", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet124": {}, + "Ethernet124|fc0a::32/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet0": {}, + "Ethernet0|fc00::7e/126": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet4": {}, + "Ethernet4|fc02::2/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet8": {}, + "Ethernet8|fc03::2/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet12": {}, + "Ethernet12|fc09::2/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet16": {}, + "Ethernet16|fc04::2/120 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.32/32": {}, + "Loopback0|2064:400::20/128": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.54/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/P4.json b/ansible/vars/configdb_jsons/7nodes_cisco/P4.json new file mode 100644 index 00000000000..bc6ec46efff --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/P4.json @@ -0,0 +1,416 @@ +{ + "BGP_GLOBALS": { + "default" : { + "local_asn" : "65103", + "router_id" : "100.1.0.34", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + } + }, + "BGP_NEIGHBOR_AF" : { + "default|fc01::86|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc07::02|ipv6_unicast" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc06::01|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc04::02|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "default|fc01::86": { + "admin_status": "true", + "local_asn" : "65103", + "min_adv_interval": "0", + "local_addr" :"fc01::85", + "asn": "65100", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P1" + }, + "default|fc07::2": { + "admin_status": "true", + "local_asn" : "65103", + "min_adv_interval": "0", + "local_addr" :"fc07::1", + "asn": "65102", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P2" + }, + "default|fc06::1": { + "admin_status": "true", + "local_asn" : "65103", + "min_adv_interval": "0", + "local_addr" :"fc06::2", + "asn": "64602", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "PE3" + }, + "default|fc04::2": { + "admin_status": "true", + "local_asn" : "65103", + "min_adv_interval": "0", + "local_addr" :"fc04::1", + "asn": "65101", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "name": "P2" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "65103", + "hostname": "P4", + "mac": "52:54:00:df:5c:6e", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "nexthop_group" : "enabled", + "frr_mgmt_framework_config": "true", + "docker_routing_config_mode": "unified", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet0": {}, + "Ethernet0|fc01::85/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet4": {}, + "Ethernet4|fc04::1/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet8": {}, + "Ethernet8|fc07::1/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet12": {}, + "Ethernet12|fc06::2/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet124": { + }, + "Ethernet124|fc0a::34/120 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.34/32": {}, + "Loopback0|2064:600::22/128": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.56/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/PE1.json b/ansible/vars/configdb_jsons/7nodes_cisco/PE1.json new file mode 100644 index 00000000000..ae1ef48471d --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/PE1.json @@ -0,0 +1,464 @@ +{ + "BGP_GLOBALS": { + "Vrf1" : { + "local_asn" : "64600", + "router_id" : "100.1.0.29 ", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "srv6_locator": "lsid1", + "keepalive" : "10", + "holdtime" : "30" + }, + "default" : { + "local_asn" : "64600", + "router_id" : "100.1.0.29", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "s1|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + }, + "default|ipv4_vpn" : { + "max_ebgp_paths" : 64 + }, + "Vrf1|ipv4_unicast" : { + "max_ebgp_paths" : 64, + "rd_vpn_export" : "2:2", + "rt_vpn_both" : "1:1", + "rmap_vpn_export" : "s1", + "export_vpn" : "true", + "import_vpn" : "true" + } + }, + "BGP_NEIGHBOR_AF" : { + "Vrf1|10.10.246.254|ipv4_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all"], + "route_map_out" : ["pass_all"] + }, + "default|2064:200::1e|ipv4_vpn" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|2064:300::1f|ipv4_vpn" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|FC00::71|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc02::2|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" :["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "Vrf1|10.10.246.254": { + "admin_status": "true", + "local_asn" : "64600", + "local_addr" : "10.10.246.29", + "asn": "64600", + "name": "exabgp_v4" + }, + "default|2064:200::1e": { + "admin_status": "true", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "capability_ext_nexthop": "true", + "local_addr" :"2064:100::1d", + "local_asn" : "64600", + "asn": "64601", + "name": "PE2" + }, + "default|2064:300::1f": { + "admin_status": "true", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "capability_ext_nexthop": "true", + "local_addr" :"2064:100::1d", + "local_asn" : "64600", + "asn": "64602", + "name": "PE3" + }, + "default|FC00::71": { + "admin_status": "true", + "local_asn" : "64600", + "local_addr" : "FC00::71", + "asn": "65100", + "name": "P1" + }, + "default|fc02::2": { + "admin_status": "true", + "local_asn" : "64600", + "local_addr" : "FC02::01", + "asn": "65101", + "name": "P3" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "64600", + "hostname": "PE1", + "mac": "52:54:00:df:0c:4e", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "docker_routing_config_mode": "unified", + "frr_mgmt_framework_config": "true", + "nexthop_group" : "enabled", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet0": {}, + "Ethernet4": {}, + "Ethernet24": {"vrf_name" : "Vrf1"}, + "Ethernet24|10.10.246.29/24 ": { + "family": "IPv4", + "vrf_name": "PUBLIC-TC11", + "scope": "global" + }, + "Ethernet24|fc0a::29/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet0|fc00::72/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet4|fc02::1/120 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.29/32": {}, + "Loopback0|2064:100::1d/128": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.51/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "VRF": { + "Vrf1": {}, + "Vrf2": {} + }, + "SRV6_LOCATOR": { + "lsid1": { + "argu_len": "48", + "block_len": "32", + "func_len": "32", + "node_len": "16", + "opcode_prefix": [ + "::fff1:1:0:0:0", + "::fff1:11:0:0:0" + ], + "opcode_act": [ + "end-dt46", + "end-dt46" + ], + "opcode_vrf": [ + "Vrf1", + "Vrf2" + ], + "prefix": "fd00:201:201::/48" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/PE2.json b/ansible/vars/configdb_jsons/7nodes_cisco/PE2.json new file mode 100644 index 00000000000..26bb2768b48 --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/PE2.json @@ -0,0 +1,464 @@ +{ + "BGP_GLOBALS": { + "Vrf1" : { + "local_asn" : "64601", + "router_id" : "100.1.0.30 ", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "srv6_locator": "lsid1", + "keepalive" : "10", + "holdtime" : "30" + }, + "default" : { + "local_asn" : "64601", + "router_id" : "100.1.0.30", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "s1|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + }, + "default|ipv4_vpn" : { + "max_ebgp_paths" : 64 + }, + "Vrf1|ipv4_unicast" : { + "max_ebgp_paths" : 64, + "rd_vpn_export" : "2:2", + "rt_vpn_both" : "1:1", + "rmap_vpn_export" : "s1", + "export_vpn" : "true", + "import_vpn" : "true" + } + }, + "BGP_NEIGHBOR_AF" : { + "Vrf1|10.10.246.254|ipv4_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all"], + "route_map_out" : ["pass_all"] + }, + "default|2064:100::1d|ipv4_vpn" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|2064:300::1f|ipv4_vpn" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|FC00::75|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc03::2|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "Vrf1|10.10.246.254": { + "admin_status": "up", + "local_asn" : "64601", + "local_addr" :"10.10.246.30", + "asn": "64601", + "name": "exabgp_v4" + }, + "default|2064:100::1d": { + "admin_status": "up", + "local_addr" :"2064:200::1e", + "local_asn" : "64601", + "asn": "64600", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "capability_ext_nexthop": "true", + "name": "PE1" + }, + "default|2064:300::1f": { + "admin_status": "up", + "local_addr" :"2064:200::1e", + "local_asn" : "64601", + "asn": "64602", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "capability_ext_nexthop": "true", + "name": "PE3" + }, + "default|FC00::75": { + "admin_status": "up", + "local_addr" :"FC00::76", + "local_asn" : "64601", + "asn": "65100", + "name": "P1" + }, + "default|fc03::2": { + "admin_status": "up", + "local_addr" :"FC03::1", + "local_asn" : "64601", + "asn": "65101", + "name": "P3" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "64601", + "hostname": "PE2", + "mac": "52:54:00:96:90:d5", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "frr_mgmt_framework_config": "true", + "docker_routing_config_mode": "unified", + "nexthop_group" : "enabled", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet0": {}, + "Ethernet8": {}, + "Ethernet24": {"vrf_name" : "Vrf1"}, + "Ethernet24|10.10.246.30/24 ": { + "family": "IPv4", + "vrf_name": "PUBLIC-TC11", + "scope": "global" + }, + "Ethernet24|fc0a::30/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet0|fc00::76/126 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet8|fc03::1/120 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.30/32": {}, + "Loopback0|2064:200::1e/128": {} + }, + "VRF": { + "Vrf1": {}, + "Vrf2": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.52/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "SRV6_LOCATOR": { + "lsid1": { + "argu_len": "48", + "block_len": "32", + "func_len": "32", + "node_len": "16", + "opcode_prefix": [ + "::fff2:2:0:0:0", + "::fff2:22:0:0:0" + ], + "opcode_act": [ + "end-dt46", + "end-dt46" + ], + "opcode_vrf": [ + "Vrf1", + "Vrf2" + ], + "prefix": "fd00:202:202::/48" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/configdb_jsons/7nodes_cisco/PE3.json b/ansible/vars/configdb_jsons/7nodes_cisco/PE3.json new file mode 100644 index 00000000000..5c871cae29f --- /dev/null +++ b/ansible/vars/configdb_jsons/7nodes_cisco/PE3.json @@ -0,0 +1,463 @@ +{ + "BGP_GLOBALS": { + "Vrf1" : { + "local_asn" : "64602", + "router_id" : "100.1.0.31 ", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "srv6_locator": "lsid1", + "keepalive" : "10", + "holdtime" : "30" + }, + "default" : { + "local_asn" : "64602", + "router_id" : "100.1.0.31", + "log_nbr_state_changes" : "true", + "load_balance_mp_relax" : "true", + "keepalive" : "10", + "holdtime" : "30" + } + }, + "ROUTE_MAP" : { + "pass_all|1" : { + "route_operation" : "permit" + }, + "s1|1" : { + "route_operation" : "permit" + }, + "pass_all_in|1" : { + "route_operation" : "permit", + "set_ipv6_next_hop_prefer_global" : "true" + } + }, + "BGP_GLOBALS_AF" : { + "default|ipv6_unicast" : { + "max_ebgp_paths" : 64, + "redistribute_connected": "true", + "redistribute_static_rmap": "pass_all" + }, + "default|ipv4_vpn" : { + "max_ebgp_paths" : 64 + }, + "Vrf1|ipv4_unicast" : { + "max_ebgp_paths" : 64, + "rd_vpn_export" : "2:2", + "rt_vpn_both" : "1:1", + "rmap_vpn_export" : "s1", + "export_vpn" : "true", + "import_vpn" : "true" + } + }, + "BGP_NEIGHBOR_AF" : { + "Vrf1|10.10.246.254|ipv4_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all"], + "route_map_out" : ["pass_all"] + }, + "default|2064:100::1d|ipv4_vpn" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|2064:200::1e|ipv4_vpn" : { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|FC08::02|ipv6_unicast" :{ + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + }, + "default|fc06::2|ipv6_unicast": { + "admin_status" : "true", + "route_map_in" : ["pass_all_in"], + "route_map_out" : ["pass_all"] + } + }, + "BGP_NEIGHBOR": { + "Vrf1|10.10.246.254": { + "admin_status": "true", + "local_asn" : "64602", + "local_addr" : "10.10.246.31", + "asn": "64602", + "name": "exabgp_v4" + }, + "default|2064:200::1e": { + "admin_status": "true", + "local_addr" : "2064:300::1f", + "local_asn" : "64602", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "capability_ext_nexthop": "true", + "asn": "64601", + "name": "PE2" + }, + "default|2064:100::1d": { + "admin_status": "true", + "local_addr" : "2064:300::1f", + "local_asn" : "64602", + "ebgp_multihop": "true", + "ebgp_multihop_ttl": "255", + "capability_ext_nexthop": "true", + "asn": "64600", + "name": "PE1" + }, + "default|FC08::02": { + "admin_status": "true", + "local_asn" : "64602", + "local_addr" : "FC08::01", + "asn": "65102", + "name": "P2" + }, + "default|fc06::2": { + "admin_status": "true", + "local_asn" : "64602", + "local_addr" : "FC06::01", + "asn": "65103", + "name": "P4" + } + }, + "DEVICE_METADATA": { + "localhost": { + "asic": "cisco-ngdp-vs", + "bgp_asn": "64602", + "hostname": "PE3", + "mac": "52:54:00:df:1c:5e", + "platform": "x86_64-kvm_x86_64-r0", + "synchronous_mode": "enable", + "hwsku" : "cisco-8101-p4-32x100-vs", + "frr_mgmt_framework_config": "true", + "docker_routing_config_mode": "unified", + "nexthop_group" : "enabled", + "type": "LeafRouter" + } + }, + "INTERFACE": { + "Ethernet24": {"vrf_name" : "Vrf1"}, + "Ethernet24|10.10.246.31/24 ": { + "family": "IPv4", + "scope": "global" + }, + "Ethernet24|fc0a::31/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet4": {}, + "Ethernet4|fc08::1/120 ": { + "family": "IPv6", + "scope": "global" + }, + "Ethernet12": {}, + "Ethernet12|fc06::1/120 ": { + "family": "IPv6", + "scope": "global" + } + }, + "PORT": { + "Ethernet0": { + "lanes": "2304,2305,2306,2307", + "alias": "Ethernet0", + "index": "0", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet4": { + "lanes": "2320,2321,2322,2323", + "alias": "Ethernet4", + "index": "1", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet8": { + "lanes": "2312,2313,2314,2315", + "alias": "Ethernet8", + "index": "2", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet12": { + "lanes": "2056,2057,2058,2059", + "alias": "Ethernet12", + "index": "3", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet16": { + "lanes": "1792,1793,1794,1795", + "alias": "Ethernet16", + "index": "4", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet20": { + "lanes": "2048,2049,2050,2051", + "alias": "Ethernet20", + "index": "5", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet24": { + "lanes": "2560,2561,2562,2563", + "alias": "Ethernet24", + "index": "6", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet28": { + "lanes": "2824,2825,2826,2827", + "alias": "Ethernet28", + "index": "7", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet32": { + "lanes": "2832,2833,2834,2835", + "alias": "Ethernet32", + "index": "8", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet36": { + "lanes": "2816,2817,2818,2819", + "alias": "Ethernet36", + "index": "9", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet40": { + "lanes": "2568,2569,2570,2571", + "alias": "Ethernet40", + "index": "10", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet44": { + "lanes": "2576,2577,2578,2579", + "alias": "Ethernet44", + "index": "11", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet48": { + "lanes": "1536,1537,1538,1539", + "alias": "Ethernet48", + "index": "12", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet52": { + "lanes": "1800,1801,1802,1803", + "alias": "Ethernet52", + "index": "13", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet56": { + "lanes": "1552,1553,1554,1555", + "alias": "Ethernet56", + "index": "14", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet60": { + "lanes": "1544,1545,1546,1547", + "alias": "Ethernet60", + "index": "15", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet64": { + "lanes": "1296,1297,1298,1299", + "alias": "Ethernet64", + "index": "16", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet68": { + "lanes": "1288,1289,1290,1291", + "alias": "Ethernet68", + "index": "17", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet72": { + "lanes": "1280,1281,1282,1283", + "alias": "Ethernet72", + "index": "18", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet76": { + "lanes": "1032,1033,1034,1035", + "alias": "Ethernet76", + "index": "19", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet80": { + "lanes": "264,265,266,267", + "alias": "Ethernet80", + "index": "20", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet84": { + "lanes": "272,273,274,275", + "alias": "Ethernet84", + "index": "21", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet88": { + "lanes": "16,17,18,19", + "alias": "Ethernet88", + "index": "22", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet92": { + "lanes": "0,1,2,3", + "alias": "Ethernet92", + "index": "23", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet96": { + "lanes": "256,257,258,259", + "alias": "Ethernet96", + "index": "24", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet100": { + "lanes": "8,9,10,11", + "alias": "Ethernet100", + "index": "25", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet104": { + "lanes": "1024,1025,1026,1027", + "alias": "Ethernet104", + "index": "26", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet108": { + "lanes": "768,769,770,771", + "alias": "Ethernet108", + "index": "27", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet112": { + "lanes": "524,525,526,527", + "alias": "Ethernet112", + "index": "28", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet116": { + "lanes": "776,777,778,779", + "alias": "Ethernet116", + "index": "29", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet120": { + "lanes": "516,517,518,519", + "alias": "Ethernet120", + "index": "30", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + }, + "Ethernet124": { + "lanes": "528,529,530,531", + "alias": "Ethernet124", + "index": "31", + "speed": "100000", + "admin_status": "up", + "mtu": "9100" + } + }, + "VRF": { + "Vrf1": {}, + "Vrf2": {} + }, + "LOOPBACK_INTERFACE": { + "Loopback0": {}, + "Loopback0|100.1.0.31/32": {}, + "Loopback0|2064:300::1f/128": {} + }, + "MGMT_INTERFACE": { + "eth0|10.250.0.53/24": { + "gwaddr": "10.250.0.1" + } + }, + "MGMT_PORT": { + "eth0": { + "admin_status": "up", + "alias": "eth0" + } + }, + "SRV6_LOCATOR": { + "lsid1": { + "argu_len": "48", + "block_len": "32", + "func_len": "32", + "node_len": "16", + "opcode_prefix": [ + "::fff3:3:0:0:0", + "::fff3:33:0:0:0" + ], + "opcode_act": [ + "end-dt46", + "end-dt46" + ], + "opcode_vrf": [ + "Vrf1", + "Vrf2" + ], + "prefix": "fd00:203:203::/48" + } + }, + "FLEX_COUNTER_TABLE": { + "ACL": { + "FLEX_COUNTER_STATUS": "disable", + "FLEX_COUNTER_DELAY_STATUS": "true", + "POLL_INTERVAL": "10000" + } + } +} diff --git a/ansible/vars/init_cfg_profiles.yml b/ansible/vars/init_cfg_profiles.yml new file mode 100644 index 00000000000..657ecd7dcb4 --- /dev/null +++ b/ansible/vars/init_cfg_profiles.yml @@ -0,0 +1,7 @@ +7nodes_cisco_PE1: vars/configdb_jsons/7nodes_cisco/PE1.json +7nodes_cisco_PE2: vars/configdb_jsons/7nodes_cisco/PE2.json +7nodes_cisco_PE3: vars/configdb_jsons/7nodes_cisco/PE3.json +7nodes_cisco_P1: vars/configdb_jsons/7nodes_cisco/P1.json +7nodes_cisco_P2: vars/configdb_jsons/7nodes_cisco/P2.json +7nodes_cisco_P3: vars/configdb_jsons/7nodes_cisco/P3.json +7nodes_cisco_P4: vars/configdb_jsons/7nodes_cisco/P4.json diff --git a/ansible/vars/topo_ciscovs-5nodes.yml b/ansible/vars/topo_ciscovs-5nodes.yml new file mode 100644 index 00000000000..05a17e0e831 --- /dev/null +++ b/ansible/vars/topo_ciscovs-5nodes.yml @@ -0,0 +1,211 @@ +topology: + host_interfaces: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 + - 16 + - 17 + - 18 + - 19 + - 20 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + - 27 + disabled_host_interfaces: + - 0 + - 25 + - 26 + - 27 + VMs: + P1: + vlans: + - 28 + vm_offset: 0 + P2: + vlans: + - 29 + vm_offset: 1 + P3: + vlans: + - 30 + vm_offset: 2 + P4: + vlans: + - 31 + vm_offset: 3 + DUT: + vlan_configs: + default_vlan_config: one_vlan_a + one_vlan_a: + Vlan1000: + id: 1000 + intfs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] + prefix: 192.168.0.1/21 + prefix_v6: fc02:1000::1/64 + tag: 1000 + two_vlan_a: + Vlan100: + id: 100 + intfs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + prefix: 192.168.0.1/22 + secondary_subnet: 192.169.0.1/22 + prefix_v6: fc02:100::1/64 + tag: 100 + Vlan200: + id: 200 + intfs: [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] + prefix: 192.168.4.1/22 + prefix_v6: fc02:200::1/64 + tag: 200 + four_vlan_a: + Vlan1000: + id: 1000 + intfs: [1, 2, 3, 4, 5, 6] + prefix: 192.168.0.1/23 + prefix_v6: fc02:400::1/64 + tag: 1000 + Vlan2000: + id: 2000 + intfs: [7, 8, 9, 10, 11, 12] + prefix: 192.168.2.1/23 + prefix_v6: fc02:401::1/64 + tag: 2000 + Vlan3000: + id: 3000 + intfs: [13, 14, 15, 16, 17, 18] + prefix: 192.168.4.1/23 + prefix_v6: fc02:402::1/64 + tag: 3000 + Vlan4000: + id: 4000 + intfs: [19, 20, 21, 22, 23, 24] + prefix: 192.168.6.1/23 + prefix_v6: fc02:403::1/64 + tag: 4000 + +configuration_properties: + common: + dut_asn: 65100 + dut_type: ToRRouter + swrole: leaf + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine_asn: 65534 + leaf_asn_start: 64600 + tor_asn_start: 65500 + failure_rate: 0 + +configuration: + P1: + properties: + - common + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.56 + - FC00::71 + interfaces: + Loopback0: + ipv4: 100.1.0.29/32 + ipv6: 2064:100::1d/128 + Ethernet0: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.57/31 + ipv6: fc00::72/126 + bp_interface: + ipv4: 10.10.246.29/24 + ipv6: fc0a::1d/64 + + P2: + properties: + - common + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.58 + - FC00::75 + interfaces: + Loopback0: + ipv4: 100.1.0.30/32 + ipv6: 2064:100::1e/128 + Ethernet0: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.59/31 + ipv6: fc00::76/126 + bp_interface: + ipv4: 10.10.246.30/24 + ipv6: fc0a::1e/64 + + P3: + properties: + - common + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.60 + - FC00::79 + interfaces: + Loopback0: + ipv4: 100.1.0.31/32 + ipv6: 2064:100::1f/128 + Ethernet0: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.61/31 + ipv6: fc00::7a/126 + bp_interface: + ipv4: 10.10.246.31/24 + ipv6: fc0a::1f/64 + + P4: + properties: + - common + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.62 + - FC00::7D + interfaces: + Loopback0: + ipv4: 100.1.0.32/32 + ipv6: 2064:100::20/128 + Ethernet0: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.63/31 + ipv6: fc00::7e/126 + bp_interface: + ipv4: 10.10.246.32/24 + ipv6: fc0a::20/64 diff --git a/ansible/vars/topo_ciscovs-7nodes.yml b/ansible/vars/topo_ciscovs-7nodes.yml new file mode 100644 index 00000000000..2f0a54f2b2a --- /dev/null +++ b/ansible/vars/topo_ciscovs-7nodes.yml @@ -0,0 +1,220 @@ +topology: + host_interfaces: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + - 27 + disabled_host_interfaces: + - 0 + - 25 + - 26 + - 27 + VMs: + PE1: + vlans: + - 28 + vm_offset: 0 + PE2: + vlans: + - 29 + vm_offset: 1 + PE3: + vlans: + - 30 + vm_offset: 2 + P3: + vlans: + - 31 + vm_offset: 3 + P2: + vlans: + - 16 + vm_offset: 4 + P4: + vlans: + - 17 + vm_offset: 5 + VM_LINKs: + PE1P3: + start_vm_offset: 0 + start_vm_port_idx: 1 + end_vm_offset: 3 + end_vm_port_idx: 1 + PE2P3: + start_vm_offset: 1 + start_vm_port_idx: 2 + end_vm_offset: 3 + end_vm_port_idx: 2 + P3P2: + start_vm_offset: 3 + start_vm_port_idx: 3 + end_vm_offset: 4 + end_vm_port_idx: 1 + P3P4: + start_vm_offset: 3 + start_vm_port_idx: 4 + end_vm_offset: 5 + end_vm_port_idx: 1 + P2P4: + start_vm_offset: 4 + start_vm_port_idx: 2 + end_vm_offset: 5 + end_vm_port_idx: 2 + OVS_LINKs: + P2PE3: + vlans: + - 39 + start_vm_offset: 4 + start_vm_port_idx: 3 + end_vm_offset: 2 + end_vm_port_idx: 1 + P4PE3: + vlans: + - 40 + start_vm_offset: 5 + start_vm_port_idx: 3 + end_vm_offset: 2 + end_vm_port_idx: 3 + DUT: + vlan_configs: + default_vlan_config: one_vlan_a + one_vlan_a: + Vlan1000: + id: 1000 + intfs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22, 23, 24] + prefix: 192.168.0.1/21 + prefix_v6: fc02:1000::1/64 + tag: 1000 + two_vlan_a: + Vlan100: + id: 100 + intfs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + prefix: 192.168.0.1/22 + prefix_v6: fc02:100::1/64 + tag: 100 + Vlan200: + id: 200 + intfs: [13, 14, 15, 21, 22, 23, 24] + prefix: 192.168.4.1/22 + prefix_v6: fc02:200::1/64 + tag: 200 + four_vlan_a: + Vlan1000: + id: 1000 + intfs: [1, 2, 3, 4, 5, 6] + prefix: 192.168.0.1/23 + prefix_v6: fc02:400::1/64 + tag: 1000 + Vlan2000: + id: 2000 + intfs: [7, 8, 9, 10, 11, 12] + prefix: 192.168.2.1/23 + prefix_v6: fc02:401::1/64 + tag: 2000 + Vlan3000: + id: 3000 + intfs: [13, 14, 15] + prefix: 192.168.4.1/23 + prefix_v6: fc02:402::1/64 + tag: 3000 + Vlan4000: + id: 4000 + intfs: [21, 22, 23, 24] + prefix: 192.168.6.1/23 + prefix_v6: fc02:403::1/64 + tag: 4000 + +configuration_properties: + common: + dut_asn: 65100 + dut_type: ToRRouter + swrole: leaf + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine_asn: 65534 + leaf_asn_start: 64600 + tor_asn_start: 65500 + failure_rate: 0 + +init_cfg_profile: 7nodes_cisco_P1 + +max_fp_num_provided : 6 + +configuration: + PE1: + init_cfg_profile: 7nodes_cisco_PE1 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64600 + bp_interface: + ipv4: 10.10.246.29/24 + ipv6: fc0a::29/64 + + PE2: + init_cfg_profile: 7nodes_cisco_PE2 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64601 + bp_interface: + ipv4: 10.10.246.30/24 + ipv6: fc0a::30/64 + + PE3: + init_cfg_profile: 7nodes_cisco_PE3 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64602 + bp_interface: + ipv4: 10.10.246.31/24 + ipv6: fc0a::31/64 + + P3: + init_cfg_profile: 7nodes_cisco_P3 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 65101 + bp_interface: + ipv4: 10.10.246.32/24 + ipv6: fc0a::20/64 + + P2: + init_cfg_profile: 7nodes_cisco_P2 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 65102 + bp_interface: + ipv4: 10.10.246.33/24 + ipv6: fc0a::21/64 + + P4: + init_cfg_profile: 7nodes_cisco_P4 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 65103 + bp_interface: + ipv4: 10.10.246.34/24 + ipv6: fc0a::22/64 diff --git a/ansible/veos_vtb b/ansible/veos_vtb index 81e5fb7892c..1539fea3d18 100644 --- a/ansible/veos_vtb +++ b/ansible/veos_vtb @@ -49,6 +49,8 @@ all: - wan-pub-isis - dpu - dpu-1 + - ciscovs-7nodes + - ciscovs-5nodes children: server_1: lab: @@ -69,6 +71,7 @@ all: vlab-t2-01: vlab-t2-02: vlab-t2-sup: + vlab-c-01: ptf: hosts: ptf-01: @@ -264,7 +267,16 @@ all: # sdk/npsuite override: #cisco_sdk_ver: "1.50.10.4.22" #cisco_npsuite_ver: "1.90.0" - + vlab-c-01: + ansible_host: 10.250.0.125 + ansible_hostv6: fec0::ffff:afb:8 + type: kvm + hwsku: cisco-8101-p4-32x100-vs + serial_port: 9025 + ansible_password: admin + ansible_user: admin + ansible_ssh_user: admin + ansible_altpassword: admin # The groups below are helpers to limit running playbooks to a specific server only server_1: diff --git a/ansible/vtestbed.csv b/ansible/vtestbed.csv index f04b8079e5a..d732fc4701a 100644 --- a/ansible/vtestbed.csv +++ b/ansible/vtestbed.csv @@ -13,3 +13,5 @@ vms-kvm-t0-4,vms6-7,t0,docker-ptf,ptf-07,10.250.0.118/24,fec0::ffff:afb:4/64,ser vms-kvm-dual-mixed,vms6-8,dualtor-mixed,docker-ptf,ptf-08,10.250.0.109/24,fec0::ffff:afa:9/64,server_1,VM0140,[vlab-11;vlab-12],veos_vtb,False,Dual-TOR-Mixed testbed vms-kvm-wan-pub,vms6-1,wan-pub,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-01],veos_vtb,'False',Tests virtual switch vm vms-kvm-dpu,vms6-1,dpu,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-01],veos_vtb,'False',Tests virtual switch vm as DPU +vms-kvm-ciscovs-7nodes,vms9-1,ciscovs-7nodes,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-c-01],veos_vtb,False,Tests virtual switch vm with 7 nodes +vms-kvm-ciscovs-5nodes,vms9-1,ciscovs-5nodes,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-c-01],veos_vtb,False,Tests mimic T0 topo with 5 nodes diff --git a/ansible/vtestbed.yaml b/ansible/vtestbed.yaml index 8be68705d5a..9af84127ed4 100644 --- a/ansible/vtestbed.yaml +++ b/ansible/vtestbed.yaml @@ -351,3 +351,33 @@ inv_name: veos_vtb auto_recover: 'False' comment: Tests virtual switch vm + +- conf-name: vms-kvm-ciscovs-7nodes + group-name: vms9-1 + topo: ciscovs-7nodes + ptf_image_name: docker-ptf + ptf: ptf-01 + ptf_ip: 10.250.0.102/24 + ptf_ipv6: fec0::ffff:afa:2/64 + server: server_1 + vm_base: VM0100 + dut: + - vlab-c-01 + inv_name: veos_vtb + auto_recover: 'False' + comment: Tests virtual cisco vs vm with 7 nodes + +- conf-name: vms-kvm-ciscovs-5nodes + group-name: vms9-1 + topo: ciscovs-5nodes + ptf_image_name: docker-ptf + ptf: ptf-01 + ptf_ip: 10.250.0.102/24 + ptf_ipv6: fec0::ffff:afa:2/64 + server: server_1 + vm_base: VM0100 + dut: + - vlab-c-01 + inv_name: veos_vtb + auto_recover: 'False' + comment: Tests virtual cisco vs vm with 5 nodes diff --git a/tests/common/testbed.py b/tests/common/testbed.py index d226603f513..16347f9c5b9 100644 --- a/tests/common/testbed.py +++ b/tests/common/testbed.py @@ -255,13 +255,15 @@ def _generate_sai_ptf_topo(self, tb_dict): return sai_topo def get_testbed_type(self, topo_name): - pattern = re.compile(r'^(wan|t0|t1|ptf|fullmesh|dualtor|t2|tgen|mgmttor|m0|mc0|mx|dpu|ptp)') + pattern = re.compile( + r'^(wan|t0|t1|ptf|fullmesh|dualtor|ciscovs|t2|tgen|mgmttor|m0|mc0|mx|dpu|ptp)' + ) match = pattern.match(topo_name) if match is None: logger.warning("Unsupported testbed type - {}".format(topo_name)) return "unsupported" tb_type = match.group() - if tb_type in ['mgmttor', 'dualtor']: + if tb_type in ['mgmttor', 'dualtor', 'ciscovs-7nodes', 'ciscovs-5nodes']: # certain testbed types are in 't0' category with different names. tb_type = 't0' if tb_type in ['mc0']: diff --git a/tests/srv6/srv6_utils.py b/tests/srv6/srv6_utils.py new file mode 100755 index 00000000000..b0219ffe18e --- /dev/null +++ b/tests/srv6/srv6_utils.py @@ -0,0 +1,103 @@ +import logging +import requests +from tests.common.helpers.assertions import pytest_assert + +logger = logging.getLogger(__name__) + + +# +# Helper func for print a set of lines +# +def print_lines(outlines): + for line in outlines: + logger.debug(line) + + +# +# Util functions for announce / withdraw routes from ptf docker. +# +def announce_route(ptfip, neighbor, route, nexthop, port): + change_route("announce", ptfip, neighbor, route, nexthop, port) + + +def withdraw_route(ptfip, neighbor, route, nexthop, port): + change_route("withdraw", ptfip, neighbor, route, nexthop, port) + + +def change_route(operation, ptfip, neighbor, route, nexthop, port): + url = "http://%s:%d" % (ptfip, port) + data = {"command": "neighbor %s %s route %s next-hop %s" % (neighbor, operation, route, nexthop)} + r = requests.post(url, data=data) + assert r.status_code == 200 + + +# +# Skip some BGP neighbor check +# +def skip_bgp_neighbor_check(neighbor): + skip_addresses = ['2064:100::1d', '2064:200::1e', '2064:300::1f'] + for addr in skip_addresses: + if neighbor == addr: + return True + + return False + + +# +# Helper func to check if a list of BGP neighbors are up +# +def check_bgp_neighbors_func(nbrhost, neighbors, vrf=""): + cmd = "vtysh -c 'show bgp summary'" + if vrf != "": + cmd = "vtysh -c 'show bgp vrf {} summary'".format(vrf) + res = nbrhost.command(cmd)["stdout_lines"] + found = 0 + for neighbor in neighbors: + if skip_bgp_neighbor_check(neighbor): + logger.debug("Skip {} check".format(neighbor)) + found = found + 1 + continue + + for line in res: + if neighbor in line: + arr = line.split() + pfxrcd = arr[9] + try: + int(pfxrcd) + found = found + 1 + logger.debug("{} ==> BGP neighbor is up and gets pfxrcd {}".format(line, pfxrcd)) + except ValueError: + logger.debug("{} ==> BGP neighbor state {}, not up".format(line, pfxrcd)) + return len(neighbors) == found + + +# +# Checke BGP neighbors +# +def check_bgp_neighbors(nbrhost, neighbors, vrf=""): + pytest_assert(check_bgp_neighbors_func(nbrhost, neighbors, vrf)) + + +# +# Helper function to count number of Ethernet interfaces +# +def find_node_interfaces(nbrhost): + cmd = "show version" + res = nbrhost.command(cmd)["stdout_lines"] + hwsku = "" + for line in res: + if "HwSKU:" in line: + logger.debug("{}".format(line)) + sarr = line.split() + hwsku = sarr[1] + break + + cmd = "show interface status" + res = nbrhost.command(cmd)["stdout_lines"] + found = 0 + for line in res: + logger.debug("{}".format(line)) + if "Ethernet" in line: + found = found + 1 + + return found, hwsku diff --git a/tests/srv6/test_srv6_basic_sanity.py b/tests/srv6/test_srv6_basic_sanity.py new file mode 100644 index 00000000000..ca5e7a98c0e --- /dev/null +++ b/tests/srv6/test_srv6_basic_sanity.py @@ -0,0 +1,128 @@ +import time +import logging +import pytest + +from tests.common.helpers.assertions import pytest_assert +from tests.common.utilities import wait_until + +from srv6_utils import announce_route +from srv6_utils import find_node_interfaces +from srv6_utils import check_bgp_neighbors +from srv6_utils import check_bgp_neighbors_func + +logger = logging.getLogger(__name__) + + +# +# Add --skip_sanity when running pytest to avoid current pytest use /etc/sonic/minigraph.xml +# The running option could be removed once the pytest sanity check is enhancemed on using +# this file. +# +pytestmark = [ + pytest.mark.disable_loganalyzer, # Disable automatic loganalyzer, since we use it for the test + pytest.mark.topology("any"), + pytest.mark.skip_check_dut_health +] + +test_vm_names = ["PE1", "PE2", "PE3", "P2", "P3", "P4"] + +# The number of routes published by each CE +num_ce_routes = 10 + + +# +# Initialize the testbed +# +def setup_config(duthosts, rand_one_dut_hostname, nbrhosts, ptfhost): + logger.info("Announce routes from CEs") + ptfip = ptfhost.mgmt_ip + nexthop = "10.10.246.254" + port_num = [5000, 5001, 5002] + + # Publish to PE1 + neighbor = "10.10.246.29" + # Publish to PE2 + neighbor2 = "10.10.246.30" + route_prefix_for_pe1_and_pe2 = "192.100.0" + for x in range(1, num_ce_routes+1): + route = "{}.{}/32".format(route_prefix_for_pe1_and_pe2, x) + announce_route(ptfip, neighbor, route, nexthop, port_num[0]) + announce_route(ptfip, neighbor2, route, nexthop, port_num[1]) + + # Publish to PE3 + neighbor = "10.10.246.31" + route_prefix_for_pe3 = "192.200.0" + for x in range(1, num_ce_routes+1): + route = "{}.{}/32".format(route_prefix_for_pe3, x) + announce_route(ptfip, neighbor, route, nexthop, port_num[2]) + + # sleep make sure all forwarding structures are settled down. + sleep_duration_after_annournce = 60 + time.sleep(sleep_duration_after_annournce) + logger.info( + "Sleep {} seconds to make sure all forwarding structures are " + "settled down".format(sleep_duration_after_annournce) + ) + + +# +# Testbed set up and tear down +# +@pytest.fixture(scope="module", autouse=True) +def srv6_config(duthosts, rand_one_dut_hostname, nbrhosts, ptfhost): + setup_config(duthosts, rand_one_dut_hostname, nbrhosts, ptfhost) + + +# +# Test case: check number of Ethnernet interfaces +# +def test_interface_on_each_node(duthosts, rand_one_dut_hostname, nbrhosts): + for vm_name in test_vm_names: + nbrhost = nbrhosts[vm_name]['host'] + num, hwsku = find_node_interfaces(nbrhost) + logger.debug("Get {} interfaces on {}, hwsku {}".format(num, vm_name, hwsku)) + if hwsku == "cisco-8101-p4-32x100-vs": + pytest_assert(num == 32) + + dut = duthosts[rand_one_dut_hostname] + num, hwsku = find_node_interfaces(dut) + logger.debug("Get {} interfaces on {}, hwsku {}".format(num, "dut", hwsku)) + if hwsku == "cisco-8101-p4-32x100-vs": + pytest_assert(num == 32) + + +# +# Test Case: Check BGP neighbors +# +def test_check_bgp_neighbors(duthosts, rand_one_dut_hostname, nbrhosts): + logger.info("Check BGP Neighbors") + # From PE3 + nbrhost = nbrhosts["PE3"]['host'] + pytest_assert( + wait_until( + 60, 10, 0, check_bgp_neighbors_func, nbrhost, + ['2064:100::1d', '2064:200::1e', 'fc06::2', 'fc08::2'] + ), + "wait for PE3 BGP neighbors up" + ) + check_bgp_neighbors(nbrhost, ['10.10.246.254'], "Vrf1") + # From PE1 + nbrhost = nbrhosts["PE1"]['host'] + check_bgp_neighbors(nbrhost, ['2064:300::1f', '2064:200::1e', 'fc00::71', 'fc02::2']) + check_bgp_neighbors(nbrhost, ['10.10.246.254'], "Vrf1") + # From PE2 + nbrhost = nbrhosts["PE2"]['host'] + check_bgp_neighbors(nbrhost, ['2064:300::1f', '2064:100::1d', 'fc00::75', 'fc03::2']) + check_bgp_neighbors(nbrhost, ['10.10.246.254'], "Vrf1") + # From P1 + dut = duthosts[rand_one_dut_hostname] + check_bgp_neighbors(dut, ['fc00::72', 'fc00::76', 'fc00::7e', 'fc01::85', 'fc00::81']) + # From P3 + nbrhost = nbrhosts["P3"]['host'] + check_bgp_neighbors(nbrhost, ['fc02::1', 'fc04::1', 'fc00::7d', 'fc03::1', 'fc09::1']) + # From P2 + nbrhost = nbrhosts["P2"]['host'] + check_bgp_neighbors(nbrhost, ['fc00::82', 'fc09::2', 'fc07::1', 'fc08::1']) + # From P4 + nbrhost = nbrhosts["P4"]['host'] + check_bgp_neighbors(nbrhost, ['fc01::86', 'fc04::2', 'fc07::2', 'fc06::1']) From 31112c0a2ab904342ef397c9c3053460ecb837c9 Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:22:33 +0800 Subject: [PATCH 050/221] [CI] Enhance elastictest template, use bash script instead of azcli task (#15300) What is the motivation for this PR? Enhance elastictest template, use bash script instead of azcli task, improve and fix azlogin and get token when requesting APIs. How did you do it? Enhance elastictest template, use bash script instead of azcli task. Improve and fix azlogin and get token when requesting APIs. Everytime get token to access Elastictest API, re-run azlogin and az get token. For test plan create/cancel, only call once. For test plan poll, first call once. Then during the polling, if token expired, response are not valid, then will call again to re-run azlogin. How did you verify/test it? Because PR test will download test_plan.py from master branch, so the change of test_plan.py will not work. Raised Draft PR to use the updated test_plan.py to test. #15316 Signed-off-by: Chun'ang Li --- .../run-test-elastictest-template.yml | 336 ++++++++---------- .azure-pipelines/test_plan.py | 315 ++++++++-------- 2 files changed, 300 insertions(+), 351 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 595a6cb3136..ebd09be86b2 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -184,206 +184,176 @@ steps: fi displayName: "Install azure-cli" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - - pip install PyYAML - - rm -f new_test_plan_id.txt - - python ./.azure-pipelines/test_plan.py create \ - -t ${{ parameters.TOPOLOGY }} \ - -o new_test_plan_id.txt \ - --min-worker ${{ parameters.MIN_WORKER }} \ - --max-worker ${{ parameters.MAX_WORKER }} \ - --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ - --test-set ${{ parameters.TEST_SET }} \ - --kvm-build-id $(KVM_BUILD_ID) \ - --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ - --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ - --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ - --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ - --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ - --image_url ${{ parameters.IMAGE_URL }} \ - --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ - --hwsku ${{ parameters.HWSKU }} \ - --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ - --platform ${{ parameters.PLATFORM }} \ - --testbed-name "${{ parameters.TESTBED_NAME }}" \ - --scripts "${{ parameters.SCRIPTS }}" \ - --features "${{ parameters.FEATURES }}" \ - --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ - --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ - --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ - --affinity='${{ parameters.AFFINITY }}' \ - --build-reason ${{ parameters.BUILD_REASON }} \ - --repo-name ${{ parameters.REPO_NAME }} \ - --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ - --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ - --retry-times ${{ parameters.RETRY_TIMES }} \ - --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ - --requester "${{ parameters.REQUESTER }}" \ - --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ - --test-plan-num ${{ parameters.TEST_PLAN_NUM }} - - TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo "Created test plan $TEST_PLAN_ID" - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - done - TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") - TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} - echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" + - script: | + set -e + + pip install PyYAML + + rm -f new_test_plan_id.txt + + python ./.azure-pipelines/test_plan.py create \ + -t ${{ parameters.TOPOLOGY }} \ + -o new_test_plan_id.txt \ + --min-worker ${{ parameters.MIN_WORKER }} \ + --max-worker ${{ parameters.MAX_WORKER }} \ + --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ + --test-set ${{ parameters.TEST_SET }} \ + --kvm-build-id $(KVM_BUILD_ID) \ + --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ + --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ + --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ + --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ + --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ + --image_url ${{ parameters.IMAGE_URL }} \ + --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ + --hwsku ${{ parameters.HWSKU }} \ + --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ + --platform ${{ parameters.PLATFORM }} \ + --testbed-name "${{ parameters.TESTBED_NAME }}" \ + --scripts "${{ parameters.SCRIPTS }}" \ + --features "${{ parameters.FEATURES }}" \ + --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ + --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ + --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ + --affinity='${{ parameters.AFFINITY }}' \ + --build-reason ${{ parameters.BUILD_REASON }} \ + --repo-name ${{ parameters.REPO_NAME }} \ + --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ + --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --retry-times ${{ parameters.RETRY_TIMES }} \ + --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ + --requester "${{ parameters.REQUESTER }}" \ + --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ + --test-plan-num ${{ parameters.TEST_PLAN_NUM }} + + TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo "Created test plan $TEST_PLAN_ID" + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + done + TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") + TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} + echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" displayName: "Trigger test" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Lock testbed" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" - echo "[test_plan.py] poll LOCK_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Lock testbed" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" + echo "[test_plan.py] poll LOCK_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Lock testbed" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Prepare testbed" - echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" - echo "[test_plan.py] poll PREPARE_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Prepare testbed" + echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" + echo "[test_plan.py] poll PREPARE_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Prepare testbed" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Run test" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" - echo "[test_plan.py] poll EXECUTING status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Run test" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" + echo "[test_plan.py] poll EXECUTING status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Run test" timeoutInMinutes: ${{ parameters.MAX_RUN_TEST_MINUTES }} - ${{ if eq(parameters.DUMP_KVM_IF_FAIL, 'True') }}: - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - echo "KVM dump" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" - echo "##[group][test_plan.py] poll KVMDUMP status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP - done + - script: | + set -e + echo "KVM dump" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" + echo "##[group][test_plan.py] poll KVMDUMP status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP + done condition: succeededOrFailed() displayName: "KVM dump" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID - done + - script: | + set -e + echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID + done condition: always() displayName: "Finalize running test plan" diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index f4b07bb2d18..961a8730a28 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -8,7 +8,7 @@ import subprocess import copy import time -from datetime import datetime, timedelta +from datetime import datetime, timezone import requests import yaml @@ -22,8 +22,7 @@ INTERNAL_SONIC_MGMT_REPO = "https://dev.azure.com/mssonic/internal/_git/sonic-mgmt-int" PR_TEST_SCRIPTS_FILE = "pr_test_scripts.yaml" SPECIFIC_PARAM_KEYWORD = "specific_param" -TOLERATE_HTTP_EXCEPTION_TIMES = 20 -TOKEN_EXPIRE_HOURS = 1 +MAX_POLL_RETRY_TIMES = 10 MAX_GET_TOKEN_RETRY_TIMES = 3 TEST_PLAN_STATUS_UNSUCCESSFUL_FINISHED = ["FAILED", "CANCELLED"] TEST_PLAN_STEP_STATUS_UNFINISHED = ["EXECUTING", None] @@ -83,13 +82,15 @@ def __init__(self, status): def get_status(self): return self.status.value - def print_logs(self, test_plan_id, resp_data, start_time): + def print_logs(self, test_plan_id, resp_data, expected_status, start_time): status = resp_data.get("status", None) current_status = test_plan_status_factory(status).get_status() if current_status == self.get_status(): - print("Test plan id: {}, status: {}, elapsed: {:.0f} seconds" - .format(test_plan_id, resp_data.get("status", None), time.time() - start_time)) + print( + f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " + f"expected_status: {expected_status}, elapsed: {time.time() - start_time:.0f} seconds" + ) class InitStatus(AbstractStatus): @@ -111,10 +112,12 @@ class ExecutingStatus(AbstractStatus): def __init__(self): super(ExecutingStatus, self).__init__(TestPlanStatus.EXECUTING) - def print_logs(self, test_plan_id, resp_data, start_time): - print("Test plan id: {}, status: {}, progress: {:.2f}%, elapsed: {:.0f} seconds" - .format(test_plan_id, resp_data.get("status", None), - resp_data.get("progress", 0) * 100, time.time() - start_time)) + def print_logs(self, test_plan_id, resp_data, expected_status, start_time): + print( + f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " + f"expected_status: {expected_status}, progress: {resp_data.get('progress', 0) * 100:.2f}%, " + f"elapsed: {time.time() - start_time:.0f} seconds" + ) class KvmDumpStatus(AbstractStatus): @@ -150,74 +153,81 @@ def parse_list_from_str(s): if single_str.strip()] +def run_cmd(cmd): + process = subprocess.Popen( + cmd.split(), + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + return_code = process.returncode + + if return_code != 0: + raise Exception(f'Command {cmd} execution failed, rc={return_code}, error={stderr}') + return stdout, stderr, return_code + + class TestPlanManager(object): - def __init__(self, scheduler_url, community_url, frontend_url, client_id=None): + def __init__(self, scheduler_url, frontend_url, client_id, managed_identity_id): self.scheduler_url = scheduler_url - self.community_url = community_url self.frontend_url = frontend_url self.client_id = client_id - self.with_auth = False - self._token = None - self._token_expires_on = None - if self.client_id: - self.with_auth = True - self.get_token() - - def cmd(self, cmds): - process = subprocess.Popen( - cmds, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - stdout, stderr = process.communicate() - return_code = process.returncode - - return stdout, stderr, return_code - - def az_run(self, cmd): - stdout, stderr, retcode = self.cmd(cmd.split()) - if retcode != 0: - raise Exception(f'Command {cmd} execution failed, rc={retcode}, error={stderr}') - return stdout, stderr, retcode + self.managed_identity_id = managed_identity_id def get_token(self): - token_is_valid = \ - self._token_expires_on is not None and \ - (self._token_expires_on - datetime.now()) > timedelta(hours=TOKEN_EXPIRE_HOURS) + # 1. Run az login with re-try + az_login_cmd = f"az login --identity --username {self.managed_identity_id}" + az_login_attempts = 0 + while az_login_attempts < MAX_GET_TOKEN_RETRY_TIMES: + try: + stdout, _, _ = run_cmd(az_login_cmd) + print(f"Az login successfully. Login time: {datetime.now(timezone.utc)}") + break + except Exception as exception: + az_login_attempts += 1 + print( + f"Failed to az login with exception: {repr(exception)}. " + f"Retry {MAX_GET_TOKEN_RETRY_TIMES - az_login_attempts} times to login." + ) - if self._token is not None and token_is_valid: - return self._token + # If az login failed, return with exception + if az_login_attempts >= MAX_GET_TOKEN_RETRY_TIMES: + raise Exception(f"Failed to az login after {MAX_GET_TOKEN_RETRY_TIMES} attempts.") - cmd = 'az account get-access-token --resource {}'.format(self.client_id) - attempt = 0 - while attempt < MAX_GET_TOKEN_RETRY_TIMES: + # 2. Get access token with re-try + get_token_cmd = f"az account get-access-token --resource {self.client_id}" + get_token_attempts = 0 + while get_token_attempts < MAX_GET_TOKEN_RETRY_TIMES: try: - stdout, _, _ = self.az_run(cmd) + stdout, _, _ = run_cmd(get_token_cmd) token = json.loads(stdout.decode("utf-8")) - self._token = token.get("accessToken", None) - if not self._token: - raise Exception("Parse token from stdout failed") + access_token = token.get("accessToken", None) + if not access_token: + raise Exception("Parse token from stdout failed, accessToken is None.") # Parse token expires time from string token_expires_on = token.get("expiresOn", "") - self._token_expires_on = datetime.strptime(token_expires_on, "%Y-%m-%d %H:%M:%S.%f") - print("Get token successfully.") - return self._token + if token_expires_on: + print(f"Get token successfully. Token will expire on {token_expires_on}.") + + return access_token except Exception as exception: - attempt += 1 - print("Failed to get token with exception: {}".format(repr(exception))) + get_token_attempts += 1 + print(f"Failed to get token with exception: {repr(exception)}.") - raise Exception("Failed to get token after {} attempts".format(MAX_GET_TOKEN_RETRY_TIMES)) + # If az get token failed, return with exception + if get_token_attempts >= MAX_GET_TOKEN_RETRY_TIMES: + raise Exception(f"Failed to get token after {MAX_GET_TOKEN_RETRY_TIMES} attempts") def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params="", kvm_build_id="", min_worker=None, max_worker=None, pr_id="unknown", output=None, common_extra_params="", **kwargs): - tp_url = "{}/test_plan".format(self.scheduler_url) + tp_url = f"{self.scheduler_url}/test_plan" testbed_name = parse_list_from_str(kwargs.get("testbed_name", None)) image_url = kwargs.get("image_url", None) hwsku = kwargs.get("hwsku", None) @@ -229,8 +239,10 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) - print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, - repo_name, pr_id, build_id)) + print( + f"Creating test plan, topology: {topology}, name: {test_plan_name}, " + f"build info:{repo_name} {pr_id} {build_id}" + ) print("Test scripts to be covered in this test plan:") print(json.dumps(scripts, indent=4)) @@ -320,10 +332,9 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "extra_params": {}, "priority": 10 } - print('Creating test plan with payload:\n{}'.format(json.dumps(payload, indent=4))) + print(f"Creating test plan with payload:\n{json.dumps(payload, indent=4)}") headers = { - "Authorization": "Bearer {}".format(self.get_token()), - "scheduler-site": "PRTest", + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } raw_resp = {} @@ -331,17 +342,16 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params raw_resp = requests.post(tp_url, headers=headers, data=json.dumps(payload), timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" - .format(tp_url, str(raw_resp), str(exception))) + raise Exception(f"HTTP execute failure, url: {tp_url}, raw_resp: {raw_resp}, exception: {str(exception)}") if not resp["data"]: - raise Exception("Pre deploy action failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Create test plan failed with error: {resp['errmsg']}") if not resp["success"]: - raise Exception("Create test plan failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Create test plan failed with error: {resp['errmsg']}") - print("Result of creating test plan: {}".format(str(resp["data"]))) + print(f"Result of creating test plan: {str(resp['data'])}") if output: - print("Store new test plan id to file {}".format(output)) + print(f"Store new test plan id to file {output}") with open(output, "a") as f: f.write(str(resp["data"]) + "\n") @@ -349,15 +359,14 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params def cancel(self, test_plan_id): - tp_url = "{}/test_plan/{}".format(self.scheduler_url, test_plan_id) - cancel_url = "{}/cancel".format(tp_url) + tp_url = f"{self.scheduler_url}/test_plan/{test_plan_id}" + cancel_url = f"{tp_url}/cancel" - print("Cancelling test plan at {}".format(cancel_url)) + print(f"Cancelling test plan at {cancel_url}") payload = json.dumps({}) headers = { - "Authorization": "Bearer {}".format(self.get_token()), - "scheduler-site": "PRTest", + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } @@ -366,73 +375,57 @@ def cancel(self, test_plan_id): raw_resp = requests.post(cancel_url, headers=headers, data=payload, timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" - .format(cancel_url, str(raw_resp), str(exception))) + raise Exception(f"HTTP execute failure, url: {cancel_url}, raw_resp: {str(raw_resp)}, " + f"exception: {str(exception)}") if not resp["success"]: - raise Exception("Cancel test plan failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Cancel test plan failed with error: {resp['errmsg']}") - print("Result of cancelling test plan at {}:".format(tp_url)) + print(f"Result of cancelling test plan at {tp_url}:") print(str(resp["data"])) def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expected_result=None): - print("Polling progress and status of test plan at {}/scheduler/testplan/{}" - .format(self.frontend_url, test_plan_id)) - print("Polling interval: {} seconds".format(interval)) + print(f"Polling progress and status of test plan at {self.frontend_url}/scheduler/testplan/{test_plan_id}") + print(f"Polling interval: {interval} seconds") - poll_url = "{}/test_plan/{}/get_test_plan_status".format(self.scheduler_url, test_plan_id) - poll_url_no_auth = "{}/get_test_plan_status/{}".format(self.community_url, test_plan_id) + poll_url = f"{self.scheduler_url}/test_plan/{test_plan_id}/get_test_plan_status" + # In current polling task, initialize headers one time to avoid frequent token accessing + # For some tasks running over 24h, then token may expire, need a fresh headers = { + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } start_time = time.time() - http_exception_times = 0 - http_exception_times_no_auth = 0 - failed_poll_auth_url = False + poll_retry_times = 0 while timeout < 0 or (time.time() - start_time) < timeout: resp = None - # To make the transition smoother, first try to access the original API - if not failed_poll_auth_url: - try: - if self.with_auth: - headers["Authorization"] = "Bearer {}".format(self.get_token()) - resp = requests.get(poll_url, headers=headers, timeout=10).json() - except Exception as exception: - print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url, resp, - str(exception))) - http_exception_times = http_exception_times + 1 - if http_exception_times >= TOLERATE_HTTP_EXCEPTION_TIMES: - failed_poll_auth_url = True - else: - time.sleep(interval) - continue - - # If failed on poll auth url(most likely token has expired), try with no-auth url - else: - print("Polling test plan status failed with auth url, try with no-auth url.") - try: - resp = requests.get(poll_url_no_auth, headers={"Content-Type": "application/json"}, - timeout=10).json() - except Exception as e: - print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, - repr(e))) - http_exception_times_no_auth = http_exception_times_no_auth + 1 - if http_exception_times_no_auth >= TOLERATE_HTTP_EXCEPTION_TIMES: - raise Exception( - "HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, - repr(e))) - else: - time.sleep(interval) - continue + try: + resp = requests.get(poll_url, headers=headers, timeout=10).json() + + if not resp: + raise Exception("Poll test plan status failed with request error, no response!") + + if not resp["success"]: + raise Exception(f"Get test plan status failed with error: {resp['errmsg']}") + + resp_data = resp.get("data", None) + if not resp_data: + raise Exception("No valid data in response.") - if not resp: - raise Exception("Poll test plan status failed with request error, no response!") + except Exception as exception: + print(f"Failed to get valid response, url: {poll_url}, raw_resp: {resp}, exception: {str(exception)}") - if not resp["success"]: - raise Exception("Query test plan at {} failed with error: {}".format(poll_url, resp["errmsg"])) + # Refresh headers token to address token expiration issue + headers = { + "Authorization": f"Bearer {self.get_token()}", + "Content-Type": "application/json" + } - resp_data = resp.get("data", None) - if not resp_data: - raise Exception("No valid data in response: {}".format(str(resp))) + poll_retry_times = poll_retry_times + 1 + if poll_retry_times >= MAX_POLL_RETRY_TIMES: + raise Exception("Poll test plan status failed, exceeded the maximum number of retries.") + else: + time.sleep(interval) + continue current_tp_status = resp_data.get("status", None) current_tp_result = resp_data.get("result", None) @@ -441,11 +434,10 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte current_status = test_plan_status_factory(current_tp_status) expected_status = test_plan_status_factory(expected_state) - print("current test plan status: {}, expected status: {}".format(current_tp_status, expected_state)) + current_status.print_logs(test_plan_id, resp_data, expected_state, start_time) - if expected_status.get_status() == current_status.get_status(): - current_status.print_logs(test_plan_id, resp_data, start_time) - elif expected_status.get_status() < current_status.get_status(): + # If test plan has finished current step, its now status will behind the expected status + if expected_status.get_status() < current_status.get_status(): steps = None step_status = None runtime = resp_data.get("runtime", None) @@ -460,7 +452,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print test summary test_summary = resp_data.get("runtime", {}).get("test_summary", None) if test_summary: - print("Test summary:\n{}".format(json.dumps(test_summary, indent=4))) + print(f"Test summary:\n{json.dumps(test_summary, indent=4)}") """ In below scenarios, need to return false to pipeline. @@ -477,38 +469,34 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print error type and message err_code = resp_data.get("runtime", {}).get("err_code", None) if err_code: - print("Error type: {}".format(err_code)) + print(f"Error type: {err_code}") err_msg = resp_data.get("runtime", {}).get("message", None) if err_msg: - print("Error message: {}".format(err_msg)) + print(f"Error message: {err_msg}") - raise Exception("Test plan id: {}, status: {}, result: {}, Elapsed {:.0f} seconds. " - "Check {}/scheduler/testplan/{} for test plan status" - .format(test_plan_id, step_status, current_tp_result, time.time() - start_time, - self.frontend_url, - test_plan_id)) + raise Exception( + f"Test plan id: {test_plan_id}, status: {step_status}, " + f"result: {current_tp_result}, Elapsed {time.time() - start_time:.0f} seconds. " + f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" + ) if expected_result: if current_tp_result != expected_result: - raise Exception("Test plan id: {}, status: {}, result: {} not match expected result: {}, " - "Elapsed {:.0f} seconds. " - "Check {}/scheduler/testplan/{} for test plan status" - .format(test_plan_id, step_status, current_tp_result, - expected_result, time.time() - start_time, - self.frontend_url, - test_plan_id)) - - print("Current step status is {}".format(step_status)) + raise Exception( + f"Test plan id: {test_plan_id}, status: {step_status}, " + f"result: {current_tp_result} not match expected result: {expected_result}, " + f"Elapsed {time.time() - start_time:.0f} seconds. " + f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" + ) + + print(f"Current step status is {step_status}.") return - else: - print("Current test plan state is {}, waiting for the expected state {}".format(current_tp_status, - expected_state)) time.sleep(interval) else: raise PollTimeoutException( - "Max polling time reached, test plan at {} is not successfully finished or cancelled".format(poll_url) + f"Max polling time reached, test plan at {poll_url} is not successfully finished or cancelled" ) @@ -930,30 +918,28 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # https://github.com/microsoft/azure-pipelines-tasks/issues/10331 args.test_plan_id = args.test_plan_id.replace("'", "") - print("Test plan utils parameters: {}".format(args)) - auth_env = ["CLIENT_ID"] - required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL"] + print(f"Test plan utils parameters: {args}") - if args.action in ["create", "cancel"]: - required_env.extend(auth_env) + required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL", "CLIENT_ID", "MANAGED_IDENTITY_ID"] env = { "elastictest_scheduler_backend_url": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), - "elastictest_community_url": os.environ.get("ELASTICTEST_COMMUNITY_URL"), "client_id": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), "frontend_url": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), + "managed_identity_id": os.environ.get("SONIC_AUTOMATION_UMI"), } env_missing = [k.upper() for k, v in env.items() if k.upper() in required_env and not v] if env_missing: - print("Missing required environment variables: {}".format(env_missing)) + print(f"Missing required environment variables: {env_missing}") sys.exit(1) try: tp = TestPlanManager( env["elastictest_scheduler_backend_url"], - env["elastictest_community_url"], env["frontend_url"], - env["client_id"]) + env["client_id"], + env["managed_identity_id"] + ) if args.action == "create": pr_id = os.environ.get("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") or os.environ.get( @@ -964,14 +950,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte job_name = os.environ.get("SYSTEM_JOBDISPLAYNAME") repo_name = args.repo_name if args.repo_name else os.environ.get("BUILD_REPOSITORY_NAME") - test_plan_prefix = "{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}" \ - .format( - repo=repo, - reason=reason, - pr_id=pr_id, - build_id=build_id, - job_name=job_name - ).replace(' ', '_') + test_plan_prefix = f"{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}".replace(' ', '_') scripts = args.scripts specific_param = json.loads(args.specific_param) @@ -989,7 +968,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte for num in range(args.test_plan_num): test_plan_name = copy.copy(test_plan_prefix) if args.test_plan_num > 1: - test_plan_name = "{}_{}".format(test_plan_name, num + 1) + test_plan_name = f"{test_plan_name}_{num + 1}" tp.create( args.topology, @@ -1033,8 +1012,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte tp.cancel(args.test_plan_id) sys.exit(0) except PollTimeoutException as e: - print("Polling test plan failed with exception: {}".format(repr(e))) + print(f"Polling test plan failed with exception: {repr(e)}") sys.exit(2) except Exception as e: - print("Operation failed with exception: {}".format(repr(e))) + print(f"Operation failed with exception: {repr(e)}") sys.exit(3) From 27815402f3ef11980f1832b7c83604ad32340d31 Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:24:28 +0800 Subject: [PATCH 051/221] [dualtor-aa] Fix arp flux of soc IPs (#15266) If the test server is Ubuntu 22.04, SoC IP ARP flux is observed on the DUTs for dualtor-aa testbed. Let's enable `arp_filter` to prevent this. Signed-off-by: Longxiang Lyu --- ansible/roles/vm_set/library/vm_topology.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ansible/roles/vm_set/library/vm_topology.py b/ansible/roles/vm_set/library/vm_topology.py index 80ae1f69cd4..7c35917144b 100644 --- a/ansible/roles/vm_set/library/vm_topology.py +++ b/ansible/roles/vm_set/library/vm_topology.py @@ -396,6 +396,10 @@ def delete_network_namespace(self): if os.path.exists("/var/run/netns/%s" % self.netns): VMTopology.cmd("ip netns delete %s" % self.netns) + def enable_arp_filter_netns(self): + """ENable ARP filter in the netns.""" + VMTopology.cmd("ip netns exec %s sysctl -w net.ipv4.conf.all.arp_filter=1" % self.netns) + def add_mgmt_port_to_netns(self, mgmt_bridge, mgmt_ip, mgmt_gw, mgmt_ipv6_addr=None, mgmt_gw_v6=None): if VMTopology.intf_not_exists(MGMT_PORT_NAME, netns=self.netns): self.add_br_if_to_netns( @@ -1989,6 +1993,9 @@ def main(): if net.netns: net.add_network_namespace() + # Let's enable arp_filter in the netns + # to prevent arp flux + net.enable_arp_filter_netns() net.add_mgmt_port_to_netns( mgmt_bridge, netns_mgmt_ip_addr, ptf_mgmt_ip_gw) net.enable_netns_loopback() @@ -2135,6 +2142,9 @@ def main(): if net.netns: net.add_network_namespace() + # Let's enable arp_filter in the netns + # to prevent arp flux + net.enable_arp_filter_netns() net.add_mgmt_port_to_netns( mgmt_bridge, netns_mgmt_ip_addr, ptf_mgmt_ip_gw) net.enable_netns_loopback() From 4d6500668435a9788a0109966c7fdaa5d52b96c2 Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Mon, 4 Nov 2024 13:19:16 +0800 Subject: [PATCH 052/221] =?UTF-8?q?Revert=20"[CI]=20Enhance=20elastictest?= =?UTF-8?q?=20template,=20use=20bash=20script=20instead=20of=20azcli=20t?= =?UTF-8?q?=E2=80=A6"=20(#15339)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 31112c0a2ab904342ef397c9c3053460ecb837c9. Creating test plan failed. Revert this change. --- .../run-test-elastictest-template.yml | 336 ++++++++++-------- .azure-pipelines/test_plan.py | 315 ++++++++-------- 2 files changed, 351 insertions(+), 300 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index ebd09be86b2..595a6cb3136 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -184,176 +184,206 @@ steps: fi displayName: "Install azure-cli" - - script: | - set -e - - pip install PyYAML - - rm -f new_test_plan_id.txt - - python ./.azure-pipelines/test_plan.py create \ - -t ${{ parameters.TOPOLOGY }} \ - -o new_test_plan_id.txt \ - --min-worker ${{ parameters.MIN_WORKER }} \ - --max-worker ${{ parameters.MAX_WORKER }} \ - --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ - --test-set ${{ parameters.TEST_SET }} \ - --kvm-build-id $(KVM_BUILD_ID) \ - --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ - --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ - --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ - --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ - --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ - --image_url ${{ parameters.IMAGE_URL }} \ - --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ - --hwsku ${{ parameters.HWSKU }} \ - --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ - --platform ${{ parameters.PLATFORM }} \ - --testbed-name "${{ parameters.TESTBED_NAME }}" \ - --scripts "${{ parameters.SCRIPTS }}" \ - --features "${{ parameters.FEATURES }}" \ - --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ - --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ - --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ - --affinity='${{ parameters.AFFINITY }}' \ - --build-reason ${{ parameters.BUILD_REASON }} \ - --repo-name ${{ parameters.REPO_NAME }} \ - --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ - --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ - --retry-times ${{ parameters.RETRY_TIMES }} \ - --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ - --requester "${{ parameters.REQUESTER }}" \ - --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ - --test-plan-num ${{ parameters.TEST_PLAN_NUM }} - - TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo "Created test plan $TEST_PLAN_ID" - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - done - TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") - TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} - echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + + pip install PyYAML + + rm -f new_test_plan_id.txt + + python ./.azure-pipelines/test_plan.py create \ + -t ${{ parameters.TOPOLOGY }} \ + -o new_test_plan_id.txt \ + --min-worker ${{ parameters.MIN_WORKER }} \ + --max-worker ${{ parameters.MAX_WORKER }} \ + --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ + --test-set ${{ parameters.TEST_SET }} \ + --kvm-build-id $(KVM_BUILD_ID) \ + --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ + --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ + --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ + --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ + --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ + --image_url ${{ parameters.IMAGE_URL }} \ + --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ + --hwsku ${{ parameters.HWSKU }} \ + --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ + --platform ${{ parameters.PLATFORM }} \ + --testbed-name "${{ parameters.TESTBED_NAME }}" \ + --scripts "${{ parameters.SCRIPTS }}" \ + --features "${{ parameters.FEATURES }}" \ + --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ + --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ + --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ + --affinity='${{ parameters.AFFINITY }}' \ + --build-reason ${{ parameters.BUILD_REASON }} \ + --repo-name ${{ parameters.REPO_NAME }} \ + --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ + --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --retry-times ${{ parameters.RETRY_TIMES }} \ + --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ + --requester "${{ parameters.REQUESTER }}" \ + --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ + --test-plan-num ${{ parameters.TEST_PLAN_NUM }} + + TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo "Created test plan $TEST_PLAN_ID" + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + done + TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") + TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} + echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" displayName: "Trigger test" - - script: | - set -o - echo "Lock testbed" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" - echo "[test_plan.py] poll LOCK_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Lock testbed" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" + echo "[test_plan.py] poll LOCK_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Lock testbed" - - script: | - set -o - echo "Prepare testbed" - echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" - echo "[test_plan.py] poll PREPARE_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Prepare testbed" + echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" + echo "[test_plan.py] poll PREPARE_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Prepare testbed" - - script: | - set -o - echo "Run test" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" - echo "[test_plan.py] poll EXECUTING status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Run test" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" + echo "[test_plan.py] poll EXECUTING status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Run test" timeoutInMinutes: ${{ parameters.MAX_RUN_TEST_MINUTES }} - ${{ if eq(parameters.DUMP_KVM_IF_FAIL, 'True') }}: - - script: | - set -e - echo "KVM dump" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" - echo "##[group][test_plan.py] poll KVMDUMP status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP - done + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + echo "KVM dump" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" + echo "##[group][test_plan.py] poll KVMDUMP status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP + done condition: succeededOrFailed() displayName: "KVM dump" - - script: | - set -e - echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID - done + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID + done condition: always() displayName: "Finalize running test plan" diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index 961a8730a28..f4b07bb2d18 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -8,7 +8,7 @@ import subprocess import copy import time -from datetime import datetime, timezone +from datetime import datetime, timedelta import requests import yaml @@ -22,7 +22,8 @@ INTERNAL_SONIC_MGMT_REPO = "https://dev.azure.com/mssonic/internal/_git/sonic-mgmt-int" PR_TEST_SCRIPTS_FILE = "pr_test_scripts.yaml" SPECIFIC_PARAM_KEYWORD = "specific_param" -MAX_POLL_RETRY_TIMES = 10 +TOLERATE_HTTP_EXCEPTION_TIMES = 20 +TOKEN_EXPIRE_HOURS = 1 MAX_GET_TOKEN_RETRY_TIMES = 3 TEST_PLAN_STATUS_UNSUCCESSFUL_FINISHED = ["FAILED", "CANCELLED"] TEST_PLAN_STEP_STATUS_UNFINISHED = ["EXECUTING", None] @@ -82,15 +83,13 @@ def __init__(self, status): def get_status(self): return self.status.value - def print_logs(self, test_plan_id, resp_data, expected_status, start_time): + def print_logs(self, test_plan_id, resp_data, start_time): status = resp_data.get("status", None) current_status = test_plan_status_factory(status).get_status() if current_status == self.get_status(): - print( - f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " - f"expected_status: {expected_status}, elapsed: {time.time() - start_time:.0f} seconds" - ) + print("Test plan id: {}, status: {}, elapsed: {:.0f} seconds" + .format(test_plan_id, resp_data.get("status", None), time.time() - start_time)) class InitStatus(AbstractStatus): @@ -112,12 +111,10 @@ class ExecutingStatus(AbstractStatus): def __init__(self): super(ExecutingStatus, self).__init__(TestPlanStatus.EXECUTING) - def print_logs(self, test_plan_id, resp_data, expected_status, start_time): - print( - f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " - f"expected_status: {expected_status}, progress: {resp_data.get('progress', 0) * 100:.2f}%, " - f"elapsed: {time.time() - start_time:.0f} seconds" - ) + def print_logs(self, test_plan_id, resp_data, start_time): + print("Test plan id: {}, status: {}, progress: {:.2f}%, elapsed: {:.0f} seconds" + .format(test_plan_id, resp_data.get("status", None), + resp_data.get("progress", 0) * 100, time.time() - start_time)) class KvmDumpStatus(AbstractStatus): @@ -153,81 +150,74 @@ def parse_list_from_str(s): if single_str.strip()] -def run_cmd(cmd): - process = subprocess.Popen( - cmd.split(), - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - stdout, stderr = process.communicate() - return_code = process.returncode - - if return_code != 0: - raise Exception(f'Command {cmd} execution failed, rc={return_code}, error={stderr}') - return stdout, stderr, return_code - - class TestPlanManager(object): - def __init__(self, scheduler_url, frontend_url, client_id, managed_identity_id): + def __init__(self, scheduler_url, community_url, frontend_url, client_id=None): self.scheduler_url = scheduler_url + self.community_url = community_url self.frontend_url = frontend_url self.client_id = client_id - self.managed_identity_id = managed_identity_id + self.with_auth = False + self._token = None + self._token_expires_on = None + if self.client_id: + self.with_auth = True + self.get_token() + + def cmd(self, cmds): + process = subprocess.Popen( + cmds, + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + return_code = process.returncode + + return stdout, stderr, return_code + + def az_run(self, cmd): + stdout, stderr, retcode = self.cmd(cmd.split()) + if retcode != 0: + raise Exception(f'Command {cmd} execution failed, rc={retcode}, error={stderr}') + return stdout, stderr, retcode def get_token(self): - # 1. Run az login with re-try - az_login_cmd = f"az login --identity --username {self.managed_identity_id}" - az_login_attempts = 0 - while az_login_attempts < MAX_GET_TOKEN_RETRY_TIMES: - try: - stdout, _, _ = run_cmd(az_login_cmd) - print(f"Az login successfully. Login time: {datetime.now(timezone.utc)}") - break - except Exception as exception: - az_login_attempts += 1 - print( - f"Failed to az login with exception: {repr(exception)}. " - f"Retry {MAX_GET_TOKEN_RETRY_TIMES - az_login_attempts} times to login." - ) + token_is_valid = \ + self._token_expires_on is not None and \ + (self._token_expires_on - datetime.now()) > timedelta(hours=TOKEN_EXPIRE_HOURS) - # If az login failed, return with exception - if az_login_attempts >= MAX_GET_TOKEN_RETRY_TIMES: - raise Exception(f"Failed to az login after {MAX_GET_TOKEN_RETRY_TIMES} attempts.") + if self._token is not None and token_is_valid: + return self._token - # 2. Get access token with re-try - get_token_cmd = f"az account get-access-token --resource {self.client_id}" - get_token_attempts = 0 - while get_token_attempts < MAX_GET_TOKEN_RETRY_TIMES: + cmd = 'az account get-access-token --resource {}'.format(self.client_id) + attempt = 0 + while attempt < MAX_GET_TOKEN_RETRY_TIMES: try: - stdout, _, _ = run_cmd(get_token_cmd) + stdout, _, _ = self.az_run(cmd) token = json.loads(stdout.decode("utf-8")) - access_token = token.get("accessToken", None) - if not access_token: - raise Exception("Parse token from stdout failed, accessToken is None.") + self._token = token.get("accessToken", None) + if not self._token: + raise Exception("Parse token from stdout failed") # Parse token expires time from string token_expires_on = token.get("expiresOn", "") - if token_expires_on: - print(f"Get token successfully. Token will expire on {token_expires_on}.") - - return access_token + self._token_expires_on = datetime.strptime(token_expires_on, "%Y-%m-%d %H:%M:%S.%f") + print("Get token successfully.") + return self._token except Exception as exception: - get_token_attempts += 1 - print(f"Failed to get token with exception: {repr(exception)}.") + attempt += 1 + print("Failed to get token with exception: {}".format(repr(exception))) - # If az get token failed, return with exception - if get_token_attempts >= MAX_GET_TOKEN_RETRY_TIMES: - raise Exception(f"Failed to get token after {MAX_GET_TOKEN_RETRY_TIMES} attempts") + raise Exception("Failed to get token after {} attempts".format(MAX_GET_TOKEN_RETRY_TIMES)) def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params="", kvm_build_id="", min_worker=None, max_worker=None, pr_id="unknown", output=None, common_extra_params="", **kwargs): - tp_url = f"{self.scheduler_url}/test_plan" + tp_url = "{}/test_plan".format(self.scheduler_url) testbed_name = parse_list_from_str(kwargs.get("testbed_name", None)) image_url = kwargs.get("image_url", None) hwsku = kwargs.get("hwsku", None) @@ -239,10 +229,8 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) - print( - f"Creating test plan, topology: {topology}, name: {test_plan_name}, " - f"build info:{repo_name} {pr_id} {build_id}" - ) + print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, + repo_name, pr_id, build_id)) print("Test scripts to be covered in this test plan:") print(json.dumps(scripts, indent=4)) @@ -332,9 +320,10 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "extra_params": {}, "priority": 10 } - print(f"Creating test plan with payload:\n{json.dumps(payload, indent=4)}") + print('Creating test plan with payload:\n{}'.format(json.dumps(payload, indent=4))) headers = { - "Authorization": f"Bearer {self.get_token()}", + "Authorization": "Bearer {}".format(self.get_token()), + "scheduler-site": "PRTest", "Content-Type": "application/json" } raw_resp = {} @@ -342,16 +331,17 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params raw_resp = requests.post(tp_url, headers=headers, data=json.dumps(payload), timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception(f"HTTP execute failure, url: {tp_url}, raw_resp: {raw_resp}, exception: {str(exception)}") + raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" + .format(tp_url, str(raw_resp), str(exception))) if not resp["data"]: - raise Exception(f"Create test plan failed with error: {resp['errmsg']}") + raise Exception("Pre deploy action failed with error: {}".format(resp["errmsg"])) if not resp["success"]: - raise Exception(f"Create test plan failed with error: {resp['errmsg']}") + raise Exception("Create test plan failed with error: {}".format(resp["errmsg"])) - print(f"Result of creating test plan: {str(resp['data'])}") + print("Result of creating test plan: {}".format(str(resp["data"]))) if output: - print(f"Store new test plan id to file {output}") + print("Store new test plan id to file {}".format(output)) with open(output, "a") as f: f.write(str(resp["data"]) + "\n") @@ -359,14 +349,15 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params def cancel(self, test_plan_id): - tp_url = f"{self.scheduler_url}/test_plan/{test_plan_id}" - cancel_url = f"{tp_url}/cancel" + tp_url = "{}/test_plan/{}".format(self.scheduler_url, test_plan_id) + cancel_url = "{}/cancel".format(tp_url) - print(f"Cancelling test plan at {cancel_url}") + print("Cancelling test plan at {}".format(cancel_url)) payload = json.dumps({}) headers = { - "Authorization": f"Bearer {self.get_token()}", + "Authorization": "Bearer {}".format(self.get_token()), + "scheduler-site": "PRTest", "Content-Type": "application/json" } @@ -375,57 +366,73 @@ def cancel(self, test_plan_id): raw_resp = requests.post(cancel_url, headers=headers, data=payload, timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception(f"HTTP execute failure, url: {cancel_url}, raw_resp: {str(raw_resp)}, " - f"exception: {str(exception)}") + raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" + .format(cancel_url, str(raw_resp), str(exception))) if not resp["success"]: - raise Exception(f"Cancel test plan failed with error: {resp['errmsg']}") + raise Exception("Cancel test plan failed with error: {}".format(resp["errmsg"])) - print(f"Result of cancelling test plan at {tp_url}:") + print("Result of cancelling test plan at {}:".format(tp_url)) print(str(resp["data"])) def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expected_result=None): - print(f"Polling progress and status of test plan at {self.frontend_url}/scheduler/testplan/{test_plan_id}") - print(f"Polling interval: {interval} seconds") + print("Polling progress and status of test plan at {}/scheduler/testplan/{}" + .format(self.frontend_url, test_plan_id)) + print("Polling interval: {} seconds".format(interval)) - poll_url = f"{self.scheduler_url}/test_plan/{test_plan_id}/get_test_plan_status" - # In current polling task, initialize headers one time to avoid frequent token accessing - # For some tasks running over 24h, then token may expire, need a fresh + poll_url = "{}/test_plan/{}/get_test_plan_status".format(self.scheduler_url, test_plan_id) + poll_url_no_auth = "{}/get_test_plan_status/{}".format(self.community_url, test_plan_id) headers = { - "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } start_time = time.time() - poll_retry_times = 0 + http_exception_times = 0 + http_exception_times_no_auth = 0 + failed_poll_auth_url = False while timeout < 0 or (time.time() - start_time) < timeout: resp = None - try: - resp = requests.get(poll_url, headers=headers, timeout=10).json() - - if not resp: - raise Exception("Poll test plan status failed with request error, no response!") - - if not resp["success"]: - raise Exception(f"Get test plan status failed with error: {resp['errmsg']}") - - resp_data = resp.get("data", None) - if not resp_data: - raise Exception("No valid data in response.") + # To make the transition smoother, first try to access the original API + if not failed_poll_auth_url: + try: + if self.with_auth: + headers["Authorization"] = "Bearer {}".format(self.get_token()) + resp = requests.get(poll_url, headers=headers, timeout=10).json() + except Exception as exception: + print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url, resp, + str(exception))) + http_exception_times = http_exception_times + 1 + if http_exception_times >= TOLERATE_HTTP_EXCEPTION_TIMES: + failed_poll_auth_url = True + else: + time.sleep(interval) + continue + + # If failed on poll auth url(most likely token has expired), try with no-auth url + else: + print("Polling test plan status failed with auth url, try with no-auth url.") + try: + resp = requests.get(poll_url_no_auth, headers={"Content-Type": "application/json"}, + timeout=10).json() + except Exception as e: + print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, + repr(e))) + http_exception_times_no_auth = http_exception_times_no_auth + 1 + if http_exception_times_no_auth >= TOLERATE_HTTP_EXCEPTION_TIMES: + raise Exception( + "HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, + repr(e))) + else: + time.sleep(interval) + continue - except Exception as exception: - print(f"Failed to get valid response, url: {poll_url}, raw_resp: {resp}, exception: {str(exception)}") + if not resp: + raise Exception("Poll test plan status failed with request error, no response!") - # Refresh headers token to address token expiration issue - headers = { - "Authorization": f"Bearer {self.get_token()}", - "Content-Type": "application/json" - } + if not resp["success"]: + raise Exception("Query test plan at {} failed with error: {}".format(poll_url, resp["errmsg"])) - poll_retry_times = poll_retry_times + 1 - if poll_retry_times >= MAX_POLL_RETRY_TIMES: - raise Exception("Poll test plan status failed, exceeded the maximum number of retries.") - else: - time.sleep(interval) - continue + resp_data = resp.get("data", None) + if not resp_data: + raise Exception("No valid data in response: {}".format(str(resp))) current_tp_status = resp_data.get("status", None) current_tp_result = resp_data.get("result", None) @@ -434,10 +441,11 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte current_status = test_plan_status_factory(current_tp_status) expected_status = test_plan_status_factory(expected_state) - current_status.print_logs(test_plan_id, resp_data, expected_state, start_time) + print("current test plan status: {}, expected status: {}".format(current_tp_status, expected_state)) - # If test plan has finished current step, its now status will behind the expected status - if expected_status.get_status() < current_status.get_status(): + if expected_status.get_status() == current_status.get_status(): + current_status.print_logs(test_plan_id, resp_data, start_time) + elif expected_status.get_status() < current_status.get_status(): steps = None step_status = None runtime = resp_data.get("runtime", None) @@ -452,7 +460,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print test summary test_summary = resp_data.get("runtime", {}).get("test_summary", None) if test_summary: - print(f"Test summary:\n{json.dumps(test_summary, indent=4)}") + print("Test summary:\n{}".format(json.dumps(test_summary, indent=4))) """ In below scenarios, need to return false to pipeline. @@ -469,34 +477,38 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print error type and message err_code = resp_data.get("runtime", {}).get("err_code", None) if err_code: - print(f"Error type: {err_code}") + print("Error type: {}".format(err_code)) err_msg = resp_data.get("runtime", {}).get("message", None) if err_msg: - print(f"Error message: {err_msg}") + print("Error message: {}".format(err_msg)) - raise Exception( - f"Test plan id: {test_plan_id}, status: {step_status}, " - f"result: {current_tp_result}, Elapsed {time.time() - start_time:.0f} seconds. " - f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" - ) + raise Exception("Test plan id: {}, status: {}, result: {}, Elapsed {:.0f} seconds. " + "Check {}/scheduler/testplan/{} for test plan status" + .format(test_plan_id, step_status, current_tp_result, time.time() - start_time, + self.frontend_url, + test_plan_id)) if expected_result: if current_tp_result != expected_result: - raise Exception( - f"Test plan id: {test_plan_id}, status: {step_status}, " - f"result: {current_tp_result} not match expected result: {expected_result}, " - f"Elapsed {time.time() - start_time:.0f} seconds. " - f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" - ) - - print(f"Current step status is {step_status}.") + raise Exception("Test plan id: {}, status: {}, result: {} not match expected result: {}, " + "Elapsed {:.0f} seconds. " + "Check {}/scheduler/testplan/{} for test plan status" + .format(test_plan_id, step_status, current_tp_result, + expected_result, time.time() - start_time, + self.frontend_url, + test_plan_id)) + + print("Current step status is {}".format(step_status)) return + else: + print("Current test plan state is {}, waiting for the expected state {}".format(current_tp_status, + expected_state)) time.sleep(interval) else: raise PollTimeoutException( - f"Max polling time reached, test plan at {poll_url} is not successfully finished or cancelled" + "Max polling time reached, test plan at {} is not successfully finished or cancelled".format(poll_url) ) @@ -918,28 +930,30 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # https://github.com/microsoft/azure-pipelines-tasks/issues/10331 args.test_plan_id = args.test_plan_id.replace("'", "") - print(f"Test plan utils parameters: {args}") + print("Test plan utils parameters: {}".format(args)) + auth_env = ["CLIENT_ID"] + required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL"] - required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL", "CLIENT_ID", "MANAGED_IDENTITY_ID"] + if args.action in ["create", "cancel"]: + required_env.extend(auth_env) env = { "elastictest_scheduler_backend_url": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), + "elastictest_community_url": os.environ.get("ELASTICTEST_COMMUNITY_URL"), "client_id": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), "frontend_url": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), - "managed_identity_id": os.environ.get("SONIC_AUTOMATION_UMI"), } env_missing = [k.upper() for k, v in env.items() if k.upper() in required_env and not v] if env_missing: - print(f"Missing required environment variables: {env_missing}") + print("Missing required environment variables: {}".format(env_missing)) sys.exit(1) try: tp = TestPlanManager( env["elastictest_scheduler_backend_url"], + env["elastictest_community_url"], env["frontend_url"], - env["client_id"], - env["managed_identity_id"] - ) + env["client_id"]) if args.action == "create": pr_id = os.environ.get("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") or os.environ.get( @@ -950,7 +964,14 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte job_name = os.environ.get("SYSTEM_JOBDISPLAYNAME") repo_name = args.repo_name if args.repo_name else os.environ.get("BUILD_REPOSITORY_NAME") - test_plan_prefix = f"{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}".replace(' ', '_') + test_plan_prefix = "{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}" \ + .format( + repo=repo, + reason=reason, + pr_id=pr_id, + build_id=build_id, + job_name=job_name + ).replace(' ', '_') scripts = args.scripts specific_param = json.loads(args.specific_param) @@ -968,7 +989,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte for num in range(args.test_plan_num): test_plan_name = copy.copy(test_plan_prefix) if args.test_plan_num > 1: - test_plan_name = f"{test_plan_name}_{num + 1}" + test_plan_name = "{}_{}".format(test_plan_name, num + 1) tp.create( args.topology, @@ -1012,8 +1033,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte tp.cancel(args.test_plan_id) sys.exit(0) except PollTimeoutException as e: - print(f"Polling test plan failed with exception: {repr(e)}") + print("Polling test plan failed with exception: {}".format(repr(e))) sys.exit(2) except Exception as e: - print(f"Operation failed with exception: {repr(e)}") + print("Operation failed with exception: {}".format(repr(e))) sys.exit(3) From 416336fccf4ef044a0291dfbde89547a94e13a84 Mon Sep 17 00:00:00 2001 From: Eddie Ruan <119699263+eddieruan-alibaba@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:35:07 +0800 Subject: [PATCH 053/221] Add phoenix wing ptf test plan (#13645) Summary: The purposes for this ptf test plan are Enhance current sonic-mgmt infra to support 7 node vsonic ptf topology with provided config db json. Verify all needed SRv6 functionalities and routing enhancements via running test casess on a 7-node PTF testbed. Use existing sonic-mgmt test cases to run a 5 node vsonic topology to secure current SONiC codes' quality with new codes for SRv6 functionalities and routing enhancements. PR title State Add test cases and infra changes for phoenixwing ptf test #13785 GitHub issue/pull request detail What is the motivation for this PR? This is ptf test plan for Phoenix Wing initiative. This initiative is discussed in routing WG. The progress is tracked via https://lists.sonicfoundation.dev/g/sonic-wg-routing/wiki/36853. This PR is for layouting the test plan for this initiative as well as sonic-mgmt infra enhancements. How did you do it? How did you verify/test it? Any platform specific information? Supported testbed topology if it's a new test case? Documentation https://lists.sonicfoundation.dev/g/sonic-wg-routing/wiki/36853 --- .../srv6/SRv6-phoenixwing-ptf-testplan.md | 291 ++++++++++++++++++ docs/testplan/srv6/images/5-nodes.png | Bin 0 -> 1673383 bytes .../srv6/images/srv6_7node_testbed.png | Bin 0 -> 1982863 bytes 3 files changed, 291 insertions(+) create mode 100644 docs/testplan/srv6/SRv6-phoenixwing-ptf-testplan.md create mode 100644 docs/testplan/srv6/images/5-nodes.png create mode 100644 docs/testplan/srv6/images/srv6_7node_testbed.png diff --git a/docs/testplan/srv6/SRv6-phoenixwing-ptf-testplan.md b/docs/testplan/srv6/SRv6-phoenixwing-ptf-testplan.md new file mode 100644 index 00000000000..92027002f92 --- /dev/null +++ b/docs/testplan/srv6/SRv6-phoenixwing-ptf-testplan.md @@ -0,0 +1,291 @@ + +# SRv6 PhoenixWing PTF Test Plan + +### Revision +| Rev | Date | Author | Change Description | +|:---:|:-----------:|:--------------------------:|-----------------------------------| +| 0.1 | July 2024 | Eddie Ruan / Zhongfeng Guo | Initial Draft | + + +## Table of Contents +- [Overview](#overview) + - [Scopes](#scopes) +- [Enhance sonic-mgmt Test Infra](#enhance-sonic-mgmt-test-infra) + - [Use vSONiC with NPU simulated data plane](#use-vsonic-with-npu-simulated-data-plane) + - [5-node Testbed](#5-node-testbed) + - [7-node Testbed](#7-node-testbed) + - [Enhancements in the topology file](#enhancements-in-the-topology-file) + - [VM\_LINKs](#vm_links) + - [OVS\_LINKs](#ovs_links) + - [Setup configuration files](#setup-configuration-files) + - [Launch 7-node PTF Testbed](#launch-7-node-ptf-testbed) + - [Launch six helper VMs](#launch-six-helper-vms) + - [Start DUT VM and bind all VMs based on the defined topology file](#start-dut-vm-and-bind-all-vms-based-on-the-defined-topology-file) + - [Apply DUT's configuration](#apply-duts-configuration) + - [Run Test Cases](#run-test-cases) +- [Test Plan](#test-plan) + - [Basic Sanity](#basic-sanity) + - [SRv6 VPN](#srv6-vpn) + - [SRv6 VPN for single homing](#srv6-vpn-for-single-homing) + - [SRv6 VPN for Dual homing](#srv6-vpn-for-dual-homing) + - [IGP local failure case](#igp-local-failure-case) + - [IGP remote failure case](#igp-remote-failure-case) + - [BGP remote PE failure case](#bgp-remote-pe-failure-case) + - [SRv6 Policy and SBFD](#srv6-policy-and-sbfd) + - [Verification of End End.DX4 and End.DX6 Functions](#verification-of-end-enddx4-and-enddx6-functions) + - [SRv6 policy with single or multiple candidate-paths](#srv6-policy-with-single-or-multiple-candidate-paths) + - [SRv6 policies](#srv6-policies) + - [SRv6-TE and SRv6-BE hybrid mode](#srv6-te-and-srv6-be-hybrid-mode) + + +## Overview +The PhoenixWing Initiative aims to incorporate SRv6 features and some infrastructure level enhancements into the SONiC community code base. In the short term, the objective is to assess the deployment readiness of SRv6 solutions via using the SONiC 202411 release on participated hardware devices. The long term goals include to promote more SONiC based SRv6 deployments via finalizingg the testing toolkit for the SRv6 solutions. This document marks the initial step of testing within this initiative. The focus of this document is to verify all needed functionalities and enhancements via running test casess on a 7-node PTF testbed. + +### Scopes +The main scopes for this document include the following information + +1. Enhance current sonic-mgmt pytest infra to support 7-node PTF testbed. + 1. Create a 5-node PTF testbed which mimic current topo_t0.yml. +2. The 7-node PTF test cases for verifying in the following areas + 1. Basic Sanity + 2. SRv6 VPN + 3. SRv6 Policy with SBFD + +Note: The scale, convergence, performance related test cases would be covered in a seperated spytest test plan. + +## Enhance sonic-mgmt Test Infra +### Use vSONiC with NPU simulated data plane +We aim to set up two types of testbeds. One is with 5 vSONiC instances which mimics topo_t0.yml for running SONiC existing test cases. The other one is a 7-node PTF testbed using a total of 7 vSONiC instances for SRv6 testing. Currently, we utilize vSONiC instances with the hardware SKU as "cisco-8101-p4-32x100-vs". This type of vSONiC instance enables us not only to validate control plane programming, but also to handle high throughput data plane SRv6 traffic, which effectively simulates the behavior of a forwarding chip. + +Note: +The infra changes are merged to sonic-mgmt via https://github.com/sonic-net/sonic-mgmt/pull/13785 + +#### 5-node Testbed +This testbed's topology file is located at ansible/vars/topo_ciscovs-5nodes.yml. It mimics topo_t0.yml except it uses "cisco-8101-p4-32x100-vs" as vsonic instance for all 5 nodes. The purpose for this testbed is to secure exsiting SONiC code sanity via running existing SONiC Test cases. Since all test cases are existing codes, we don't need to discuss them in this document. +
+ +
Figure 1. 5-node PTF Testbed
+
+ +#### 7-node Testbed +In this testbed, three vSONiC instatnces are used as PE (Provider Edge) devices. They are connected with PTF via Ethernet24 from each node. These ports are VRF ports, a.k.a customer facing ports. The remaining four vSONiC instances are used as P (Provider) devices. They form a v6 only fabric which is used to connect PE devices. Since this is a new type of test topology, we use the rest sections to describe the changes to set up this topology and test cases would run on it. + +
+ +
Figure 2. 7-node PTF Testbed
+
+ +### Enhancements in the topology file +We have created a new topology file located at ansible/vars/topo_ciscovs-7nodes.yml. This file describes this 7-node setup. The current pytest framework in sonic-mgmt is designed for testing individual devices using Ansible. While it can launch multiple VMs as helper VMs, it does not support establishing links between them. To address this limitation, we have extended the existing infrastructure by adding two new options to set up links between these VMs. + +#### VM_LINKs +VM_LINKs is a set of simple point to point link between two VMs. +``` + VM_LINKs: + PE1P3: + start_vm_offset: 0 + start_vm_port_idx: 1 + end_vm_offset: 3 + end_vm_port_idx: 1 + PE2P3: + start_vm_offset: 1 + start_vm_port_idx: 2 + end_vm_offset: 3 + end_vm_port_idx: 2 +``` + +We use a Linux bridge to link each pair of VMs. We could use "brctl show" to find out these linux bridges at the host machine. +``` +ubuntu@ubuntu:~$ brctl show +bridge name bridge id STP enabled interfaces +br-b-vms9-1 8000.8a6061a54580 no VM0100-back + VM0101-back + VM0102-back + VM0103-back + VM0104-back + VM0105-back + ptf-vms9-1-b +br1 8000.7ed1ee77f36f no VM0100-m + VM0101-m + VM0102-m + VM0103-m + VM0104-m + VM0105-m + ptf-vms9-1-m + vlab-c-01-0 +br_link1 8000.fe54004e04d7 no VM0100-t1 + VM0103-t1 +br_link2 8000.fe54005cae9b no VM0101-t2 + VM0103-t2 +br_link3 8000.fe540026e26c no VM0103-t3 + VM0104-t1 +br_link4 8000.fe540031113d no VM0103-t4 + VM0105-t1 +br_link5 8000.fe5400cf517e no VM0104-t2 + VM0105-t2 +``` + +#### OVS_LINKs +OVS_LINKs is a set of links which also has a connection with the PTF docker. This type of links could be used for running some PTF traffic verification. In this test plan, we use these links for verifying SRv6 encapsulated packets. "vlans" in the following configuration represent the ports connected with in ptf docker. This usage is the same as DUT's vlans usage in the topology file. + +Note: we don't want to add all links as OVS links, due to the following two reasons +1. Limited ports in PTF docker +2. We observe more chances to get ovs-switch crashed when the number of ovs flows used goes up. + +``` + OVS_LINKs: + P2PE3: + vlans: + - 39 + start_vm_offset: 4 + start_vm_port_idx: 3 + end_vm_offset: 2 + end_vm_port_idx: 1 + P4PE3: + vlans: + - 40 + start_vm_offset: 5 + start_vm_port_idx: 3 + end_vm_offset: 2 + end_vm_port_idx: 3 +``` +We could use "ovs-vsctl show" to find out ovs bridges first. +``` +ubuntu@ubuntu:~$ sudo ovs-vsctl show +c4e06a39-342c-489b-be81-09fbad6c739c + Bridge br_ovs6 + Port VM0104-t3 + Interface VM0104-t3 + Port br_ovs6 + Interface br_ovs6 + type: internal + Port VM0102-t1 + Interface VM0102-t1 + Port inje-vms9-1-39 + Interface inje-vms9-1-39 +... +``` +Then we could use "ovs-ofctl dump-flows to check flows and counters. +``` +ubuntu@ubuntu:~$ sudo ovs-ofctl dump-flows br_ovs6 + cookie=0x0, duration=7718.212s, table=0, n_packets=522, n_bytes=93445, in_port="VM0102-t1" actions=output:"VM0104-t3" + cookie=0x0, duration=7717.895s, table=0, n_packets=257, n_bytes=68105, priority=3,in_port="VM0104-t3" actions=output:"VM0102-t1",output:"inje-vms9-1-39" + cookie=0x0, duration=7717.812s, table=0, n_packets=4, n_bytes=280, in_port="inje-vms9-1-39" actions=output:"VM0104-t3" + cookie=0x0, duration=7718.202s, table=0, n_packets=0, n_bytes=0, priority=10,tcp,in_port="VM0104-t3",tp_src=179 actions=output:"VM0102-t1",output:"inje-vms9-1-39" + cookie=0x0, duration=7718.168s, table=0, n_packets=0, n_bytes=0, priority=10,tcp,in_port="VM0104-t3",tp_src=22 actions=output:"VM0102-t1",output:"inje-vms9-1-39" + cookie=0x0, duration=7718.158s, table=0, n_packets=264, n_bytes=25384, priority=10,tcp6,in_port="VM0104-t3",tp_src=179 actions=output:"VM0102-t1",output:"inje-vms9-1-39" + + ... +``` +### Setup configuration files +Instead of using minigraph xml, we want to use configdb json files to apply initial underlay configuraiton to each device. Topology file uses init_cfg_profile to provide each device's config profile keyword. It is a logical view presentation. +``` +init_cfg_profile: 7nodes_cisco_P1 + +max_fp_num_provided : 6 + +configuration: + PE1: + init_cfg_profile: 7nodes_cisco_PE1 + hwsku: cisco-8101-p4-32x100-vs + bgp: + asn: 64600 + bp_interface: + ipv4: 10.10.246.29/24 + ipv6: fc0a::29/64 +``` + +init_cfg_profiles.yml is used to provide a mapping table from profile keywords to config file locations. +``` +7nodes_cisco_PE1: vars/configdb_jsons/7nodes_cisco/PE1.json +7nodes_cisco_PE2: vars/configdb_jsons/7nodes_cisco/PE2.json +7nodes_cisco_PE3: vars/configdb_jsons/7nodes_cisco/PE3.json +7nodes_cisco_P1: vars/configdb_jsons/7nodes_cisco/P1.json +7nodes_cisco_P2: vars/configdb_jsons/7nodes_cisco/P2.json +7nodes_cisco_P3: vars/configdb_jsons/7nodes_cisco/P3.json +7nodes_cisco_P4: vars/configdb_jsons/7nodes_cisco/P4.json +``` + +This test case's configuration files are stored at ansible/vars/configdb_jsons/7nodes_cisco/. + +### Launch 7-node PTF Testbed +We follow existing work flow to launch this testbed in three steps. P1 is the DUT from existing pytest infrastructure's point of view. + +#### Launch six helper VMs +Use the exsiting testbed-cli.sh's option start-topo-vms to start helper VMs based on the defined topology file. The sample launching command is the following. + +``` +cd /data/sonic-mgmt/ansible; export PACKAGE_INSTALLATION=false; ./testbed-cli.sh -t vtestbed.csv -m veos_vtb -k vsonic start-topo-vms vms-kvm-ciscovs-7nodes password.txt' +``` + +Note: PACKAGE_INSTALLATION is set to let pytest skip package installation. The default behavior is always to install packages which include docker. This docker installation causes the problem since the command needs to be executed inside docker sonic-mgmt-test. + +#### Start DUT VM and bind all VMs based on the defined topology file +Use the exsiting testbed-cli.sh's option add-topo to start DUT VM, a.k.a P1 in this topology. This step would also set up needed links among 7 VMs and apply configurations to previous launched helper VMs +``` +cd /data/sonic-mgmt/ansible; export PACKAGE_INSTALLATION=false; ./testbed-cli.sh -t vtestbed.csv -m veos_vtb -k vsonic add-topo vms-kvm-ciscovs-7nodes password.txt +``` +#### Apply DUT's configuration +Use the exsiting testbed-cli.sh's option deploy-mg to apply configurations to DUT, +``` +cd /data/sonic-mgmt/ansible; export PACKAGE_INSTALLATION=false; ./testbed-cli.sh -t vtestbed.csv -m veos_vtb -k vsonic deploy-mg vms-kvm-ciscovs-7nodes veos_vtb password.txt' +``` +#### Run Test Cases +We use the following command to run test cases on this 7-node testbed. Some options used are highlighted below + +* "-c" is used to specify test cases. +* "-u" is used to skip pretest and posttest, since we don't use minigraph configurations. +* "-e --neighbor_type=sonic" is to tell pytest that all nodes are vSONiC, so use pick up sonic defined user name and password. +* "-e --skip_sanity" is to tell pytest to skip_sanity check for SRv6 test cases when minigraph is not used. This flag could be removed laster. +* "-n" is to identify topology +* "-d" is to specify the DUT node name + +``` +python3 -m venv ~/env-python3 ; source ~/env-python3/bin/activate; cd /data/sonic-mgmt/tests; ./run_tests.sh -n vms-kvm-ciscovs-7nodes -d vlab-c-01 -c srv6/srv6_basic_sanity.py -f vtestbed.yaml -i ../ansible/veos_vtb -u -e --disable_loganalyzer -e --neighbor_type=sonic -e --skip_sanity +``` + +## Test Plan +### Basic Sanity +The purpose for this set of test cases is to provide basic sanity checks before running other test cases. The following two test cases are added. + +``` +srv6/srv6_basic_sanity.py::test_interface_on_each_node PASSED [ 50%] +srv6/srv6_basic_sanity.py::test_check_bgp_neighbors PASSED [100%] +``` +1. test_interface_on_each_node is to check if all interfaces are deteced from each node. +2. test_check_bgp_neighbors is to check that underlay BGP sessions are up. + +### SRv6 VPN +#### SRv6 VPN for single homing +Publish VRF routes from PE1 to PE3, and run traffic from PE3 to P1. Use traffic to check VPN traffic works. Local PE and remote PE's MY_SID's add, delete and modification would be verified in this test case. +#### SRv6 VPN for Dual homing +Publish VRF routes from PE1 and PE2 to PE3, and run traffic from PE3 to P1. Use traffic to check VPN traffic works with dual homing. Local PE and remote PE's MY_SID's add, delete and modification would be verified in this test case. + +#### IGP local failure case +Shut down port between P2 and PE3, use FRR zebra debug to check quick fixup kicked in for local link failure case. Run VPN traffic check from PE3 to PE1 and PE2. Recover this link after the test. + +Use PTF to publish some V6 IGP routes to P1, a.k.a increase PE3's IGP level route scale. Need to make sure the quick fixup would be handled before IGP routes. + +#### IGP remote failure case +Shut down the links (P2, P1), (P2, P3), (P2, P4) to simulate remote IGP failure. Use FRR zebra debug to check quick fixup kicked in and IGP convergece would not impact overlay convergence. Run VPN traffic check from PE3 to PE1 and PE2. Recover this link after the test. + +Use PTF to publish some V6 IGP routes to P1, a.k.a increase PE3's IGP level route scale. Need to make sure the quick fixup would be handled before IGP routes. + +#### BGP remote PE failure case +Shut down the links (PE2, P1), (PE2, P3) to simulate remote PE ndoe failure. Use FRR zebra debug to check quick fixup kicked in. Run VPN traffic check from PE3 to PE1 and PE2. Recover this link after the test. + +### SRv6 Policy and SBFD +#### Verification of End End.DX4 and End.DX6 Functions +Configure an SRv6 Policy on the PE3 router, ensuring segment list includes End End.DX4 and End.DX6 SID, verify that traffic behaves as expected. +#### SRv6 policy with single or multiple candidate-paths +Configure multiple candidate-paths for one policy, and run traffic from PE3 to P1. Use traffic to check policy traffic works. +1. Configure candidate-path with different preference and enable S-BFD, verify that traffic behaves as expected. Shutdown S-BFD of the high preference candidate-path , the traffic switches to the lower-priority candidate-path. +2. Configure multiple candidate-paths with identical preference and enable S-BFD, verify that traffic behaves as expected (ECMP over candidate-paths). +#### SRv6 policies +Deploy multiple SRv6 TE policies between the PEs, and enable S-BFD. Publish same routes from PE1 and PE2 respectively to PE3. +1. Verify that traffic behaves as expected (ECMP over policies). +2. Shutdown the S-BFD of one policy, verify that traffic behaves as expected. +#### SRv6-TE and SRv6-BE hybrid mode +Deploy SRv6 TE policy between PE1 and PE3 and SRv6 BE between PE2 and PE3. Publish same routes from PE1 and PE2 respectively to PE3. +1. In this case, routes will recursion to the SRv6 TE Polic. Verify that traffic behaves as expected. +2. Shutdown the SRv6 TE Polic, routes will recursion to the SRv6 BE, verify that traffic behaves as expected. diff --git a/docs/testplan/srv6/images/5-nodes.png b/docs/testplan/srv6/images/5-nodes.png new file mode 100644 index 0000000000000000000000000000000000000000..0e79f66f54a27882f479eab42e89a14568345dda GIT binary patch literal 1673383 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%0DLQ*EKks!A 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

6#M5kll&uAp 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

&=OU#fSClqPTF>^xKij)KrWb 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 z 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 ?jCmkK! z&()4Qx+Qc!5@p$sJ*@9mIRQ3eVM0fJ5EhV`p$OW79OLwjycv+fVDAFGnYbiI2VHiU zK|5aJeHpzY?nUztRSR!<)_h!7KP3-h$ZU}3{JjdJ@P5t%QR1gq35lJ5fI{d!KiDU# z3206mj`swy{)6C47H3|~kGD%SFElP*iwX_nG;|R*1@v^R{A%)@oZQxZq^`y))19()pDK9OyrncGy0d_|6fs289q4{cAm%UbpI(5nk1%zOg@BU& z_*2L=vR(QBh92AI>MQRn(m}p_?Ru*-dT_Kp-}FO%^A7`%n;rHf^Oi>-bKt5)Gz69F zxEMfWP6G>mY?B^)>w?ds`%C=5ki;t9%r4PB1lSk@MS)XkyaY&JRyTM01rjg>y^+SL$0fIz)KplQf*~M6moi}E4TS?(V3JXS*a~K^Dh}T#Ce1Fr z2PO#B1ALe{FaEo~ilSl4=%?Xsfa>S9Ht)!i{*&WYxVM2WC~Yr6x3p}7TRaw;F-FD1 zwmM}nz-aU-$oyHK1QdbV&Cpg-%5erZsAL2qw%@o8j1x@T?7ZGnr!47dFeJ&xnd?D+$V*{$zs3#-=vD&rz~$sS${<1Wuz*5oB;)2Hz;ZpZ|f@|!r2VlzFWsrPl zt8S%|;ybf^k-dZEcwXI?BOu8D1&NC`2#g${cW3jX9fr9GU1x0R^MU4*?i(>VAnoGm z>j+F?gqm=BXZ`=q>vKnITuIjhiRg3EpB$^p^Z)L(@P?C>$q0>*=QZzkCb#|DI>U{U zD*TYpQ}42_PR5G&PcZ?J14$Rp??oKA@mhqqV(>~{AY=M!ewzJamTlML`gu!%c`dLC zGkF9B4pEB=dWiRBdI05rR^>TdFMeg|qx0ALm`8Zr5(V3DrFDVtgEjGNsIIhQ!j;6A zuDAv>XGWSst&0q~c_kz3f9J6+9A=se3V}4%G(R09SC9B*s>(p{A8`}U#sp)QH{E3wbKc)qP+5|>B%m#=Vk6moxjh* z?E&sBWhW)jG>>{3`B4+oEM$jjtBQ9M)@cE1;>Sh_q(-8_p1)Z%>3NT_f|Q__=tfkhs1@{KF3=`+BuxKw58FBhEr5>B); zt{hqXCjLV)I>tAw)bGKedqD{|8Hy_*E~Z_93)%G_YLW1ayu1D>^TE`+gR{hHU8lc0 zy`K6Yz*jy7wzx#B+k73De2C_SH!0t|hY4~z(BLh`n9a^RB%UiFj0n}&% zT|5<^ToF$8taP|q`qhph)@W^Oae9RAnnT2#)FkWk`idSMbzx!s)K)0AR($w6+;@8E z^g-QCGY6KQ@q*W5(JlPd(tmK96F?IF(m(fiQITi2F|)w|X-56I7@S!Wix;E|LwhAY z@15MW@~KlD8|T4B!?G!cgP+foWp14q>n9A>zQ8L_t5YU?!^IOTUaRv4HH~5F{=H4y zGop#WSL5FVbmL$_YoWn>By-OqebJZQp;P3b%*RxzB-ZLkI8B=2vu0{PhDZMR+>{38 zIo5@dn~qV{F@OrHtgW3d?u>QOkRfU{Kh=la_f)g7WnC`lK2(D)>OBT{ZE{&vJ8F2y z&wHq_9UZ7v(|`M=1VbFC8rnQ;hE=rzA zmr2%82f8GHFWx1Jr8l-Bx+?LIW!a%jbi`}cHDy>Q0?hwBX%&5hv!*#w<@zahiCghhl1=_{Hh!!1}sR?i0pl zVfxiQ62r| zl=)h51~`nlE5#R&TZV9z&X!zp+PNznm&L$qcoEx=P+%JONiG}-sG zo{|oC$IVu7n%2_mf=nGQYulPLQt)Xb_uB2D327a+vqxvPx@D~Cj}l9#X5-VOA+sm> zm<81-*v3}57|RlwiOl&@=B=U>gU*85LzqP4_Qx9c3xhOv_cqDs%&l9#0kAKNWULV2 zJnM}?tb}T5ie=hOb*w02EnFY)6M7}xou=lJp5}(lZ~}qP4L%__auH_x)cM!gRzjOr zCDwkr4+h%l_0m*rh22v9uB7EO`miE(jC4%*y~V;cLv#C%_@ix$uE^qbvnRqAt2WGu zLC85hU1I1rX ztE2HvjC|zDDb~F{r42M~{`!V(D-xbQT|mOzHK2Fk=i6k=4Xy44sfQfyV0`6&QKn?d ze6_m28(s&tC9W^72Y^FC@u?lQ7bSvK$D(l4Y9Tc=&BqMf#w^V8cANDRMKNAQo7aUe z{UwQJ3*5}F`ss9xPUWwhPGp9g%glf<;2;HI7-QQQGFW2gr?!6`%>}H=&RTB1^OOd& z?)L3|XAUEzj;jh_@`kSa<~D)8O%mGybMcw;xo8KzCY&%CQi{@{Kej(g8OtFx4p`cU zAGGp*=$3x!0o!C9aB;B6g05EL#X;~{8^+ux?7=f4>8TXpjr$yKykV6-u6mydy(h4h zKlqq!+8|?1()uU|&ZB*lnzhwO3zt)PTLXMb-g*0~?NyA3+;Z1-#DWsR3#33L?|IS= zzn^J=djHqf{wdjQ6KigxjhLwv#jdwdy*5R!3&eBcJj7|WCVDE#gyRe}R43obj#xf)_s{o@Cy2D9r5+LCK7va zy9>3vUSMt%z-aWwi4BHY2g15ZgD*rjt*Iwquzo>4;E+c~920nJMH_D^P(>+nU5H=l zU#=6NJ)NdkbY8x9U1MJoT}dUvZ^?rA?;cA_Fs6FkrZf3cu6~$M7GQaE@ME^!hsX(c zHcc!JJX?&3{=7*XW%|jK7-9?AUKJW~{pJjz8DB{@kEe6Gi@mq6#_IJj?;ze#(^FjR zSJoY|z1qN4p42?9?m0R7QIA4dWC#Y$=!$couebH|B2d*fqmObVU1=|Gklk^LaaET{~JkSQH3x-?LRZn+()f%>`(t z*H?{7H|5}|6R^Fo-x?AB-5Gg{JXoI!4Dylfq_vGvW)9wd?6x|jdUpE{`aKf|CEtwX z67;LV-SUUe^F$VBO{@P*^HoWkecGGoc=Q^Z=!(zL82P$L2i+YdRU(j|G#ai8(~SGv zX`@`pB+GbR(0nO8P7lX(SY06(=oMhx6C`170w#ItEiI8@Am$BFCCl_l*&Sojdx%sk ztW;OJj@0U0o8H*3!juy%WeUE#kmtmCt+(Ne=H*^)gr-yko@Yb(0wI-ZwvHR->q>D1ft+PqtXuQL+b3)IW@45NMJHVb(_8JeW6i(heCLsUUFf5%rs-K9C8 z#hj11rsePLpii}&9^9a3JXoB=kH3>gKy}`-gM=#h%_q$NzHYwpB#1}#+gG&hv%}H} zWW@V=*d4tie=m-g=s2vHAi(1EzfFulwURn|}CZ5P@;(uFPwkfApmjHfeAT0jWvcbHL>HkyL%QRPz1uf*Shy>Mm? z*`xrQBbI;vxozCM-Ob!+41G12w|{zR1BOtT2T^p+J?*Wci&jL|h1WG{RSw2+r}Jb} zG1-s2ZG?#GQ_WGe{fn5R)CG9~ipKp3|I$(~!HJzHNOKeNKVjjp0XfJ#52DbRYF9Q! zd!jPhFzO+({nusj<9v=u zVp6+y3*Txr_5{o*V10)f+Wii{$VQwr(ky21x_Ve^nmi#cbt?tOy~o`y^Xmyek_Jw^@#696&vD+`&vu;j(5m#N13xxe5J^r}bZIY7UBAvco!EmXfNqs;rx z9_BP$nNOBtPXAl#I0iCpWWphJMFXGo)Zrr+kZB{OZZeu_-xay11D>Npma-?>Ibgj1RCRBCRHm@Mti7qiMgO#-|!LlE;2NbC5dnatwVHQw@f% z7a9kwr+>eM>?!)0abZ)p-m{f|6K~)HCPCfjfFuzbC^%q6xK;eX`bk;d0xqJ`>jL?o_URw9>uyz3pe+w?fHH3FQfQ zjsisoqBroP-a($h%bqJEa7!UQ9toUDyMxXWYP_G6U0`}T!$sf8pJ{9}1z(2VzU~$K za^2*|a%N5z2e@dWjVq26#n1DP)Xs;Mt8hl+szn8ST@)~5ch_yJJ?nCm-HcAR_z@Bt zQ4u-CVk~6WcG@Cm#a{WxYo=eza9)|iMe|{t9b9vo1Dg5sw;If*p=RrLLC;r3&oC?Jj$ZANd`0D1Aow4;=r_N{z1DHZ zl2b)vE%D<)lk@|z`&0H7B7gHO(uo}_u4<`gv8XvnxBqnGbk=b`*?Lc)aBfHWfqwv| z)>d}a@c8fQuJL>TGicUP*~M2Xid&S(@u_K1TA9G9oXt9z&m3A~{V7*ljc(=Uc(Ueu zxTcNM4GW7NPm{^A8?(*BPx-=zFOm90_~w6%$wX?HahheHD}Jc9jh{&we8et}>q3FV zSu_1{rf>v9d*-NaY|)y(fX$C(@t&@#X*(%$iD8Y;SS<>g99SzMnH9%5CIZcAj7B|d zrD2KJln6;EiuH-tX6NH8?YMX zeF474+%AUoZN9T%-erLk#7DYfGnDYUya-1SeXFlpF1kQ8J)m({EWmi<>4Wqwk8h@3 z=5~CYxT{E(A+g=yQjBPToaPQv6uSkp#<5-3NXhNWqdZV5(8QN;;NW$Zy~-T^J0rN|l4z{KfKk&xhCvD20SZyGsmGp%(S!RzlM!8TSW!xgLyO z>)Lxv^0yr*`c2czBYW`O%O-@jTu=X%hKT-IrYCKj8VOsUOcQV2$6lbc`jnt8-((FyRB}a)Xmb*` zU-ZGW^)U1I_j`@6b8NM_2_C~rl7_KtP;wFC3vQ{`Rwe`H_Cpp;7X&LKy1CmjPk%Sm z#Rob54`%wi$m%X9|L(Cz^xjIKKL-Rtit2&Nz|rzsCPLN<$36Ybi@z&FS0uBi_3-d} zrUF3u`;B2{PufCMY?Iu9gUyS5W}2qj&YiADMRlLX$Ofe3q&4&vvXSd+Q`h?dh1c0W z^CKHggy2yhnwGfkLtyPIM8=xX)3@_O9qOx7N#_5R>A2Y}FHj7(g6&kZsOAeMsf~xy zjjo+B1|M?^;s2iLY6)vK*p4|lb(R{EXocF}%5a^PAmp*3$@ga^zzZ8rzq#tx5G*;a zghL>D+ec9|NPW$-ssPLFAm>_2d$v2sQWYt~6Z92D@FMeUtoZsL?U!lGQ1IG@o)tC+ zAdPATWg?BC&bh#CWa|H0lHxYpX3yUBA@v(8$TIWhfB!!u{_40EUj;+YLyB~C+Ah2z ze?c5bG*ue|VOt`2m>c#S>S13>iP0&XB&sGxoJM~cf*!a)-1}m?vBUxI^N=zD^WMB9 zZG|0bMun}f1(Ehj`QbGefWql_g?SxBWLDc5C+e9`x<{h1k&_V{%J&VOu+Prar)8nVF3QS0coU5ILg6@%U{D&&^@INFtWH1R;S6(`g%oh4clzsKeG zd9jF5A_(GVrPV6T+?Eo$m1wp3F@?TVQ>~j|XFcy;ybqRM?g7eb09!%%ext8%cHF<- zCs5}U$JJ!gzL-zQ@ZJd~I}mnoF_VGxdq&-!-i6)jtz^GY@uWXdnsVtHh*ZxJiv*ptc6O(%&`~5HT>d z(8q*7XNPGU7JFNC)2#8%7jC5MZbDPV-nGuGtG`wl6@)*@x(ad&EI-2k7`;Axtm`U% z@t(Pn+PQ}OuB5C8sy`dh>(_8nf-?%E?gxfr)e2Y~hirBkPG?wn{j-7k$fWmTCbSG0 zB=5Em-Y%M7O=7RMm^5X`ECXXpNOwfyx^|OlkqG9zXbf+XjFd*LT43K>TmUKl1T}Rk zKD&r~)jX6p8yoms`Sb5)nc0-5jI9(bJ#70qIKHKMKK&x5{&GmH}#t%89hTjY0$d`9RkCkxr8;g+#yCj)&8-g zq^ek_8}G|rjSVF?Hxubl<=PZCH1DL=cK7rvQ;Y!bpVW$Mvq-N<-#f-drBt_ejPw%G zE162_opqL$Psif@VlghqsLRs&AR`P=D);FbXlIF;_rgDajUZIMtpN3lssamd4 z=cK=8T;)%SMs=<0SuS5=oCbIPK}0(~#+Sq$C?Qvs=N-42NnN{Y-s8YxYe1`__NNqG zc5Tgv(VxGxQ7@cpnj;EZf9F$w>nQzMUM`sYahMPm*nQa|bM05u7kotI=6`)er*;by zHnm(OD@;;0R6FsD&!E=HCb2UUOepN}P`>Ya!QxR_t>;|Q08#SRY5;#OnTSk`55w;+ zNODFJWGg9E5j?*(lZg4Btgw55wLh^WGyuFWca7y z2cOw;KjKhfIXk(u+*9K$tjOp{Zufa0rMd%EM{yuq?%irC3o}Ci*2Wv9-6e!UxgCj* ziu(BvXLv8DeQcm(SOPJ-yu~`Za??mj2hBli20+oUsv-wuqq+TqU?{ikEEe11<_V{l8r4knA)g{ z0X=dvquio82A_k!OD^xq*%B9q{*R`g<}w zdurI4K!PmASkt0a)wf)Q91Gth;W>IW+D$$9i*%AlBlq9J?+c`QsvQT}T*U0r0&ky{ z+yRU2;t!~0JlGevaT++Tt>SFgG7oyq&Bbxthg%EdC1pwnt;Qm;|^>bZC|F^TB_mXsq} zyRpWrfM`fD|E|$sLwRDsXsLbT$AlJHXT*mYc~re5JCz)?=&qeSX1CJT#D9kRrAZ5yhwI1IK4tGB}Y|aHs7c6__;(f zLyR2rG$9vtd`&%X#gw<{Qym>M4M`YZ;e5V2iA*kXbok5B&9E>Oyihf=kST*bhoI)% z-4L2;4H6>HgtRehJ39uC@v1h7&42(ERmP+G=t4}*l7WhrBz1?^Yh-9~(qM7QiA*!P z29L7c9=Jy3@#7V%Nlp8p+SH8pds;lU3j7YK<|muj}t!24Yv4j*76kt zXT!CsL!Xipv~R34I32p~hsA{WJD;tRcGJq89Q@GlM-InxmqOUryJu{YSGo%mLx9(D z={A02H4;|HHXW-8k6rOE(bOokTwGnxXxX7lGv4&|M#U1m>g1)G2iA@>#$0NuDd%#3 zB+2x3UPe)C#GBXw-7>r_aU8BLt-mT@>~ce0qI$mZhiv&Xvi+m4+F>9ohU$^J>kiBT zIP@O9^JXYCqR?VW*S*`yiXBuxiCSnNKAKJbfgkYtFjW#d2Rk?R4L>E33bVW=t-W z{6?FZJ2<}?$Xf38^&--&kE_)aDueNarK1h&3%TCx$0l6=G;H| zsg3O-aBNfjcdupmMiOIVaW}B)>`zduekV|u;rT24J&~ZvZh16Tm<_K=D0g4`y1*$? z9E=FbO)g_4lzYcXm-#1Z2E6yK{Q!wnlymJ~$W`U>ByZEMC&-(x*xsp0M*-&t%8hXO zgTO!HYX&~K$;4^ZfqxZt>5Aa!WTRAO=KOsbBc1LVO>OM*L<6r1 zE}2u#-3~V!ZiLc3@c;wPc`#Pqp=9;w<)DP@g1}r{oUlI$pbBDM4jzdno1abbT(W)O z_pWvEQcq=vaL4y5!i+kJ*H=SQIv}Pu+f_v*phh?vki7Q+d;H(H&t+b_4`-?eJzgTF zwoZX`@5gquFXRSJVGce6Dwc77$9ZC)13vof^r4F(|MP$4W(+xWc^pRQ2EN@7N34jm zI~>NmF2;*rIZ538&|lkZ0z(G&cyn#?T5M%a>aC78eK^1i;_HW35_4txl=y|&Vwice zh66R1VNJFOyu^7DQ=$s;gXw)nj|<1BGu+tJwx;UXxgtpe8Q;6l75!n-Vhdxu>gIk1 zt-g9E4}cE!UbsmkKTX?OZ3sP#JeL@YpWIjJIk&S2v*hSv>V%mn)M)_KwEGu>Ypu!G z3dmcr`&|BIr88{iol)e3d?ddj9J5?vM(IS=WSA$TNI z*7y%@?g`zManRiZ6KdJ2E|B}#8YE>juk4^7a6?f+wqY#qTTIiyfhN|jzRrVv2j3RI ziX)u>|NOx5>5llW_8+WW2-jJY6V4~CR-8E3Db)y{6F0;?4OgLMAg=iVgCgwHg!_d zet*fG$(R*dM=XE@bbuBnaq0Hb8fC6VI4tab5)6~>f~}dX66&1S>d7gm>zF<7f)pnZ zl0Ge;Iq2UM`CggZX!yh()~E$3M(I}_2>xATe6~09ilD4jby*tdD-kjwWV;7x@71Za6$mmAWs2+qh)m{s#FIBqyoL|(FGy)XS-T}Wrth4Ro)|EJ7~;ztuVJY?oLe;r z!P*gmsx=z@rBtqG>@Oa(&vf?=+x$`fsCSoI&y||MOP(t&WhpxSF>0ZQmat zCl!=V-_$1mhiRYvJ52uzp$B*fod8S1B@Lg0NyJjri5C|_{Ukf`gK9eWoB0NVKa6B1 z*=!DwRs#|1U4A(Uu!t;z_y%cf5jHUx`Hmay5qqN&WnaAO68MsXK)Bx|5U9Bm&3MVE z__BmY?TLFvY>j4_Bkwb>_)(w1VYGC{U^R?OS!PVqi)F%8KQEikzpX;h7|Vp4qLrRn z*5T_AX}a69V#XjJeH#mNDy_VuP9vG16o*PZm(J5oR>zYA6rfU;dd4xi8nH$s=oN+( zGlwQe$AL5w2Z)I-_yHCSL)CMy13q=1q9=`0Asv$1|G+TDkW;284Me!POj^Oo5~&sg z)Cb8s01=lxDI{OsOuAF3H0@gPgkXFB*URN+siJ+`@1(_gGcTgJGqcDnyYBd)O? z`u|q8o~L!c-9>Xaanecy2Dx9GEav}ZgdG2HZmvp&UV%qW9CCMH#t)&2W3l?#*MTUh zY0x6tHTGsri@S8nNj_v4WSc}sUqUWm-)y>sBmAgYfMt9&I#>Wz=e>XRy z1l@|evZV_ZsKw)Q&xauQrO6vj)Fw?#leNhJ(xKn(QQ4sHBU@s_~I@i>?d|Y{LwJ!S< zjj9SHyO&R^LBp!4=UY!gro}DMK9}B&+>LW9475buW=J$yMpbCUTE}<(Nox)2^wT3E zK0b(Fl9}$9lGhV&e)DhSdaz65G16u-=)3D+-qjMJ`%3c2?dttKdpsV@m%@=G^vOh$ z@^Hg9oA7m*#?2y;&2k!djx%M$R?+Du@fdN1KU*|&M2h%vROqG?>AorqG47Ssk@2E& z$w^k^z&2W*Oo>q5V?mx9qc2J&Z*W|sU$mvW=27z_yma~mwGU@HMD;A|I!OrzOz-Ku zBF95p_kow1_tA>T`i~y`+kTL_FaZDjq<7?1n^GKB^aA7;n7BeE zlQ+m==E+7^3EG>VvaUu#TOr?B)Y_8(;H}{yCm?wgmo;_ z^)=A*_qt4icjnng&`;;W@F5iO6;_kyljnR`t*4+5*!>!%UOkdpWHdPTK>1qxNQdS) z43#Ec#-UH^xkMiKhLI#l`qm(k{<%@db}Qw;%m%;F=A@BpHbnjR zl3KMkgE#<^vrB^##w=`V`-__}iMbJ9KKFYp=C?#tKhHZD{hN(5#Rr&BPCUqrsHKUK z;e!>pIO*4dt2lE?!PIml{z$Vb7=FDCy7_S_>5x7lxfwpmsz|alU#r0Q^A>iD?v5j|5yA*J6%h`*8_I*hU=uf-61EJBF&9(v?bcxQ+hqga(=rFz5t2BJhzeDpigUoVI(bEOcvtj! z$YYGprC*)g4lBFn1HwLsK26Hkc0D+Yp41g*;4X#5=5IcQN|9}*SBC<5V=0$F#mKNj z?$;ViX|kc~y30J>zRO=|%l;GLs5FoJ^7L1+4Z- zF#%Z#1rh=7=B|5VV_^KUNcp+VF+5dw{y*oQbZtb|=RPMK?e5Az&3jl7gBBJF)j#*U z_aAtQyMulo+$k@Ip)OfiaqR9CdDB-5ntdYF2NsW6g}5zf46N|1pxL``kB7TG&O`y< z5k~4+lFL^$hCaF#=RwjV7il2G3E~WNx9D*fj3>x!D)OwyE!UHOi!HKZ8vi(v9)(P| zUXt^Qk`qG&HaDdN;b$#eeyVssMZCUvR7RL=gYM<=Od$<08cyf%isorm*V$?|w7;%T zzEJa&FNwg%;eEK*IvAYM<8mywIz`*%OY3)Z6Ap|RA0kky1Jwu#0^Ke?RwE0-y7wl8 z!@^Y@m+t0{wyb(wWg$jtC*L7K`I_fmNyw??R9M`;+ko#{*S~tuMguwISs={JXJEmR z4qEDjJhOgXpd$)gab=6dS^$+_mu{$G-D;dv8z^ToiLAzMY!!hObhFFLSJKF_pRe~4 zsxr+8p-uvh9S7k{@<^+@icdTX?M(F!)ZD;D3@!ert`m)^asus*&FYfuMph}DEN7Zc zlbMaTv08t$c;~ig_@wwnLk(2B*sqIt_#A=(aIeAY1fyaft^29#EJnWhP59uK8TSy1 z&=0H}@=Z3e^SP~u1tmVvoN5M_3=l`e#+Odnrgtd+ny_a_e6{Kzt;8>>?h2s(K0QgLH9m3m|QkD4p; zL7awZvR|jl$n?}uYf88Vzo{i~9gIr8j*)oV$QW^~;fyrbbu~hedU;8)Nc1#N@b$8G!S2o2*`plH1`5mb zw*xiF2L_vcI-NhA=Bdd+ZmItlm~XgTvH1hN-VHJ-A>&OO-16N;+ZmY6Xcqyc*PTEN zU0B?eIdE0j4a|xms*#u{7EtutmvI-*33Z|(XKBv2`HGEOIGz`+Tg{H1-XGGGs_dHD zhV~5nd>DI`^n>M=Dw3es_;CEaK!^poo-(n4P*gb$BpI>SDt#6XP_+YB&mLzQGcpR&Ir=gKBbJSC)RA+}|JK*I<~Xw$Yfq@$8d@{-NCfu*0Tte2M0h@z;vF)x83P)CjCw zY0_>AZXZJY57yrNujzAZ8*OV_cDGfkv<`rz7L{5RL_`QfvRf@^QBt*vOo@UL6(K^5 z5Hi)$ij*N6sRV%}wTOriA_fRyif$$mNJJoE4nqb>0wD=W$oziY&-1+JJ?A{MbS720g6c4&zXJH{ES87T9P`BVb~E5z%Eak%&*<5OtAz zw7TqX1x?<@-1#2%r5ry*D_A@d<9*a{1{(sN86pQ43*wLc7Z<>*4vMY+*c2Y0-QyMR zY3_HuK{2M@&)T>79EOM5zg$w7f-OjO=_&F^iDT?@yVhkky&~L4x!uK_3f`}Yj-D>b ziB(JI{FX3l+z8SOF8s;d(!;HB&yyD4g;x5@TgL7OGcJBeIYkwP4Gdk2rnrcY6!z z^pc-1t4gJ)BhB+fyZGtb-!56ZM#oILTVF8wwlZ!Cu*rRxiCI=dO`9!~f43**ULx`< zM7GQyC0EiDl#WYDBoxU!u}O4*{u{-y-Wudib^vt_p{ClohaxiiM&^fO4WriwkX%>h zNovW2eh8UXLb`LeW4elOyYJF2Rarj+zJTY)qhzyv0Sr-xkv+6WbVC?KjaRC)Nm?d) z%$M!t+9!zU*+&IV&&t#mcL-88aF$RPrrK`41`3Y7ZspU6z{*5|dQR>*w>k!+!vgJq z(5P`7(r~Y#z2|!(xjcP-d`W~JXdhsS7*>=K_5|j-q&Fq^T%L;7>LBcVbk_x347l z^VSuA^v8Q>lQH7Hf?{@Co`S@+WqdSG^qjZCGiE9!wErF8e-{z z^cLpQacZ&dR7v?mULa8KfE)QW06T;M&^zFHpp9AK$wv-&p@(}fjS!dB9%D=CJ%N8M z83zZd0uBYG-a4FiCE{32IC@}6W!qR9@U8)l{uye&;Mv4s8E1Weg#dstqcI1o^*393 ze4mj#;q=4SAdRK7uviMk+pl=BfaYF*HAA0qBcJ!Q-P7=P3L{o(K~4)oZ&|mF*+w+; z5#6cN1eyviZ9-8c0P8OxIY@8BU@JIayCzR%t=cRE8q1C9)EqSbC6!_P5F2@VCU)MApI{JEckk>G)%=-QQjIXcFRy>!gLkcwf(I0Ow=;Y=gI;|2H5mv8`ujOx4w?0KycmmZ$^qI|A_ACYQi3k z;BAGHGiYVjZFR?ddq*iAo`{q4$7ppNA* zC)SSse(S=9&BCC?F_R_^?S8kKtbCz)HnuyK9Re|ejjcCq_r8?9O*k3y$=NoqIl_%nvs3}aV zFhbGvo9<6h5g$BywWLyM>~8}E0?a|{%~v^^`zV5xe;^;Rjl`Pp+Wa&&uBI|6W(;1W zKxdunAoHPdnnTx^C~9sRq+Zv&OLyUAKo6Xh-51pISl7i)7jbQeQ2CM3N%V;xQeL#- zgtA`74caGL(FL#9d%+A`GveL7gu_Wd5aifj=0&s82mSHU>v2y<)Gi$qyy*q&2?O;> zk%tjO*IQNffbwBp!RMiS4IYOG4aoh{oa*A-h*sZ~z5*gavx^>(K35Kybd@OhaWn81 zr1#YENg&-xPy^olowO<<-0V%Wzl^LqpFiT4zay=l6t`Cqb-3mG307Tabqh&T#D}%8 z1Cx)$HB7P;bh;De!Kbvc7S@vfKv!n&CY1{6@bkTRoULK{n6E6}R-}yN??@8r1-h!G$X9_mt7;TvH4T2dOs(rd^sJ zgV@*JECIn7Hs4@z*y^Av7y*JJaBe7uyEjj2Y__YiFrWNjR95E%5 z<9z%8!NOqQbg_NhX^>ChdB-M3vRgcbonAXSiJ5<}W|n`yu`*|8t^Ol3IE;i!*#nf7=0 zYb-UQ^fVpNsNdB8bj)f%5o*Pa{%`OrF*+TpX0}HLstd};+JN-BE~g-{C*&R?flb1$ zwO)2%>V)ccl9d53-RBC>Rd`^#5{0HIh|Q>~HI$$}qa&hXgw{e%ZxU1!341pdGFdGr ztuxqF8`Ac8dY-6}3`w|rdP2P00mdb%6LzL;BJb#1{Vz*T-uZL%)k(z_p`~PxBQbvI zehemMwevyCa^6|#hBVs<>4YMhtr>xL&N`Id)a5mGmPUJT&0>zPo?De%rs->7)BO<+ z$AX}w-tCX1F0kFZ2x9HBg<03%Yig*)ni@{;qS)efFJ6Wwzl(>aexLk)(_B|G$$EZd zpeuYmy1;W@dX=uXP#ktUG+SS0k#~l0Z|3NOqq(LR+R<@tt9V-}w^iT=D{X?*y^Mm! zpK*u=17xv;Q^|9ZE`Y?yf3#F1}z?klT7C`u|3ftOMjpl3n3 zcyR(jdk;wZd7$%pqxjF*(!TDEiSBa+zHpb%;`4n^zbe>*FONYSmu6Nw{0Q0az8-yV zE>!p8VyoNV;-nSH({(1zcoqO|QuAA}6kNyh1}x-C+9%g#^n{KiueZ_G&-%`oU($Sv zh}uL~Xgg3gXtN}ikR9OXW7V#SrJP3l0E3%iAoZh&kLqkkAah~s(^JpjbGB*ntuaTU zI-NDMU0Jae-WTWUCY)8I5dQ2WiV34(h6_B+ug}7VO#7I+-NK`S<_0)5nq`J`MUbjT z05mdKc@*L3()ModD|7h%w*#tcHD2OaWM z;Fo;un!%cr=xT2U7#=p{!7ZT&Zxj)lK?DwJe|PBWZ30e(%hC!RJ)xuv9+aSwtfb?$f6O_> zuh;aoEBhW*LahtcQTGwr1GjAgV1ve4=m9n3kVG3AG#q#nm_WkMb{G_n;o#TQ?E%%} z0~3bIeX9OOQDEIl4wZ#G&Z=2#%?Qtl7NvJF7t;n5AoC?p0=3mX>4%#fC&`YusO;wm z&q6G#k@`V^Ap|;=c{9~oB)qPeY&fG3WGLo|>9lNA(-44t!T2Su2bRYtDGe_&0W6Fj z{l@4R$|%q=>bmO*g2@_@Kj317%2*=IIt($Wpn$lHu;T)gkqqov^QsqZ(QS=hiJ4c_ zrVPc+o`c;{?D2ICBcXJzzoJDHdk+ga5pCe=FGSis4fy99Kcv$i901j*xTa&yZT1A$ zPdR(7g4nXm%HJKH-8*fS-tEAxe7`yN*Ni9ktOd{MFiFBg^OTAhW*xMVN3zz0 z)zU*KI;C;6P~OqAX0q-K;QnVY>(cBFsH^l(^786CmM&?wJFmm4aPSMTAIPU!#OH<1 z(j5?Q>DOII0$O3QgB8(h7Hp`SEo;3gUG#)f_Z&EG;rZb0Imau&r{P} z|AaqOqybUwP-l$0P5fD9&8ieC-exwN$-d$>WXF~t;$L>gvq#9>R#UL39%-^ZTc3}C zSDz-#)LsERZu%9O$RW))(1I6GH|h2wt~!a2fGfU{4AnMmQfXn6Z!Kt>W(O2x92EiRc$&NZtLy)U~MKr{&hZ z0)Gtn#bacR)Y*xd*O_*Tuz&6VTYkPQZ!+8auTzy^|s&Nd9-vb z5YS`D?!iLDamI!4Ij1!}U;8Oa!{{8_JC`1V4)ZhgyO$2)-s^h>sT=6x#~-x!r$EHb z;^!aZ`VV=4)xFi9SH^;U@@e=l_Bi;*&kc10J79%{J&4-e%&qD(pZZ61&G-1dsv@F$ zHy{Yohm-%BN8Z}Dh{(S!$BjI4*uU58eHJ~$tOX`B`{(*ydZRW6QV8-iM-Sudeh0#@ zJqUma$Oq<{;>JTjn+A=PlohduLyKU)hdSFkbT{PxvUS16g6jcX3&$>jvGNWrJj&&~ zpY$^I()PN}(Db=%ST2U0sz!Pq%4rSw&~jZ!tk1p_yqvmcfbW*K)ArEhOP{Pk#Uz{G zkO2O@_jjX7;(cXf&COX}88GKpUVuRh83YrJq6Gt7m$$Hfu1#7c; z2f6NBvTZs`yIE~yF$E}k!OMnvm9!yCS$Ic3`H{f#)a`DAp53-pVZ6tc4UB)XSy(d< zDMiJQ)Jr^=IR(^KL{N>c5ph})ru0$0V~1#NsJag8&Dz+m$eOyu~CsWsH5f|wo8qwyW>KU|+H*7Z)=tdUI=d2wTjMWXq=Nj08M!Cli{o^u) z8;WbA-n6HV8IGAjvsEn^%VN3KhjJ4lAr8ZycsaW6LtcpHl?t+$w+@jMIib&H>UK2- z=u~q07x#Bt5b9$>4i{{y_lUdA0ZRXonOziYX_q&V-W)s+`ecU1h;Id0{BL{8}8}7 zRK0k#w3U=1-S$cc!A%kl?j~EuV5ZV!c>E7|*-{kU3qlSyH8X2iU&`je@V52__VT;K z9j2wWFoQ4pBQ!zwe~f2p4@9>lmDBCrQ`~3s=Jr`0=U~6uG`GkQsMKl;j+8h6m)o3n zCM;?(WIvHtP`(?TAw%a zbAUkxOGe;pQ>a9x=+rw!`W?{sXrlFV+6rv+6?<#!Cr$qoi$+6 z2mEV3QGK=tvdkU}{tq-!wJ8u|^F6OO11k5o^L(&NPzTOx`8w z&3L#pFJn%|G4h_a&(37`3=(pD1l*gHYvt zXjc|~A=E>a4K?=+X^94AQE)a&c2-1c+1r0JF~L;AZ|O>PKP6#7p7KUaOmBtRhWpeD zk$P^T7=P3)`y-#IFXA0j$x87dPx7f;U)bClWG&czclSK7*q-_me+yXtO8l+gf8>SR zeD^Y|UUIS|Yu_fquO773&U0ydHj|`rte09#N25d2h`KV5rt5dgJWloBqo}6;1ahNT zXISlOaYvdK`y1TYDFL<-B|fn59bqJW1#^2h|BK9lSA;WxhOgjm6~(_PKgZAX`yzLAHNm`1 z_kcVuD6c*4c0;S%!%B`5dnbPi4U2ZGz>dZZ{y(nacp2$%15rtCj&#hO{9(U5^&x|J z$_hNcYihXmkR6}wyFEv`AR!_YS|gt+I5zL*=Eyv;MfP7vDmUhmLsX;j}^T^-O1fPH4XQ<1;e{yI|d zy@SFn#2@GthveJJpaI+(wP734{qA~gjcC>Xre5sz7kp}auSRI}Yf+JIl=XkBZ`K!^ ze<1X<2ExSm`b?Fms%Jg1fdpnaj?OLs}JG=8;3P#DQZS!rn zlC|iY14GCt@HgT39})qkrryGHD}&||*Q5U8lXtUdeXdsNFUO`_)xHVqcBbDjA1B7A zekB<=Cpa40S~j}ZJ9R9q%l8IuQz=B<9THR?mAa*aXMM-{_HXvc=XYJQ^c!7+)B}Hi z$Did!@%?$iJ;0kkTZ8&^;R$Xa2DkBWK4fLZh2Qb8|Cz)?#p$Tg>WM z{>1!TiWuK(OrxpQBGH|LLmEf;a_?_8FQcu)t!l9*{IrPkb+4{X`=q+Iq8jG5lG=LYIkzn>qjDw}tP3mz3;P@LX)n13nuf7|`FX4t10jPE^V zpi^$%GwR(#C~|jDRw6;W`L3~-pRhVXA4p=_H}MSxRAdB~8j>YDrPwVhJ*BcnLk&NZ z759W?V^AUADU*8kxv?k$!f7+$wsizWfYw%lnA z93lOSb?4TZN2vFe`{ggi-H${ys336H){aKcfOFtUD6t59KBN&K#Jv7i`Y4ZniBJI) zz226qd2+4Sj5}<(7@1cen!$)jQbe?0>)4W79T68P!sDg$L*X@$`J?EK z>@(cBUat8tjeI$0T3VRnTa9+yE;E{u6HOa>GxnueuTfWiXL`iMy>yDOj&_PSQS>Ju zL>nUh;I=-0Xih(+l>j+Jr;%qVFk#^2cbxfu5{aL9mW{q$J3SNr%IlE%eJ|B5K(~Lrdo8}yFiOM!2X(>{lCuDNNOqi8(R7Hx1YCtPK&pVKyuoJFH$HS;2 zK{wl)=mhFEW{{b%q)+>KXme>korqQ@yfxF5T@RoM(wohdLidUMQ_hIsql^d+tP=@#Z^U zA>UBs0eIDP>|TZ!=MFHTl0*8x&ClrY0tJKx8g*Mk$0Oz%Y{$rO@i)&ea5f6xU{{ zB7uc*fv|Xn?xK4!PO&N#i_U>}_{Ws$gXXkNKc1N$r|WB#w?+-2LoMy-gmP<6*fRns z#m$&^v~$u6j8oQlSz7#wZpP^{-{FDKSJj^v(xDr(c=6S@&pqsOt7EpC^07et13Lu~R_kR+lYA|fi3xHuka%9hxis`D@QmfnmDNztU*Mm!w<e z*oBs;wsvw2nZ|_1OWh{8Om2SgBORPENbU#_SeJF9ab0c<(o3Ov|5?M}hP4XIFnoTS zC?AAH_g+dG5V@M&CJ44XMsVhUao(4db&g6JVCS?J0s~OG(lT@{a`TiM^^^8N+l0-8 zsg}mc%-nR#Ud5l$YmH6x4C4)>$|g}xPNjc%9`0Iwi2sPsH$Tr@LMs5RIVJ0(M#bsU z&~|%iX1(wvxs!p8qKSWEhiD$K4iq(7#jPv1SY9{IO0G;xJ&Mf04$$45sPXKrUA=wt zc;{>sE8 zNq`3UTww>kVoTD)Rfg8_Q(##qRu@*^ zH1U0{adk3O^VkWtw=vAkaBJW$Y}=JjslO%B8hsZ6d?Gz-9bYCohE6z-q?s-M; zzdb3xcTV63q8nH1ovQi%Z^}9^Su><7HC5)~+boBn#JHKoloS}Uj zGy@As9$LCk{NW!DcJ77!?bP4qUnURHcHY`?eB-bCN59;e0$G!XCd!7HS4W!7Rne-% ztj`pXzpg@Yiw%NlKDhD;A`LN}NUEvTKZu^KDwv;?5s9FGBy>d{9aNLdPsTslCVTcs zbdP_wo*N_!&{Fp>Cth<^ePT8rdU=*+{$?*tm?V=n_^ZL8w8cSABk-1>|COZNBf=|2~_-E%ScZ8^>u9C-0!!9-m zYfUfNp;C@2F`nBwn}aKAwF?*vuwR96jrw6Xoo<02W3=w6fmGs&d=VJGnx(q0MdE$r zTSr_LM`XTfy#57_sHN;upi3COB&V5x4q1lt_K8gQmh5u|1YKy05SB0Hm6b)(gZRXx za8^$BVmb!?`-8qHfD*MrbVW~twXcp~vurYCN{SurDVE)b$(|y#osww7H8Z}_N7-I! zYf1j?biFEj9?Z9;Sp23IE z_?L{5CK$m4D8Q=MBq8H^KYJWvfBpc!6!x!gXu`ZVBMtA3Zjv3f0H^hha2MhASVTL= z>LcouK?qb9$xfP{f4~jaohXZvRh>Aoq?<(g2b0h5t;?NZIK=Pd(KbiHZCV#MtQTiy zq0m^0YBxUb^EIAR*kDFx>+n{!3TnRy(`QJa_R}J~@AXL!2dM4{c8I?96kBt3J#nD| z8kE=>wAt5J!#EvZA^k_KXyn$Tvq607t9F}4^7fupa;`A!IE{n3N*gMH&)LRfmKC5Q z&9)c6FQFF-NSOtX>1%4uIy#sAD*FaLzbsTD$z7K6OJe5KDM7S4ci4b9WkrO<_Q7R+8=f8*z*2g=bSupX

w&(``UTV9x0G5NltAbHXy{PA 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
VqC4y?nsQTy1{+LdQtE}wVwqKLZv|A< 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�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æ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 literal 0 HcmV?d00001 diff --git a/docs/testplan/srv6/images/srv6_7node_testbed.png b/docs/testplan/srv6/images/srv6_7node_testbed.png new file mode 100644 index 0000000000000000000000000000000000000000..4321536fe1c170947499acacb80bc1d9ae68e8c4 GIT binary patch literal 1982863 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ν4{Es)BIzh@clyB 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

  • )e2h(+f+O0GAm&_8iAFreP6dwX)}Zw^ZEPw-S;0 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 z
    MHBv9hE{Kl99Yc1AGXJLnsOzsG*Ewt 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 l$vt2ih1-pn> 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 z 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

    (t|2}S%S#vlqy|TOT}kOsG}!t%Fwz6@ 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ℑluFodo zR4YGMeKgv0_HOS%Pk zFzAj`F)w?5+;43;ol~yt^c_fnBSvDnqx3@QmCZ}1?VKaba)hn{&Rx9pcHl3L=jcLI zG}Y{L*vF7cK|8-+Y(^^`D?j`&xUh>%HMJ% z3!?l>zMHOQy}s-B6Q}%ms^RL*`KE}@4aW6j{*Sj6NXr(9GipUN?r5^Z`i4PX#ALa3KBhzR>AHQg+4g`*=Aut0|NfI^&9l+7yfX~l!vI^4@pjwgx-~uR z&UJIa02<-vZtLSQe)OwweOPU6(e}$DFk0H8Iysb{Q{e=$M)#0Sje`sGqy?RPe zqcPc_wU)nyZgqvWjVRF*@^z4rqRjlzCU1)Ys#5<(CU?yGNH{~>OK#xb8*q>$QWM%4 zY;A1)4(%~hbEKdFcI@EnZV|*v&LzC2jTMlJ}*D@bJHp%JiJzjJA27_LeXGwHdVs1Z$3t2_F|l5 z!b5`fkDr@ta5W6Z!C@ry-@Rp&_k1pvxyhf2%DGg~_n-fWenPXtb^q&iW|26CW>juWz?FL{!~iDx^SW@=DL@U2TMcsB{n*<7YVBK?6Q(cx0+`9KS1z$}f@iTI;M&>8)b z{}ZD?n{wOK)U+XH^Hp_kR>|AaCeaR7GMy5uu5Y6gX&z|&sg0eX9ytCM!CpUS$%8^p zqoEwxcS2L$?{d?wKDe3b^+#459MjJ2I>JK`q_ zS!)N*@y;4k7M}FuCOL!opyoze{5_ec!?b5$7v!c5sc4($)KK4ck#HA5bd9;AznZwz zxVm{1=d|4dI$a+q2909Gw>aZM9EG~P*s`;xfwTH2GM<(R!3b1VqXJMfv@da;`V*M* z_x*hS`@aM;-!KL>!oeHKm<^YsOnx$i*W&<#)dl-?sYhekoq}cAMHjM9MY?}FRI=IM zlIHx0si*}ut0LE`UgVi3;seH4jfy|4P?Anmpr^DbNBRRQygs=op>Kr$?0KyN6-J?o zg2tK-*y+i@bT~IjwA``zhazytt8-09NW<_`P5Vg$+L?Kf8}{acqG|#V$>@dEql#J9Sx0 z0`fnjBA$NR#}zcL*-x$55P>b9dt&dO5oYe6RZa(Ty9R9~f%1(Z;l;yR`KM|-puU+K z;Se6piZZRgk^*w>PM6ZY9F%nYE`&@g_#?BrLGw%=`?0v4fwpKxK(`Q7pF?QGe|UV* z7_j@Ms!CJ7>6e-tD5x6_S2%a~%0f8B;LM+UoLFG!8*F&8;B(GVPyGm2yP|%P4sP4H4wrFp$5dK2qzkX7M-%BMiO`*b#0bw2!a~&S1|a7-+3#$oVj3nV zYj=PMC9kwaabx)8>46i%7{SEY1d( zW^Nr?IMZ$!h|T^O4E567wE_E0AR8&Y8cv7zJoI{-Ad}@{k3ad~cp0lP(9`33Fvh6C z9)&F&cy)d-{@6Z6r3JO!q0g#8(4X{eMr@e=j(Ps|TD~AF$)P8^Ijbutr*WAHW&Gxa z89ibGjbfVqGhai@3josO^E}tpYg0a%T_3P=jy_z#32+oR_HSG zw-)mb<`BzZ_!wOiv)X%rk}6v>;Ouhz@dCrtowayu&#A(fnq~&+p6*?%+U!VK!;r~w4<>Au28km5w)VOV z2Y}Uld2Dku(@@(Je;RO2x1)|y*hGvDV(pp&I;)f|9gdP5oC0d^Fpnv<6r)`Y`7ade z++M2hp(zbeG5F^=TtBB3P(pUfVbu^d?i>3Gl*io)PuwFtI7e`-{8@hTW+-y zHvrEC``u3tMzX6q_M6@E!-=R4k4@AuR6~-3nu_4a*KIonKQpw7vND#&TuKtmtMGr7 z^HlG0YIw!toJ))oK_HPc2*Lx>&{M7CHcxXRezx8_eq^)B1V;Y`N#p_a_2Jt^)|Y?8 zd7v6LPj3eVcnP&T`lj^i+%shRGH5uAvrQSi6_vGu_M97g92`!>2VglWF&r*Vr&Y(o zwfQZ%ah!9G8A5yjOJHqE?=OXftbJGCd(aXMeJ@jhxLH}!c=Y~w_t%tCpI5uBumu%2 zPQ}}5OwJwdWMUN&(kXal4rQ{hOQ}&ZcGGdMC{BHU?iyv=m~2ILc!~q!8E6f$0mN?0 zou*BJ5Y-q}ihI&e%VQS=;<@v``HT80<5U(oa4&0tk5Er!VF{G|z})EcUQ16@QXn?> zW-hMk%-Tximqx1(T8USzD|>&7;?b@`WzySLVIn zm~ERh-TV|Wev|T1`<=f!dN}ex!s$aeJm-c=J^+UX`p*9qJSzv-NlTUGz`0&lginV2 zPK=*VUUSjY1>lW}UQHCTu9T8$VK@wV#vW95!Lm=HM`UYut;=>-;W+T&qisRv^Q{|< z0rf+l&T{Z!*Bj;+Sg?8EY#5|QT(b3lV(fQemBAT_d~LJ?BAf(IaridpPB=fBaiW26 z&!S!wXMaPY&4X-=f(L|dr(KZ>?xH5LHyLmKPak~>eJ>=XRHN7;tc;211d)HjHjP+c z``L2j_{GzDHRI;gJwG&qfyQifCYZFfH9ecT{CRQt_5FZ=a?(ND7Hj5FGdVMDTn!vr z)|ClaD0b0LdzXB5`D6FuJtVD|X|z~6#qKfPj5G(kE&n$Wswj-7`=QkMpa>+`L?snexzjz0gvAyAV^XpYUhcXaYonRJ5jEB?CV9>1%jC}2 zbO5}2v>(_J(904IbL^hVGHidQ*1L=N-wQb=T!`KOp@k?W8uUHrIreM%i>UN~Y= z1X7J~!qy&sdxC&fQhsM`2mCby9uy-kCaWZFBKPmgLL# zf7)EE6jI@0x}oNPFDC#B<3k4{NQB}>8)do{3K8_px}m>=C0#K)j_eJs`8)3g`jmwl zrdGRY`-SAgL;~=P2(Tu&K|tIr)I?`}Qy^z2KQsad1x^q>uqh$*(PIiOD^|3F=vP3)7r814QL%;_rkFC%9dQ^$3KrFIm-98Q}$ zfUg85WP5cX!Wn(vlS@k12IMviTXIdRPQVFPO51Wy!0 z&pj%&8EYYkXY^4<#R>DHFKELj657P*;mePX^c7+k={r3M8mYvo!@rBY-LqGiBao%0 z^V7Yl&b_r8b%XsU?Vs=fF+?cRc>Two@S%9ddYQdby6FG&lqV{J`ErDPm$w|HuqTGOw<|f9KAk8UwY18mHk#3(QuEJUKr6h zaMVL-GA!k>SM=W@XKISO*OvTsC)Rn*?3hCgf=A&D=7ezHG|KeqQdANPA_P6jwlj`X zhxQRTKDj4y=VjpbQ!1vU@2MrkQK8PE!1KSh26Mg_MHkqyw@`WO8!EFNJ5;{n;352t z71cC2VF1O`+Q$ceA-j!wN1J`uU|U2jzrPwhSM&+kFooEUEof5v%7_Vgv183uO`Ez{ z1gseg`Vdn~@@spzI@Vk9qg-sC^1*iKJs&fy5uSD}^TA)wpg;Rzb zKyuUNzM^Qs1o+ZEMyN0GOsxI`7Z$6cCc_);ttg{xr(YuP;X<`-HDzY?snbziM*De-)y~K-)O07RnBFBm0^dRpH38dHF-+W9i9?ElR5%SR@=CLeyT*!%_fJg zB~b#`K0ot0ZsL--XBbi*BZs<$NTbsj-}|RG+lXQv^y6{kf-!w zWAwQd$=jYl?JAs~6v z3{sO*u$X#v-TTUM#PiI-;Vb?Jza+|cAYq;hGwcQ0GbeeMJFV-0)2&bscUzhImFJ7I z_|w!mbM?lh2qMpI`Jb*aVs*}5?qF4tp?>b|0O1Q+-gG52^@?`Hie^60df@HPE&@1Y z=Yhp(p|TF^OI)373$pvn{;q~=igJAp!_*9f#h93SJj`azonW-71lTB191vr!Zq?!A zGha%=#%54GlMZ@r3w&X#z_FMpB@>GAs@=E51@{w%|4qAW411>ifKt-Xy~CTB0**L8 zmju3r3G?ZPIo_EB3ePmyA_{Uf9UJgYG0sYuH0Lbke7gSZtwoie|MoZlHKP3^KIwUG zb!A2IHCQgF&+L)k1YisDT1ANDFqNrE4z$JcDE>DDb@l3IS@a$8C^1J3t0?G#GA_8q zT;~9_CA2K=(~5~m*n+oII-)U`&ZF3GDj3s;jGJy>J(|@9t}bo0C)zI>2gu%);3Oe? ziXGgnPBDY!kgQ^;3*7B9+UVQw->=sNbGV|Xs7p5y={6R>^$jr0ore`YdViH`_3lsY z0)RbhY-0AY>$k9$QX3C?ZuxhYQ!$gPPt`FZ&Yi%{??sI#Adf%xNID?GJC{AxQv!;C z?DL{GjFf_I85INJ$+2lUEAglM2?6mWe(4I!xq+l!yOu;}JWg7YZ(^Z07(3lb8`_I^ z?~hP6g>^*BCu1@B(2g_mIa>jbKhbMkMJyXp6zw&f7$o3JH_Rm;Fw-Uj9WiN77d3Kz zjJw}nVGi9O?-(hi8yVg0?9MU-QAB{(LUD^nk;e8@k829mwJV1qAz(nua)P)qxLhdW zv>6FcdjmA@PiKGv5gNWa!%7#0h&3Ra{oTzRIiLUl<$Y101opCw7OV7li79iG(R2U5 zk+%}d*b{nY3yaR5rw1Db+gN>CVk6e%FFhVB>ds}%Ylxjo;zT+QLyWaKbK+*(`H6Mz zaVqm~(IEXXN+Bm0C!FFO+-5oS@YnMnH~r5)w0I~Kh2Fvx8U6KTvKYhaRh#e5KCYTi z=s9ZcPb3g4!(7guh<+y?H5C%e2*ZNER`;4yQ<|}wTFTy=jYQYb@wWslj#iSJpp-od zwJ#>y4UP9!2!D{ZUSW#Y+rN0p{n?0Cl-Z3!aw+WJH+ct3s80OR_w8;f1f#5b#y;SW zC-kYCa^Y*>Zytw2T~-_vnrAy|IB)Aa6VWdJZA8IVKJrQ4GbM*8j-;7v@cp4VMB)Qd z>QmNnPleLf{i|-cH|hky@N?u&;Z8AVe)`qHlI*`)&U4SdxS95Qtrm{Lj=p5i3a0MR zUd$Ruat(ic-d8c><2CrY3wzmZtWaB2LCDla4N2<75DC09)2{B7QLp6by=W`c!*14{0z zeyI@TIXhZr(Uopdhe~pV1vHR;(;hFxQmUCIrklJcSgj+gJVVH{?^7W?iVlI*2Zku| zU{!HZ<7;wXCVOw$Zc_X+T5NY7jj3TO@}wp9PgGOOa&vyRLVP8c|d1E)@gIAwRB^P~y%DB;pHElX|0(?iXvnc;ss8od(9RK2%9%4pXN@>7>+|6s3{KM=%UdjgSLC)5jTaKd2|r<%Q+f88U-)E{e}s&I&gKXuQ} zcb^L~g(xILb1wLF28Qcv-$&H6m76c=HlN0!Es&m<-SI!!=2~2lZCLG0FO)Xa>vgdl zlBro7{>B%FM6NOc7sCpHYxMr&$&*eTGrPo0S1P91NmZ#S9q{jqtc!TuQ4ulToDNug zTE2NWxvw8kY^CahnWikwsW^PK7q)*<<`%#AYG9r!B+6B;e9NA^d~jaG?sPx#+#*wve){JZxAvtP2Y<3e zG}xdi01*GNx$%CT79%6({#@rp(|imI;ht@aU!PL9fW5F&NBb8)OJ=S1YPg>))XV(9 z>R2nu4eHjNe)?l5$?04&HC1Q$7lK@-?fR5oSzGf2P#_<*_CXsO`ar97C1YnuXC!Wq z2!&X7XA~qkBtK_Jw!HB@BoM}kr)m-#yTkD~%{d7yy|)6+nGtHgBov|6?KgfjNthV^udxVdI*+wQIeGIz=He#euGh|V z+tNVhL6XDXfa0g@y9syH~CYWgU_HX|}5CVL>&-e*OOr zQY(P|LDmDxQpW||JoA48)%;WfalQj3R2Fe3@PjR&9#h>VJbPtfv`7Znu<{}msxB9W z(E*2i(u%}c1ddPwL&AL|6%ZuWM*;fl>p`51P#LP_xM+N6#cN_B)@` zG;SK!l-GJ>Zg_kYNlC@9);`1J^{;+WD2#CUJb-Fi595;hfB|I$*J&l!I+WQwk^G6t zT=0U!jQg1|wz%pkH+K zz>7+jsu#IDNS9v;A4S(X?wxeb%ZdN>s@UbXt~&T4bvw1!E>RLBxRar0W8bYrxW??G z9fC;edK-KBk?3)7ZSnJ~8SCWOc$2z0*L_A7Qrgr$)Z9w2Tzv8FJn4|ZG^#V3Hn*49 zDDSIAbH`$>HRYq+%TE;Q@%^x@?Ip-io`Fu#IaVQ%_lX7q>c=Z~DtiYuPT7wAXufvA zc7gN3+Pnvw3WR{Ge!m5u;)L$CFY$t;44*w=e^z!b%ZvQ+F4RUVOaz#=WwHOSi0Vm3 z)~WdmTQ!t0z+W!^j~Bpj3I1w-^ZneIvp=3x=6I=_d@=3RliB|Y2-b7+}#@(!{pPC6I| zie_gbck)BN>)PF2>Jbw-vZwI{Qh{GBs3XE2SuMER_ID3VPHG8b3JUCWM@pAV)IYke z?O&L7qtR9d$rTP7JuGp4=Imv0r!4?2_HIF`6#r+>5(=n2-V!Ak!Z@k|L(2qe?DH6X z8q*}h(3X}{Ch((x#IjZ}OpCc8VYOMs8;L*$6)~YPjhE^&z{qe0$wHUnqcBiw&{>B? z8U3ZY+4}*q^P!p!@hI&$4+S@8B4rX6wq$_0`n$D(-;t|UTZ=bViM%}&69^embdm{9 zZ~beELFIOBSJRNZ!$L|Hndaj0rUlCoQjA@tBc;ZpQ`Ro(Ug>hgaSZq@(3$L|(NcBj z@isj$ITIr2-7~nNg|p)omW1AV%pDv7Mk=MV4lkW(O|jzfiTdk70_8js{Ri+?M?3$zRcc_AehLl30`oy`5Cz51*uOq%c;=RUnA z_V(_V;jy-Dh;3|+{}R$%Y(t{6gE6XKFaUxICfFrMD#Q3t@sfB`<)OO3=-c)Kwz2jB zzvuG)oK-N~3=UYtjQh?X{4eI-`>)Bn{r|qKSG87zDpf#`)LKOa!H6t@q?Wc+5x6WO zA|q-TGQyOZRf~$uC@V5ki-^p~27yEb5@sSZ$chjkK!A`%c52J)jjBlD(R8U0mfa&*hF|5gvm6Rj1)V-_?ovyIy*) zqmLLCW6zMMQdYml7W^1fbKJy{v-IqkX4B#0qq^ra&)nRad9@eOTYUyJbzk^Zl8E&Z z;s1u`VL&4HLf6C|kEPA_nXOI53x5soT)Z}Ld3LM>d3q>Ong1KJZuH$t=2_V;vP$(M z3(8hneaL~%9+X~sQgeT1=f1yp8=DT|mAPwHJlMo`e?I>Ko2X_}UEw{t7ij5$qa52` z3S>OjTb*jaP5>w%q<@3{b=ZoX!^QgH=Lrpcl`)usl}*yI1{1|d#fmhk76u`OZs#QW zEe^J{bC@6O)Tdc#Uc3otC!|x&dH4Hicu(Xg*rD9=mrJnQ3y%e=bn=7!NHyDNG@AUH zMU`F-C1__CPYryd!SiR_Os=#5?}tTAob@hfqz7-VbMB>`JL0kO1;>V`9oBuoN&{!d ze_HTd4T$8@u;=4h8CI5b=t3^p`o+(b9utwXcEc+3S5EDbXd9l~DA^43;QmldL&oIS zZkxUzb@WW*qdo?X@LLQAO@u8P6A(|mtwl%dW%r(xcrqlMOM%9kAY(-O-z z)Klko!LLJaOTV^SBMl;)-mlfElbUV53)}Z1-k+f<&^>xLw z@*jE+GR7mx2cq?j1J>rRCY(g3mMU_^uaaxiq^r7XtwK+<;3KllVpH;p!`u)XJqluR zQ#q`dXf9)0jbcN(#!dlzkR zu6Hl-w)H(A1ZkIjTo)`Tc@In7Q4y7ocbS=ft=k{Nv)9B*-=As65fxntFs$OE{5ER8 zfD4MuHjjKt)V-uy?Rsu3yI^`j)mORjAARiF=bz1BYXbt;*foETpcvGGiL$KxG{k!C znY-LF{_cn|#CjtOy$iPf12$1P$Qrf|QYc#g4pcmIuZl2vE9dF_>TRGN#ak16)uVwp z-m6K;{UKfGnqC}b6xXtG_RjbbN2xT&_e;%b-xa%O|5eFK_p{3C+|N+)JdYYY6eIc7 z5y=uH;g$?fEg8Rh_=9ZsInS=+rkl?k9KI3qGaeq*acZ^qz2(=`^_Q5pknP+H&wf4d zrJ;evRK2O($Wtd=o%9#`8}iqCe?`zQqt?(5cVqqTqT17e5Y9yL;Xgev%p2i}GDE-O z_{Efk95$!rdP8qS+j1V*%(>%sU~x-50=JXva9OS#GH)`R_a3EhjbPe2`pTq?QJv9iR>(@VK=m3fvV-c^2SxwJ_8Cn{Y`Kn*IMn>+H&Smvt! zt9C!Ee@WfzIhpF1351N@-Ins}=AT{-Tai?X+>^N|(nqYxc+Y!~XDri{#hH>x4EML3 z$0!Clgos7=GfFp5wE71|F?QtB{D49mmZ=5vF#r)zACGrC5^Pl4xjZ*tsQ|xJ%iVVC zc2rb49u+*Q$%Inzbh8&eJ2sHt`)c=kmoTZ{VHH)8W08C&c~M6PRYu;pgDT4L=r6%R zW8*tFq^oAux?N5;3spJsxZPDpJElornPu`-`%B*0p-`>wPv9}Dj|G;%D(Q0THiH2Y zX=SqhwKIczi>J$rV{dzdoi5dA{uK$Z+~?8aIhIyDKMBTjU!taZy@QRUetq_~|K)7* zd;+`pG^>0QZ}x8W?^UYQDuKV$>fF%m|N1?dax~;o2#{qD6PRc&ms$TKdbW#YmmtGB zn7hbxu`|8WU6j@FQ=kz z42qwYX6|zYiHD~quX<|POa4f{NOhblFG2U-G}-j`IvuWU6cJ=mT^QDB9JZ^5^dOd| ziNsxq;d*WYf3^($GJWJ>@dAXLd%%^Mb~FXt;T~ccYK%%(Jor zZJbv`drI^Yg~i@l;0- zM2&TXpc4^Nba8$Qwj-1{k`2!(+dQL;NY6xaCLy%Bj9it+7z?3t_-VnMU; z?2?1s`MwxwKTdb5Yj7n^B2hi|BGoADf3^GkifCNc>5>QZ7)aA7XM6m2Ze|05e#sku z9V!+thdK|9MxR`+N%36AQ&M?0Dx~G^?O|l)&PO2CA@ZW<0irf) z*i4OOeV|p)$x$Wg1tIdxn~k#rA)7IiT2ffHdNdno$|JJ%g@hW6Ldy7$Y5`~!bAJhOc*&pS%{I?{l z&^RDJY#-on`NMf=QI0cEN|rH0S~{7<-x>v63ADdIul4Y_VUy&hSH1m4J>~sXwKilf z`iIcq?otVVS+JkNRDb0}k{r*5s-`M>*<|d5K0Jh*(eJ4v-Sk8Y08 zUWt3`!gtcG!NwRT{eZsA#lgj5*p?%gtSfLhkDBKJ!CdoQh>qbd{g$S|5RVf5oRaJC48W zL`6DXN_f`e@V9RS>Y0B{ygv%7`t;WGia0hnmrZz(*VK9FiOR7Fd18;M?@viHpU1P0 zOBohUs07DyHWNAk>7!@=IOOi|KEXhpLiM<62!=B7x~ogSps6eDu!x96Ow*bx;3SoPpOlQd9UGa$24P|n`flxBkyv*OShL{Lk9bo}cL@E>dTrzk&Wat8XAVv43&KA4T`M z_fqG{_n74s8~@#I<>E^VJ=aUHB`^f)M)$eS>CwA*moGIE{XW_4MMR{R<9XL>zBk3% zWi`uO?1Cka_=x@wzm@;*3ahWmDe9Z*a(s)_CP39snF9pLR7Kf;7uc!SiZwH9YkTsv zu)GIZgnHi9?Rc);dH}exzO(Z)mcH-ylD*WS&HTXV-RpXQj0zgOxdRG2UuFV&0BA=3 zC$2b!tMJ?Y{H80fX)z()53Ab8-CXqGu{Ld?6I#8Js6%koA%-IDTC$z9N8GJ*Lg5P=;EnP zx>)x9#GRSCfo%87z2sB>Dy}ztLQA-K8vb|Eev|qZdGkh=`&HVT2jMYAHHxby7a>P3 z!SF1uQ9w|yNp6-`QR3RG$@Om(&-y2!hD6YJP0E*7i;KyBkN21~Ul_0arhTK{DZO3t zw8jC+?K+NNXa^l-mBX`C4+)LU_wt4L$=)M8n9EPdY-kKMImpYGoHUVDlL!f z6k6#dk72SX31h>}U$J3A!pqLm6ZhsWdIl0&~%FqY+&kUzwo2-vE44Zdo6^C})}3mu0#& zzamno$ptUQN2@lS^gv!I*^s;0P~JKuK+-^bGhG7fRC^SgpeG5F+0bHog;rpy^HJIX*%4#XX@&{7C?LBWc(va-fr~e9P|F7^h7h7565LT z9BzYropz2CKXoUm@i70duB7fOP}!A@F%iS}Fh-&br^XMOwxA@upz`E0#P^deq{wUW z_Y|yyf;4lwmTl%$F#-UUu?#-nI$ztbfO2JQ>dP&;SXoiLP)RkSf_;J`yd)oFK^9+8 zE=t*v*(G3f$YRlUvQ^-t7NgiF`NdBbP9PY!m4E&9J+0>EdZ4j?Q{j!}=W}eM{NE?o z9P&mgcQZI!8?mu{k{|;PglFgdHxB&hAg>R3L>jCx~X^?jJkX1=$^P9H|x~)9+Px8NSFPsy5ZRR&u zPAJy0C(`{_X3VDe?m<7fbIZ=%Bw{MC_AAMxs<2>aRIte=(IoJiW;Vt9+=T0xL<5}4%H`dyb*BBkX7M1UHRG9Dm5Z4dUYTsUc>LTzo}dUfpXv={`jazHdfd-! z;)lVadIzirlOsI}!QxA6XJXhOOVm0JChFLgW(LVZ>w5xF%M!;?w{>g(DuHobgvm8^ zo7xQh%xSA9pG*GVML8a3v2+bn?3qj^b`EV6Xe66YxWWSt+_92)p2w2F42mF=2u8F z=bxj_XuC2ia|x;uSluY!+ljW0ltmI%oj51C;@l+Dj+X z&kt^8+;eHpy010E_xw^0C(<>dH=BRn5j_!SR^c@Drwni2x@eDgnw28c?6OHR&2nn| z+y|8Ure41}u5hD-$wHe50ZeJgpL5J9EIJQnEA)czzgAbGS}ctv@_$|$|M#2AK-DwV zmOY2xocCXA{WI^_lYr}rHp@>T(~=nn_RodFux8(+BQ>ED*G#SZ9hC$-OW^(IU5C!f zFAA2atXFZo`-f{UdrkSFY_aZ*n~OP-&G$+WdX<{_K>Z z4P*1FJqTZq`ReNM5(QrHQX!@;DMKE#K{{f|E5B{2=#olS*CR%|e(~bz&)qjfN*Z~8 zW~s{C!j39ItZv&BpvGnryC z&BZS2ArtPTuZwa=YLG_H4N2M3&)+7qg$SIuuA?Nje>ZtOYb<)?iQ}yYz`WlR%N5|( zq2R-VEzjMJ$&YPRA1a?=Kau@vNZQ%c@+1>hsgY)V@Vz|XK$7fpsu=t4v$}#lXMrv? zxudT2&u;+{fgEzh)ah9H`5547O{2p6#ZC7JhxtBuN$buDv*aJRNX2Pz>L$rr!OSbpmlk(r~R7@>S(G z`Jat^$`D^a{us%AL2Iee&^kbF>G!hxc<6&TEjdtDMFFCWiyeZUnY&cP7>vV7zP5(u z!52hkcIu*aAz_eXt^WGzw-TLlb!nJCEX>3`5)D6XyAK>pI7&oF3<{Rc6~d-+O6jC6uT(RDU|yD2zTor*In zd2)%;b-?6;1^jj2e104>q4ujHX+wFh zcsPxW%NNr%0vCDgP4Vx8>>ivH2+cHgL97~Hr z&DC^SOlzNzBpv<&(&V0n=u#5JX&O5L&_L?XQR;q=uMQKEmd?WXg0`>RJU&0hsqm!F z>(=kq-%*l5CejaSo$e^b4Hhe=QQMWl3wIg1@E0cj#&ykzgP_jf&=|zpjaA32ES%yt zTK&+N130Xt)`n?57P@?Z0!lCIL7FsYIVMIl>g+KF9p;UMEweWvz`{2T;RDEDSv6lw zQvbiG+B(;1(|qp=3%#qxx1?Z(7J6Ftq$aYjIP&g?93kJ9T@?M{prgS-Id7#f{0SiX zv2|%YY7u-x@zO;(_Q*upXQWy4DyHvv^2O+pN{<2OR=~?^Uj(!vs;jZC{^4w)jPI%z zx{kQkr&6EFHyY@g)!T1}3T%_bzVDzz1cqMoY;a*j7ts_!S)xK}-bQ?Kx0S3Ck<7g1-Wrs`gViiU1JO-1BgKn}p%uj(uhDOO8 z>q_C)oUO}|v4JwCdV!ow-+bww#%}{XUR0$aTY=H6VjArAG&$Evoz2}3Xv=&eq*$(u z$`iGXg$I9H#eOKmyxEj<+m@X21K~E2zXrazG=|9u4xKT7gR8-OB%Tu@TnUbE{SO4{ zkt1(Y;E%L!`K=cX{z-*FgoU@?c@m+=0_+GFlLq4y+RqhZ(vPdb)WyMMmHsRDS5Kw= zo%kox=Jlj)zLU!iZTsR4^sm(*8Kvgm=4L!2Tmxvo5n9(~36yXYb8zglyN2>9qrp|J z`)hauGx7K}bU?b#_EIh_XrVENh?m*b-WaY; zh6A`JbszmAZZGu<(hueIjOhv1Cta#;1%T@9&fa@|VfpH{CbakTQ5&gLBKhNr<$2V6 zua2iEp!e7J8Q9SYDslSAESCR9cI9fD5i-~jVc_KQI#{#bLmH*-rCMBTtv|0h3ra}_ zbl^PuuWNuRGz6>gonE` zA}80DxS|r`P`fGqkl7HkRK5L-0Bo;|jOE*b#xZ^V&M0Q!-2p(4weQAb31D24R=feg z_UI4iT4oP5uCI={mhY=FgCY1+j3WWP5Q}2OW$x&Yod;EKnhE4q;f)OzVhCB z7Z>W?`!(&`KRMS#vbb4>mX%rMH@npr$z6~=iiF<$0<)hlxFCYh&JN}M%2Dvx|&Ij9I-#Z94pTV=eIm&s;%4+k0kL%~?P3&(6*vj`79 zEU{emi>mLOxM1@}&#AtwBO8!fJsbecuwkKrr=7zAcxl~GWx%>#09k(ZMNoFmy}FOP zt!8Z+%}9TytSJib12mQy(9;Jdce9H^N0DBD+jh31*?vhM2rO>O;0Md>;~VTlmq$+y zj7M%O0m#;-R2=>e-4MqpM0t9;9@aCaEe=G&7?V8$(i zMF{Owr0^7Kyr+g<*ZIx{_OP|_wdZ~@%Ny)$mg9i&5XQg`S*j5N|bvZ z8+Kj_%~Cb~)gKTIX?B0EUmh?2ySw|348CCc=Nn3eMPG<ei{adNO;;Vr)fqYYGdry`&`8&2^ zjgTKWK6V=W>q?K5?eirdeCXIuH=>H{PWifSrNm(XLNluX6RzO3)cN!p<Oj?$Ay+T2ka zHNn#BIk>CEwc`M&bXY!O6e-~@9x}7N6?zgU{CwX`BToUibMwIO^O`ScMtNovf;+9* z>Up~QTl}p?ce&~tSW`tnuKWuW;!}EpjnQ<9nmDiK2 zKOJ&U`5ip*ABVof2=|erS51F8aCv<8sCiD5`gH2MoV=rzfOh#!TgSg^j_*5*I6N|w zs(bau_un3WeeI{Skz!;GS6)r`4de=xzaZ6kEIBQDGO>g$K$QgABa6{HT$IO732P%p zMq6v@$`7G+G>(;g=Q+2&LqBXeQ45j@oom8nBBr)#FAmg4o;C-f##@Q7nVWOG9-$ zc2seL=+ZLD3PaNyqDjNwso3lDAVSZrz?i=Ask}tQl)#*zi*_p~*jxJE>0Q2M(CKVY ze=E@!qmw!esaww|Ci%nj{*`!H&w4Z6`8%-9k?=$9i@Wnq;i9fn^kWe=n!oA2Mx?l* zxrGTKg=scy^1ku|w0RHxL@K4EJNk=%8RH-WlD`VGrDhsZq8^C%)KTLfQLEDnVc^|k z*7IK!tEUet@npqvR7m_Ein?s*H4Mj#c^2E){^4-#e^jljKA;Zxky|ziISbk)+mE6c zsSUJB9IG2cM9x(ybg~rBI@P(gP=%7&foOU|w~-fix4T$}&Gw0M7Zz~U>RTV!*R}My zFAn3*T-;;n6*kYWy?xlxKGtgv%-QE!so$`T90KEX=VKJMgC`yviX}z|92M)kJ=%(p zv`^jb%oxR4oi>uHiFlypo%H2Nlep*c6mx92;=~FWhy7}r7| zFedAxtx;w^hqzYBE+Q1UY4Sv-2K-lK%xYtJLdKkMZ$Zz6l12N;Xju>{p`Ko}9s-=I4d2lbi zo@RC_h;FC-le7ME1zb#sQx3VBFn1$ z-7dv7+$+5_Y@o~Bifz$%vE%jd9e=eX!Uqp<#GPDpvIo#3?MEk|EoI-Pl#W$J41uZD zlfx5XsFnqNm}GmqCR{Zmp|*u+VMUqZZ<*#0WMaa`cVFm#;6_Xp--K+d#?-Qp+keRC z8}6uO#az8wX*R#kBQ`uE-$#;gQl!z7)&TA#fJ z5ufugY(>kO!lP=M>`GU6y5|?PL#oM^LU)h0X6o`K1e3hIW-NX^Z&yHnU^=~gKOvxK zWw);e_M)vi+vosOU;W2T(uF@pC{)%4x|m>Sif+=+WGrr8w~=5tIoiql>6g%w`N?Co zl@3U@i>7?`^O0^tyqx!Uwe(;E;+8G@Rf{H5Da#*DISBKFD=g{3^V~_Xek@rC`Q;hs zgBbyW;=myP;U9sj8cuyGU}8nFbrPx_L5>`8+rJQ95tr z3`|zZ0PVD?&IKQO(UPg2I{dcv@STwFYX3SLZ?HAZOCIZ3w#e+D{CC1x)gB@L?{pgz zxXL)mVMohrpx~Wo)l{BnOv3jgkYZ*R@wVonH5RqF*9pz7{nT3qsPqhQvUXAin5dGI z#o9BRj4Jy!?ZVb^PD{Tjq)jg{ns#r=>%&6(zUHzA8Q*HoOMl2Mm1qS@@jx z)Dj@t?yd=osanV;DE!(~AFQmd@t$6eev%eR2Ja`hx!Cx(t~rO_#++t{ZOtl$M;Wbq zUM~vhY6Tr=AiDizK_w<*KRv~jSSw34M#j>EOp#n{St7N11Rz3~nd;7Kc8xVd0Y+@&LII;=@@akvb_iEsCtFR%GwWLekkTqueNRRBrb2tb z-B80Wb2{7O7#ajcWRA6Dmh{JM{Vz!UYjvxF>o^#l7*0RqQtNCDjyS(EfmMqY z_mG{DO-6C|wDE~b%TK*VR;*A-srCuxAx)<93!oE99<lRF zbl0et9IwT?H9*~6Ch5fT2XkK-qzxOi2*6qiIm`9b+H=(D&9Ua53SSUXf}HUlGE7pR zDzc2|Bw7kHyFMiX)iEGOTD9zt8ly|YN5#DC!N{l!TY~0x)r+8T8vBRD>cE}1F^wm7@_$j(DQGqn>n*` zZ%0>Qwb1yGgKl~mr$L)!$ptt_ibKnlyh02On@z$Iyfd@2BMGiF3qcPS0ndA7|DVpT zoV5|e?d_;x=}xmR&DzGr8@kXVY7^P?mEv|zcD6PKqLjVI0}+ko&|4yzNO{N*ElVvN z>tCao_$TsYW`?8&rTR$4I^vXVfodEq20bqWr! z(*u;(x)`k9WZz~|AZ-(Oou9&wH#QT=hFNj;BnAIWI72^fK0Hyea0pr(`sycK_?XVb z`qYhzPO>OcT3hq#f8{U#9=Tv2GyU5B_yNPbBAYi2cwH{P*J!j zi_FDuyE7*V)`DS~xaf=(s)pR`Ge!iQ1(Sr3(lx*E&V(w@4>Z;!YcN}o+#uEoB>T)J zATzMjfe?Ghw8->vFgXbmhI;U8XZKV6hV;4$Jku^0k9v>zaHmkN%B5QmICX+owx?H6 za>+eQ>C^uC)@UFE;gl9N8>AJox?hv6}8mnBgh$3tRdeaQdy{;TFY;1nwSv8|^Hp4zv&HV2$H)o!4~ZhmJEW?fBbW zTA1x03}d%w+dLc=Wxe#wVL75- z=Ho{Df1y7KuZ_H~rD{sX+n)dSE-Fb}#aaNfxl*cA&{ z#R|BaNoooESNlSj)lsX@u=A)DnCrO?yPfSXu@a-**zH0ZT&XBkl1HVu?~&e4U4t`; zhyn!KZ*J+jFMxXMZQ_z+yydE{Nr7JATzKV3xFMOt^Urn7S1odjpxzH?3`*B8-C?W~ z!LcCqAC~i1U;db0h*3mJfMZCH`!r&!^>WpG?_F`H7-SlguS}l9`Vr5q-^8MpKV7Ju za6seS2)qfO2VDu>V%jloM-#g&c}@)dYgT#LTdl0Zbw&b>EM@d*zwqL5XU@bVp*4UC zPjohN+&KX4-6|l}fNexxm(<<4`j zeK83+|1a;1otT2e#sG^sB23Tmb-b_PBrFG$wF2hdo>jra4DtrIzfOMv-e#k%HYD|oZ6 zNtB#3Y<+;7?z1z~NO|3+=V;0@4uOrP6;68r8+2r7z2$Vd$|(k6;v}gI=eT;O?RKmQ zf_s5dpc{sp&@Y&cU?)4CuD(aWrm&=HBBdYG4+W>QBcgd@u7u49iOKQ{gZ>&^EE3#) z$gSF2$TwLo)oOLt4V{Ea$C$j=^SUd!w-6Q4vsBkkmd{#-t%l$iZ%zryeuAQZ`&qJ`-(ei|&b)kHYzS(KyUjbH1zL*+Eb3axhPSx} zz1WIAkXbe!L^Tw*QV)1^EFRu#csOVCFa6m_$x1#5L_%*#V6}3XZN|S8L~N42rdDEK z_ml3ec=kCwHv@XZzC&>*W(uobUT8Cm=RIW|#E8fx&+(uJ$@Tq10$+(bbA3n4@jNtc zOkWca18!~4xFS~~B2b7oGxl2+3Yr@hNGRZX-!5$KvFaGvegbD&e*aqi-p^N6 zx+5Hem@D{qTTD%eNS0S}Quu@4x@@tLdX%Pr5n}-XV56FUn&n;+1j#4t4A|BXZFECC zSU@Y7<;WUov-KoX8m$pTO9Q`1Aop0fEDk2Ai#kNS%9WaTwTzkqbJch_M0LrvN_~Vi zwT#mcwbn9%j63TZT-?Y$X@m~6BFM*UF1TZf8a?MLEjU1GlNPoJUevNI)fFTPphjfj z0HR|^fxu^g%6cJiB~y%zqG4)9N`qy8Iik2_qVC?bqBx0Uf!$adk-Luz2;z+e7D#^o z;8_>$v>Tafx5HbmtFWgF<8P>NXkkty{HDDJXgj;*=uXE2rP*yLl3$li_y3irn@_Y{ zQX!qIb^QR~sPFi%u;}W}*ccjvD}ngR%(nz%n&AW;%YwSqt~#6K_V3Y)+5}yiH7lL> zycwy*XrskE>DGdF*pX;d(&rG!N)XE5dO1c@HZt~>F1_ni(iSN*f8B*Y$MRy%hbhL* zOVaYG`Wgz=OD*Z2`%O>B@%*k0O86rUU`{d66fmNteXb^S<%{xTP)mol=SASciu)Ay z$e{8VM9cc~AN|E`OPsb(sF=|!M!E4}@BW-|_W0aTcj^KjrEyWefhM00d;(y=dfsy5 z%ZJ6-)e|SUVcj9VBL0FWJwAA}dW9i~rhc56-N93CXW$-UR%OQ;?9>b5_b~g8Swxy` z8UL#yby((nX%d&`#Oz4vS8*r{BR9_~iJz83*xX?>QI zxh#RARaMeP4k$W5jmh?4FLb<4u)+!(6OhwOaS7j255e+NdzFlck&bD2_F< zLZ*$?LS>4f&J_k*r0gwsdA*_V)W66w4pbI9bRWjoPp&AJcH`UFtu5}K6wkK(Rh*ca z`pi2lSLF)eP;N{N1!wxyB-isM81WMW?J=XZWed|qa)~Eno$;1d#kcGva4E2QT_!)V z&!pf03IxSv2v(t5G;AfP^e|~zR``%j&bp$ojXDFu!HZ$V;>6-$#lXJTwb`e%SSO-0 ze=-@)@Eoe+-$Y}GrE8mgDDIB+TO0MfR=YE^M{Kz?uUXE+OGd`>HiELr*6HDW7*HA~ z;aRbIRFq7b9^Qw!O@p%5Jbq+(5eTvI@(v+5FJavQssrnYjdr71r!Q|tehymPoEXt3 zw^ZoN46Y*dn6fD98AIpz1w7TOg8kJi=ioce>_bSz`| zuHEk=)}9_4ONn&ke8W;beHnAFRpG9=tRG_iau!@wTV8l9F-bNvI!3UVl|Pj)ST-k? zSZ^J}+IM_TAX};S?6h4mojs?tY-v|+zo6RR?Z}?Ox$AUL1S8QUB3qVd-gw|rZ$vK7 z#fwU2qrFt3jx4rwlmbLfc+j?+aW1T%MTC7h_LPe3R5CBAo2~^T)-P4S5rHMq3)?d6 zrIx22(^&C>uQ~(k8m3Z>=|Ftd&jT>lv0aNQHXuIE$w%!{^u$Z38tEKTk_=;oJ}9`+4KQJao=+00$(Qib5ZsZaa+23SZ`ujT*;T-Gf}} z(npuf7}ZKznNQ)3il_nn?Cdjlbh=|qj2zU;q1_6Oue zpys7~{cU}ikm$vPIFdJqW>eX*5p_46~4|eqj4@8_K?3CyjMpz~w z4R)3|N?|#}iZ|VKTpVkiLGHnoH2b+0Dthmt98O`d9V0X81Z#v)51Ihr>kZ`bYi7O> zzXIOca#fzp)VByCTr?-eZ%*f!Yr=uQi!X>r#t11~#Cq?}g+wn(3u$_F`8Bt& z<}|z9-qYQ=s8utIOD@K_zUJ@+Vf3SSci6d)dnS#Z#c!^!X5cT0(5UD`w(RyQ9vijX zlw1`qJJ-953D1IOHi$3Bf`ySwlYtegDf64MyA7fjK*79I!Fb})x$Zv5((GD50xpBY zI$M-q%*`lM(uGh0dglxddhy7Ms`*uqKfYBM`zm@qbOINP10F}Q9Wxvk@Qde(*FG-Qa}$lvl;6!XBDI+<#VDFFRvWpm_~b_2I(wHRlw%aUuwDjP+pAm+u|j>rBe zFX+ql87jj}aM){#0{@947$xc&h1aO=tR&d%buBs)F^zW~gHOY)zS#LsG7W5`g z{hH88fU4ZQ3)MGZWrYT)&H7JYoDn!!s<k8*Be#a^d;DHT7pyH?pBRj{(BTLwJY@6KA80E2sRKcXaBJ9Z*++z(F$ZZ*( z9&H2e13rcrSvfW_e$@f=F0UN?mbv}J$|RO`CmMc)mHy=^(C*Ds;0TU>gUgu?)E=7v1)hjGL?S3{Tk~%V64U(8C>}T3WPVn9M9s?=6zd z$7wm*FEYN?iqlipl-nU1TSBxW^x9>0d%hk%3;iK-4PKNQrn@XsK{2W%^XPuv^@$ob zqgLJH2UCV*R&d#&2GU%S=O`{8_iUIA1xNIEztA0U;=LbfB(l5|sYN6YvL#lze8YEz zz)$h86)Uyy)-1V_2m?Vy?H4RzAx<6X#*QEud04U*dBMY`99>1`ZR*#eRpXn%D8U4g zOAW#y*fQMNTjFX@pX3^q`yL-2lUu4`>;Oby<}7_G7p9c?5{6uvJv%!cs^5y>@d+Z# z%KlnVsX2&pQHkuFje1(;o9lRuf8GU6x20yQ7ME9fcY>yRzcVrwrH|Em=kW4WZyHqm zPw>E@kS&Rk=Elh&VBo$pqxL6d;(2;wmJ3qcvWx9zBVXd6O8T-^w9PVI0@O0J_jA|V z01CFfcSmc(5&f>WCuY)9hPZAD>NiY7tlVb%{qDUO@<4z=)F0Fi?d~b>uqX};eu33; zUcW(g|4aFf1f;b+Gm4S(!U>6)zIrWt6q$m@Sou%=`R(<-JSwsAPe0Y!E&@2rgq6AB zL8e#?a($zj*w6WnawX>i{6Kl!o%E<{tE0dhl;Wp{S(EnYTb%v&&xY%g@mEo7{@V4<7d|jQW-fms{ga_{W z7SekAc{e2TP9BNc<8QjYI#IHtnI+ zW<_ApxyaR~Dvvw|bkwTR9-GJtylZ_Q}^_@RN0d*+Vlar-O^-Z>3B-9z`4U(x>{H6{phh(U6AFTvQ^PVom%`^o@)`S zOa`alTFHQT-TP?dqJN3fS%Y78CqSY^xlhc%z6(^ddjy5C7g0I{qUi1>Y{%18JDQED{33s{N4m$ zM$&k{E9(MH1iuo_fmgN54;*97PY&`cT|sR<)s_J^*AMJ;CcT;#mHulgvBO%~c%n)> z>D=b3TR=4~ad9ji_K4?PZ7tfF>D6I~op|ziN)u#YEnHJL)%(p@onWj)_4#dSv`RKI zxW6`hYH2h;!wjaFrG2 zI>oEW3MKo(9HP3&2kt;REXhq?hUgcSlVSQo4C<&R?9*JsugKv z*kffjdrr8nKZP2;9(^r)LY%b3ZuMQBL0Dya$x%AXk^q(R-BnvwaJcAa$4sY$8|ZGa zh)QT)g4Lig8LsVU81Zai=a0?N?+r@46VbJFlIo6JQ7$#1{?AJ$9%Zn~?L_MNcoZk$ zJuBRfN7Kq@jAIj3aMk#;Q#VWgPH!0iZcPx)`Xc^VHpr4eAQ(A_1Rmk26|HcndUJ7* zrC1u2CV@%uNJad{9^9*Cay3bLH*Wk!A`777>0Y!fxImtb7p;&XcUx&O*x=>es?u_l zpY`H)`?qrs8M4PwRFlOeib=wVxuqK7DysU|{-kOwf6a_o&wB~qNchDYbV_N!al)Be zeSSN_{+yIx_p?v(9f-8wHIKT?b3C?nDgh`6YXFzYO^WSB3?iPNO|bh%aCcIR`+Ev* zxMRqz(?0g-P7(B-?@dQnOpujkbEu7$P~tZhZi-nHW@~vCTZaZY(odbS40z~YBTKf4 zR4RCp@FQ_Q#|sLX>A|C|*%Nft2K~q}ILQA#>K=rb;%dN9;xq#@a9_Tvi`-IjvFZq_ z?R?#=`%4_|TITxN!pgy?japbq_sPuYBlPLxI_vntmbZ9Ey%NzH@WO^j!9%R#ehTj) zRw7@xOO924kiWB1xwkdk_W>2sv0+1t;E!gCQhcUrQ$ame=gX_d1DcuJ@TgHC@j^zBFdY&}F znwIp?Si*3LN>(a1cVUV}aS$0iuzEvQWmnB8=0Jl-7|csv!0xA<7FThYva}Y4D}*s9 z899Tn`x)*9bx8@F6)eg84p@=aq;Gx=;?DGj_pRMOgBfn92^9F=#xAO>eARQRFvq+P zzZ2-i{Jj3aZyjKPOLi*5!<=*<4NK7^tfSL=aa2d+!Z`*W0+h?H6{azxQ%mtqCBWd{ zv9eG+?Pi;?fZ@NOTL_eE8b6g2;Gz7XwYTLEUV6~f!f%E#hp#h-t4d&_qZ{cmX=xJj zj20XiRLrNwDsz~>5{TVj0*~z%v-q~`7l z2B?!D+CcJ8lqX{Dqhw-{m3p8dTFK_EbHa;jO8JeLO=KyN9FJ5kRYmy{A1ZLg>RWWy z@24}Yd(Qh#G>bPEt(G2))4S=884Vnct3qp9M8I9}E1B=l`TEvio3vCQFRx9y*`N}X ze+hz(fAE;rV_d4C>fmD~Ihz?~^M=U9XpKGjD?EQ+*s>M?k2kA{~_z$ z!;(zbzwh6St6Z}xoyI9O5vJ9YQl3fgvxCV>so<-IRR6OpXeZEw!A+%~L(R!N#?pyMkhcD&xB8I(_@P=MD@UHD?dhKf)Q+D*|PywTkh*flckl8`% z+~b8GbKv0|?Mu0Y7IL+-oGEf(HL*|+F|nL_=Knvw%Vg$AWE`RW5XA-kO_Z~Fb1DJC zM$z@U>}_O6@xC3soa~@4{#N*-n@i0XFXZ~wZFYy6Kk&7)so?90U8I4tmU~dm*(R5f zsf5e~?}*l~Q6U?^@TwX913x6kv0JeVf=0{TvdrO6#wh!^1#7O z5Hb{kLZmva4m=tvg}9HNHWf7h_hUV$G7$z(G-%2DGyAP{CLScv52%=4h9M;w_Ub@; z)#c`Zj|*P9N~0@v09M6*1Baie>U*KBmhFh{eayRq_^K4ufO&Dq>Xs!6Kd>-1Ec&R^ zPxq*wF*+B;XiRep@?{3;J(jrbaA-k#{<8#7K1DIt$iiyw6cAZayK*TSe<;F;gT1wm z3_^`GQjL3G4es-myg)(NGh;2vfD#gdr0iU=qCI3N{Rjx4G%Kp%kKO>5xR_teyEweQ zg(A&|>$LG9C}Uqv4AFpXlZMYbJMpbW!3lI#Pq&WZsVbM%L!zZ z!-ff?vt%dNcoYApZrp3~qLhn&JCG3je)x`46|=AlNoUYS`hh`mydb&EjUnFOd9hcw3yT5EDpEz$I8ak#2 zps*+Rec~YcUkSg^mFXVPh+3zI*+HDLWc2VHr|)N!UK$W@P1FPT)09qoH?rVX>JT_P0Uwbx#3FAz__ zNQ*8A)SCND0OUAq`bR(ehI{Qi5+t%x9k+e};@+B!Kd zTHBw4({hA*`VLo?f8cwUJ(Kg75gz#EipXc&lSZD15UbeSGL7yOC{H`(U{;mSJ=k|{ z$kMSqt;Td`)qGI13?`Fcc6v0v0apP1M@I%*s};CktRIy+m9Y3SzsgaoU{dp3t>Nmg z)$Ah;$*MjEI4TFxr+Q&)tDw{5i=&^5wNaA1hmYxf*M2nb*-(mp$W~V1x-b)3^&Zh= z5qqD0OG9-`;;Mha7oCxAX>7a<_p4Yf`%vSrMa>3r2><5jFyzfE6vLVOmnz0HIUIeN zbLTE49>!XI!RMsjjH<1+sa>$OgMxrc_2Cw{^EvIqdMNyaPvr&@^}X1J7{>SWXakjx ztpiY4UFu7ELP zza6p<)>=p!YHaE?XS;2csR@(wEx(YYW5z8($W3-JRKct;y5UU__@+Cyy?um~IN;)hh2&McOTL_0I#bi}LqQWGb2x*vY6;*-|n4IdFfAce)E$b1Z z`)WNnTy6cii)^fZla^)xI``4}%nKy)kHaE4m= z3Jn|Z=nstR?KBZc3+8gSFm>l~sPp|bs+WaO>k(q!$P+VJd*CkcF zuHbV5!BH|;Y6t}4;nPO6w)9A#LF!~ZXgUP``t<=10lfbS7&4lqG|er{Q2}pwj!TgboP^N{75*FQ z>sjl2A~E>u&jXj+CR2t_2O+{!-7Ye3={l!MXxIq+bcfBzt}|iQhqE8EiP4O6xsAdolebi z%jikD>K`#Ko|UQEcKX_)akjw$*Mm7{C@M=d4Zo08imXPO@1-g_?_!VAK<^0__Ut5; zR%>Fp(dZPlVtQM9_7!O^Jl;>msg;W>Ad$^$XYDWzO!cK$`OHmE_0K+}mtWo(?}(}( zWQ)csLSjyB7pLlKx~QN;Ai?07L)1y}|E#X-<*~^kqwqEZHs5^oZfw-ehZqH46t6gH zkqcPw1+LPV%DXiYzrx071BUbLSMXw%N-TnT91aNOA%x+vqlRHx)e?urhJo{4+Hnp-6{6ED@{Q`@0|*NS*)qOHlg z#d!*Gk+L1^y!nyBy5*`G^zTtaiDD?nD`N?I+imWt|Muh2AFo;T0|taEYyWn4>8d&1 zy~}0(bV3#z7(&03w8bQO6yn#q=A4dANC$Gu&{W4p)`8*B7fQ!!{qY{@#1ft0H9j9|7O#?}FEVpZ=t4^41v_ zHZfngu-qJFdD_8)Ikk;Q2I7C0obs0%=w>-cM!y<3&G|ILEnMp^khSpyrTKhw%d>Hq z?~@jCd~y{qLX+4uR26$EXFye*+%`k8sZVfz+S=^Y;}KDtlX8B)<;?gt88F1JFD^SO zq-52}GzCC5p*uH$-}Q3x`5xC;VUOm7>2X;1&t@(ePV;J@+o)p{U3Q6B_NbO@l3v2Q zAHe`Tm<$=mwzdz6!N%EX)@It2^!f5QwjbqsbrA=If1DoBsOD^eGxIrNiA?wa*-FCUs@d zueao|TrXR&Q_h%%ZZ*?~O9h=O7tLla8#9%nribS%g42%~{!w%4IBEWw2qEqCz^J-M zi%1woLRD1uyQb>oX#e6ltxaSxg!R{vXv(~Z%hPzj1~G=;j6~@U(c6X)%Q=~m1#b`1 z*tjdC@a8Cj4Mu8fgOD&{Qt{UzCD~jDstP6WPv46mSY9htzSLHK#S>=yu#JyerA*xD9q0BrCWc8kYX&cdQ48zq$>&@U z^-K*q?Uks3Q%B8zVm=ZmT^vxQ60#k^g=o#}_bb#uO+$sKKiL5e(o)GfX*QY>Is&ku zhAbdYMS@zfGE`x_1tS~mnLn9RS;efN&?!Ta=J$ssx$c}95U-C-rYO1OLw*nj<=uvo z4>1$l(ZuV|EGI(vbnXkk(3y|Jvg|vUenfm&ouJs=HMQ+c?=eD$W2fKJc;IA_Qe?iN z!6czCgMZ%pxg-2Lhkq<#cbo~)dT{QO2~t~rOWZ{YJgZX$$?C}1%?K&v0)X}B%TuAk#!)2uABEt+GpAdD12b8&cO8vUshJ6{6#a`B< zqnye{v$xquu}(sKxgXlLxOS*RGnAQ4843pLD$-o9?D(BwNHqB5RaCLN2iBf) z)rUQ*;lafsi5AOxR^KU?MD`9=^xz6|8w=Uk&-mO5qD(PYFBjX4;KUppL+QlVuw^;hsZU(Ne;uGiPY9ya?>@U;}-ft-EvCRI~c$xhOGx2ZYM z$m0Xhw?664Z|$1^Vsv!`KYL(tRvb?RFwMK^jwDUbMTQQL{MhXT=GXIkk{=~1;uFcl z^^%^53V`%O+ap}AD;C_210aY;kN9)8y3^6jF>R#hvQ>)k%g&OO*0E>jT$Dh%Wo`|C z0gRVNngQ@fCH(cQ0iv5SO%EQQ*=xVkL}HTHN>gM-?qm>_qk39vYfsAnI#ky!8DbC< zYwtw*58vhV1)aRU58mpqxQU6MT#GzP)3SK2{KmtEaTP`IW7j(?a6*kBHe?RY8_zFg z2d3TvaUBVZ-u5d@ma1y5I%sACU>588o5g#%*}GDs@Ba}qnh)fdK_;{BTftjGu9;)X zyB&WXOLiAmUqJ!H;(Z25FFR{|70`Cmb>_i=pODse(1PpGm{ z<9vT>TjCUReQnw*a-{( zGzT)QEsOcQzlI3WKqQ_nhKps8wZY%G9=Q8Ht z7fM)0RlQ&9_{e6`99XO(w+byX!EVbL7ZB+`g3!-XI9g#z$(-(S?bvz%rB1wl0h;b5 z(d9zghzX^YIV?d*&oFoBJ`nkU5TlJC7lD=<_D52CoCzIwshKnbCl?Wu&<#yLon91R z)C9-$?u%JYwx53@DQP^E6%!&J!St5^D~0HlAS54oW2x8MI7f1#B7r0-DkA%3CWLl{ z(P-!h6jjpEPU|y+K2AL{pcJUr;`cG|dQcWMsi`ah5Q0(LXc$KZmw~Hh_r!$kzJ!1P zZ6=1T{0ieTNhTER38J1Vv!us93__Cl%9ug0Of1PyqS-y^1pX$&kU`57jXkr-?AP{Wde$yH<`-M3u=yQMWf_r` zWKZ`i{SfOGA5!9B4_`)*!2!+lhD`< z<9orHn$?RKn1+9dj>lTv65>KX@@TcQej~L`*|`Z}Q{OjQa&?`mq*`x9L(f6qAmlo* z4S{zH^pV;cmn1W2E_oiGS))2ccXxXVRjobz@xLEe%SR{@B7w(E%TiG+)4~Q0&^?`` zlH(cZ^A@~7NZPH}g@_YLRD<+lQXyPA4*^G8>J>m620E5vih-HM)jdIk@SS2Ub-5++C14S{5!IoREJy?S&actAu zchB>@KTj?4=eb&*jeo#|AD$iTx|f-{HMnhVG|mD{?F*dQ!X1e+l?Ud`o?+T61p+lT z{%!A~bFpEqfaAl4Ot)-Zfy}R_k+u7I)GBq`c6WQzDhC zA--g^NIuByyO73_*S;qhN+Jdmj+Utch8;)=5uRfySB&dX`P~=8ImcMKmW#$&Z0ij} zSk|5K`SixBU8*XG*8#ZX0PnR3Mykz@6v#wehNj0g0tNS9CjZuV(JKRL_!wUd2vBTF z=3I){N#esyWNTYq>6_mf*gbB`HoOp)w3mx}GdcU5&vd)|H00l167nCO;6nIRMO%s= zoHXXyU6Yb!h@|QJrUBK{+Uk(P3}#fnF#iJ_yMaX@me|I*ZuM%KDEVqThYL^bj-#bb zHZSyI$=;}>CeiLqP!8aMlR!U`H6F8o+$(*fj?nLeqz!%|DLZQsyMLmPEHUD~sf?<1Usfl^vmV zO;LN2`~L`)xC^Yu2e;+)T^_&I6|zDyZkYon+w!=jTCUmrnki}3wEcpY?WL7hiR%Mi zl)mfZp_v<*Y;|UM$(IIm!or#Kv5A$W@cNy}qwe~3{tibQyl`CA9l)xK-q7@?c%4W9 z{znmN<@PTRW~#vK4bSh3vF@QC@0%6eM-j~}!|BY+i@ErmX+>BlIL+xWz28bWG)B*H z;*z~A3|nlYN7#+9#T%d4xO71Js0{D5Y1YqU4D+kNxVe;0QbR>(%+&7x2vb_8UjP8_ zDn#?%t9xQ__FJe6%5x>2Y*P&s67zflIPdPXgn0rzGo-EeEwxTa)(hh(E#u+p36Xx{ z#5rDQqieNLGIM)62LLjQTiUG|(Y;#jV!K-;5wEVb2OZZfBXo=*Jg57aN3VXxh#!rc zQK$UiQZypOC+Tg*<5E7H0lR>bxLVxb{F;lEmGoT<+z_fVOxJPAY+nwEw{=c4Gp$qd zYyhx;1aCE*Vt}B}2|jPCG@;j;cmz2DHua9}5;A{cE2j}+P@;-{SJsF=aw4~9bN>?` z%HAa!dt|@;mdcj$R+v&j)V{=sOqQ`o*paKp;A$TU2~Y29qUf|cit`wn1~uRHl2j2h zNr4fE>$B-96eGEhKfdKo#WE;%N{o|dp342BwkMpHBK9DOGcJj=drPj(pQB0`>B`3> zLQxgU$dfptLygUb=cPH7woeq)7})ewqjk9B*aCzEdDNv>9E)%#5Y9hz#f45FQqFt@dB+-+f7vuF6O2zudA(5(F`cDAF2Ui zp0lmc-~69X#n;$O{O@>F#7+%gUa;+Xj9+;BR8-Z-3iEZ{Apa*1uHYziby$P_o{*uQ zH(3X5se-+H<;X=(yzYoo8gwu{#%G8(j>+zEW zWZ&e?&rPcO%R@;j#gSJeXtn6fS~Vb%D}FE2yjHjThEcL+63TtrcW}bXu~@@Yoi&qO zQaRyP>WEej6)Vz~KuDtapx^L$LW0yDGviP9n`z*SBk{FulWI57|HRKicl6Z&49#6H z(fXuByPz|Y4bo=~CCNv<)?S#@Pv}$=Uz_$`)J>vB#+L>ni5v@z<0MN!O*bSQ$z=M0 zYlR&Z{&}C&5$j#M&N*!UvG%vb7w52j&#zz<-J?UBAh5}@I>-pl92d_)k!#0? ztKn`9UH{(?0S+2{!c&xKGM%<3NVD#Qwh^T3G#PZdb|mZIq^2TZIA^jJ)Rk`5o1_#Z z`-6^q11C^8w%&`TvG!|iOW8tVz}lYjqmyu4N0YZI_SU+^QS`^OU2(YZ0glM_aRM3APsBYT!`7t zze)JqONjpHzYVwALW8%yB>USpb&s;^lS0P21aS!)xG(wR*3jblp7*4`cl#$AzIjGe zD(KPkR{}XqZOIPBSW{{~Ly1WM%hstJsA#>Smt_Z!Qs_J7vO#VrMQK`6DL%<+h=&JG zze-RBKSYhxt*r65nDNwz?4cph`(uKiNjq(>;Ct@k6;+8pf`K{Q>NVEA3d8UTv4?Ty zq%u#{-uksjV}ou{_l}_735RtRzCkUmmx>vRCw-s-($;wF%&#iBSkQV!Z^L}w9c37f zpO72JH9RkCaLUx4^op$Hv95Dqa>}4nJ5Mx|SMsLV1~~D&I3AG`rEe#70=u1p<`uuH zVe@Vx&mt3RugeI!T4`UA7L<$RU0h1uinQZ-XIJx%mr(6T3g=|a;=`6}11TZjkiVa;{f|1(+i4-?U!dfWr#dd6d%RR94er_2<+KQXHV`}!v4Z3TaP4c;! z>fnW#NG1+r`m9*qM*@C$`^1(0sxuikY6 z$ko(nY1V$S%j|maL-XQ1!+UQfSu>Dx_NpabAN-z7W6wiP8$;>76x;(bS52{bp&PNw`3j#mfD)fVZK zR#%^Gg}lA0tlnvf(#hLBCRfwji^Z^YuJ4)o#CZxUaAmaNe^a7hh|`jKS8$@5%5x7Y4&Y;=wdZVuR2*!luW4V_RT(ehH6Pgtz5nk|^vlF6 zH)Seevmr|LoDp9&_om9WM8y*&sRVF+NP}3|WdG5_`F9@Tzy1k;m1KEt2s-E8b#G5J z&ML};MlAPpa9R`EokP`*KI#jl20E?x+s8~f=b^XO<=nORcRaZ>eP6iYY$MIjndwjD zfYuv3oE!JvNRB>wojXz@m%R=JBS}+ZX#dFKelM!xv9)6-*VmggTdL-moRQ7Fs!EL> zj`@O;!kNE@*FB+gWhP}1I!!4M75gZ)8pzlGR1%yvAOdEXG*xWA)QgP9V4IdqD0lrSM4o7mSPekHB7HlgbtNV4%wRkTzeD z$C`szp~GH|^{XH%X7ylhJbPa2evtKx2b_JWm~E)jYFiAjoCIr;iv2Z;wJ!Ra-RHy8 z@GkXX-rUa<9G3kZjHpNq?JFW(z7U|EIi;Xvj;81rbt?H*sb*98{r0GxJb$0q#>Lu# z;lqmAKcbOqmvK`2h_3B|Yn!fb@~xFEdk6^bEYLv577GD{Z+1vz^?p%6GJflz{5OFU zS-GoKVMPaz96AS1TVB^b9Lj5svar8Di7VZO=Ojea4EjK@Ta6^J)os5WL%j6v{RjKx#zB^~ZvqH{+fK@j|2(;sQGwlUVQ$M+J!-fXNPM~gek1lrhY1?LnTe2u&1jZD!xYUL%6a|dF zjXcWTSQL@x9-E})bW$x6*4+ESSs-mV$Za7eBXUXM*Mdgx_vi-`Q1s=sRb@Jc>{Enu zhs1Ea01^V?aZLZ1GGk-Dvx-vDD6I`*9t@eWrlusc|Ng_*pD)@pw-$^b=+^K zkPzpXu%Yms`k})%C}b+`<9tegnQwoyT053`sZ3x#_A$ON^PZzN%trKU#gFS2E`Rqu z8J?Ed*))9&y$%=V-CC&iI6Vh9fJ}waVHZu!`?kF-4CF|&qsSPZPn;j3=4ZM}iX*?fO%7$D|)G5s&*9cU+a>Y6R{_w-n}*4fA+~N_dhq zcO&aH>WR9a&alB_ePB+ooEccZ;lDo2!iX{)Fj=n9jkKO{yzEklbv9->@Wp5L<}L(P zc|uPxUbbTg#wM8aU%!GlLg|T^W@|_bwi2y4h0%A|G1S9M+)E4gFUE&aDvWXxgiyv8 zDu1?vG*+@T)}q7%lW@0pe~m@+-EGc*2<`nqjlqEi)vDthn3uVQ2z4bJ`zvg@sQ@E8 z?IXx;3>%3vh;xEOhNQH?Z&H+DIwMSRxZMQOTf)1k1DI=J79bZ+6NxGDwhqa2HfEGI z-6;jA-?iBQw30cGyf#DSse<5%QYkRc=vea6za%Q47#0WQWx3Nw%w29yXor~&b;)1< zwNkPZ$jV-r6J7#Jci#Ao-uCRE@q0VKE3Zn6TI@nM-w2Kg1#K&d?bGQHI9|)AIW*rn z?d1^U?Q-++j_ei(C-Z$a^|3@Hm7+*T=%%Nq?wUKGMX+Mvuo{g6%=e!5xsNX32KOs6 z!iiv0afKh^cxzMHm*h6?%@TRcS`?sIP7)s(<8@k4J@K3c!ihY%^pSPi#Gm6_OER%M ze%PwKl6haxNCrGS2cPe6z^1!M&t!A! z@*>(^fiG3uc-$yOy$!~IbBpbqurMI4qC-SBI6WGP!@mo_J-1I)P`+g;%L&(}V`?*a znjJ1gqVZaV=D8?!a+kk=owA;AqU_X|ySeZtu`$2moh0pJ}y;gIa*u`A+ z5J}@)O;gXFN|KGi1~X8v*b45ey!~o-OxoaZ%@AA}->cXRDfNX%ujc!G(U=;A1FoOG zQw26_PZ>j`0C7M_kB#rxA!_~&(F}kkhJkvt&E(ebwXM6@4}y>#trhGy9gU-}HSO>0 z*pJiMGxfj#|?Bu>UHGkz`)bAV6Deq$IES? zdvWtsT)TgXN@eCtS~>*1-kMZx9OfYiRh0n@QMEyvp-fqA*+V~ioyeSV{m@amWR+f| zMCrk`hpLbarK-WU2D%^k_=#q3eTsv>E zqu)t8iIHf5KaPTbv*CfxjUisr4vEA(ILtcJInPr_EHvD>%jMB@quF=Hp|uO0V|I2) zxb+|5F~Icj^!S-hmD30Q2gi{kVOrMLkY9j~weV5Qd=wdu9S(rRyl<^!)8%MnJx6Ar^)R+8RjC;z4fcmD8u zfz=7e9T`5MGaV&8+g)P1*H6Y22Yv(y_ugX);j`s5r1(zXA&11cmwxbD){tiIL9p)} z>%$H7Q9n+8`+GXD#b`VAk|(FaXXpQqdLl(B7K+c*ZGEn*|_t@(;;8kW|uRB8%Xqi!MJmy?wEWL z6khI{GkucifjJdR_^IRA+i}F}j2n2uk=CI={YAV)K0XRte~nT8<~@E9uks(iWq8&M zHa<>hbmJBVBzVO3pSrL0QP^|dHbl(W&`MlLC)Lkw>WF%6`#I;mT$JdQ#Ps~=Nn$5- zGPN)-Co25AquV|XpY6%i1;<=jQ36S;L@SHwxI}Tf2`^Bl?vl0s;|cSUGv@1OE!r~T zHsrN`yuovNBOfwA!so1hHj302`}D@j&E;U&$tuIBz36F4UxoJRW)-i6xW0?2(MdR! zV-tp&>3|ht%8TQU|FM}+v$M%_9=|W(JmwDAF(#a%!a=4$Q~e=8Q(xn?Z8%Dj0JD(| zjB#VNHxgby-XOI{X?}{IGy4Vhd5&gH?Y5G7)|vdNMPovC`WLY$c=Dpl^=sU8kBEsy z-{d2yw@#8xMC`DYR6&awCY4Wp=rbuNZnlU+?`=519r4pU(hrbfbubrm$iC#ke_Coj z6ak|R+p)B*koy%OHI5Tb-l(vI^yA=xg`)h}w6U=~uE!J8B=EAjj?xzW%)%Xs)1M8w zMcwDrc^!}ccqrXz9{>7aBiH&&mS@xJ!s1N5L3^<(<=BBDR zRV~SxRSG|(fj9$JSiP1VW}nWjUR-57k;~#=F*X3BJWoQyDf{X*AGgug?}s!DZer|E zz}79ZbDvR-_u5#aQ8AY<7ThXIK~ioo8MTjY=2*A%?uelhm!u*ELs9cuYk8x`MOA<@ zo}w8GH5QEd!C@R#a!X$j%n>lxmO_j}`-ad_ZIzK#yE99w*@Kxe`6smO1Op&a(r8TI z_L>vG$=GVyA4Q1ydDC;KOaH{S@LNtHi_m8ScW9fXb2ganqCwtdg?~P*kT2zIiCpp38BrY7s1L5?%TdZ#_#TlFc!7!f zz9G?Qd`MLGSo75@C^+JqQ3ZvEZbC{@bzJgHbUOrv`^?&ZY%t!Sgj%9PRU(y!dWM5h z7FHv$&Uupi9lTDS+vTnGdgr-IqYc{ji3H{-q*eJtQ#X{HpHxk+H3p13Uzk4@13 z9%3vY>&IJb6w;X93!(kH+wftjLF_@E=8g$p{PyGQ$TM|9DQbTP6Yi`1TlA@u@PFX_ zeM8rN+YRvNXJKX?*Z4X8@nKskJA@TSuklKg=K3L0#o^I&Owfm#$S<=~VWR_=O^M}KH{%e(tVa0`_mkW*3#6yX-hq9_5=quebA4*yOl(lg0 zOzz_;rp(WQ^-n4`&-l{7fCrM((?!Ql&e4A-0rQr=2s-q3=3Viz<(x03{?-xZT+`-~ z>i3QQi|=r=|3#~P+OP>1-rzI@cme3Vsh!)yYxrDL!6YmJCdu?vEkYwL?9Figx(<*2 zLao*Nk$i*>r`t+7>|AEOV+8%cLB%-@z>K51J5jJ*W?c4-EsuyrO8nG#3>5x$`OMLk znM}tc+TLAM-1`HQ$h6LCqZl_qe)C$bwV;tgBwCm4`j1*ZWT)}{L=02Iqv6!%*H%Y> z8ERE?r9MRcK#6zI(y!L(GLUvEQlEyLM?CM*=omV7#ljl6m@&s&JQ6amzdkU0w76YmQPEdGE@wU+8-b&NjMIA+v zMx1@_SfV-=7FzSMx8kQ5@Mr>Z;Z-ZkFuPkM5iZ@k#~g7<*2(Y*4#$Y%s-)|#z*YMs z=o*F0PWhSB;1v)YY`nQ{($k|JU4|AJh53oo_bkoKNwWj(17u>MLuopn(|ivr)Y;Zw zei@G*_DbIxSN5Ncf9p4yAXI+bqKw9Qrwj|^MuXhk4?knkb6~4~A0+o2+W%|n?}g^> z91fFf6r#z;s8w&{xJO+gY9CAcFhr%)0J?#g+6al!^vzFvqUqGdoyj`q_8*j*L zd7xPM*Q$A%u>C&5AVxUA`aPoVoSuALvI+YuKhM=|i4SKQYI}HAy+Av;*t|?tdwIC< zdAN5Qz(x94hcu&yt&&<_J&(S^4FD^E4pk$FYI}=+ARItr)Go*m*)598zSmu0#sxu~ z+IY3t_)~;x$HVDA3lKl?NMFPi`v`9SLXc{(|NHuc;cF%J?N>&d4Hc4;hybGD6-*yJ zC-KG?my{*_329XVB8qQGE)fOJC$JdhtHi^%Q}||=Ti@J%=5@Sevoz)ks-a4dQ&ub* zBYpFqYI3+4Aoa%T+eiCVp}SSKvHLb=KR|5qfeWj075g_9ChQ_$D|3QK_6fo8&Cm0C zbT@h(-8x1#RX|mK_5I_db-m8QE}gJ8Wg1{G+zlmis8U*>IyYp}{1(*$vEeW5458EhBWt$M-0zBTa%;;H-YCYyh-Vg8h0>Kv^ zEf0)z9Iz`B0Bw*QAjo!n!0PWzQe5!AV&Mx7&Jje7KC61u*);m3KDpWm-24OWtIY*x zLk}*$IVGS3IvtkDwP%K_9Rv_DAT~*!)7h~#>pFsO20FTO64QUk#SPl&*D8klN^8Sq zJknJlwnQRVzmXRjN1Mk+uh0SRr(ffU@UPw>$e{ z5U=t`Vq2T;JPxX?Pw5ca@K7QzKV!waOE6HxGABYD)rwr1B;fP~4`(I+ZslDV*a{1Ftsq zFwVX30RuY_Yz$+PnX}#>r|nC$)L+X8&(+|V9a#T#ul{ebi=Z1#8driy3PUy?r;>4HBBjs zc#J-Xhbt}{E#i8a4@1o6ESa``0A%aQl3Z|sD7=*b{2IX8E7EMHh+pzxg(ftFY9=j+ zlm=W%1?SjBY$4Gg?K?9<><*TY`!q6WX9Irr1&zv10=xrtF z_VRd_ZM`--XtvKhWH2%oJ?ss5Y)(HW;PBC+y;5FWUsVL&7%FyKR;`nazDM-J#4!?DbN|?Bv5Oe~oGrV^vK8 z)qnbx+i@A!j^;QWi+Mk~B`2veCxo@;F%}q0TUd>HUjIFa`%` ziydR!3=F)XqG4Wia2XU4Qwhu*C1-B<0GS+(=I^$!rM2OzH`+);eq^?AmI4S+-_3*8 zL;u<|T#6MLwJI2JR|tN#Pc{L)$x%e=ariB*3huv^s_*oRU&jAFA#QkW=s2c&#_rtI ziNx6@ldX>`s)&ZcOnJC|IosHtYOuGd=kWX0cJ-Ye5pDsgvKKk-FT|a~H#eA~6(yaW zvXuo*cQRZI(JzOJ*2XZ&`r27?alqQcXH=p;(an@VS?yXBf>s9@l96h|xYIMYS=f{u zH-G)sqTP0q^4fWCo4SosRO7*!WCDc0ju^-=0wNNH=X4+G^>Y#eBddhV zevUDo;*r3{`0%=~_6j5+6CXDbYjRN~JAO&&+E*p>VZ|+AL?mKXJs^sp5#%Tp@at>z zn5vh{WxUW)W(6WJg(8(}w}?E_r%M!%&Fw>%_r||>VHyO>GTApySzBTR^BSCR!jaRh zR|H@T-Cg%~wGlAh&6@%*lK4+^@p3g{U9LYd3F4@|<5f&K0>K$u(W1K`o{ZT&_E3G9 zF2PLeFrCYYdHB}sDbwiLJC&%J8hhtPH%yvpow5(%8e+}(yY;5e$8Q%b zK6qvQxZxVE7>NX_7E&Ezy!D0Tac?*lw^)CeWrZt3)D?P0^ydX~6Ql^PXZmUG7rR^G z-i6wz`7?!YkSh5b<`PkkG8^XCFmEdQQYhC$a zfGhH`C^{zpRiZ(okvV;nO+OaSefD^BPMaAdxpror1Q?t9&lazmja8+|+LSkEK6zeUCJ!z%FcvKL?3`8(ckgqVfU2w;NA_65j8x zkc*T&1bcjcRtl_J0oalL^e(*kQ$C%Z4qtz9&-h6Xyy}clI$xx~fWCYC@Y~dven{@< ze5xLL%_0}AemZyG)Yg%+_RxPXO%IC5u_w%Pu)tiF>4CnvQgcH8LAQ>VCUjq2*?<22 zKVAU7;ZEyqz`|8TmFy;sQw=rh_Xp4QBWWVGFmF{Gm(&R3v6u!!ILqD;eSf<(0Iux=v*in8q4qtLe;qWp3ix= z`ne;UIFs5|my}9a*peXtS?KAqF2H&;W(|~O{67h`5Ak9Qo zE+$7nL}EG;S7f?NhLLQtE3?ru`nWVu2Fx!Lur+=Afos1Z^__pBl1uUjHGk#I4X-RE z_Is@yq-7m0)0~(5QN+6TYFI-Kw;D4SsZh-hW9~79@d<4X*qr{V-b&xNctgguaj4r+ zFlk*MxD@`BdSvvMXaAmhEuij&6Z> zI>363QFK8%;EJByMKsnMf_Tlfr;01s>W*2fmb$={4~np(j8AclcWu7uV`MB$ zasXf&CPI+f50a24XR_Smq_e;5JtG>sm~<3LS_k-Qk&Gndk$~-dKBd~K96Ph2&-k1$ zbL_dh{$fNWElIxs9huwB?l@2_@q<~#ui>sbo5x5O=AQXw;YR_Uoa2g3NmRc_WAt-l z9VUmGA9YfhNgC*)0!k!v&*d_HlF2!nWb#xqIu9?-x)!83uUg%-lRmTrteZq99z%S# zKBF`3p(I@+nL)#yG~TqP@91$AZJ0cVuS>0a2G-98uV)KBy-QEGedfY)nz~O5lq(qV zvlk8>s#<(JEMdpWdG-wk^~a7)&0aBw=`M%M=PxdI^Ic;M{`%J&YIjn6_k0v%A|-|} zr~xdB{yKWAA{jnRf0a!qVH1cAmh_1?-=O(yGGh|A;E1Y^Dko4yxAd8UYKnFreTY3G z!M&!E6M%m+@Lk7fq|{a&0jAn81_3;`0T>MsKvSQ=+?we0vhKD68~q4t7VVxZT2ZFd z9J$VIw>4|Yov$?_fiVniaz)SCx8Io1xj%r##)?2>31$nuZ&yFL8j1 z;Wo#V(}39Xv;C6aiaBK!zd!fY4}X38<gAd6jRo}VX{p$6X>E8!k`6=k=kN5kw-v;Gl!b~kMXD8f zCBa~{sf|WZ2RZVI#k)XdB~3JimQ{&tlp-HKci@D9e28_11%YMt>8f^(yKLt}F=;0rEQs>ux8*Q;?F5v^H5z=1h&JM`AQx*B$gn! zP}SzLD3K#)uO@+19iW#cAopm??2K(*v-N#%CAi( z2qIlAopcM;S^G_N(B1WfYf@3lRy*KhE%WXD>T>GLZBxQg;5mM?^DX8s_WTxrKw}GQ z$FkS&UAjws^Op_p;oK%-Mt$o38G>eLmT!Wb7Y9y1h(zez%ysVU6s2zZj47DYeW9Jf z3d7<$%Fm!rtxbpTG$Z{kp}mVFoOrMmNLbHDh_md-sc$ubgtZ5`b}bHO=4v-^T!BdO z*X_IHM1}iIZrrh-RJf96PJi^RCTbVA378iN@}!opR!I4-9X`fF={tSit}#&qzU%9 z;}Ab!CONJ3|94g83}7hKf3K<>C#?cQ#7$p1)m$qumsud!Paxg|#>Le+?6W^d9Ojyv zYgSdRk89r5D>m#ZlpVS?87)gq4pf`wcS_o*xV5vr#A64?u5&7Pmgn@C0w0#Bn&rb($AIVdKJP(65~_e@)Wmw zbUBvWLHNo{!Rei}qphoV?vP!H%)fqj{!8p{1`8a9uo7W^xl%Y&v*n$M?z_j`#Y+x6Li*$cuuz|O?z_|T|oMmN3kohsU8*I8E6_eJ8dc<;=AtzTo(79 zfo)Cma8m+JDNSMyabG=NM%49Qb0E7W&f+u?}6I&~mNRCRnIYgPT!#5_-xjl?=N*q zksdNLy0g~?cqyHOQ<(!&3t<~ua`?>j`3o7H$Ty+osZ*!J0Bo2Wiu7<#>dr5 zgsPTBsy2pYy9L}i7Ducsh|vPfk$l>U9S5c5G3&?9)p@?DxX}XT+8`hvbvLFzMuySW z#zl74GSRrUD-0JQuO`JOIah~Fem>a?%+9-j>{pyxHouBJ?P9|dc<%7JJ(Pao6Bcc% z^7|M1wWH@4aX4;V-Q=#7W2rzA4flw?wTEv3lr<3mx*2vhv|;X!s2Hv&?sM$-wdvzN zM)r&3WsKdm(MKkXS+cG!^`}15*-ZDLvxi@Myv4}cA))ogs(TRmy*pm3z|=k~Is}h- z%y8rqM?%wI#f)KcV2Y(!i*{hza6`6r!|bit`8?S=MLZ}1xI~nt+lMRY+s%o8#ja0% zcvFBd^DWoMUg*TaZg`1oUs_{w`bxIxWs*oMfoYpiO&0d*Eo{Ju`@MdxW5E zPHZ9>JEG?vP?U-E#8qtoI@c>B#Hi=iCd3-z8!K99ez7ZM=ccK4C9&gAS>m0b>R)v~ zo4j!weL8UL-TQn=LD%rdGyfj1%_$~-*0kPk&HBA|*Gu!NIX|-Xjzj_1$&gU>bQfcG z2sES7a3>mJjlB7cGiB@{dK&Jey@60bj$CknUi0VZ=w6-Kl(Mq+M*Q^{JvpFKgC(#fORJ z%oaa+NY8_8z(Z)nlh?*6xyBBNOcK zUL>nJ$J`2al1Zo1@Nd7R78#9rBRWe$bOK@qTEG6BEcSl+4c0p;r`Yn@EFZ!^@HvqsFTk=$ep)gp~-7va~S;|Tks?m2o41a z&3rLL2@hH1k(k*9s@X9>mj_FCDr&%d)DA)BrgiXc9#_ZCMbR*; z@l!b<1*OS7Fs@e`_T{sy^x3}npEJtfZF3Coh-9gu(Sl80j0skLlz<8LGl;KBE`T+^ zlpYV%gE-Hqi+$!hUTxRA;4-0^9lsFC1wL54Kj#DlqL5WbnKNnt$3kaf5Wrv~d0>cb0r88s~7=(GSag%J-)0LpVK%VpqsW zekzOCKh>7tgML(%xH_Q7ZQkpKHM6vH+=l8(Ipd?=rHAjz(529az9&?dvzPiv2@4+L zrgtejJ2pPpwSW#q$tHyB5YD&euBXGhS6Vl9>IeUIPCMh1Z5LspkPXoZg@BfK{6dKp zV;^@?8^D%-1{k0MZ#O-mZsyU{!JvdZn}?lwY9 zA_4@7#Dd9wM&OU2|VFPLeyU?qKip$V2qmf6aX_tS{vo^^}57O16 z2}Jku*~yp2bU>gyRZDuVnVv|{>8&4Cp|f-TtBoBCz`8m4VZNaqo?NmIkSfJm1htPxlmGvo^Qlp~>?h^P9U$XZ+CEx4jUS9@O;5VF$ znv_k0W2GjHI1}@$j$!LszIL77XW=LLxR2g9C?AjP*+&Ygx;a_5d)iDTVJTmV!dB3U z0iHfKZq^o7+u=?&Zof7C2?&yFRgu8Zb-S6h$@==TYs(A!JI`sCOGth())&TGZ+^{y zDOY2EJnvSH>_0Ew(64Qn{y}WuZhrNT6ZJ<%doBkTU;K}5FfhWh#YUQ*{1 zc3kzX3~=;Hu#HHZYP`EW^H@ZeU^eKK56-24#{L*&)^d2PJ%v=TPfs-GQG_W1u z&Gk7J3(r}b{ci?udAEtx@cR5)Vt9yC;hS5>NjB#IF9gvx$;;cX=ICF|;3v+$%Zk36 z{9vmA1*@I>T_@+08(L6Ja!J5_$q=8H$X2YAJhd+{?j3I|`n5?a4?DpuT0DcRQ5 zQM)w_70+cv%t6-^Hm3iDd(jW%AfXF$#W1D-CM0rwa!9;pzpiikaM`smL(Vr_%pW(t z%UWUhWCgZ1hm8V5>|EtJebE2fvz5!IpdknJJZ%JiBL}=1h>s({X-xRzn~NQmqS=?@ z0EGLy6?L z7ShXw7Z#jsF)l3NM2$j4-q7-U^hbZYaC}m|twlR$ngotkXv37@0w^JSBRwT8#YT9e zb&6maP{kQ4`v@UGI|0+$AQn3lIW|$9j0qu3yUQI$FW#ANS&%L2`J6j>syaIw z3Mt1dCHY`wrn=i6M{!7H1QVGF!t&D3qFfzU8v`p7xdXM_z6B4Ir z6HAKRg9m=Fi>5;d$sGymgNMa0bFQB&c5FHSQ_&!Yhl~zx4QQVEj)^EgA^lAccRg5R zMA#@1AJ12Z$Izlo`Ne5u@ux5AJOUFP8;5WuF&DGj51yiEUX1aK`S_Nr9BIt86vb~a z^y<|OtVZw~_-#P59%Xj8{o9}&>-Y{Kzu6BL+PIX9A9+4>5~QwIcQEefQ&)H29C(|T zk6E7=(Xd+MUOVQhPpA^2?5WR>LM7r_#^&}(Jkwb3&qAaND3vhdpTi45O-h(ng7pkJi-=KEszcX3 z;Ov$0f9hMk@tj*J=3SSovC0%iegE~2Exz%)&6zB`YXXpB%~pjc@6Db&lS9)s!MVDb zj0jO#cJzXIT7z=Q;-!w5ZtYeSKlEUL3e2_W9%z`;|<(R*ez&VcG@zk7~^Y8;%P(P`dj%pZceO7Oj<}n$^ zV$qaT?PJY}ZA!OQ_^Jg)FMywcPI2|XK;o`!C^Qo_kD|ghX^96eP9A%Wu2p#KS{!gX zRcsV9v&>EY&v_7=JH5SJ?HiWCGaG-J^rH^VmgjkqLf&A)Wy_eMLb&Fi{KJVdXEIbw z!oN$K_J;HRVM#=>$sWA-TzFSX=ca_wv`|cg`cr#R;$^~Ys8Y9)qCI2)ff}*t869kx z-`AE-f;n>}I-nAiQ_uypwHz$te=fFx_TB^R-td3juVRKu*!QnFI66>@)%20gD#qhm z%#Pr$p585yK%TY+q@Kb1qLq$aV&Dudw_Afnf^>bHv~dqMJj?X|RRk)h*59*=2&g2X zjfyk(8`l4q35#q~huhVTC~r(oF6!oUGq_{NGy;NMB%t!3!Y3BZpZrgjF9l_Djg-40 zHr=w*tF_gn2(B5=32I}uf@QNa<(A{2Q3 zyNW0$D| z*I~gOhn^XI@J*Zvu-Q_zaA}7<5$>=Euh#%sEMKns+dhH3R?`ZBMBg5zj26&mR_d=L ztw0xVObZo3-ziqjI>ZXDL&J?8;{j3uw@NM6*mrjM+&8CPERud_?SpC67xN&tmqb6o zWs7zACE-@X4`s3LH0pOR>i!+#9>13HP;`@`ZGA8HK6(S?Tvc-h#cOP?II652AF4+# zoaXIwGdmk)y3T5FdA# zd?9k_X`1`EuVd3$rf=Nz`LL()zYX`CHUs+uGWkXOTvZhQD{@)j@}J)G-=lDL17|>E zk-UofJ;C?3PBQ;gx?#Q_srV|4rrwMMIO}iA0=Azxe|QosGvgxk73;R6wf z^Jkb}oiNe8W0RNYofhN3S#XeNB%s(aJ1v{CI*}}Ks)v|iu$PyxQdUvsC3M7gj&`Rp zuq(v}%XB0Mj|I=BKPB5-?6{IzQYczg5b$r$zi7KzRDx0F;A3`A8fA~yRQUQLJH6|1 zQ|C9TO|_3MCp|*pSvi&Dii6XiOn$%LYSBG5ZoH8EdL^^>t=H zbDt|QDKD-;DCYQ#*=AorXtiLE5=%B)tiGVGG;A5nHJkVK)n)}~%6CO9?qbjWSU31D zU7>^5svhtHm0T$*zJ{s_E`w5O*ODqL;f*6I2@m2pU!)Nf@AgNIBsSx)e~j-@l3GKs z{ag6o9pya6tM6s6CEPe#9{ly`|2Dq=+pc>fToA$!|1Tgv-%;-5;(O-4D-0uIdqBV! z6nl$pcJ7GX(408sxYEo~57_Ly?48}>nmzY}D=g2cdkgT8j^vnu$_yQ6YZ&U4vZrOR zi-QMgAMYB|xOU;#HoBp%{T^)B!qa^Ed}|3TVIvSR5CwII#gw-n1hnnF`jtlHkjuk? zmN)=6LcBPmHF>OTBma*z4D5H3x~@f9oappK_WxK5pypH+*WaEd+!Q@A7M|as$T%0> ziC_S9vW-UW!Q)L6mCJjLml1^oHSlmqMqhs=P3Y*brLAXPv~wldMQ1Tm65@a)gR1Gc zZ$PPFUW>;^ozi_%BA4)?XYdR{j8ty_w)4&v@Gh?_ioH+8Z^|F6@tY1ehyA|O0tX>Zu@)H6U-${*+IP(R;MCUmv2tr|TJZpzx7 z<^>Z~W!&3hr36x4qo$Q&4iU%z8iYxHTbSmUtm<&|aL_4mVuB?Y1C-iPv7=Brd%=V5 zL=;65F`X2$uxZ;K->&%*zPzoJqh?e$TC188cauiEPGw^vMg-ThUY3JL0kK(uY?wKb zkgm%=j3zRw_i{~Ea`O*YX9W=xTu|6WGWB9tJ3FDRN^d2XCtvft^HcN5zklkwEXqki z<(XXAZB>>QRo)k;w|`yrc)9own4%^)N-_F73~jrYi;3S|V%?{DKthYod@9?&M}XXj z5pFe5Ti1wy@V={9`RMav9q7c}P}M1zD!k`)H4d3LnBZ2U+L~XrV12xFOIRf6&igey z040-`0-v?%DA!SR2vgcO;dk53u>ME!gJ}j}OU)UW-RbHPc~IfOI>_ar9vKA})i79Q z|44H(OZ4D`TF_n$B{Y)?%0(OBuR|C5Jns%AKC%_bO9=hZdkG*igBZN=%Ca%<8f2ckJ|Yp~{_YLM0_iF1wEzz~4(j1w)zGmD#WVX6Oc(2k?LWLSiX z6}@h}5zK^}zCnS5@jvX>>w3ttX=^Q`+N+8&!C#OgHUmxRuaPFEK>cP-dwJ>zD&BUF zy@ZWGHiF~eHWxU{$EOmy88)2ZyEa`;1WZ;sSI*8)9g&R1<^1R0aL`^=ygvbfE%%ii zD?w&291ZPDi#I&Js>8l! zo>?qLO2mq6*-N?EZ>u4X%MNe&KO712tr}$%U~D;Fz^gHQ0!z{Yb%rvsdu-YVHt4fW z^G&$w@!MWzF*j^oLf5##(9wIjOpxS|I|Tb-rShgxZV9vG44(gl0NxYYb+|_~1k6?P zIb+OoMvc0tRexa2%6wcDs+S6u>|dt+*PV^et}PN5x!1B1>g*&lEIseiPb+aQ@3Np4ZCh-a@#z>h^e2tI&L_{6PuP3|w3zByOmNg5ZUd+7I}i zpe!pk5k#Kf2z+6!ByeQ(^b3Sh{fX!{sJOF6&-lW?L%FVT$PjZsnRS;TMnrH6Gua4| zkVp*=_TGeaE!2Vq-_k*P7A^#vK~>HfD~jN^)=F{OzCmvXJ86>NZ_Wk|H^$>A;wvuUQJ#&7??CzG7yW3v z2wcLvsMXnkPKp3RMw&!1_iv!f>{bG+dc}=_&N@m%-`624W(2^Bw^O?Q|FGo#T2_%u z68Pl(E6G#bFEXw}+Ya4%q6ijr9O&xZt>^diU}=NuQGv3Pjppk|^|f^)JO+ud_{FD2 zx1~SEUVEnRnl=UP#Py5nI8h)cC#loZ)C8Z+$FHn6ZRQrd zrfo>_HOSjBt}Py=Bdn^tK%(45O3s@ljP6YoEAjmy3W__6iMr5V&+FlZtYZTbAz51| zCM9v$>j=&7W}6@IujsTem^Axh*7yd9Ky?`l(!N*OBJ2L}vzE3e2a^^) zyw8Z5jVM)TSTI%QL~jH^JJ#{a_hSv`~pP7 zqs)pO>8FwX8SIG5?1`bM6m%lxR?NNXS15XQ0e?kFVxSrhqOLXJyuMQ7*Xi&acDe2( zV$wrBK?7c+Xlill};BEk_y%9Lp?ExVw zW@bAOm8z9m{8MX^I1!AyU}tF*o|vTu-vBD^m#anXY;S1~h$JxLecsjhotN33;;~0| zc$WhF;*&j{!)g}OV-)ABld+oj1)|b!zbL+i-F|^LFtJIr#xS|$zgEiA zo=_|E6aK0VLrTy%4Ao!BiK#q_S~b6jcX$Ji3?aSNGF_>PYRwIDQL*x3RASW%^={hX}!qO(-)8*ORdSW$fEUNU)%3Fp;?YFWO> z&zfVIW1QDXv3b*kRV%tl_$f!ukVmh6J-ixB2sm5-rysQrkhVAXotOHZucYxmMzT}v z>xcX&^(@Ro;nh%ecS+vbCA|xy^vw+Q*%*3Le;9rfUT4O;`=B7++p7*gYB0Gwt6a2> zl@*EP&2SXenN z1zIFIzB(E4M&RGmbMbw2R#%i^L(k`F=Y0s-i)4&lT}YN^Os55GZZ_tyBBP8iPV-2Z zrH~uCLR;4Ncwb)JXgvyA{>%Jg%|_>TSFF6{jQO4&ChyG_8#m@&S}{^|cK}uN74EjQ z8{;K;!>YM6U4W_p7FfJlQ;wPD40xt!OkI;!*b zK+YbRrQ-#+M?f7$Z;QR-Y*hxYdRX;<+!dQW{2EYH10ql5NmPUcs|h~@B1(5NCn}iJ zU+DIKx`s(g9o{iT@9-kb*`@TD`AL=I6KnydD0NC3NdQeGTW& zlcwNlIw@9-mCJ_VAJRye`f!ekYT}F@rFXac&5n^TmbVj+{jJF2#{cf+Ll~%pCp?7E z$^)XBL|g|LClQ7I=mh)OJ9wl3D&cT-t+1pg)(u~j*?sflBQ86|oGwTy%Xr(|q{-m= zFnSb&WzepNTWC>@Fx*_El}+%tp$Wy&Tq!oRQeAszMpJaOLqZl63)#Zoif3T&jY96r zOT^Fi{7|enHcGqOFNB7E{lopmVMCq=Ge2!VcrhicR*^iSn$P?O=%g`t1bn$$EDA5^ z>+Z+pN?HN@S}yM{r4nhP*@a}jhMZc-zbS=A$9+&QsRt_9EH=og^2P^zh%rO>ZkI5- z9u8eN!+edpOI5etGpAq{PGVv-v(+9@zfBe_XSx_4@q5uXO98^`kH>2A4hLVsKTtUe<#GrsQ3j&F?(eU5CAs` zneEhEVBi${7Y}va2Q!`Tdx;SDnoET}h=j!b~*xXpR5cbJK5NOV9*cX!RV7ZGs zoZe$Rm)>*LR6hIMng_i$=XHa{rO6)mFz-luV5*wN>On^x__%lqf%4o5#vb#?g`<{z zap6Fge$#Ga)QI;gdHfoMT878F#^Ud!#q7UDikSZO?IZyXW;7PnPD~A)EbPD%9f@#( z2iD*+>?iYbv1px454#ryf_pJ z$Ek@M=eNwuo;bd`?jAI*U+b5&5*KoRyq8!*>OK*1scrd+w?{k#T=JxX3@xE*H_^^8W zwi_eX99bORC3&@;tX>nPCRtsoL|!s~Q0KkAb_sL{g`cv|GXN`Z?RW8|J7pfr9+Q*| zLTO=+VG^Cx{#26-(UCi7Xj68CycR}n!~hYvK0sz_zQcjQ-jW%Ug=uSK&>yx(^p1HK z?6Okc_A;X@KWzpi`#}nA`>1*Rg4986VjgzeeE;K^g_K-sx%f#csv2;bc^NyTU2z41 z`!MCrC8j`l3G2nyWyj`)K8jiDeZICM6-LP_)qy8|AU6caTJPn{-`z6P12^Y@cI>gr z?(tx~6|g;si*lI>0l5bb%YFb#qYINeom^paQ(SicoC7D=vj3}mY+Knq_WwF(tS?ve z|8GtjmCd38Bh63Dz%lr5U3d0hmD0K&t)~g9!h%<^k%GQwZa3WV-vxoaWsk06*{@<1 zzlQ%!U*KlDV(q@pMOp8kn`Uj3Y=@&)UmfUNKF&=uViQ^35gIqyX>)Q;gnQr&fD%OZ;+@9P>g+=F>XclQ8Tn4?!UGWjjH zh{~@&Kc;y#VxnSN3-hmxlgqqEJh>o)#PF}n_Gr4dW^T2>ZVY|C#affIWmjy*$gw!B zH;PzY=}QZJ`SIE2<=F%$ZKZ+G&+Dt&mve+EB3t41Aok?nm8__jirMsHh(s#4etjvF zos;WIf@9<$tg211iO6@LBvFZ zv4_fcaym}9-+1>573GUPtveJm9)_O_O_f3 ze1h5xZmM1CE9J$phTOkz=FcVdZK^?5&UFwE_Zi?<*@C0LSJW|R&fLw~QV3L$^-vqV z(=1NU`C?fJ4-hj>T&ir^w`t+5=THNkn>F`Lr)r<1r8@J{;2W(0tqNR)o$%vaCu8%m zvrVRhQExt3{7pLcc(sZOOG|azu{XskPkJs}@(u2Ov7xt6gKg1fWG))5l-U>%dI*|V zo{`=8FIqDt7^a{>0oFHA2-?hOVdkpY*}$v;yOdm@oM`dQQfXiA2FYnM(xjkqyZHYJ~bPQj8;wiX{pu?jR2fZOy;o;99|8WkbcMd-M@-U$> zn3UP=ghgp#D9&l7Z2=%|nV5Ot)|$+B?<$14IL?x!oQy$AX_ZIEbdZ>fwD@1THyPfh zC61Nr_@(yA3ojLpdSr)UxzTzHtZC_$6$>dyIYG+bA_fr`OK-ks(TcSMu9!8YQc}<@ zXr)ALJ#JoCsPIs!HiLYXPRM$EPTWl3^O!bBW1(*UYuqY)WbL~ppgr2PsW_NwakQHz z_AscsNs=&Iyf)-jl|t|>h>PV^_>sKxdT2q-Wi{3X-P2CHhsz<47y@2pvy z7LwN;EoZ@M_0T)!$cUU!^_lRX_z>4cQ1a0%pTCMT{8WGIiu;hI$IW3)*sX(Yn!w3lk~tUkml=}r9u z{gv~zRO!L6Yt=0uv>JqoHZ)1FDXJx5lOE?&xo0Q&_td@P6_@%_lE7I;29M{b^al^3 zA~w9NnAW$dU#>`Fd|fY^tFT&bl0`*oXy7XVJrhE#*H^8hURSjm=(QkAx4Wf`U^9}{ zXE%obHg@l-SxV`=C6P+9QgvvnuN(*2yp7HmX*>%9D{hZs?+IV;@pI@%gkwhXgQD?{ zh>f{_B#RN!B$i#bSCInjq4()nnK+8F=S9x6uHeeK2#L#nO9jwY`OjfXUTMmzZoJAw z^fkJ|A_B3p>hO02)G@}r0@WuNWq8d6$c}_8psR)b({Mh=3k9Md(Yl@`K>@xBA_7xW zRAQ1XOg3IlIhjUWO-pe=FYV%D0o>MG1q$w^yT*60F15exSkNXrPBCek{K|u5_gn{E|Qr{E|r<8BQc>=PAw%s#h z9k8N_L&_J8z+NnL+cV&K;3QJUwn1K1_8C47iN(GlhAilNji*6$byTuIu}OLlvR^#= zh52JiD}ZNpuw#|n{$V{{A_=z?hy5h!5s#YVzoVP;5_*RXA^+PIvTn}AD$jE_9-Q0z zS;i@>3nt?C2skX##2OWvQB_&jnGHXh7cT0QYgcgYuS$F$*Ip&{ZPKZY~-k zmvx-*z`Mhh57>Rb`Rj@bs0 zvzvwr0?zDk?mES!1#L75PU4t!n!TswG_PPqs%WMupO31enmkl13Zz&8J@3U>6ZcDM zP)#IiRQm(8Y)i8f>291Fh_bD6uxFW@2b8zdBio*pjnw!rh8%f_GO(t~vCv z;??H4wd`BGeu;~hA^Birlg40O{;Ryh0Dh*jiU0Z-!RR0ZI={?0UqbnK?Zy^M%Dl;P z?(O{rrT8XwYo)UWJL1UF?d;uM8+rJPrqCRvArX_r12!QDo86gBg0c6!LRRt(rOi3g zx$fB8yI8J#vETqpBIIWSJ@#5^SMWMLU%k^IK9bVbpY+*HC)q<%*ZlV&3l2V({le@k_A>9*wOXr7B1Hl_B4(_gj#e zKyzts+CWaon+CB^$ZIW4s}$)<4ey>Wr{JdKxADYssAiTunXeo?vwJ0+CK8x|9vDL! zN`0`bF-~2gaYi%mk1E9%+HM75H{B%qM#APUM!EUFrcQqpj+FE-W8PGlxhP-o4>J-n z2zI-`TC8MqFR5AiZ)D%P_4s7alxNV!wGR=qISp9Xilii$&vO!*+!v%xcU#LMDo;`+ zLT@C!^VmmcxRLR)o4KsCjG?3FkI~H5LR7yWtr`iUOS?DJboC89<{pc=RXZ~=cCkc( zt(<0I&#q`3rwj=uHPkgT$I|Klly7!0kOat$f>;=;2TJS8hI+>N9T zcy1l4@+f@Oj!k|nlEjnnOi!}Xm#*}Ac-*Jy*@4pqgK#h8lcRci@?j(S;(S|<=(bb} zk48WnaT|q9@$5x|IH-esbDZBeLwanF3%=4%^kLbo$C>im@2!1h21DT^ee_8pUx;?b zn*jtMCewRBEvun@u7k|+Do6l5IjsW+pp+&H{+!3+lw@7K4<=&8s8p^CSIqpW>Ar+j zTPzO9Ij9mc`w!UQ(_Hma8yCOEN=5IiV_~kb8;W=Hyl|P%pG|9RV{2L=H1Di|2dCOjkGYRG?uS~^@wdS&SU!B=a!CoN%4jSVc*OALhV1Q9K0cLr2=W(zn)e&yk0JI}) z$Ve;+o)G0^MvJ64(o}@=aOOTM?jWT@=l;zfE`h z>u_G(!=vK|?wANm2jo#VZkN0)XWh*<29QMreC0N&Gw$5uDnXbhTzqZSgm9iEe%0C7 zGCmbILV|6rcpz3}JFK+r| z;IaX_l1&`s(lC*7S3#u&++54qfUvxM+zVFX^j+iP23XipIAw$fryil22?5VaSNVy&<^q%^&|Gr_kABXf$61_9@>$7cgbKs=e#+s2D&CFIV?5z*RE{R z4jK40%Mew6R+wO)ihogWeO7PA%MS^|^hzJ3)SJ{S@Oe&tcuv`1jxibT)ZfFrSHQOp z$1PSe?!%iojNa4DVUH|}MPA7Ml~coyLy__!oj*+H_)3U)xj`bi?E>Ke*<9)O*sl#PXvWq#*e2bm#Q``MSt~mztCJru zzqX!_L_cB+dTu?;46-yDollUfNrsLS{iQbE0i!@1HU))^r|DV(5C{m|L1e;(35q{< z90xlJ{zXhxU+(_===;A`?+1~LhnnP#5B#SeahiOY`Ej_pe0Jf4G|eyHodA|2dRjd~u!oZ|Z)XJEhYqAwStg$^`zzE1y_tV9aYm zhm)scOWC>h9!kWg50#7Q?gOS5n6Kc!x$dcUXjV9&X80#TTBAdXra3+VOLg zBAG|Nls)W8!bsj`o7GioY^`gIPx$J*y(?WK>`%xtj+c)Lb3EX94eF)kn+}79QYr)C zsL**Ad#W@ZZsTSX{4L`(O!@L3j~nrxq)vqIZ*zgGj~e+CjZ&1*VbHPr%#^x!Z#GAN zkBWF6cG}P`vd{~wG6Tw+fH_qQ=v46?R>k~i4#`B7RV_0`?rduyRde6Rm6_Oag$>fw zlPMRWgqwfp*+f=#1adsKOac`Ue9l}PlyU)LRW(aIfmO|RM-i3p2*LUY&CJ(+qL&nP z{H;5d1?6YVGAH2EY!W%2{Ktke(a}ngA(8GH|7Pk?K6FHK-<(|n^+n<6q0uUX`bXk5 z0F~;8A3xw}S@fZ6*JGBpCjxkKb+m7;IZDVmw+J`Ee6PXB^;!ac^QNTk7U;g|WX_?m zgpVLA!cmXKY7H>WVBkr%Zz$Y}thWRrRrBx2hR3a~?OROY>f@fXmJ#Ne;5k7kMIQ&Zao? zkZM!rzbpD){qG9^3WZlu!{QA7_8Ai*?-c>%V7I7iMG zsMLWc49+>s*IZtl-ehTaVKJK`t199-a3TJ} zKntoPwyN@>a`gLES209*?}WPT-SS0INO{`)EVo=>%iTgY#5y42!#g5(igF2CGdua7 z)iH{;#ba%Kh!hrm!!!-Kr?4@;>)G+cMfAF#(hMEF=WC)Avee`tJs@Bh_+?|l!~4iE zT=+e^$^qeE1q@mnb6 zSi^3#dp@me`^@EcR9?fs8?&eEz6^{i9wIUde6oAuOy$>QcAL=og`;^A6IG6}@bC7} zjvt6W3vQ)3E9V|ScEIWfQy`|Cn{PA^oyD!Gke!?aGd)r{I7+dX?=zUK5kVjpe|hyk zOCG??d1b3F@63;M#wo1t<{U3x|6@1AtL;}Z-7_iN0$AFIgqHUC<} z@h5^5USpY}?Qf6|y?hZVpWErf$VCy$k1Qy?Caqx7kYjHui<(&FQEdcs=nvtsy}$ zr_-Ct)Z*mL7c(EZS0?s7gukIY%8Z1^NrU=OGYVGU!!(z-u)zZe)A%bN&LaEYrw8Vb zmKCcy5980QPe!5o@H4{<3s!_G?$pXRIx&o!_?4@g>>I-S+#_v&>sU~y-@dH(Rk33} z4?gFXm$&v10W0>~w|f5YZnbJ_0NHfwhcPAz5d~R)@Wqbbr=w8epYL`D%^(Cpx+rGl ziXGt&3!8EM)G4&2mO*z!IR+0ttqw2J+0P~XywLZ0d%LQKk(j*7Xv=Qs;de)@f#ZtG zAItCdk<*wJ-d%2VbrHY%9!l7+lT$zt_9XThb`rhRyRL>g+}^E25wsSn!}~znNSB0` zVS(OTaCXD2DS2|No%tNYVPiu?G-Xtn)4-GOm1{>|>TD;wy)#7Gh&;%OU?!hRrSN;D z_kAT97jUY%KU3RCiPu`NUAgm{dza3=6nT)8rHRcGviFq1x}qJ>TV zJvsSz!l?+gEE9eS0AqcO`yw3zzzE5^Wbb17gEjXdGw&o&d1vDzS_V)n=85U>3gq6A zx(n)yXK$`u|Ksnj_pNunJMwMb)2w|tnkgmx%cb_C0|+vC*u)*9(0K(Pzxj->x`I`Y zs+&sQPX5LVehz3hbWI!_y!)Bus#@}8XKX4Z@on>T)2}n1)5j-&Bl#3fRQ^-4Hmz@K zAOFz&WG{ZWkn|dL4K{U*&gShlN^B7;1n(@~Rvw)WYoal4!;1P1*hBeUgTBsv=Owiq zQ_z$rc{MK1`JlESCFfv?iRih)EM?@Qs%ek{bGm?vk@++P6n-s6ANEXIRxD;Q_owPV+2P_txfMJQEUHF78?TsH{9li~K+y_aZLpuMGrI8~q;0 z3XTo2F2R*@Qbj$5R$HM3Myq3W*I{^3&5KY~{WLyA?p@LOmRjuR&wJ9D?qLd-sQ12RHqsbK1&-Hy zZ_SgcO@#T?lha~8zVZZ$5?tJP<<$4ic@2?c2nbCeTkcy2G6$FOYFBD#dFgmxeRh{E zy{~>)k;|PDwX&U7l-vXK*4(wL5`<4>MMKwU>Pc&KdNDu7B2T!)mSPCms*Kzcs*!_a zx7Y@DA#87PfjB1~ic)7gyn6@C3Rq1;;eM7)Ie~EU?#XNFqj8HVx^Sajv8xF+d*kR# zBQePx0-fkj13KDs&#VFRhCMdB3RufUx32Q~@j>GVjBy2x4b7+WUh$RHk*)uyr7Zam z_j%7RB~1gW^9q>@3vEW5UnnJSbH{dKvXJAKx(+N-%)ksUyqVsAUrqV{bu|IAQjcBK z_7}=$+X#0=lwE0IX6mdsD{j$<4vpmsuxyX--;-{zqqN+hA@r2qR56tKy*oG$)AhJ@ zd#?CCAieNZ&mS75$9Lei@)JbEuHKzKz!#Hs!1X!#q-yji12el|zMrW4w8KBobPqUa zZ-o@=*9ONth*Z$)Y+V&g@jG+O2n}pgE_PX*`dz{YCjz~LeY#;4pn5ykF(9T6hDm@7pmDS%6Jyzr)E+hduG*ZA({6t~0Om*%+6IZ~v;krPNAbQegc`dLkL^W6 z=|8|5&9b;kq6^(-a4ue&1Oap3{U5ZwXH?Va*Eafh97QakA_9VB928WLh)R)?%;+ei z2#8285fD*YC;|aeR8$0!hzO{Z%!u?7YUqj72q=*nAV44i0t5^pg!JUZ=Y8IHy{D{o zKAd&<%9s1Mv+uq4z4yMZOHT{Qi^coZpgv(@yD;G(?YV;OJ71dc4*+9pV!dPcLbiUg z(hQzZ-jm0^7Z&y=A&S7cnHW}Sni!MAndMmu?%$y#xtTALW%SxK?_p5}q;*rR?~F3M zx*auN0`^q0n0;~0YQ6DUdb5VbRm9@1A8p)E<@!I`Y6SLENZ&U975)A>O6p0M)#g_C zY$?@1`A3P1W;yXA$Ih|=E^v_fZXAi1We~hm&DM*f7dlj!?1v&;g1%JxbI6Q!u@qCH zBi>8@^^wIzh&`B=G?POP2ZSRU^mnLAw|7R!+Tk)Q?Zi+cL+IFmZEtEWhQXezt2f z+JMig+eZo+07h7=s7+b9HF?evKoHGiaNn2#+U)+sR2agt!$Ozl1rWc;lJ_9ASmE5! zvAG%4DD*9f8u?&{(;Xq781k_fdiTj_lRP6lWgGD|nZ57&_2->FM4$Wk#0jH6A5wx< z_`tb4Z9l{A-LN2w?aHH0@cWL2)9??ilnp1o4hF66`Om$hq!%iN8&O)q;cQu*G=ITs z-we&&{94JVR3i~okoO4{JrVxdVeUJ}7f}mB7R2?N<-T*`72E_-5AgRRLeF zZ0G#WXvV=&EB3c9MACRuy;Kee^y_ZUt#shULz|E4Jh9h-KuOtKA_kC$-puuIWe4P- ztzip~llb`yR#{|<;!OM%PAA3t4cz;6t;rmzydeYiEgc_!(b+m`3HlGXc^Tagnci|) zlK=?8!^6y0sjTq)%x!Iggnfpw-2!+rYlFK4|pT=59s29MI982yr770aX_A{xWthNnA|60Mg@~Hl^ zqi$IBLX&R$2Id0yuR5ML7ymqnBG)ke{@%C&Q5pDS>jH7`@QI@`!^V{-!kBr6`x4}+ zZ0!W3Tiw~rbdofgz&?Z-6qGJYTc>QL2R^tF;6uLCt3`M zI^=juVsaESXryg8?`&Xf?w@lCiPSUdyb|yb$+GX8nLPdtthtJ7bY`?5a_WRvO%91@ zuLRg#ZooRsB%wcY!;_zrX#P}3-iI`s3D+So6m2wpR3i~*`K{WpDRXaRPpSi$^Ee&z zF6@U3Kt9=r>BPv#XaA2!k;CSFr-etNSao_S?%n}6`R#KtdwLKn=*{!!i1PzPoz_T; z!-UlrrbO~9RY$+jkvTu|Z`y7W4a>Z5vl}^h73A0vTWSN;&xg}H^AR7HMvKkc?`3f=Tbmf3pz<(UOo5jy z&ALvq0zN{PxR~Q5pX|LH9LYsj$v5$1_GgF_rkzx7hK{6im4$CEAp(EfTOq6?? zQ0UGb=~+wkVKN+ zt}R`lf)=QmeoB_j-Ca@b13a=mq&v$6y&C(;l2IIx;ga)F|5~^E?#@Xr*P)<#;O9DB zTVKEIU!RL%{kRQWz)0Ec`ok2opr4xrM1GuVWfqQuRAuvVzl^(a`_G-tg|INgbdp|Z zNfVFkajr zZk^vlM+!H}PRSAK_mo~q_>7#*K{Yi&@&O`HAEK=fL2hdP16nX&h_MS>%HL<_42rnB z-1*J*Fq}D}=bPg1rpFs}`5L=GHp60|;0NpbGvN_)J+~MqQ}Je>2Z?;>mYd5gs=3l7)N0k`Vx<-}-dMY^aUC{#&H1gb4AJru)UEW$SxZjmvt zw=4?QxvJ|X6arYN*{TLVC_nKXSWZP=YeQU(0=S~vp>Zq9Bfweo+rNSU#d^NLT?wO?3M8fx2C5& zcXNS4p;IrTLAULXv=nRiV}?U92U@F7L?_okd*MbKE|8-*gLdpqSJyUrhu;*l|9 zkbMX&M2ZJhOE(@^Jo7F`dAxf@;AQ78FcBxb)ezL%(wSgXNI-aPUZikR!PUd(BhowT z)hE@Rx~20M$Ixl=b*Sw+_%BIuAC*lb_okd{MxuA5=gEvv(&37iDE1H}*kza1{r;_u zC;4=fK}v)6$W{h@GUQ`};Z`>Ol~DL&nn4I+wN#3QPOK23+L<5^lnK@My}iYJUEH%) zR;8Z)M+zAe@+peST}Lc13?)s0F+rrvGI)0?_9SC0-RyyM;!A^`$ba_a9V7QudIwQD z$bEKmU$&K0GE-0RFl=TzBJzx7k18mAom{SH3F%OKoy-_C&68ejDM)?mEQdW~38XX_ zDBO$lqG>baq=A&UAuaMein_h0*>z=jJPK~P(clIg1CyCXVCl7frkbIAE7)$i)MuLf z3-_8}{Z_5-9fXL^F%xd20dxGk09smoYR;Tr80y>y14;7n#Dbcg?N6u6@BIJlbgJ1% z=qOe`(wh7DplwM3r~@`xf*rJVUkUe2$Kav#aV6~_H{*#0$of?fXN{=?4gzDbLKg3Z7{C$pjSAbf7!0M0S;U!jN@+U|7iJG!Q$2HdsulFZ}Ar8rwLKU6>%>+Jfy8+hNkS(Xyp3X8h2%dXHx;E&O7;mHxuVbUOva6R zQ_wYF_+6G-33A~{XaU{4z3so+I7E~vdbT|DvxBj8EmB?Q!Ku#Cr zjO?wP2@KLIt1T=yr6h8<>UX|$QZjRUl>sbU`(?mrW%&DDgO~USd81SARq`DoV&}e0 zBX_)P{vGFZVKo8SwJbQo`5DJ@AqbxbsTuan|0tNf8YPy>V_A|8Z!W`0yYI)tD##D&>sngj!3 z-*#(&K59&FXAz@Azs%D2j{k$?_8oS9#=J5#HL{nOWwg<0(Qy_<{O==lo+8j=N#`&LvghFR=HRuD*o)g6vt&oBe*yAukwy&v8kQ80<#``2Q!|C{_@x*FUF zRTm!IlSEm9u5B!?TuEr`d9R5$t4&lu`)*vkT74jNJ`4KxC7LToz0Q5wxdPo&wkl2rMkGEJrSuq(MiyauPRB_dqO#vr|MJ#5c$p5}30)0r~aM z)-r`tb0eSSj9EI9m|D<*1?<@V508^Tf;-hqz|<4{f{O(C42UwxSx$ExtnWA3M3NLV zo4kQ(B?ZVa)REj&?S3KW$_&iP0?hnwWuym|{tMhI0>s8vEG~i*F`RfS9Z9*x!m+VjkN+JX7<@ zNuhNMJUYv)t@T!1AYZ`tp}yk$4(nOfl?%JVz37sawL?^=%9$wc8&;Ebu9J5hEyi%n za17$!Djm$wZSuY4_#;-Y^}qy>qPeb+xCdhN%fl+cMCF~{D^VcUd1YP_1&vzTlMjjVvPj4?rZT7LSpe>YKntlg573F88xK$bPSKDN! zT_|EP4T3XM-1=M~C58&I;i434=Gysa%d#94O<=5BDCw)`0u+(;GoZ^vx5;c$aRX_* zk`ho3mOhrPN2!fLUXfAb#kP8^2#d>$%0EbryEcM(5QfqGif?jTTv zh|Q8ONz|a_ZNPr6i>C`=5d5jQ8WfBvKXU^lm24Rkys(x0nB5u6Yv;!YydYv7yEVta zC3*dQWX;0ez9P16DP7srWbt46?SHJr$@79ZkmSz&C1F?m-%AX5RT`6f@V&d-#Apmz7c3Od$K30_GMv8)%?6f*QA=J6j5WuT$E*w>x112Sbh!2_3XM4iZFw<{9l8umWHEK?YX z=$hW$((u2zf(TDSA+EqB3*3-wGBi|#4x{x+zbfyv9sLNRJK*7QyE>7-X&bMv?MrjUsbXkX3k&Pm~TS`^esGF>&!>_SzVmXG88Q|ClaO6OJkS&)0M3% zR?Wh!oANgxUiNRAC66suM*q%p#+P~9URfJz0iGdLb4=Z353DWgTZQxFI=r13Utoj6 zPjT0$xygo!S#rchQ3xSn3tTJ~1xQ8pSnz?>5<+XsJ+kpar>UnazEL#RBWU%*xC|g^ zF(XnwUtUzqj7Ho>Av8nuT$a1amxbMN3<*TeiGKX-2fMGrfpqVl@4-}PcR%j%>`?rQ zYV8X6?R8oIimHcq>_$wz<)&M}#ablacls!Km#+O!q8dX*U}ZDh0@xh3CDCI#5^lYZ z%r7B2z(Jt{!g*J?{2h!o^z&KpyFm@-f9?R+4AlORkRo#-$nbey2oZ_{YA>cm7CRz| zUt|SKo%#b&aw@TZS$^CSMJ88;8244AgLrrjh+HVckTH#nCX#66>`!mmm{{6$fdUhA z-LZDHW@9H4L5Hc1$`<*pTO+J%BDM}U`l-uXDpv2(@@dz79*j)N`P5Rq_Pj&H1K(H@ z7d&C+Qib>9DxADuj)lisXPSZXnu6tm*5y>G|Gg$#Npq~0YT)=O_*A@JDjbZccXr}-e=PfQ!-6)A+IWxDO`%-4KH)2Lvx>xJ<#tw`B3zhL^ES>|)TGK9&q`$Wy1?^qmkRkoj zamK6pf+uY5*<1`kQ;zy&O z+1yi=4!I=80ZGdWfp)7)k?=4ui@q}&5g38xu-QxLVMDS2n%w>6c%ILv?s>_2libac z;p~#ygtC|RQ$xya@KHH2xd<0enZG3}Vp66}i&SgBT*2oxv`P(YolIFdQ7*7P=S9yD z-mOF7xggn4ER@lq$GPWMP zEPB=*bl6%u#Ja_aaA3_c8}_@awaY2jZPqhydap%OuR7<3eUl`*xT^9!-Z+)WW~+4c zJOkjHC+wHe2A+M!QD$tcjIW|L(={=LTK5-!B46ZD<$iX_qYd_~!uxBNfzWXaL+20k z6Y$Fi3IS2#Hmj3Jak?Q|21bkAT_2PQRz5^lBML|3^Ivt=r&lTh4UwldmD++SosqP8 zfd>R{+`Iz)q&&fJIITRP?D3;U^@r0?_&%R>@9c3#h{gC{g?TZspB4`;|AIXPRVAh+SAL?2PyeF3fXl zal=ekj};a%-YwlKcuR-mS&z4uIS))_l~{30JSOQU;Epm&>t20KRIE&`(xB^Yo{2aL z7FOEUR>s%X14CY%IBNFrzYTU~O4yYMP@>)Pvp#HBkbTfm# zgSQS?%u$1aBFf<{*&I+pGcrH4a=9a~ek{s7< zoj=~Bq+D4Sqe@63M#h4K)`onMXB&2vsRBTn%@*~f8suEp06!S6{dq4gC9AwQ37=h$ z2IL3Fd%8$?$gaQiQa8AX|9>9SA8dg;H~+`$UE7*VtumwE|0C|79TFrw$8MgUwP_1p zy3HJX+Yo$+zYgST>t_=ab|l!=XeYBMC-C|p(iKfvREeq@c(N4Ho~mR4TSl}fq6rQ0 zV7p6v=6ctyZ&_%XjfY0G^f8ScSjOjPHeGOlAQk`8c7h|fxsBtnjHJ62dQ>p~qe}$t zUNRy3Ss)3CH27RvNwb0! z0g(mD!hz=Z`6?cxZzT+6end{Gcfp7TMCvbBGSk3tT=BEah(EJvOI(tID@YAI@ZNrE z-X%{a*MHw*--~RW8GCLWqMB*3IHe)4IYMmOs|!2_ko}=$!*jx>pyZPjI)J9 z$!=uZCQuL6@3n35c&hwA%76BD64m5-lGpvTErvpEFv(SXy51gh@j*lPNkG`O(*)St z%2Xor>0>avP^`v@g2j>gsVZHYn8_+Y+;e0<&#oKgkMy&!mOxntzGtL>+nZx|ZaH+?4i z>7X1Fcn|S>{P?(l?S6rz>z|@g=fO{08$RyJWf4unqkD$3^3l4-_p*vYj4#3FM-xL% zXiz|%(hy(rYC&0W**On~MTyP~V5Ygd-6V9`+w6&leM;6}2*rOuQ}UGjE*|?T?m2Lx z?|DL8P>V<9l{405lPb0Dr2|QBvH$54f$@LegfEmaxmi8q*t!tSzcV%@SVMfz8!>r2 zD~B34=iyV`20b}?J_gi@BdH%NG+SI3uieEscu|ZH;#G#=mQ2OYaz^)} z8tFvHutY)9o!r7`GM61G zs|oNz_3=5uv`@IC)NUa-NbvP+z{Hf<;SZJx`O4P;Sf`5D zrU4UWKGF{YpPQsVal1PgP2R_28!vfd@-#h)AL6IL{mx&q;~{(78Y*b(X(8Yb8&!;~ zHS_iKB=7_5>moedCkyBby8QLS53nPK+|#?0iekslah*89zkDvP!c+`}arSyleD1hE z3aogSVZ#{j4*3|e$9gyAFP)gN_w>;P>~n>Xa~S|s#cMJNCt#nT)M5b^siS56jOR9x zW`m88Lvhcs=r*&;zDHK!_mnEZ@4?4P`8VTH#{qMA$r?0~Ghl(8R#?7{&yAiu)yk*6 zO!G9c)s5Te)$81*ptV2Me5E+rg+2VV+=A75-tPN`O6{-5O=%6e9{aF~*a2k^FMQV{ z&EVdIwh=lSP!l#JcsEnnd;dsQf|B`3t=Rdr5QFeWStD;IzB2$Unm8LWS$BWvI$PhR z^4BpVsqo6$siK^NNI`$yLB)$-{#^5Ji+i@vpVc5i*xf0vj#ZlYUN-H-M&hS4lud*{ zH~fFyh(JI(Zlz{~Ta>~ws+-${|F6(_oV?s-r;g4l|K%#>1`~Nn#%*%KGp><4o({lz z*S(;qhF6fcx~=^LNp#4XV+_dH?qD}+dgV#iu3pEoh-qP8#T<|$J;)iAD97?@u4w=$ zTYf$_;zvinUass)WI^{x4V45)gsLMyd!kKSCKiOT=>`xpOACh(704;Gex&**=_)}W4UJ#zN+V(a z`s{isYYntGd9xwoU-&tEy1faXi|h&5)^+RE(W7vFpPgn3wmqK%pF#6y*Euk`gS`62 z`P-f?tQ1!bs)?OcwjXtca++_U!RmMCK5>lN&M?|wXz|Gi`^{}goMGe%AnM0D?=OS+gkG!(J58p!3=uqwhWnz&5Dq9Ge%-B61a^=9bmP@GQPq-c z`)sIryuiwwl1>(xL^rLeJl*^ljwVB6v~qeti6CzCvUZ9Kie>lv?1kT<@*S#|mPL?MS~V_EYlQuT&g z=P~NY*p<^Fm>ugS=Ha(@V*Q6K8%@GneWNn=Gj8>9hUbZ>%wX31!4HkFgW&F7&yG$ayiyB^?&-W7RqpUHG?Ot>?12?bi?Z;Hww<8E0@Evx@nf zL1912K9E|c@F=ECt4izJhOR}YJvnsK+aMul| zI;!e?j`Yb?_jz`}jMgHyN_AuNoI`Vy$S8VJ*W7l=`47ZJUhA~W3rPA5Z#o!KLeZc9 z<_^-2H~=B1we4gbHL@(RkC_NO`@wUx6ZeM|V)KEC(ZkFT4OnCf>JR2iI5kEfWLJ1N z+)kfyTBl1*Pfw>qN^D|FyVfFTf8A(1EZCM1SyPC%_t?c1C;%nD^^EqpL#EfBEZv{3 zd&AHF$bAYOsFiZDXCfb-aZC+2lS8X`qd!4cv0bmgH@NnjNrs{;E1oK% z&6oS7Ueuj>=qO}AAzg_k_-4W^i|+15zR5mo%R+_C>Qy$InEmulrSgXOnV}yGJUp*$ zExd`{qe*FcJ>2nZPp4ZzuBwzL!>wJa*zbW!=O?+%&Ve{z&v)7*H_}gP%k_}w9l#yQa<{5IKAge3opUL&Rbcpo}~#op}qHKP|!4oKP}iN4+<>Avor%uX+c|Rkwpr; z54Qe~_4Ah;Wep41=6uNqT-7*RKL~c+3YoukBYn}Ihw<>q(pFl&6(8bRy%HZSJMKmB zMy%l(A-ITdc3V8?qi^&v7$acdh82H3y%-BqZD=ERoLmVNqW zlw{do2Es|KJKsHiV6&Q|zqce4xx8{>t_6rB>joISBA@Y+Dyi2HZ0jU15~DDq9a*LR zLR0V2L}rrtLKHYsV3U<-8m!uQK+=%Rd(?c-62xM!Q z8dEmGVj{fWRo(a1dRY;|Tqdn*p6EX(W1R2fd@kg`5y1Es9 z#zwRC(r5ZMDnK*1YyZ$gcgXrH8za1@2^e69rWd5~~QG8hl>Io|&q^#Ds> zR?@+o)3#hno1=*@_b6#w{mhXD(c-=%dAHC2cJ}H}=P}F=T6{S#ga*mt&t&ms(|8&8 zqR@o?I5j*g+**)vTK5E`SV3D zk%5nOGQH9la#OZ)xNc;Vv2pS~>I6zGW@BH{qXJ_VF&kguPUxp33GqX0DUmSW+j!y8 zm-TW@5D#E!$&43g(>{_~E4GI|Z}c4t_Au(-ty24?6Af;*_C|DNIurD1RHMzKbHx>@ zD`vpYS8p$>ORS1{s`LD)Hu3`7+GlKN!sidxwz)kPD9|Qz8VqMVLnW0N z?~2)4s$C*%UY}s~;*7_ijPA*I z!*_}%GnH^Vc35gatfUd&vkLjwXCmllrngjw=E>LIn3HTO-bG2?VytT+MtkH6r?0^3 zqw`6Iq7$|cu*3z9vZy81LdT?=*kurmH>Af>nsMEK=8f=$Jb>JEa?!nqrP=E>v4F5B zbMy|qTp-^E=#O^th_?FdNH6*zQf9rJW{wz2Y?_oH#Ag@)N|5Oqwv?8XpsisM*BeM) zUZB(II##fHW->9(0y*=8o)tZzj$&L+%T(W?lHe|v?2Y<>V2d-^bp;z-D`1}-=gfX18ET0!3u4rEekw@ss2C0r z?TybKx$aDaM#8(&6K7C$zGUTK?it(JC5q*QN)KWj|_}?EfuecCWF6^CcB=`EL40Q z@Z+t^mw3Lh$1&)=X2|f<0e{@aV_GY;OVmLL_I=#*jvwj#HPz#GkbhIcbFD+ExNBMN z6$^zf?kcq=_WI@Dq1{gZf`_n_uJQ}sXP{+6;l94kLodhiU+PphOlmWF4&|rpN#%bT zK~t`mH?)bNgV3-4cu^<;F0m1^x%M9rR9NX)mqD`Zmz(Bt$ak6H18%|BEa5AIR$shK z!h+iWF(lVTyIH}*G$*-ja4o}13g1R=uG=`bbR84%AaKN5Y%3Bm2?B+)c`CK4hU0~Kl1l?ZmI-=XtAxd6m-Vbf9MZom0h z1mVRAi#Y7dzbcA`y!*7vaI0~jtzTgRe}G$o(OAcpP2hq#{HPjofeoyl{jQ^;@H0xi z8Lj-kgsD=MTIBuL4<+q+k_->2_`y_1K<7S3)B(Ean(eHG1hJW8%D?-K3=kJ!3a{Z+ zkVjm;J46HOdU4G$?)CTl8@nrs^uv~F(+WHdEqr6Y8vXhs2M5ma8R`vL6rb5jxS}6^ z3sCoqFBfqzewd5Z{p*U;8YF-)XK&Xe>mM^vR0E4%Z7~h-#_TO}ehiftWY?)rU`dQ_IX{y`!+Hj}$^Rb6*H z;BR64N?opfEh!ae0#o)lwb>rV`?{&~UI%CXyH@qWfh}{`dCRuh_v`xE|CEqB3UQ~| zF43av7KY)sA>#6iMSp}t(|t55)IK^ndCc)g7TDgL1m1AIiIODj(Z0LBlvZ6fwt^z$ zvHM}uZ@kKg$k5FI4}FRYmM{Ti=mPk)R`oB)4RmG#6(`{H z`F|^WuQk)EXHqc@B7T9FNe@-@C_z&*?(XVHRJ6~aV*<~F+G96;NZF!w_O(B+wO|?z z_GI4b+@1+rO7rKj+Y=nUOr^7y%AVu5v!a97Z7N@)Au$r3Wf&H^_P+wltkurk72Ve0 z83oVW0l)TZj6KM4n+d5JmaUua@}e?!-k%jg?g@+>+i zzfE>Pfc$T{z0AwSa*V>}L<0zQ{XP76KvIqN?e~8xKK%Ckr5?khih^1Gqx8LYphK%&PpK3eZ#F+6Wi^~Ha&N5J zPh~8I*Q9IWyVA=|Y6AJ6pZwcnw=Y$FD9dvEb6g8C%WN)52Qy?Jy11({p-@500Vue6u2$%&2i7z)Un$HRpe)bFqe;t61}i7s~c^>Oj9|1D zTNG|l(TQm6yWA7J?HF ziB1t0hXBvw5P3pa%D#&tGX=_S{e-p4g)R4F13y5Q_)F0}e*GWImRyovQa!c6jpk5t zB>mGF*s>`jDZ(R|a2MVOYK;pUK=_m(Gwv_U9#crnZxB4H7c2P3!hin)m(vpO>I{F9 z$nORJzIv)#P8ef`3N9U2J8T80#E3a}z(^%Og$MD^(E-|;bvT^~IXHp4aj+o|xZW8P`)Jk8u`#SrUX4woGM&P-w@^9rAUBxz+JaQ0M(i9aA z8}{~*MAwQgq2#&!Q~n)!i>wd+bT~iMa`rW5@^l`Fl3(rbLZOHePkCxeZpJ&Ph0;B8 zB3AM3&dWFW?SC7_c3+mwosla`L-u$arirF3Q~9&=z<4h>X^#Gxv6g2)UL%|FmTa)B z`#x(w@EuF8*AKZ=6oRQ{Ud(jC%k~%TwnTqLm`$;hZ9mj^7WS62j-)x){cdWe0)kM- zCa-YCMIlk|#^yqy7^6`fsVZW`nUw;!KLaxl4e`s%0JgornneabE7#YXJpBi5dM+aS z<|4Z1KOWB(KOL1CrL2HUhmz38F`cu3RibtU>j!z`x_}(xr)yKT^+ZT;Ho0JN4&n zdS`l7E*S!4j4vD+xP9KcW*B?=_p8-L%sjNZ51*F#U5b*r#_!zo9 zoOXOCtmIY2=->|;gFcVoFpCWV5#J{CAgDY(zauS%+xULO91y!U)}6jqO_uI=(NRTH zb&q%tfP1dQ5x#8-pwv7hm@|2Ea5xmCzhrK$daibq;TFu@6;sTfB_hNefgyeXEmi5BVxykY* z!5_tH!A|d_$12YSP#%=r&vqhY_)MVWD#rKDcKpWL z5$u1`K&5tG-%va{Mkk@9k?LS1{QKRH3=9giD%Tkcf07m^5pwqs0T|~$Mx39!8!_eY zccsa`b$gW1u~8-!b*@g-cFx4Jj?PGa#3asjChFfX*x<1U$@#=cl9d{6GO%ok6NBQ# z_{@HOyv93wQ7YvT&}CO1Q2wY`iCV~T={cijovNkbQg~1*mp%*jiyWQ&p(``3Szh1%gEVNK1p;}qhe#D;e1M*#d z3B9oxA=d)#9<4EKntyXPZgc4$;m4PT$@KChw*{Dubh8M2^rzO^**l*fo%QQUaTSSv zVec-2JAJX(-K}DRR{N`lMF@-AZ>X);c-ucnocb-Lkxp-I0#9(wLqBt-fB* zJHQIzag8aHTNXH>>RZgzT)I!upBC<4)r)m7Ft6N)uiDAa*Gwl2LzPcbw>K7^2aX1+kAL=~a z_j=nM@myMY_yQt>Kb{sVJ3*4?7(vrl3y(hj`Ys1GDuw;6o{<4&L~CPy-mjv4JXHAc zDXK#h<1)hxyH72(wqmafc9#biAb()6KQJt3El1S}cyayahuS;&CK?)c^`n3NyipvY zELqXzX$fxhALmw^rpo$jZ0J5#1F87)G>Aj(^utPzO`>sY*~*i@PnT8Yw(J#J$cw2o z3~RUm=y_zZ@|~uHG_jC#)k*ks3cm>RjfR_(R4tTOT_7Z^=K%viVDis`<)_5 zd+QB}1JmB=g~V-z-?c8>$qbQ7u9`trX8Hq}gHG@X8!#=)gmy(C{*5OdOWXdO?>{qM z@=TweX+ld#Z!^RFfJaa&a zSx4*wH%qg3tFxn3?aivft`*8s(*JKC@~*oCsN_p!Hx1l z#@<}@F6@&E8u-RoTHviNzB|1A{Sj>_N3!JeT)o2SF;wMWR`N~tRc-qg+sW&Via^h0 zN20z~?(1nz?^Sjjtfix0Sxd{`76d{jr5R`g0DGlhx`Kuh%F5Wslsr577X8K9@K$XU z9KKJ_h^?|Sdvdy4?P`IQQGZX_gKPY!56gLLvCY}cTv@DW6n{9Xsvtxp+p zl5iUT(NkhC(DyWc3QEPqx_^175$x!bsNA$KjOeVs>eO1fZQ}BoxesjS3<@QU#|PF; zp)fAz@#m2lBmi3cI2m_t4zJr<2Yd2rc5=PxC^!gkIE11N z4x4{jE_{&v>wc6VU@c8zy|ZGVY6x$sdHxQ09c_^_1&SF!E&d|Ps6rG6dMv{ct7Lt` zuUo_UbJ+W)$tyy>IKHmsaKLHAK9J9=NJ310E#K(^>8}plS4`%==WRY2&e-TVpNz1~|*n5r- z>WIvi;9BUSSIVunun8LgU^{A5D((LtzjQZ)d#9xRSeCK;<#6I^4Qz!ri&kc@Y))w^ zGFh+cLD=Q2nOa!~h% z_=16Z{mI}_C~WFuuujWW>4OFW!iY?GPzhDa8r^3ds-i~w)^skyFE%d z{77*Dmd2#Yve^?DS9IH!YrJpfkBTkzR_hA_4wX}{r>jv4L4)RODpWV%-rDwBqmcNm zU$P%%IDct@q4&^}73FI&Caw4N=eaY*0cJs)7kxH{dc%F&oN1F}XNcf?vC8D3zKm-M z#9+h?vpXEgw=o^di!9RIViq*1QN9Iogt#K0jwZVu&|(kjCvRFCOVC78@!GCmakZ)1 za%=<}RG=-uxrFXP6Qqq@RTb0u$T*@sk?C~1uJTNd-cVBdn@uheqCO2cWjcL6sM~;5 zmgFWcKaii~8w<0}-$ZEVr_GGK_|sDDhTw^s|AV^sjA|+k!$oJtQASZ2MMR`z6a^Il zL8(GAj)g&lj3OX4(nLz=B|u0V5s?}JDbk`MAT{((A~p050YVQDA+!Y2+s&N2&OPg{ zbnzPn)W7yJd14sBxG5pt@%BWVWZg;q9v%1;$i|>_OT18?C zAIw5f+hOT9Rt}+;?ZUTfQz?rhpYL`I>MY8g1hST51qnI}-&QX=B$9@1@5&+evlct; zz9NUi7bJJE#5%(eylq%)cRm;mlqWF~eBg>^17i_+5RHCjxTq0H2t}^nM8^=Nk|P@o zhbS>6@b4eC#~}V6ap~?I_8gJ&?clOXsAPTcuPE!(pM7N54kPC32;TL6t<=__kQl%|y+7?%E_B2w=n=JiCvn21 zU$c(XhY7FB%B?WAx2(Eg5#EI?>+-tOyKlKTSaQ>6$AK)A=P%Aa`an6NIG$h4pLV&= zv)%H_8hF}ewJ6lOAn+VUsA5ATYNQs17w3V69`iRpQ2&Uuki&?JCJ`$U*$km{lA0W~ToIk-`jr40>dH#U^*}fh%Q07%H&U zJ_RcK1&N*4Ie7)h{iTF3ofYdItH1yj;UfEzITnUS`L?cvJcdfU{|=P-?V2kvUc4n_ zpheMvd&yILdU%@rwqtwuA1Tgm#A!$nFY2<{Mx-DIpR4q&Ggal|L-27Pbzi$SUrgoW z3iZd+^l2qIkwr_wzV}Yzv_(hU2>=Guk#`7%|O`Qv)a!-eHT z^1j(du7jaAOwRr@>O@x?;5s$)U}@6>{{Q}ykeR*_v9{jZu;!DGE>-;eiScaXQa@gK zL$5--|6fbn!=f<7i;;9e(m-xSTOMqTzV#8I2ZnF49*e8k_L5w0u)aMY`%PCGD*?4> zSNIQQT0Fcw!jb5DuWPY|e+hdJpY%XFG7a{OPKTd%kl1s8knt=Z+_2xDq;ynJ%TJrI zo}277P-iA=q>z<)%D&$Juk+|C5GxslF;`$qj4EAc7f=bXeAb5RhsArkz#vjl1D&S_ zY`mI_KMmS20M?c;;AUjn^xwapcc0C1$IS@A$M+wxZTpn>Oc=cY<-Jid{5W(UK1sJ3wU7%(2>!` z@l^qsphXCq6k5H#@+d^dJ096x81OG56git4U3R<+6g)oPfv>;a`L}G%Qv6*M4j*P)B)uTQZtF)G z!Bp+u4PKFhaOpeP---a5*}ySVk>*0z{riYB!^_-wdo9?EyR%61e$Gc36c_|wB|(>Z z4}YXy54ZqqD0lH%`AGtxeGscGFMj6c#9n-%(tL-6~{wOxZ9xNZ>an2pbvK(c|Fb5t= z9y+;5+w)zuGJWUPN=!t>pR|Gm-;z%v$GW50v86M z>wO2myt5M4Ox`49c_0-#4a-iLSgOWIo?K})YPnQ;BK*WcbCqhX+!&h(=X3WdnU8`4 z43ObI6Drw_{K_WCldUmXRl(>xO$YdJpF_cU`WaJQBDAjc9D z#+W%+!*m-(B%_rOy}Kfb!?DZ;Es<1mj|33vUbn8gRPIF|Gf|JiMvO~$iVohN;o3y6 z>I#t=<_(UwroNnbd*?SX1=#bs;KxuYdqB-ts?rlxyM~IKI3=3|S)Fpe;CiVg{bD+j z6^(pn7u5L8$I3p)LQcADDc^7O8sxk*-B{1wuS=?O5cW5Q(IpL$6Zx#Le@a%5`3+*~ z^#ay^EgQ?Hjuu-3I3v+3u@H3}&)>kz=A((^)Py=aIEbH;!9Q@lrr zG1y5?YEsc*hv3=gn{b0}Vy}d~Jb(?8g>`k7*Rfg>w5f#qM^u1&9wpE3Vqjw$f=+yH z3$41Ms;zo{AyhM2X;2vlH|z-5T)Da&YYZ|?4>Px9$=gZV(;1SxWm`r@OYaI*ZGukN zS2*4I+HEE`nfdOsvC*|^uh-oY%G1GhY0MY0K4-Btl=LqS;Ne+Rm|)V z|ELp0Zoey7_^xE1S#BK?6}@h7CP07Ql07O~qF$4pQgzOcSRBftl%#q+RI1RZg*Fu& zi-(pC^9_I}9?W3+p_F>}y2Ez854nX2duj#XH3+kj$)PPS8L$uPaxx=S+Iq42A8~n0n>aGFgj2652{xZy% zk-aKiuUQlGkW<-b-JI=8{yBFe`#nlw&(5P{!rkPrRLSjV&1NEM^C^#ya&cN_O50xD zERYG7m|P)fznlFEI;Bn(2zTA`BwUBLhxg`wObnr#>>UVRu(jFpEu-WBs6R5 zgI&;Zs<~k(b#6!BWIjNI6c%zd9fX%9@M2~&^q+R=0v0K~93&$F3f=`bCmJEHExeUGQKpPa zc}S%%@iFm`b!D`s&c+p5^xY<<>!IJlyfLHT)F$fn%2O}FKtxI+D_%Nug|fZ!GC36u z?*;4X?xkG6UHMhnVFtOYV)s8c^*eH26H5_h)0^<`;-u}>=<-Aqyyb)_a=2s=R$TT= zBI|#ZdGkaNwUT6HT7DUo-nNu?J_qlJSNh1B?#Vk)aosDfEZXKzGPGx;z)=MBmV(#< zdU4?-@=~Sp@_)Azgop>hRtVH~3;f;O1tqv>*cO%voCy+Dnf35UI zwaG4;splxFOuPj%#E(r@51#lvovoScs@93esK{jLe(#7r5uqn~qY?qNJXe*_mg7eN zlRpej-q!Bz#6M8Thg^-cN-%})?(V0V-lsl=@sq^mCImdj|Gh_vOvm`{l@mIz12Ph? z{tUj-`nt@zT4}u?QRlKLt$5AoNwRyt^h|x;Snl2-Q3;&Lcc?mc$egxhWD0;oTvhmQ z6w}AjpZ$n9A)&7eM@Puo$$$-94qinj;Pu#A&C6_dB3R11+S>%9=UCQVJffctHyJ7H8m9Oe=kxVo>%&Zio)zoF;p z0EEXPs%LtTm5y)~-Ljmt3(bueBO#%?dF!P6al;1)6qfTWJHypYlsoy}LjEBn5eIZ> zT&z3sl>L1Q@Q!%oGyvdqLy%0K#k^6kh3stJm{Cz=qhLtg>9oMY&eX33e9sz6N7YRu zN{8lJPNF<~;s6p{xp0Fnz5FqX^aWK{tY1+pXCS9hwf4p0>D2V5dT;-N(N;%=1LL!_ z!D`-l2uFRp=c7e zlFzDH_?GdSR(91xy&@Ft@=28!8`&9x10T}4OU-+Ykj|8$dMQX1!EfN9y+~YCl6WW{ z_OLlUB8!5C@0pji1ev8`knHsURh;m1ioM`Nfgn7-Vrhawz0Cauw;Q?Dj>Z~u&D zVHeBWvnL2hCfnQ#^6*vVnR*k@UMJqne)Dn(OYrWH0`HrYE$Z~$1=hc9U@dGXO?!6l zk2s$R2mIIc{Hx=gr3ZrW(dsg(YL2%I?s&y$`=FBrL}=r1qpKBg$a2b)IUg7_w zS8q);EVIhfq-LW`z3bw_A3m}#h;GwbS^iv=x`?;XVZ~-8OZl3ve_!;me@l1Dr>G+~ zee6Du09UPMnik*ra)#UjPUCvBtt zjq+K8&sO*57GR~^m0>)Yw=QbcOkWZn!mkNE)79VhD?6Mzi?No&1sXu{<12l6sNryf zIYuAuKBDY>NIdjo-u@mgnCP}`5wz;_TQdaTbo)J z*WL%xOz?m7>VfF0cq5#eXoF`?)ng~^^HS=Sj__&excFZPM=d+`*E5_~Jj^>kGbF2P z=9mA=uc+uc>wZ|i%$wc;5Zw4nxEBrTJPKZ!e4}cb@nrN~VG0=7m=jkg`P94bG4XJ2 z==#S>A#lj-_V$^2)rqfHx{Yf6TldYf3|`(R{_as_@iA@%#F%#Wo4mgKAx`N}*mk1FhJW_h(}1t>d9dLjV|z@Z1;*12 z&nAc$zD{KAEg21Je6W|WyqSvSG+NN9vj{kOBV!F4^P5$({tgz6tD}_dj1A`|PB;YYACAT#C%Y|W(KFMkx zC8?3*ZAx$dW$(c2{rk-A?DLrhLyUjwS4*ba zD`iUOgmXvkwl}}U-Og+f%-`J4-TOW#w!+q}5^DQp-G^Hg?*FNhY zSewVXq=3dPM{~%|jLENRY!1!UHq{}e>4%v15GbPV+uUX5$<~!V*6ovXr!pod_gi=9 zMmzdy*~1eD00oeSC+8*(iUURw?uNe4O8(PoO0Df(k|DltSLnNpipL#%(0>$~^L~r8 zWGmVSf5)to4`?sQJ)zoBX^^ccvx5q$Vxvr3t)0@n0~ zgjQ%=e|O6$X`dFH0MH5TT3D*Lo5AD;$6J|(&vOzNv7u|!||URYp2*0xYT zY@VwDUyn>&`g%x3o`kZmy%F}KR$NRAopIK ze%n6!WhCqu0VuRiL9^yM0D z7qF^A7n|yC^mU-$D3J9g7*V{aLe*v_QyZi12gIV5{ql1&I==~DnUL+U#!-=Wmy~nO ziq?Bp;$WRXjJ-0XT$cDvGwv*y^} zEvcbiBR9<~utO}7lQHDrBRCVDmZNm zkRttawQ$Vcq#a^btDaWMRXm8|nH5SCh@5>eAqy!ZRCg2mho~>tY-*!-W6f&t1Z0@~ z1$x)7Rp|wNB-YwJ{K)e65wMHy$Udi}o`Awt%s?td$v3N^1V6XV_hXdwXjZ74K3WI5 zfNT>l3Eqg@^7HNd)dqa|Wcd^InE-YjS<2gfLAc3UZhKpr$y!i~u>UMkrL|^F7IV;e z7m0MgD>1Y`*~JX5H36|6W)V76AP1LGytblw`>UaWTL#L|<%1>Oev7Mt=<%$Cw#X&y z6kWys;R|hMRw`XmHXZm2P=C&@`J&ehzApdVKKr-tmfg5vrSA(OU+X*ecWuCLK2Wez znS*n&pf|YVR@PU2q}{{s<&&B30~teZ-P`_Wj4;Ru$8Xy=w;mOjru_!-9~xdQOl)o9 z)v_*sEP2ka?xEtty=_D#HZR*+m z48vuylZ#K#s~ifBEH%VL>rQkQkx`Er6Enz_aM|pfARst%C5ZFM80(7Y&4gZ7Ur;F2 zZYVZH-465BhFj`$(Y|^>k?+&cop|6XXD8QjJ({6CIwpe6YfNiq^}J(?oXI3lIqYpg z^YWxr-C$Z207^79eWp2zHCeo3T2rM?>7;TA2()F-&5>nWg;R+&cvcjni#b7&>bAT! zqbw5R)X}K9*+S{8fgszO-DWm+IpdU(QMh`zyt(d4<8qL2>C6KdQs5XVCWG+UTAThC zUFj9Zn)!;JNxPjHh|_LyD`CE=_n|Tp31AsfkIs5u6f@izv|+7b0-X_k$SoNze*gDS z$Lqu5E9aaDZ?2gBsV_>_ApLsjfTiK*dGKS@uRXb{pP6TJ;@`-&;3rEO?w;#U%G&}b(S%9q@dKWJQ3F! zE(1YJ1pBCjwtYKdL?pfxA!KM5pZzeHtI=*{ZiyLco^TmF&QJFZ3k(q!8t*reN3~XR zZE3AC><`qQ`$&~V4N4*_GE=gi5bW$8OTt4Dj)~z+_cKUGr(s)VBsD}7L7hLKEl^3H% zd%al!nkY~(wdjOT>?Dt=uDc5v1V3>T=398n?g(kqUp0!thwwP}Y)VVA8aoYNRFm3b zAtG-7G99SGslO!_=elkC2TyvP=AAo;Z0Yy1y<_@qVi_kT#%KBv2CZ^RPO_A?;R!5 z0&Y2#x~b+!fru9Yro{xy3C8&BjUmK4);E4m-l@k(@R;_yGSzCs7%!W~-OXOYxv8PY z{Z?p^2hyUo*2!|mXTG5eS}b6!@?A<#6 z@vBO5=Ngih_ri25LKh0O1yx)@h?JPxqyo9I#R1waW!RVo>`}1lE{aocfm3*f=|15O zY__0(-NXvfehL6UsY9Rl&5~MhzCHO8npjsM)zxe1=V%;$l%YMF4}e#NXA!t_BjMNQ zmfklPn<&WN9yYesHPjUvxXBFndz8Qw)Q$4OJz~}0k&8XW^K=Egecj>Db?QLSY*je2 zwlXv#W}g~y9Hm0fO|Qe7kV)Z4|D^JxVn@7PU@ZzKy>jb|5^!5sp?%lCCbjrb(aeCX zeTn~%U9>cbXfF5o^pzOj&7D7cArgRr`ejuO2XJ%g+V~lOSM%Me%BCmX_bto*D$l>3 zg@3&tHrt-046K@z+A6j%z_=XLbWwuZxsrFa4f{l(5o_~ULzBTn2eu@j#bf!sdq*5t zrWxU688de7GUEDGv$4GD$JKJltNY&*Pg>UwgEcdX9rzDPC_{D{U|<#gy^Z8LyYlJP z-6JUnbm}A|AubkwA?}dFaI}IvZ1TrmikaUg=t>`7jJ*G^ie^KAqGQQ$=RQy-iTg1~ zWRnQtOWVw~vu(npR+Nk2Lwt;lK1t+r+~oYlyEcq8K+xgCqJeT;cuyq4S!Jy=1xD?i zGscu1_d$n-8^|d`ht=6*x^7!hrnf4_5is=fa=iV}JL1HZ`bJT@LBBHpQaR@jws*ak^KEtVp#F zmap;T-B58$AsHTQ-d*0A2{DRtuplSs5fFpABQ|W-O`z4IDv5q+uqR-Lza@?*%|{Q$ zOTm&fyVHqNCv9T7%Ppr86dWPk8ygMKF|p0(Z-y_UK>A8A+~sZoIZ_ogk?gqOj^mWR zw~w?=Mlp~M(cfyPb^Ym~g8xwH5+RD)+(7DS^auP_@+84(@UHfPumv-01ohoJs*-aI z!TQH2&v0_NWe|sXs16hgRC34%+haWvklt+Qb)g9zbT1-3f6T!r#Gp;Rp)XBDU&h(dYTS zqQs{|8z^%T?dH4IpsCiGcO=@5j=>2Eem3TVMT9lLVYo2(qmg`~-5IwIK4f0vcN!bd z;_fGD43jd3>XlmYqf@Pu@;9MG9dU?`=w`8)6S!OfMbwa-%5KSlN*caQ|Jx#@MNi__ ze{5A&O)Jal-&^1YmHe?HLrrPw(8t>^=5sB3sssL#EIm29vZQ-TP?ru}Nj(v58TB}Z zG#b`=KPpfk)v5T2FBIY4q61j3L*h}gGi{KJOqRs%(8?qJTIO40T)z!`Q`!^fJJ3ybiqDAe$v!1Y0+7LIok#GGF|tU+LlM| zN|d#{{rGBPzVrHwPh*#*x~J4yeHeYSq4x7Eh}9<1?p~O4wy}2mQ{5kOH(xwr6(Tu> z4-Fb2B5}zwn~X-;N_m`4iAX6deahA~5nJ4Qe|r}xOs-)}Tv&IR}-f3VztBG*-Fs}WauN!jl=%!=|0ca^(RGcX9@ zjiz7m%iCQ(5focT*52~tvt~2`mQnj7K%{Z$gr0J}g#N8G^dffn=(7|Ip`=VK)XChG z%I{7bB#k`oKccQbnR^$i-jBsbB!TTWt^r|-I)PZVfV=KC!nVLjK9Blb zgY0y1q$?Kqd)oM}o>IQ~sH*pPFn`xgvJZD_T}4~3*k_==gt8b}_t1)GJGJsMDw`P( z^U414$>MjYWO{}0J)h)K<}-WN&8HNhxQ;PC9lDnFyF&G(hhW~aWVDvk@EC9ledwYY zGs>^)dR9iz_p^0QX{Mc~5tGl>DY(E*qi`on3jbBF#eszuUlo6yGwWfS`O_DJJyp_W zwVcSJ!zdV0vidqu<;CTviE&%}k*hb*py%mj-ns(p9iS`-Z}_yh~pR%te|~ z`wcdI^>EiP2b+<*$ac$pD*rmkbtlb@@;wwC-`iqcXgO8LD+w)-i!weuLzw;n@~<6g z$rpU_lkSSKw)HkBb*8U0VXq7wTsH4e_Xilt+a9+WG9y)T4`|qG} zmtN-gzRK*3{DYwRk>EEMRd;dli;~i&?^IrNW!qA5UbdwkUDsD4t*%@0;~F;^&8eQ9 zFQ>OSq+K26T%Z?gngKw)U z9tE&>`zOqJ+vi#0Wdi$Xo}i>#tyIV}(e@Ej&WTNTH@ZtXDyM&AZ>oz)H87K#ep&(p z)>i(XyJXo0D^GeVfD`NK@wd|Grs=VN zI~GZq4I`0JcQp-y^!JKe?frAmH{wCTj-p7<+gdz_0@ahpbX{(Y>2#%IPb#1E5>;w5 z=+@{l@y)Wk5BDkSy zYkuwe@%vcQ`*j5(qZ0P>e$Yo*O~2mS4_(WZOD(x|zN;}Pub{)t9#X?9GKNrUSk7J$ z2B(SGP{cO=0=k z-GwJV;an_Xh;>o2W;-vR)KyPO5B%_iyw;?Rz`g~;0N``9C*k(&y?teIY*o<*jr@IT zWqMfewP^~>5QQ%maYj}&x=*+S~ny}hmm7BQ0_%6Ct421A{dSdz`tk1_iVlHr&`b1b59^qD9OI-#?=|etrVQdU20rxI`h*k?x(=1XUX_?IkgKX^|n2Z|b ztQDrJDqT0m4K3D?3)qJc)!WZaT6clp?229yteoE6V|0ctLxj`t`5EQ4^dafxiWHE_ zUoQ;`4O6l3lmzC_4KiR4o*_VcAz@Mt%X{#ew%@>Z91^rjM{2K%8=SKh)R|&-7_!+UC$b70Y;kw#rqGo% zJBNbZvBwW{(kZhn_IcoPgn?s^$#ycB`M?ep=yR{pcMe2MyTwr17TCV64$&)&G}m=f zv#q{v_S&K>og!9eW{Y#G|4@4H8-^GZQ~>>$QV+D1waVmli!atdt*nlovFe;1ELXWY zTL|TL$PvbQ>{>2(9>TsXY<FdJ<6AtHLq*4po1>?^AT?xrG+P_)o1=Ju+i?;LmfI-o>wG-L@x_rpXMsN)tMIYG$w2V z4(|paTxf?dHu(d}luVNNAtYm0&TaYKaKn3Kl@?xl0eN)dO|&{woh+YMZ8whILorDImzI31<7-Gsi9_C?LugZEAyCRKk>0{0|^z$d)6g^9C|| zskcyi*5lsmXEOtqcXZtd)zGoE?rjp=x$ILFZ>_&^j=PD8zjxLWVNYgz`Knx3B^PX@P!-Yktdm;WWTHf)wMBE5(N2|PTbS{Q6Mz>kAE zXp<G>c%<<7{?;le|Rg z6-x;bi6Lq}T#u<(mi}gwTBP=1-9a`Zqs#K`Qd?ie_@vH9&a7=^+YiSOOJbbcV%f`M)byxShR;)BQXOZds1ntu z>h1c{cHEe|#s5Tg#ce`e1WNr$2V?Nr+iSj&K zheu|ZzLKf!y;8lD-mUU_yXYW&ZlQ0a+o`nd*8@MaTv=a_H%m>(ntetFs^2nXnM%!MyD8WJRlKos}C&{j?Y#d86o3 zt{0@9g5DF#?+CGixh}`v;(SJ4LQ?ypQX5gc{5 zZ!otj{iZ|WBA{AhA>GCqxjy-(L!8>OZ2H)1>5gKB62(?~L$9vopO<&v%AY?e!(qsc z)t*}{+>X}ARRaKO&)hMgsg`pJnZ zXgU9t-#>tP{G{{{?yB~M?Y^T{=iS?jI8~;%CfyK%mQOfIX>iq~38r{e5j^kg@gz;D zq}%BWZO*N_6`D0Jp=?3nBtayes5os_INdWHxJ+4Ow~ad)%sUBP*4?s>{Tg}&od!!!*ZuGOp95JLlZGZ%5I2y-%Or#hp zoSeLtZ`!1<7MM%Kzehhz5$)6#(fCECY|h@Es4-OmI{hYEoG9^E5ArGPEX{>atpk1= zqHVsQ`~(KGOqyO%J|0?>ut2^PVSg0`!ancM7~`_0O(JqY`je{<5>6i1Xerg^A0WmQ z&BrBrujR*|Y;ma&<*SHL(Auo?JOXOYLzQQ08};{{YejCDlg$Q_o^Mn(q1QRRu^ zIb=2Gew;Cxzf{~o+T|vg!C)2rQ&IqpH;ey6v%61zKYM2A0une{a3roY^R?z`{r}7Y zSmBQrt;6#lh#gT=FBxQS^S>GuC`Bu*|BiX}J7@NGvAxy3Z@)OQU*AEg!%p7;+x1pa zzvSIDH3$j|1RjA-cK)RNv2N>meqI8g;cq8!zCz1Z{t1A{vi;Ty7&d|&w&H}(a697E zwNXCjtsGYie?f`39>@2SmPw^^7UK^j(CMO1e@iO~w3Mvw{Kc+V+LN7PE(2<<`%ZZa zv~PLSVI)W^GW_m}ed#d+Z@y`UI3*sP!(y!?YHmI0OkSyf<5U_TWJhMs1!SKA$SBa` zfF<_bVq)t4si3vAz)8PieBPvP@nFNc-3Mij(@nF;4Sz@z3azV;?q~JopO;2^;NJA= zapvH%i*_kDHF#nV&Lg{+hvDvuh<1)2NqjI&VP*Xs@P+qyefdh9;!Fx;#SF^pgN=Dw zh$+2@fKT8%6t-PQvW7vX@0;AaO_wqI!n7y#I~#{SpTqyPneMwT9}H*+AGv0SZNB-@kwGRv&kLz> z-O-c+JHlpJV{-kg@^2Dc;*=ELn}26KxO;e{(?qa$IlPLkt;;Kc4au%uzK8lQjiO}< z27LTHQRxSwvt(draycAL(@wf5`DYb!_rn7IXEAlnb8N~5YY9;>E)|Bck_E9@c6+Ce zIMiP4{C-42t6|4uFSqcZ?ZG2BTovG(52|9On~`QG+-BO+TRIOP62lt@Lzarh^Y%4f zlA@0nGTW5op}g0bn|K=9*82P zIu<1i=Pc#s3?5aestQ;(vznHnYuh)+w8;PJNxTVvvEU5(#oH;RwfpVoi0CL$ax1=1 zuh{a;=uFFxmQ~S zPY~?dXNe%Dkv~cN&l?D*DcV~9-Q9&&S#H1X4UK-E8D-hsytU5jPRp3ye_}BQY$V{Xucz4%{}BZL03v0)M;E@lBgeR zy5XU6*EG;-w4vlHb%2my>o#{jw}Pvaih?q!eVy!YUWUtHp3$wJAE~IG-)^fb{wz3) z^_;S&Ml9zMBW}gZ*F=Xhep`eKk}F{JWEd3ty)Iedxot_zU8HAXy(i;AFyC-eDcj50 zcBc3Ws1-a%^XF71SgMPhV2!0jI?8}rk{g1U8@r#qKR}w?nK0?++V#2eE)qRLXmr2p zv{-A41p`EqmjAc=xjBAg)Q1__M*8v7aL{SZ{hEbrn_oqGh+Xs7D`0Go>iG*>b}Qmp zL#(Bx`{lI!x#V(vGdiqByR(uqNlmv1J+1h;gfB*d+IN8)hRB-OlVMtFz)8f>lz@Xq zwl=o$1uv!&%S6tq1un#fI_|_aGI}R$h-wJmbF*$Qe>mGp75io{DbqG}th#V{XUiO3 zGN0N;4?;~kp2D$>ri(oxm1R@;lRvD8WZ%0`3-;%T`rl+{R+%nf#MKubB&+q&qG637 zwOL09nQA5IWRiX1%XMK!_w81*(}#6xt4{>(H~2%85E0(_vs_7OdCh_3pxsZIbzUC* zMz!gA&%x8*@(WE*oXzqOvD^n?zQV#f*p;4Qi%qYwblr`o1`e7A3vY*LVu_N^`G zf3s>bIlK50Ia&DANEMA_`b&MErSB5fc+>k~i5H+=&n*H3gqfwcc;^;VgC38Pzb$u) z-SeXVBYvLed5_)q6~_e2K=gGtSNh8@%Ifxdm{%AVl+8+`#G>V8MZA+3hIxm~?<1{3 zb0rjJ_>GFKD2bB}E;nd|yHyG`7Tgu814bJ`qc$!n9&hn5fA{YR1rOi($t6SZMr1+; zi)8~`5(U%ms?WcrK=eayon4#$+sM(*B;Lg^b4Yd5n>tyGvvIhahi`$@3lFtt{Cg;zv}G|w9_>_=UXwc2eXC_M;(7qi@fmn zTO$$nKKX#~)u+APn$xxsa3EJzvb0N5HW?a5;qal}Y#74VLCnYg1a>uPi^qCII@=Z(6bt+S1j9zim z2Y{}FZFU!{0fF`j$Ub#Cpd~OU;+eDp{S;)F@S)yGLt8=pXHv+# zU)<=tx>$-`tAZr@T#!Mmg@VxviHt&yQCp_4pO7MXVJy_ud2MxDI9ew@fq4~R%+oib zv7_lx_lJqv??O5y3RkYCJs&NFY$`bRS9!Mo`H|Uhn6#DNSsxvxBHabqnN6yeNYg$> zWGreU+#!fl%I&uyjW-|J8C)2!0h%Zq$2-bwe8WpMXz$D@{}*wwJfgbj4KXN?=)Tyq zHVAVN;h;*ML_q7Ut$>k3I-n8Yry-o&3*H+hpP=iYwb6GYG=^>S7|vFxrjIIF_`J?vfZdRI^lz;7AXjHPfS8jSFSaI_2eqagtG7XxwKEt*ez4nj7>*51g(rT zc8Imj%nDxh)3ODDoL3Z~^X_~krnyglSh8L9-O-~puYP}Y{qUU{3mYhrik@oge|q7x zSHF8jng0V>_Z*q)+jVB-H@z-xI&D~Kx z`tzfojt+3Pf`D!j%z!B%Zc$drmC4#!&2}pzvmJ7489;K#!eaPBzyrW$Fwal@ZuDc? zCQn#`7KXtP+pk)*{6m4gS++;~(zWoNW$4t2ktv87CyM9zgVSaH&)xU45B6m!!@>z? z1Bxs*Gp62clkpedK;Kt)!bFv}sj=?Mj|iRSzW;fcwN(p;#?)GS}EgUNy0K z%m&7W4kTooP{x8sbc0(r3ezyd&yEfDkQ7aT5+7tcKGgkfC`KwmWc&lZ5c-cEWkcJTT`ysg!_(M;!4PcqpV! z%5t$yPnvNqp@({h=U6vQ-ZrmlfVQN?eS~C!+dqr?96fp2B|+pa;rF~My{~D`dl|uS zym#56=aq=Gog@#V_3HY8$o@N<~G`}lX zyZ@s?=x^>*vRl3wZennLh!D0T>AO`fAk`ZkU+2>`iBMyKYmAi^_9L^QA5VW!ZwzhYIgIdcX({F?0XvJ=dL9*`bn3vwJUN7cJl)|qf5407yBa) z`;vXB6vK+eOt-FHR=4&KjXqKjhrYu34E$%*ewQ!g6xkGpEsr;U+n-Fpahq|?T$;L& zmM_h0qZ6f{d3aQ*~+}qt_IO-VcaZ{?z2)5Z6*^SXiqP$czU^bSLV(4iB_{L1GWjdM@tIuBntR z8y2@N^X&mJ0Gf`-KBeE8_uFjz6 z>ab8_myj255$DWm%o6a&cHQjQ8_mK>LtMywOYYlft%iA@iJs7D;+9szxx8ltH09G& zU9CKxT)9sW$S+pfQg#sxB_h~JUzXoGzL`8^!!GSMv@aL)j$D(-e$tb zTE52<(7d2*%BxYK3C7ds;Ub0lmhC|FvB`Rh49nnq4e)r{pBv!tdwGE^zuCy;WBw?h@2!d+hiJLlvl?xau8szl`JcYMb-1d06Bq0{j_Y8h(U_m^8-j*VrS03QZ$x`&DTkkuWLmqAFnaMTgi9?b6cRC8d(^x}1nLrOT%w^#v z10X2_+Z4a0BLxhyO_(i7B6z)7oZO1t_$0jHQTQV0DZg&K3_Eo=56j}jrKY|d{WK-~ zsh3XR7Kh14hA;`y21Z>J$bNXBIEBC4^prbWj3CdDS&{4Q8Fq(k1+D09K4B3{4?^v? zyq?({k9cBa$HB03S$^JBGpt?MBSSo6mc-GoEO<-)2;aSXj|qmT_>Uv)JyZFOzQQuu z$?rIBnEbnG2c%JakfB~k{LOJKuAaTEw%D+tRkX%pKme+fWgYY_k> zFRrbAfy$V7O<%zAf8iui-xe=}=9+{#A$$vN;2RMkywAKwoV?p8B6K zM^z_$%@rd1Z>TwyB6)p<_b#JX}f}iZNh5+X(S?o`#Rk zqCBnV+^$cI*5hZ~KI>MaO?uxi(rH{%3pz)^lw*gwWWj4iYn+eaU)A);@ohy}p`Q2l zcR-B>6Fu}{-r6(s|AVl1k8A4O)`eHMOI>SOp_aCy0;#1+*HS^G2;q{fE-kc0NfqS| zQK-a%5+RKcNSL*5MFc{T%AKT&6%a^7MDB@{ON2loB_!Mt0t6CBAYmpXVa|D`d!K#2 zv(I;a-}fK%Xea17!2m+MU!-Bu~^02eos&`i&jIzG80E`0NyaDRvhq4;& z5=QNlrnQA|!D6pU4pMeE%O>H9)&d?Rvm_p>f3r7>`)H<`$lth#Tr(63@wG!oj%zw) zqzU-;JTW*R*0arIdRKPD*khO+;iZ6hO}wevZAE>B*xFQ+tH{%{1+JK+0kzN$z9b|b zmx4*{yxWTQy7s@mU<_O-ciI%EUQ4A2hM|DHbH4%8^4j|!lBBKc{v6wW?4~Jeo%lCDMooj^b5Z?9Et~JM zGZ9k!jX|VCGD9@*FVk&MH(`g+A}7t>kN&(-ultu>*_x@s3f!m2r$?qUCa40MPu#$s z6amdOa;<>qTbm=tjj*RJgtzlK$^v_Adp z7Gs5HW38=tt)~X0{p&|JT-yvpUfej2q^@LdGw642OU=22DOfwu>hJ2G^Cr!|vC*2M)#-78t?moAeX2F|v7eUF7$vR0i#ym2Kfd(;0&Svxyo}oXi zn%{?xYfJ|=R?pv_UfntU)I7?DMkgVZzcRVgZQ^O_Mkgk%NwoWB(~!{Z&V0qicT@@v zTS1SO?ucCdX;_^6RDX|Hec8#-u3;pR>GFL^^y1y=D%o^t8iCdqaNUWq9_Iw8+z zRH0Pj60uv%n(MvACtuF#Hw5@J!)>>=i-t;H@7N@Hwws-3>l8O-xcWL9F|zq@c#2dW z$aqsMXTL@5WH#fxlR2t}se(}D;n>s;O0pVF_yK^R?I1G>6 zPzij;W%=HKVQf6I)hmYqH4vxa!J+8Xup@}vG@i*l_a~qs`!R)eHkB3J6;3Tqfa?)=~I(26>|7F|>B62in$E4Syoam)y zJB`hWQ{a6QJVJA$#MI)GO~Y3l6HHmqxjVxJ8$E|p&}yx9725mN;)SvOtg4(ZQtGzW zy*ml$1d0cS`1ZF3kgQ)Ck-v<+Ik<0>$6Xe8%K!$R$?Z&mCsS7if~KCzY~8*TKZQpCN(8%F4!??f#|4u{elWIID3NsuM3)pm>_jQ1>q>+oM zclOkAfqwH>><*Q?j(B~t(dIKZ{(`9!m-_+bPhA%l!B6o)uM$)YE=F*+_Wa7+z)@2# zg&9B4D|2zqB858}buybeyQ(j0Q#`osSE0?a?||H2yR+R3=#?KuiXJ4Lz917C+Hm9|}>@A2MXoDrHVCF6+opLgf29vCzdk#r~0iAnw z>u&g=pTpV<9dc;xaGdSCzMy85Q_!%yD=S4mR~kA{bzRanxPcV+yA?%#tlgA>jJ&fh12n|bVujhkR%nKBSiNLSpT zm;G%W!2!NDl=zLzUF@+e>^-O5wGzt29thVE#|q^TEw9BEQT(%Q+!Bi#eLmN~dBPLf z;rz%qbHciq$p7WdKWVN7Gl#^@&fWvNz+4B;Lib&Yf2nOoc_bGJ4JtR4u+#28`28fI z|HkX%xm%(w-287I*psy2a&{{Am%YKD@we|Hy(C@lfl2oHQLPlFr5jW)8o_1F#RM~A z;DxiDaBo6DKn+xt$=z;kq(V_O!XUo1XuKddd_J#w@0|Pc{e;+~ifgAsZkF58;-a!; zX?kizIrN2gUWQlv>cB($%tpR)X@R9*-elr8n|LvdR~3)Jj_oqb=T;>^@^DhbcFQEM z4m5N&fAeCw+A|9ZN)KjqKYIaP0>0|CA8a?7T&Cl^{LQ?@FL<*a*K0ft709v6mw&8H zx2Ad{oaweUi5uxVZ)r0;{KEfKdpN(4B{$BfSNJewvNm%yElickRBx$U-y-8l_B1*F zTRBf<*!{USJCaY$c_W`ObyQTC7P5XgQ+JuI)g%`}doMmp0~R(I9p|-x;fB>tj7zM+wGFp)TpShBhVv8Fopen(^?JUG42{!Ue+I|jX&-fJ zE<##xQcVkM}AqyhNeA33!nodq@14 zPsD;U*Tu;J9N04xVo(6{3Y)gbs*dD^(~%77ovMpvV4mSUHZ`{Q!xEY*wkj`Ja6ys; z;r!7k`6l7CVy@{1m%7=%r+46~X)&%J`g*6?L2&vsO<&>2v%65K>#0eNKxfvC>-n2s zLJhgr;C5s)2eG7Yh$cPNbcJ>}qM*@@uXpRfExs9T;fV5Mat z3&hd(1-;CX{mD0BJ9yptE6+zBAWJK8&sjX=-@VK;ht2{m&@FgeO&|YBzSh@>*A4$+ zvqH5NmqqsUQqc-A@x#zGlnJI9pNn6bbaa;TT z(aIa6=C47|xhe1?c=$KlToW&CS%zm9f&p&OdIuZSa~<0g8x$y0&<&o`e*dG;qxEET z7PToYK%CNFf1UlBm+xw+|L#SaHjIn-x8wQ<{U#kA(amRvsD~2mN{n0VR)3s4k9G$c z;gjJ7@|3rRCJuW_|JMh^azROYa`{K*{*nh9rkCizAnwFk&tVx?y#=%JvYdNtZf7L@ zDkga9%KF<6Y>nf#>z}UUH#_kYP#^l+>hB4uV`>*%Im7#sZYDcq<4w9HHlFsaIeU5| zdp@8ha{VD(^}z)bE;4bw=dgDDcbWAcJBVc)JNTcaU0h` zmnAV|#}E@2F-_(m8#$Wf&JhfTm(x^b{Duv$rCh?;+V`() zq$}0b$!GEeJ&G(fm>bC(jYozO&7ZR$E>}4G4nSu3ia|q$jbCam7I^<)sAZe@hs_De z(Sg+x1%JZf4vsvl6JrdvX2QW`sLnzP$b8kY_`lnxWneo_J=-a~7K3I3)@rOnHUva6e-) z`RCn4q}gfN$vg{^SrN1DaY(Ih!yv|#jcNk8#2qT#G$kAp?q=Tp&%ac1E$Y|;X2TTM zl0}s9R2~ft$WtW^ov%23W1sy|Wh)%O2X2NK{(`gP5P=9uqh+)#6dxqw0J0AFhpUCr z>|rjf^#OQk^)Aw9?P+ID5aAT0)=-f>6~q}#!NF@~jHvu}$3x3My{J1WI|ugW>9z&e zI71)aSJ(gv+N>h<&jrwPuJNsyr|a z=lM-`(tTo0cZGim1Y~U7g^p{5+u6mU-r|sK3ZmgJvc-}ue|Xx zllR*@Z?;C5?xNdHp8ATT?LEIU(MI3r?pjD`dR)_SCa2A{&d03z28v{1pLg}T#Goyf zI5~B+Xz6^O&OHZ+9o>Ny_#|cwcfvLQeJcWi&6y*Vs;akp32?n94}QBBdlGIft5J`^ zrOV#BeN6jDXIrC1&botW0DD0MzL#;**qy3v)6sv)&OS>c_Ov?3?=>f?QuEj2x0n zE{JA|pKbH?)=InfuJ8|m=37Z9--~hX{qF@03Adj4GqXL#`-wFkepa;!mI*#+gYAwn zqDlBbJ#x!4NHB1aAfk6yomahSdO+S;lMbCnYQp?@ur>tK-1X}hWpoa4rABq}w5^Q5 zD&BbxlliwKI&{F&NntWz zWiQ7%TLwWDS;DVna!z6B78%e#y>%|YQT^XJ+J4J$!)_7_eno?9b+2kt34oD9jG%@i zQh3~wE=bIXAh#nKlo}v$k6e5PS{Z7ggHmusMc$R;X?!dxTG?;C#v!&DdBElcI~l*B zPu%RG=EDoa*BoWdpk4D6?uCNif+$;&NWe5?>B}W+@YLsCK-oNX$aq=FC4)Ce*=sF4 z9$cAv4xq)Jsc?hlLw2K^rKr4Fk@#?07PeF_-cXy8%H-hqbQM4OktIaAI*O5dNnF$U zSlPLTmv?hXH8u$g-asU9U(jZn59i6)Ey|{}g^+s7@*IHX;~q8Vxm_NNezoa6=aO_K zf|nBF&+z$Vyf6pVMMA#}lneMa>qA6VsKh*V!Pt*Zl&%1?HtaEkQ$Imz zv|%NQEYts|u=fkf=mAQJ&PlXkZiHd<+586SbtN{Y_6rPz=PH?aNd|CJHEeaHUWC*$ z{MAH@>aIC;>qk!!3X-?^6-bN8|UsjnLLTl zCsF_}M{ydQ3Z_Q3oA2v=oGqq;S0DL$eQz|1r%apmAB@|!(1&$9R|4AIlcPT(FQoLr zR@(gUT2%@~GD40e?tbW zwj#^tiiQxh$;PzyJe}^nA8$`0_n*yMtT<=P2$8bD8q!MIx-akpl01HdeeP`&b@kL5 zGif=#9h6?0PVSV-(vA@0nmtpZ^Hq&bQK;8wOU-lN(vAM4U{+O)NU-uhjDAq2oq2};VQ9V*eeyWT`hUw|B)1F+sA5c zr6I%5=WvE6=v;5D{TSY3BpFWEq~Q&>*;mMav>T5qhOF3$Al0n;E)`N^Jlfv5N{bF0 zg8C0(`1Jexsj(}-L{pfBfe752E9I&LVnmwFLO3`zNIdSm3GR7?J1eFOYN3vEY4f$l ze)mR!_y7xUN35!oYQkNIh&&W4?a@t3Vbx!!>u_D@TQ9eqPqT*-&H?7L8THkk*WkSt2E z*z<8cemt<~Bj`br(#U=5t5l7?Py}9A^PuD6`WpXJdAzi~w9j(v;vK%P$@4`#5=$zZ zkb)I2&hRMISDud#iqQ0DVIzONG2f%Y zhvhF%f8M_*qTJ*IbsWG8qB4|4CB~rIJx)d`DU^lh^85Ta4eJFOld2^gKT*@{Z%-GP zUO78WW2pj@LxD4Fr!De)fy%fhZ@dMT9PdlwSkMHLu00WaYn{FTmY!9dLoWZmKain_ z#ma8J+R2E!;JwT>ktRd6!vz|!!20vbn*(5V8P&U{YRk0q86ssiLuyT$q%XX@Ho}IZ z=Dy{+CQEa0&Y4knk8Uf)9<`C$IQ2piiC=wRXx*bM=6Y$1{K|AD2O>M9#=ZSc{KMvu z>C450BiII(_bXxP-ky+wQag2q4Yl5)LNt&;n0#{Sw1qS6O`bftCyd7-?Yd07)U+w= zT=Tnk!Xi9=M83NJea;W$k*-MDq2C?;O&_78jhq>DS%n(}TWn}Rp(2@UkE zB}w+B{()7-L|lDHrC{9@uxzXnqx!T$U+mRmb6I??Jw*?)RVt6n*a`t-_A5o3PAV>H z=S>NJ_FNrk_DwraP|*$fGG4M(0jw{-U7XQdmz;32`HhW(sMI5Iz_Z{)_dSNI$)PQ~J@>z;@&FdyS0*QHnTyY6y-(l#}NTsjC-l z>v=0xJIIDp-mWf0P%kvs(Wioi8Pb9IiPF@Nxbn1`ywb5lUeisYLjIpl zhD`_~_0MdH9fldpMz`*joH0DRYdycQty`;2x#@OhZRxZ!oHF1ltZ;j0w%UTG`-uE6 z({Ds2dHrLqBYAyxr!V>(!`GP~lT8P|5q?od=r*Y}uzK>e+vImC8T6>##E=bW8i88V zz2^4&iMZ!Bm0Vca?fVn1-%6Ls-^kq2)xI?-HFwAD$c^VuO2|A~NWJOW;w?h`!`<%c zznitucztxbjrn)k{>0VZ2>M-XU;WchKQRdTn?m7K5lO>`#`z4x@4I=czoxRy6C~qv z$Ek1iTZyY%Gg-yjtmel7*jSgE(%MB+ZO~4Ibn?)GzUFprs5Zvts7-GI?}NUw$j65W zoTgSeen{dJ-M#c>4Hwziert2|F?3tL>N<3Jlr;WMOlF(MDKrUt78H#JI2=b&BWvc73oFfnl8N`NiZ7n)V!xp;jSBN50Fn2+O; z*xxL|73Uqq_(FM$ZB}qXY&qCCZvfhyGZj<|fIQFZ*T44e+uJh3~# zQV}b0Lfd&Vjx;07r|noy6m>NvYT+zNHPP=r>;T$UG*$w%Wp5dFN z#!%suWVgM*OXu~zFHXVi79L=S}ZAGTdp{q z)mTe$k)Ojr#~!0=$rJ-R!?9#sBGB7hz$&k4t!OrUnDjN&b-3g2SD3H1Ft_aQ&hNr0 zntXO&h-55`{xEyYN%JpgxH{BC>W`#H_1Z*3?ceq$++iDkILU8xj0AL1wX!zVI|Z(5 z+U%$~EWxWew2_+?`~Gk)$x-3bhJ`H2{jpnN?U_ma50Yc@f=`t%0u6$TPy1EASWDYA zZw@s$3EBEnWrqrW(_2gXwUtjZ+tNQwwQ0g>RMxPzD9fty!Kt+`cnSGRfCKYGZZ$fjs~?`VegIpuQIU)Tx3 z7?ZlQ1+SV-|CdZ>a&ek!J_Acl6N*qV%s zv%q5EQbMf@3plwm(y*NnKd@yI8fYbI(X`rE@NB}HSL<79@Z0AOh-@zFd;r+P;U|J< zD(0`VHLBL`ddJAL*t5d6;G+vJ1>s=tdE12E^W;E#U+=ZqEN%B9zuUzr(l*&2NB%qYb@DPONtfnI^$L-Sf<$M)4SvOmog!1W7p$D}M!ey3> zW98(8u$0|O{Q7NQO$Vf`o9%(ubyucMsZg!1URBAGO$lCWU>yS|MNdY(?+EsUn3?iH zeFM(WEcM3E4O&yd2wx&`c-N)pmI^RCWTAU0E)r18mYQ|{&Ye#kDw%pNx2m^;7JW5p zh9=eNy(x6agn^f2{04{I-@jM8@m;ND+UiYD+|JAsNY>kO_arhpTcLpKMPEFDX=z0p zF4cyE@NNIHX>xQ2`}&ubQ(eQ6{iHTI(=*?V#CWp>Gs5`Yf&RO8DWq!4 zam$oG#*D%(*&I`vZjQ1G_pYpSXuFu*kk(g0@6+DD{iaLEMGx@iE_TzLG)4O6TW+)D zo|6x9ghgA6?T~*gJ{>{vOGqqm?^C+?=X71Nvk}}fRR=Y!i|_E<4Gxqnkgu;FM`K-N z%yD_TumQ$eyf=J9#9?mYw7@fq1-Z-EmqT2VU z8mEoptzkF`Zl)G8e2p&;FJvBNACZL$FuvW zt-4 z=JusDW4qI|H)jQ_T0r9Lu3a^Ep>6-44g)V>3pFg?)I)nWZ_XXFZt_ljP)}5;e8N3f zRu=8D`VCO*{Y*X*9X7jY#$*h?hIE@v8ql=wkmSo2ABz(;2xOpHvahSby$1mRWYM1X1wnf4^x+^$6TeO?| zk(Y&bLgL!^fkRS8c@0j!{#E!wM?!cdKjpk1lC_vg0gefR0WLn#W_I4NY+CaXwIo9W z!um)Z$DzSGvw-}IlbAN!JKVy!bS|%w=|#b^X9kwIJfnnqs#Y13-I9`pjcq5%JTAOQ z*55yqEopR0P^_JIfaa?T?6L;-wZo-WgWvjEmb)#<(U*teixj5wqYhFWv0$4Z#=0{B~-wgfc~#DAIHFc`Z~f3ND*}0QZzY}OqwA6!Pl8~~%I9etmbaYm`5koKKAZgK3Vr06a-5!+#UiFm;^pgy zL(@KOvwrB_kR`EB{Zv#sSggyc@?2X`i>POW zdHhLgu;S2a+P^(!IiYR2Y0IFT%|}lc9Cj&oyGPiW(6bDBp-AJ&W@g6lA?J+fWoLJR zYWIoKTHxCDvjll%jcb4TU;{GFK#%cHMv4==|IHc0uUy@R*9~s4YgS^BSRWDYtt-Y?6V^`FZJ?k4VVFDHMede-eJW)k_|*Jx zb5oYmx~kVI$XvnN*yHG`O#3v_c5T@2@LR2e9sj-BqAsP1kbPnjr!rhaJ0bPA$md$p z@XkB3*oD7UoWbQz_>Pq%MXpMTlkKJ#vi0}z+GORtILM&HBQMu(+w<(4bMS2|mPt;@ zx*gXs&5xj4|F*GF|6$W1P3pWFfaj3!ljb3g$MRLJZMpazPk;{ArOxJ#=&&w%wx;L{&I9PG6-KCg9~9&9r6W|)NjhZUe0=$cyPxhC)dcc7p+qbk}pFU*;< zGYb!Nzp|>I_w2kB|Cl8DY>MUs4Ghx;*uxdc4}&*t(Ls93poH1RDCMUIy(xzuYn9>Q zKGZD9Tt+n%K-he@U@sN_K9{+nJdj@)+!G1x{{25RxT5DlJR3~Kepq7N(@TXCt*ZY& zy+wWeBUVGe#@+LspB2zzL)l-Vi%UQk_uur|XHDdyBy&V@a1E~8s(V&5(&Bxdf7got zVSt14Qc<+?{UF8cu_w`w4idsw*eSE5CP}3^H<{WM!l@+_E9(546=uA5}p@gfhVyl4kx-^P$ffZFmW`x&IKc|FCF1;1E`M&#(VfbWdKng>Eh;l805Cq#i4X#wx?Ay{=94 z@9S_P_s^1t#t>sqO;KQMu-n)UorE+MCto9~F1SnF&sQAe)WdolGHaJ0Ow}$ z1q!+yj|x2=D~Mi4tt^^2K{5<`yK1Ir{%?4?Yl zhyA~?JkVgFv<2={HKF3U{N%nV%WB6#MaJp0?ot8fi0eOy7^u5wJDPT(M}O2@LZqO$ zsBtNeP8Hv+qI`r`X(f$-Vo$xV&V|>ImEi|CS9w>XrxU`hFAcZfi{@xSx7sF+y4p;_ z8TyNxyUy_nL;hS6ew6A+n7mu`{j2?b0d9)kfi^ltltC~4K6U;@+bBstcFH1+IRj1A zqQG?Tc;xTb41}?gN;@4|?Bb(Hg;OU}ksk~yGLo(TI=Jx&eTpdr9A=rde#gOHlvOr;@STVUeF`2F5FJ1F~ zIbUr>uyt!gPPYO{oyg$+!_~djK{No_4*-VywSbJvcTaXjD`a}^PHH3MJ*MHW?M6y7 z_dkBC?~X=B7L1}~%eTzSycS?#(o>w#getWYamtH@Lwe5?gzLY77YoeQ66cs+1njo%~6LqQ?0A<@=Fn{|3@6BZRB@_Ms!AH3Fsm0b$y6l_?lTAMs`zn zsU2<$%nETUaHiS>a8du#zmF7JR2^D%CIM58Pl@d})%%|=^)5s|pO$EARY2(P`*XC# zR@B!W>JeNU-u~?N$9n?Ar4te>zvqq>qTW3DWBy2=0~Z)hut>LeEhI${v}xoGE9#>~B`tXB`?7tgSf-@j<1o1f4WE2j>_wp`d9ul%8nw*keWTUty{)~cCWuVew*~W|}`myO8pimx7m(#C9y}cuh z9$3X?j*Jn?F!EP5805QupfiS>FlNjAPTU;0yyo51btM8hCTkft6W2sTnG=5pxLe)h zrf=^3+e!>(!B;}y-7ik!kOZk|jRr)>F$W%~K(wphPFTib9#I(eY<_v;gWF8nLvBF- z0Db+Fme=l2LxGJFvs987X#HM6ovGK?|hWiIK@c`f}_358rrtZ-kwzNvt}DEJ~T zUND-&N1-R6UJR%acaqtq5zl5ESGQaE#4wA(Ej`uE zaU*M{XpRE>-o}*q&(;#%Hl`^AZZCk{&o=rp1Zd3CAU>sNgOxGd)9tl6_@rbzQRCEd zC$y)9ak`ybhZ1-QsXU4`^y#s2`V|(y(*1hQRiURJ~CnvYc*CHEf@1NEN4}8PSQ~EGM8cGcMWi zt2vwd@zt_MC>YtixU&%fQ?HX-b+)ZS$96=m6x!9birdw`DJf4aRnXS!n>yk%^MVP) zl)}1-*|Lh=%>i(YWyD*>89R$HUr0L%&4pFb6e-u+6pfd{EN#%ccm$9U|H}f>^tvF; z+z62@#4*jMn2{%;V=|r4JE@ktX0l)NtFs^Tmi4XSGKzFk#)4^VzDZ^SfA@Z88^**0 z!<_r-EfvyUQoN8zj|yp&A+R=hrP}6U+n8@zc`r-P>w&8qdMp7hUuiFHqfiS2D7aR5 z?z`obXao%Mt>G=GHm!XZSO8Rj{JJ{8rR82dJQ#`3XXF3&WPSqltiTD+IFKXCx?-R< zJOZAtP(Ep%FG+q1D#*i0@xN$FD;?w}T@WLdHiE&LubnD2UKyTI>~|CMo4ZCEox$#b zl93n-k1}|~QMx^r|ZhiGUR|m`6C92(-f!bab+t_s; zMaPO%y~)?1-2d{J|Nmanm>cAG*z?>D(XOv{X+^4FtJ!x?L^7Qz%naJE2XN)lPnQZP z)Gp~)Wu@sJS8(Z;%STwr#;Qw>&dRx47XGYYg{0qE6n)#-Ass8ajYUuX24a;djP!swTy!o!iPnP_E_75X^a?1tScZFU;}FasFPF zwJJip+U;|uQPqCGaX!aE@OnuxtvfV5GT6x%>o$w_6!(sf0Z=M?@jU!`tK3*1GhDj1 zEE}Q9asX^q4G`e5{8uW~gH!_ui31%aL`2~I>p-1e(>%4^d%;+jKgjdp7{XC(nsFrp zm`$0OLQH7q5;~lOUli9_f8x$Wt3$5Ec**>-?G;Psn?K~@ZCqdH`Od`v5`SB5IDSNO ze+RR(X`Wqp>uExecPvH<2J{$1;IPep&ljWxeJ)m@zi_I}>tXb@l%IvhW8Wu5#XWLN zuk&C5V$DYcuW+VBS@ht0Tc+#=orWdi?%x2PS7-}}h|T;b@p$-bdL7hgu@9NmO?yL| z3Rut^dfSv@CsoA!>dA~#%&Pbk!UWrTl+udvY_vOo_8#K`S{%Hs6`!*j{B^dH@8#}5 z$Hr~WO4P|$rRLycE6%Ls#FhQ6Ho{K49bXBirS~`^Xrku$QA4$65RDpAM-8bHY#fr5 zgfKSErpky8p~GFNUFlH0;`+K&w)G%@yEK_F|NH(R0KOxWVRyB)^*aP&C?YFyFcEz5 zTx>G#AZD+>Zq)C8;qz8rDX~AD#zh;5WwoD)!JB>&H2p;sp>*<59}dhJO9!9KZyrXD zq%GKvyHL!pO64ugE}^~0HtzQ3Qm4G@4ljI^iPqI}qhT|Uh5Y)SKRor1hRTG>QIbH6 zpPS!#g}7a~rlfmrG++U!(^oP1D9@;D@NTy0& z`21OX;I7VeTj?JlZ5YQ*haW6S^=Qkk?i?muq;h z+KGnEnn#PtEex@6@ zU@wZAde#fd9S3c~8~Up&4$_=^?KP-g)gWM;9_e{$y^gZHbXI zADG^{KetKZO7>?LlWr(w#WpAd76Y=oO2tQ3}UF#V%POGi3uvT5Yl*w=Fs`~nKGG}(6 z9#N7LYLc?mPEyr$bBhnd7YUT^nmBdS%g!K?i{VucEWJ~XfN(2(Mx#0_gySZM9hh~j zh3;Kdu3vd>^WV%*1A~GhMYi&n@AQm&Hz33Ho;hX*+4z8>yfR!qT+s1O7u6MggNR&($9uWN{lIb06 z|74nT*uy>CVVKAXz1HzA?~a|7Aef-bcr5*R#oB!>%rs1lpkb409IVMG88b?0BDKs( zjt7>eR7A<%ah9T#^Pue(ZU$eX%4Ku*_3nRM$tW8a^S2rm!}m##fX`zA zgE^E@N3>6yNMt1o;9Hf@Al}C8#$^t+=pG2tI6y*=7xgS32fx2v+}TE9#No_bSFFiE z!y{2BGOr??>jX=<|L-F}T3E<`ly$tg2Wt;eCWrsK^nE z?YTRoJ9mmHSE3Z&H%-HEjd)cO%PI{Gpp?`k`J!l``AlhUo2!j`&8}hcXy6{%*C6rE$0_CM@OI+K zoQ&w23ggKD3N)J)W|AxowzOyy)xm_LQ|c;+%SsV{(k=o2Q)x^^3g^xME-euiH=bgV zpcr1MNgyDXC9uTy)zJT;@DZC3CI>JKtHiWP7sHS)OeN|V`23YTf#3}Pd|M(&lLMJA#WmagQ#SVh`P{h0fzpTU72@Aw4b+^tm=6 znjPh~^rMDIqh?9VWVkqQ>RI+$jrhqSzDYvY6XRl)gt=}0hv^my)1KjLjD@&!N%;af zD`j(($mzAK*|jo_t8GqGB~DsiyAaE`eY2cHPw1+_9*<+oK_Du!`BDEeqosm-*7U#s6)2PXV3l6HnoP%G62rou%}Sp3Ihp z^Qq11?e0e#aGf2fzPLxBu!b9`X;E=HKY*d+KwtD)v{)+a3*fD?})nJ0WCCIj`;3gnAC^ z@Z^hAj+8a!BRtiZF_ijuwWhx}!IACNNPtT#>@M?ZP)xKvU;%uhs_4mXb~mtFXrH8e2@(rtVSigJ%FZ7Std4Y&fC0kF^w5;|YBL%RN}F!o zC)n;(WVIK$D07P!mQNfu3v1OtH+cm}`LznpB8&bK$c&E7BCG(~AfgCY;&3Y-DQ#Ron!@Y#G;P&K;| zPAPPbl)ljOJq@^*DUqJ&q()KoMkF4Ga_T2FYI72MCdV;dMqy_&>ewiu+~m`YsDl`r zB^tB4{=RC*6+ZfIr5s84HoZi~-Wy5jXKY%sr(`HD$iSFE4}H64)HkW#E#?Ll!`O6j z(CFOdrKzlch$)w*F7wz3r`mUTYur^K#y{4jz_*4%875*H!tuP6$}juV<{qv*V3zh* zu%eY!hghYwhwcyUFqwd|l8x<|1EZD)N_W-x4pd!bLGwMhd-8+Zb_&AGmOiz8we$tr zuSW#V)E-vQ+Fa~ZsrB>aZq>m!W=4h(3^;+N;waDs_m@Z5F@54GJs$b>+o^k(3sGRE zf{l!v&_7{ojAD$wMRQ0oKdV7Zthz(dcoTTsu65z~(Z=Tb}>{vVhRd?Nty@muXrTfFo-kRaBD5AB&XgQL*E zpg2UOSQDRNi(fr(+3Xp64SH-B40^}G=)ar*^jUG8x=89-#!Sh=(x7|k`S5+;?9R42k|!a;yYwcO zi!YVLh%RzORkQ15&7w#iOat2Sy z>Q!}*lwj?HbBY7Tz20gspT35Q*#F4G4K#1>*R!8o^xTss%7}e0PZ-|jk@9neBR(O; zsT(T8Vny?LGVxxDzy+BLMEdG?>wI*J6@Y%rLK{5l;ZHihb%H&s1AQ>M*nM{Qh6y<(%R zTkTYSb(1q!%l1YqE`+DMQoC;aAKOXIM?I}_w!(0BV!9|#9*(0yHO@(G^r-y2PromX zsjusip7m?*M*)<9Lh(cvHz!%qv;GbIF0pQQ<@?7WaZ!?>q2`U^bdvwhPm<%Q$nci> z?(&8GJv#*G;{}?hFR-c4mn)RTy9r*m6i%4&yW_v-)kWHa`qyE9%EWc*G%(cJsYn;3oVKpgLl*Rho{C2Ns{vQ<_-^n8=6z2!f^q!qgg^6yRwm(d! zzggt3_Q5vEVH>a5Hp+dbFh)z{`f8G6B*uI_QvNp#94WpJOo6HZ<3bScph1OeU~LUG zI4pcq#pP2}Lz{mE)>d;whQA_5_!2A1>z&?a|II=8^UYq}Z(n38OaJg*cb>`hn0LA) zBrP0Lyh)An4ud0+*gd2)W5#>Zjv*IHDtB+x9c`CKLG%<&S|6zEk1Ly?0q~Q8z50Ki z19k+d64x79#Zkv9_&Di{4atn;f3WxNVNIQB-{{-7-_)70l{!}OfaGnRDbrC%9YD^> zbgWWe4|!XvQ4UGfDJUor5JQe@TB}qMQilr4A#1FM2mvBR2!|Y045>mA6+#q9A_++( zfrKQioU_(mcE0!9`?~i2_O<``u4`ZK-g8~+AO2xIxu4&2ulu?0-|xOt%g|;PT`TXI z4`R&u0hDOcJn|Kv*=J~8Ckz$%&To4?7uuEEKFgQvw-}0|xhaX?zUb>jDhXe{c=*0B zg)5k`T5^xOQI@^i=`hmHE)lkZ6_W1+9ErKv#<5?G*b%Edv9!__8@lnW09PKzesU=5 zx#n>e&tMHS#}q%gE&GF(JC}Q)!jw0Bz7!J>wjB+&7~S(v;LqD zJ<`muwY>4s#y@B>=juPR+8k4X1mHe7J#@{@x(^Ivp$AbXx2hy7fIIlN02lM<;~!Fa zCuyv|tp9@%&7q7v-j&`I3%X%HIip*>H7z0>UvC_Hm+TyGIZoSqA+@wrdHI?rZS-G= z?vdKzrW`HuXlvCVvvBd>r96A;!_RZuPru8Pmb+-*skUkx^oGH1Y~Re?vQcoV!KQ>)%Th`+S0as{rrAar?Sb3_KqoRiP7W6O4v?F-@9sRate*I(T)P;h?aQ59(&k* zWrO3R=807ujEEB{*GXBEH3ZqG1Z zumx7s)6Mf+*IO)kfNS+IQD4#e#{1<>yt?wjnF9LCYc)+x@#aq=%<C?vcmi&`Bj;Uts^uH;_3-?)%1j4)|ShMvMM%P zHy4OdO7d6h-u+_dv3I+NtoPoy^=VPc68XiYpT(Db@l)B(yv~o8r4;z9k{)enJx3a! zPYgf2cQK;!T7W;wx8WW>#G3?XS66uc07g~958nm2DXTS?eNoqB(}CbIbY`R{h2OYg zLMnZcEiy#vLSH_g#^NV19TCPb4S!@FyUjXZcyy_KB~(z9d}8u$;BS+zCLd;i~qXn0d61Ij|6sRQJ=f(PKEW>WdqrKuYg>iVWM+HqSH!tc;~tmQ_FP^ zaAyBc@(6BRY#6%qsuW|mllEfRs7dd&I=BKC<0G0{&y9e@U|DeUL=1F^F!wwER_qPr zOR(WtX~&1&Ks$@eT4y$Eb^3m<=RD@tcERJ*<{{Gq;_u^T8oF*7)Q3$`v=`w68k zf*(U#=UhEWCw2ZQgNsKs$`;Szk$}vC@A+=`Uj~dRc)6)R$I~`V$UtJh4yJk2$}ZH~ z{*5(p8BxTq%1nQ`cq#&}gm;2VQ)usdIs>=gTGGzK?r_puZS}SLhddiq{r)ebH3E2N z20g`a2^t_6(1B!EHiyVYp7^EYZ$q*Abj)zy6uDqdy3?Ke z_Zv0oDgcV)A+JfLaYgJW+kYF<4(}y13?C8hvytX#>pITs;rSJzM=_qig|5~=MSdjg zz7RN14yHemD+GP)kFXj4EsoJe2H<2>`99p`*3FHzr}=dgD|eERHK)viy5+b`m-8Xm zdF~hW{iQ{ej*p7l8}Y+0)Z>;$_*R*K4B> zs5-M}785f6Lhe$vnJS8qCvE)|B|G!N=b}oLu1L!FnV+u^w@nrWYEKWwDn7Sv`uiy!2)=y!$DJ(}mMc3be9qM|=4xy9QX-Olwj!}IYeli3Y>#_I%N*6m zStsCEa47}-@SzS6QhB0C;8T$va4^f+Wj2@&#$hzbMa*i?b4px zVmQU~3^)RPnt=r84k9b`f)4__^4?A%3&?D35aEO)06^;uC)vgF$(P3ms zO}T$6Ihq&{l=MRKGkz=HEVsO4e^n7WOTs{9mstBA+=VV$st-6=J-jx#&hzWoC=lri z$t7(XeZ~OtbVs^?-hLBMt;g?cMHXy%16vZs@E*UH^%Z`6pqm)5rG*0YW}bP!T zWtquu)`*TAWuK7Sz#D%m2rlghd2?MGevGR;!Y%QL65o(dt3cekR5dv~b~?Us_|mmg zvcGA7v%gC+-iiS)Gn4)C` z(WlX$?q2+{Sb*LxYnaJVYH~9v&%0v}`~i^o;BFVuKa;#jSmt++-0K~BU|AizOrtM2 zy#9+W)d6kP<{$xV@0>y>0fY1-Bj%aA!%z5!9@_AOe?vu6wS--`D6jO;y&D}<) z`SylH5N=6ZXR9T>yh0E}@xR=IqxJRek&l&99{eWdv&@?4uKlzxo^G(E?5k?xn!m-t ze@t3;+W5&^iKwP8UFdE@HUTHcerw$}CjCEnV4H?NNZ9S?h174Kt`k2Zl98EjW6p!> zhkZkBmSomgYyWdzMQ5Qpy{zb=^!o3DYigJO>9emB|1IXs{>ZWHs%4=;3WrTL*h+e&3BYMz0rpL(Kt4HBC zj?dA5#4(&hwfg9KQF%|bPSGfaOs#_i5D@l(clZMgQ$?1AU?d?6X z%cJji{=MMqUOdtTEzLqiu&eNUsnyt|A>$+_%wo3tfIw0n2RzhQqlxNasbTK42-O~+ zZm1~P{^3~9?L%H{~B0Fhtm?0X)t~) z>aSNsxa78L>H-x~86e4R|9;>HJm7}5%DzhBqvh#E{L>;%)-uWeIv#_Z{IQ2ohBYjTQ6l%xqqun^fvaVKjAvE^Pnt6F2JflVT}bI{ZcQ<925GXqG7Pu&I`COnrj8dZ;V>bVH)4pnd$w&L-0A z;bpmocydOM`4Z?Jdu2SX?ThrBt>&>E+SdAp7gLs*VWCYIR`IY!j4X+3mu;7~76w5>O=mifpNbTb4%!t)Z(z9oUJrmh0}?2zk4Q z%<-Ar!L`O#VF$2hO?Dn&UOMz@`!AC)w(p6~qUM_S(2&xyUy-Z&Y4cjRREe@| zSic23{Wa@wRYm+pkZh4_eo>LgfxM-$>CO*Sxplu7*L=B>B1jbcng)=*y>S!&Dt1L% zV71hjyW-jAHH>c+{oNN16pSdKru&}`UUQjVs-i~bZiUXbuT`RrfAxziu=t``S}VA? zBV)*#FQFe(Y{Xlhb0%79q1+{h8IPFepUSQmtA|sQ1y%pBe8uLbsg@+Su=2_t8Lwtb zJjoChqbqOdTB3RP70sndCP1T*999ds`IVhZwBYloV~QBPWGb?7_9(8*75}yICaGQF zd!ewsjxDRnQk9rMIT>?uBU!un4n?uwKeHkyu_@-P^O$t;limIU{PM-$@Q8uSuh;uV zh@5ts$&wDK_cXUzQdg_Sze_3qOlZCFezG?uC5I-yl{VhB9mz(mI0iji=lFGn4hfKgVV$3iiNXAOEX*<8N=? z{I|V7I4);BNR1lWZhH`jODT1&)(l49{k$pgfc|+~Ipb!W;E-alWYf@*SPT8`6;lhv zACswCygb`-!|~>|H!cRw%;8zjG`j`@la-{>c+|J24Bp?MdadV>mH8UCq#pirS47#z zi%{>|Xj$Hr93G8S&ix1fP(k>o`ojr?u^4DX(?lyT6mtQaVOq1b=2^BXCAIJ?>an)$ znT(!AG%IQPJMaDOY>kwTcG^wd999tX+#fS8`}u@6dEL#7ta@Un8Hzc-IeR!IWm(YL z1%>N?(pG$QJf{2P<%73cGQ)rNV7M&B9ln(H_Pt>RGr%*yxs;PG-$kkFdV7ogDftu6 z!J2O+(UAshOm`GItn>br^@V%q+A#jo3+8iy>s)_BykJke#!bmf57B>Go?}bN%#2;A zsoq;9lGnj#0VHa1?E1b}+2CM&cFawwzqN>aBqAPw&Oy(f-YKxU{xB|rKi<5(C?!UI zkj(0l=v{<8ko>UuTHUhvHxr>-K2F&w^vn?BT^0(WmsO` z`h~8u6O}POdy4NyE}iB!j1}e~)}sKr%Zo|ma>a`IgJuD)Gdicivn!7zYtVqdf3?ME z!#2KZ+?xYGY=J9Am}5^5p1pcA8d~}ssPH6?cEFyG{u?&QJqtF(Z%TJX#fxK=e}2}x z6L|M|Wy*U2dhWN3us$J#AX z>$~r!ZP^#=ip~k34Twu0XVqr6+sGO7sw2&pVKcvj_Cv-uJ9Jhp&v}Tu!K`09P3W{QJ|RI)6B`z-`%R z^?#5u+h`-KAJ=nA!kpCZPWYle`iAt@++b8ESlJ01qfvTA@6`r)c2fLC@rAR}zN^3l z@ZvAOL92g1&Tsxce4#=0nw*2Q+bH(QmD4A|E>(_xMR2W!%nHvB7za3goi)?a%(iiU zz5xQKAI@Sk3EdaQmsCF4j}~sLogUa*mcq?^gNKJp?a5xLz_GeWQZ}v`?$?ZJK<*l0 zs7%lbc%y zcWjk(9vbCjD@|{k&h2PQJn?*88RtPGe{=aQ#ht}^#;W{bqM(h}bGRg+mh^;dFtK@Y zTWx9*?Lt4vetouE8bEZN4FJ0Y~W_9_@zV((_0i_fsd+f10{`T9xrwLb! z)^~k#V0aGLd}LRs*!d;*#pmvYTP?JsrSINynsWDlyi5Csuas|89KRrR(;geGWT|QT z@jK4?B@uj}Ji)oIk_@=5`=%Hi>tKqVkm85Eqnq%%s;P%1n&1w1IOw%8{3rDcj{UZ- zW8VF(d%&A7cIRNA(h=EY#<6IDoEg2?8_-Z_$qCy+rh9`{^7`E(^|VGW>R+izAvH_! z8lJtm6VkUzEt5vqxcexcstgoMa0$W!oOV=Xn!_DE&x|BDM^U=d%F3D&ys$u}>;~1B z1W6Lffjfl_rpgv)@raj>KPmwbcDRwz?+|BF_fs?;+5^9q(WUdZbLc5%!+i7>j^;2f zf}R_;3Dct*-h*8)4nl&O_jT3<8-=7jZ;KKr^`I@wt9%xqsP(UmWAonu(+XHgWK6?k zJZL|vD?J4!Y?D+8_S6U`n)_1rG%yfNfn`EveWY1O)^EyARJaDmDw50$F_@s20#aC! zq4nynrL_r*g6W2kU3|b18qX9*l{rsEG|Fw8!6g|TFq9L$Z1-}2ws1Q@%v?b!_d!X5 zVp(|&(c(}+EsTOWR+ei*!q`Q&*Wia_RSiqMf7#!tJh16HgVT*VUJTqt(EVC?e z3cj?b!Q=-!bV^!T&qX#9Nkby%G7sV>9psT8r7~L!3O~*@Y092wVHJiMRW>%w-$?Tbm$r(Wf5y^cypvGw9W`!R-KL} zBZ1h6%A4Ox(<}Ce`Pa?~Q$vA9qR@~k=exa@z?e9`2hM@KOh&Gbj+?hA59k$|O0#E# z$7m2XX=8R@bQt)x#`aSM#Wl5N9RfY?^K|vQpdn3C)xOwKspFI@J%I`v&5ZBPErZ^HLWxB>bx7E7I+@B9t*jSlp$7TVM&mSgL%)S^_eb_wV9 zys;QyxJ2MdTUGEKETu?7NG+3@Uaq7%Ct+n(Rad`F*krq8kB5mY|2tHjwZ1G!XwYtC zi{_=HTHJ0Y{H}Xd32kbvgIZE<@+j-so5k-%gY%cjT9+bwH?v{BUU*8$ciSw1%3GZ; zDHzg&59D1u+5Omb$aTM`=CnZCL_fjie?ZobSDYw!9-Y1-b)FMs@_O`v^!q)Wf$;o8 z+UJfYNX9x}FYFGd&yK9Dza|X+$|4Lm3!79S--A99-8K*s1Y93TMzK7mrZ(SuejwQ9 z-9rtE&ZDPK0N@zZOnYEEliD)G&{Rg2Jesv#!mcWwZmIWPAC%|R91wlnU{xQ_laQ>2 z(QHhaEJhODJfS->Jt>d1QV7ax4FrD%QOql+J$SqMx6AF#-xjdW`-RID&=Pj9F$@dAg(Imp8YWaQAY^-{9u3DN5= zFboO|8n9Xut)Y~1Wn}XOM=5-ftQ+(Ar!(Tya*%FcfIWAZ`GpU(yDRNZ@{w%m;Iy|2 zS%BuZih>usi{kJ#JoO^_k-!_C8w*5smjK$6#PSl{CnZ$NCx@lpT+FkS#x>HB5KV}V z#d9GKuVM|2$XD}y0oCx6@O=;tN4AdK6~JFge;G4G=1v3)K;$KumaUV|mDR+11PtE` zc)==#vl&Wow;M5JoPeM1WS`(Fmmia2#%zhH`!Ee!3t@MVF68R)x&0j0NC;?h^ZtYg z+@WVxO$E+TlqKN4f;{0);B09er22p&@JyrXt*bf?>g}~lqH9p`HfmC~{C{dux8CMh z(5~;Zt#fK`taaqQ!YxlglPjnC3NV<}9dH3NccPiVISis%>dx-a zj=>0CuUlPJpQiHAR!RW`{gQdKzt?+J13&PF1|aA&Bds9GkiISTnf-L;Gf#<7nnBYM z`u}k@67@07eTLG-^8>!)fJG)duwIG;90=?{KKkObdA)D0@?U6g-G^qWt3#+8)R0Mw zPGBVb`{9f78UO0g_r%1!!Xh!Sh zoUOy`;$hD^i$-?Q1F0e7v1qNLYN z%EhN+be^VbI{R_e-zjk6ON0J-#q1zz8`z(uTVIZE7fZu9E#MPd3IkM!-r#HxhA&fU z&_1+56@s2YxI($FT0{CdCQxDYjSOqYl=e{Lz+uPV=qc$PdXSCG=Gczwq-l7u9yH`p zRguKWM!L6`F}PHd1SI;ukqe}kqhK_|2?s4=Ivo*hJy;>$iux7w5wBna=)Z>jU~JI) zG;iMO6`J5sobj&BJ7c0e(UULY^14l4F*oMI65aeg2U8^TTd$CJ>tU;=XnNDK0bhW` z!G~1{XPSaL1>3JqMb9k!!(Hfp0RXZAI#q<%1<`urT-fILW|bgY&y0en30=+?2oHAa z5ePu=7~-_ZAYTvru7sR?-&ct5Ec~eGE@AOJf*>l@xx*XjsIr{m^AcA&| zvgtL@m3HQJOwjL#QzlKfCN1G$<;qAZ&e9!W3H}1~pI|=0&37Jfah~JtGnqy~*eS#Z z-}bX#;4M^85pj(Sa~;UA19gJ?VB7qg5dA*z{MzYV*EQMf%WDOJAc#m1zrZUCS~9%L zRx-$_#jnatx{Xk2c>S5_Gqy%)L+}4EIp{7YanepMQOA1k&;sLX!`Z<_-@egcxJ54L zO`bE@8k0zVFWTv(z^m6va#)ctTbp7Jb8UF7)PYNnAcSRGIFo-g?iGhjp0Y5!7$oQe z1f@#l-~{;v+6f!W1(5B<_ysET!&U&4D!WCbUfKNZi zANmt^pG|W4f~dk9@&55BLa(lJTE&3`D=peTc0CJRSXX??uO*Aen*nho&=4Vvd@@HZ zQ!K}-Ho?=TZ8}9O@w$Z=At=L5D=`tp$ienz423o92-RDma{wbpPpi6Q0Xdj0!35$M zIXoJYX+X3+RXAyT8vaevu_wSgcy#5_0k!73+%2MLx4({Vsa0Jqe{>9JWRJxquLwoD3*)+R_oGJxJ*|g7AR`sV^`(88MFrX?Oq_Sm!NsNZG@T zQpXDTqrk)3$mx>~3E(~|sEGuJvj%6Os)Gs&#Gc#L7p4KYpYXV+L(Xq()9+}c6YNKh z|8-VY{Tws`cJaVbEn_ibHW;^n|2QHwS&OJW_^Z8giU1RySY3LeZ( z!|MWddOuceTY-3bB<@ukh0-A0xN!opf@V}Oz3AB*466VnWC86%;i;fN@8V7czX85u zyJof}YX=;9<^{IqgjN2WN9ek$?0W#ygWT(RUE5}f@9pHQw|V=k$A-M zC5t^nJn6GhzyCVK4g{}843DnpsLaYm3WFa=Hwqx%g~stY*MOAXo`&CD?+v7@(P-3FOJE6b>skq%Cl0BMtND%XR zk2JvZR|)Xq@MAXO*5eUBZ=eM4g>6Dnj2AbJxelh&mhbV}gGr#rTH)+VPi#UPIE;t( zIpoUkCqb{}bjY~j)uH~+eT|E+YFG76=hy4Q>LRUQ!*KHaCm72W>?BQ;(=}qikVrGy zHu^R?8(K)UtgwfiFFcs>3BMC9k|==|66g~Op=RNJ8ti8x=wt-1MK{nmF3!}~N*w=+ zY+d~O>Cy14S4xj>{9PsTFqGg8TI7`imSb0xxZOF6^_*nmj*3B;{c_N?_`e^4M@1Pp zO&xXa2UnU=_09de4!s-uTqbuhh`E3xQeVy?K0Fx7*lG z@i!x%iE&N}#g<0tbRmJwFO2Ix8d-eZN4v{0SSl56aPpUt3!~P^DC8jq5JS0t zy#-v`*`_M+3PbY(0kfok9@UQgr9;xooVu+j5yoKc+0wu?1BoQh(`B~jq!e*(LQx4i z=6&&X_2J<{BjD4_cn+DL7IxGA2WPRvqxt%Hk?a(V?;8_0mE(fQAd z())H0cfO9r9X$n?4uk0>;~0)Ke2ze3a?N611Y z&DK&Pl+YTuDqZ7=U~QxTVIx%KxX5Z6?4oyC2Tp)yTi)(OJwIY}BV}6BDgf+$J?-+B z0_V*8d9iPaeAl1*hhqV>(;Scvdtz`jC#?aQi9`bK-|G$xNEOBof*a4^IKj|hwkOz1 z0`t#T9hX=vUBMi?M}soiwH{RG^hY8&7gzku+&fttNo^;G7sN=F;FQ<^9TPN>;u^Y> zDH)0O@g%~i`#EDpG2k*ldIzF>-ar&HEB0acu_EoGOfkR3%zzHkO|er%2vTJrX%Xmv zdG6G8{*A99!GtuR&qUxR+csn=L z=M8BC=A(2RgK~eKKoX&ml|CiM-C7@^vdUT=_gM`BYNDDc!0i%<&IDT}aGwRR9IO)$ z)i$2&PFOJ1=3B7B(8Co4VW)2r^v%dDN8ws>$fmkhQ7{j0;SAsu$Xvz{;EE`E?%>l| z4Ijky__?6UPU)K@ll_L1leL3Q4|7>1{@#O)#$p0#s+$cBdSR?&0y?kh5|`5Zj*J^b z&{%JdK7F^Uz_Gg*6dM(m!V_e* z2Ja0y(no&ORFu|s)V)DsKAj7h>hLr}8$KEct^h^8bOqq50>ZR+9Bo>?xkSVBgJQXl z03VDEvi1rH@iN&Kz1#gf97_$_HjZfx#+~ZlsVwPJ96V}-Ox{>)u(jK2RDGAM_LJurmI@6@(Dsj$fuwe-j#B*z>fAVHw~65Wmf`)bV71mDlT~{*odaj}%Xo6xHdn1X$lsCQc$NSZBLdgy3 zltM2CW=9PYcfu0sCmXOmzB5!y`uye^oh#Dom2V^!rP!Q*CWFb-e0>y#DCYW@hD|__ zPj05#OC3$>VFg`YE!+J_3$jKft)xQZUa9H)p~2P`-2Gr)#~@j%3ekME7$xjb%HE;ZKGLcV_nu zlv#5E!&>zEQ?E;r#Sk(=hJarDxwit@mzi_yitSA(6uxKeuIq{?zqGB0VM2{YW2w z+gt`bTz#6N8)dGBYdJcTopi!_AdL)IzL%y+4~Vw7e%~Qat6|+$GkeG+J$*uM-GZz@ zci!FeEQlS4^aC8$n6Z*$fh#+*n5=j$~>uBWqKfqdLp z+?~ez9}sQMV!Fl#u^otZXF119DZeAD>r?)RN{?wnA)4ksBf*v2CrVRr9rO&R|G@#+ zLzMROyj$$eUG%;Kj$RFqo;dqYi2lC_(Pu#TZRXrUfo~_X`d5qIKil#|I;ic`!b09~ zI1gW}QhqN`DTwX|`o7ZW!c+@!5UoLNdStvmTRc-1JZT<;)Z3yzOss)dL{{ea`5@i& z@I|y?s#i4{eLf8%$(X9zYrNM%PJGkbtoL9ed!B?2sfbDtwp&_?C9ranPM6f@tX`loA+vhW?}Zf~x|KAmJG+DFPZA8R zs6UKdH%&jO6r45M8V`IgKQpTR$>NzEskHH{(!VH-3dh7PQKLgb!;~Sz6So94MwtSD2`{40g7-)Mj9UCo*t% ztS2(2s%_#1b!@JPP3i7CA32!x&>gyIT;|73)0s!q)AZhT8b%^N zM_H&hIf-SK#w@agRFCigz^o4@4UVK)T2w`SE|XrgmXKQ`KK706Ns4rBjewH>X>{Zs z>IQI<7mw)>#JT?3QnCp4CMOKb1m0!jnshr+0&qS5G38&FpC+}fjW`uA$A-oNNO3O#DCLiG!f?{VuObRwz4Tewfyq?QaD1!iRu zPr?+(A!xIo5viAQ_6k**1!_u7!%|uzw>OIM{FmrdW_Dr}SwHeadR&uzJ5ER_z~z$j zW?suOzQmW59I2}!JJw60Xj1|vl0JX6*F8NsDBhnKJr~$JctY<#j+7o;r@(rcrqHZ| z&9$0sj*(KvQu#)yd)7H>y_6Ga34UX9Ufo-1n=a0EsN0HD_^f(4SKh^?CBP4~Ankmvl5{G}*pUom-B z)ezZe34^EJD2zjuH5%hq{xZ#=wpYhLpe@}OjN?cf()3LM7t|lZhlBBmPP!&vmqK8X zhA&}JnQDchbneRyxg4cmeS*n~uX6RC=wIib!ZrI(u*xqk*;RcFc_6!bAdW4j`buX? zq^_|0PNhLvNr~_tQdiuz5#JhQp*5Z1GshF8&)k>XJZX^D+9;6556{O&2|`MqoWLg* z=QTN2bjU0Bt?#HDC=nC8`b}+~yl5biDoKG%wsJoZ@D{*gAbvzt#tn$-Hj-fl-}%7w zYw6KG*JdK;s(Jl->*-F$M~^Q_rfB77!1rZzGALPfSkkNcxfar zM>O?ju1~h;>;Tu+0KqE#nu8}zcc2-F8VdwVQ`5`QlrPhP5%va91>n$xpKeeh7pUIw zKm#C(AzOl4^ew)s&;nEi!HZ#|5GOjnkcR4sOSpm17q%Png3aP;&^gLBg`|@OZk^%@ zFkw+jeQ9%n7Vn5j6G4#nhgv{b0zlb5ffWQp*gp#^{6srmpx#Tym+xPSc*rl8BFEV2 z6BVWOCs9!K$qH+Qjo}mnQwA&2%wAh$v7Jjp;&rIVun=}~navKWTd$bLx&}4a@!+VJ zqYo_n;l3k1td^k;@N|29G$>o#!X6?7FS(IoP{BybM2>=Kh{18&#?!^ulkw?ctBZ%G zTVQq3w6qmqyQII=8cgIqM6{2{3XdI(4NU@9v7s)%^N8``?6$J8q^Hv@#&(Cy3zt;! z5o+LQTeBd>9#U0M^-{iH&Ty4W^a>!UQuR=*zNOb0^ z(MjJL{5(;K46wF1v{7Lm%O0wd4t9WaRW3XH-}lZDBnr+Tt+4+g^4`g+dcXv`v-2P* ztFn86f}D{osLb+f)iJzC#i#mDDtR?RNu)j~kL`f>Z`87o4l~B_P~&GO zA=)VTJv=jfNQ`G8zV-;gdm-g0IS)O+_-FK4=Yd@mV?pQ+IR$Zeo{La8fu24$7G5^M zwq}(1p}|o>9AM>19c1w;m>;mjAXSfJN${nhs;FG8LCH<`rQyiHeS9N^vxVD4O2}kw zSkFz>{S#3CB>@ElfJY~)A2B@t`r^<{Q|!81q|ocAROA&-6(%1~9TJ``j23KQcflqs=i_>ze^q@o`7`DHOls#LBEYLf>$f`&YI;hY{@`&CjaT{$jwbeG4A& z*GK9lkB9|luiR0))JEs0mcb;gZs$~y6ff2 zd)WT1{f4-BtMhim1avKLeQe%-f*0`aAfTiP_jA9-GVY(7@P}UHkk{{dqBCF#ikLQw zghLQ91$)+?ikwqYlY9;{nZykKf!w?%|LMMAB1fLt9HBqSz?M*DIod;}+dThpB7q}7 z>3x@Y%#yCSeF)ds6zjN|nh8EGrWGJ8(Re^;J=2*Il zEbh}3R(bL^MwK)@5xmU};&4uvIJNv)-t9EK_Jy<&pgHIH%<}xpJ91*l8PS+>9CLJD z{6M>sQeJgwkZZmrT*WKg_66c?OXk-p;Q;jN-Zf!{CRfITE@<&82-_ zDZnoStujcnm9wQyXSIs?#7Mz5vZOz4X%90HWX(l|en`8%(f-G4(GkJF=iw*RPoAEE zP9jurF+sz_fv=F!tmnJ{ONiLoXl*E)Q}@GCT`RDudtjaTE+5P?VFytW*y$nvV|)9cOAXM7wGA8r%#2C z5Hoj1j*o`*tf!;7V1RiFhWg5J11Ok%{{-{@H^2-7;eWyH`QhMT;dUXCu*vS4Nk8wm z>eo!)cJa2YaG>SrsHt=zkeDAwrWi>t1F@Dawy3$p`&zJ#Q&!Llnn&;A+?K4|X4o@x z+W>V$s^+LofpN(6(73*M83t9=Y=gjJKd z%t8d2Wn8oIxqN^%>)wywPnr~*MG3-entI%7yAlyuA5*!~5t2Ou6NYzisBV7y&~osO z4NI2jh6HScfb;ZS=B~M|3M41UO!efNwLPK5Dq;=+r9L^UGy|mcE`5nLM^hieq4uUQ z9}H_E{lFP&${kyIN@0-q9LM^U907Df*%DlPFN@6|3~pjWVQI92*1##iI6OC0hr?gc zj!W0xlt%eYdvo{#^d6JTjY2u7ksE=hn_@C_3PI1>Oy<)LDbr71Ck=%0{%4j$^!&Rx zoAL2G^<;KR;WO7LmUKJ=62{1}BnRC&!j`vC^2pqD-L!dOIhIVGL00Nak2^G`Tk~Lk zaB&+eBP1Iy@(1o1JpT4&4pge(Md%5Zqc|>0G+B@1K&MUJ;lj&s=}bNGc)Nt_KT$#} z-S1SA+d@0KnieaPq!Wcv&K(1=%VawqvU-u3!(i3yl~?<=H7ge#8hq>EFhN?;4UOr! zQPK*rO%@+q&y$q1Xs(LN#=%SxlXVdxR@84DAk|;%0UG8&h2vbEW z15uCIo;30N6&`0XIgmacQK#|n4+e%Wl1bg&0lIlmW_ox~mIidXVicuMjoMHlzvMy8 zd|2nl_E^mJ@RaQ46+$l%0wY{Bo@iR=x# z-FB=b?Vb)jhg4~!yw7qie(RLGT`rqVGQ6B$(}c;a4&K4%Hd#*+BqenmG&IbMBD^VW zvWmf8+q&Ysd6ywKr1cUa!R@L|%Sp|8*Gx$pz3_?O&_?c~mopnRWdJbp>mnyFo>)zZ zmcRp-fd-VD_LG3Fx+tMLlZ7>14Abz^Q)nqErBd>V%HisWW~&_Op%?s0({kO{LXd0v z92<=o3f;y#i)1w(?|=;hE9RO7!V>QQt%-q4jen4#r{^}YH`M63_xvSey@cSPtYwdP zW?g~5_YPGjb3RxYZqWtL4M?WP)p1y*OwU42I*%@n{AOD1k0nIQTY0ORvC6ow%e$_@5^JCyM{;I11QS=`$*VOBRfO&cRPhT^H!bc7;Fk zJ*?!-S7ANR{xY>Vxsg!toI~2YXQ!aaK6E?pL`F~;Q_;CHI)5LliH?L(D&SX_ymuc! z0?qweAOT=Mp4R!FeBoaZP$EnxJt%LJw=F^-!Knutq@fSj29uD7;HeCgneUhj9QuFMO4xzhFDMZ!>Htok$i9`s$5wG3oFtcA3|K^C~^M7h1Aji)IX_ zfQiEN{vdoqwqvW*VSx^?8`A5@oU>9t0lqV9KQDD}ktbeDl}to0HkMh8u72k~P4`dJ z{r?W2%|BEJ-iv zi5Sh{%uk=e`ya0)62;l&n{_g4PFewNQXbw!Up`+1Nr&BNMg%Edh4m?G2S09zVRoXt zK?~K^d=Z~ZRvqhID_DIhST7)H3uo))NxR53(r8H$!>zL8C+9{W2JY?{-9Il4D(b zQVm<&OdyKF?L^K%cGtoY3fLnNj}7J!q7$m}Bz?(uDypzIIho`TO3{bI1IXabpk!(y zXk35V=H=eA-UD?~(-X2}ZQN5=p6*cKf5pPlwWAM+fYfmH@kOuEaTFOc%*s!rl&^ao z*cwT80*{^&pyKjMyyZ6a;Q6`(6{2E1e8^W3s*54dx%@BYF7U}0?13BppBIg;8+|7A z5z-axr2E-IsdV%7FnJe<>o`M1OR%A;QA4ccG7gQoQ78VN4_W#PFZIvs$6djzLmlaqoOAdCmj9D&PLv zIIvnkH{}SDMA0=r2?E+*GaB?&ePuf5DY*Gy941i*&e1IOqh=ZCs5axA6*mrWn~2b8 z#=WGD0v5^4Kj<&U>U3yl?d!2U71CA}UePa^)MIW=ePPO{Vp$1WetMq8&MXK7aqyE-l7h6}_yy;@1 z?W=;CUQ&pAd$FCmKio_ej|d4ekQ7{geveUTeWAY-Q(d)b;mT>f^kt6j5BQda--4_9{k;IJA%@s=?gd5|{u z>TRLY35e`aD7raSvsgk+PWU8Yp}K@NZn?obi)zEd0(yo64r#+mp_TsEg$X#uQ z{b$3fv|;Xj>1*JO}qigBm!Hc7Uaz`fxV+&qz=#8W+R0> z&^+tlXk0I4xAXXYVQb9#>Q98_G!EC3HP&)u|nnAMF zlp|&6>j&lk8+-2_-PD!liFQwJhpr;vPLUvjjdhz$l`9RlpfK3RmUL@UKynGF(oPUy zTPi~rjt#buALuPr$^i!ixM?Q{{E#}~p@6UjZEV@rE7-^i$dZDEEbv3Z60)#lNtWaz z>F9CJY*Jl4v+ndCv(~+T%Hdi6aV9m zuivx_emRm$2-QC4UoL^BmItcDhNqp^vx6NSukYP3B+LknEE9kJ_cI5BWg{nEmEh5q zN8D$R{|P`3BaBh&$$RkWQ3^4AXtG!k^1XSTVZL$7lj}K9`!rS+q3=jA> zorX=mEN;JCFQjyxFl!5`#i(rHj5?F&r5T) zF{&2Izk+z3PntDr6isQ$jIHXw3z6t|P{MbDpeH-E12rY1{*%jieXyuG`Nq6udk}hx zK-WD+J#k~62}6EPRcG}+t7P9LZPvh~0sLhh`XI^J!rI#6fbOxvKOMoqPi$;QWRYU3 z@(7$A%E(wXEs{yx;lcI=!&hK{Gu6Ev5om6BB{#I^|r|+GLO%o|YhbXDP z$L(xcwneyC;0q`2Zklvj1{ZbA4w=xlC7Wx;2J1t0j*XkeJZJl=iJ|l&hk={(H9&WT zBG+eNB6@wZNlydaK3nNE`ie%n%(SLxeU-*lZnp}4kJM}qF>9PeXF9MV^6p zt1H*<9e{6V%6FxbGu@{c>boG!&_KjkHUpvSa`rCa<59bIqf`M(+JW?-YMgEQR7z7|Jn zF`Kiwt>@ASNcd>>Ui|xcS_MV2dgoC9#Cy7?b(z15k(}iqsS~C!4P>+@soyFw`#Z22 zLR=<2dAe|RZlq3?9SSlOYwghZ%>udJWh$UG*-%Djd_L5JY>1G1;RM0|A=!@cSlzC;K`7;y4_8;Xjj$|cYpYONxo|LH=;KA4N zBO{yz-3LR5Cao_=-t{h!ykqeWuIc90Nsb&Y$p+WT{+1vdnJO}9dA;`s0$3ZDprG;N ziDz>0>R&iN>&Q@s*!Q)LnHr{Tx6H1}ZY>7mRDn9^PN`m*kdIM~bH3!=UFv)W;Z{75 zD)v>F3MA5!nL{smKA{)Flvo8B=Mi(;ShN>&?MhAKA=R(Zy?JNaW<1y1b8_}roXRaYZc?6!; zz_Y$)E&Jf5&sWtE7Dj!qqkM*JwgT79j<8DtV4N6ff&R24JLuK^O0cy<9<*db(ZXAkPCZ!>8r7Gr)2wOf;SO4J)xOM~zU9AdIj}_9dQ9zL-G7S9)eb=L zH>_`8EPS=#Ov~>+_#pk2ppHX-vo-Xfhr*m$mY*4n$M`J>MNv_Ta)tq{-Mckufn zqTtsDH1_bYFZP8Chq<_tIxSW)MQ@qR0?z|Wo+cvU1}OyBC3@QO?LI8cgR8=Savak( za$HE_=wGJpJJ)Fr$HwRbJ8gjg#u$b!VklZ^7CmEEW{`e%-9Rly$0%J6TKs%0oM{Nz+qGjVujL?8&4f znHLP%PgG$X!QrmaLD)<97K^Pe!(3@mcYyT4CB(A=_R9h5%Gm8X#)LMifcz4`z^4bUn&?4=>KNX2MSmC?EU@FI<6qyT;l%x5#t@q9hnWws#^0<^~x!b}Q& zd2qx2X)#`3EMfYp_on>hVga1j?)K&4RD4nqQeQd0r~@1_#^u>miXkrXJB!f=v4DHa z`L}Gu6~`cO8B#yd{3>H}(QAtMT?QAt--RXO0R@9cPJ&}^ET)ZB*j;MBDNo}#S$wV` zV&(k-@WlJ`c4mOZ)`5mu{59wjcx4V0V=sZHh5n{Ht!U|~;-zLN@(Ro4 zbe~mVB}WR>MF0^)t-Z&5b9U}bzRvI!^%$&_L*Si@JAO1)uHI6RakK*0d5Gf0B!k5L zoL+fOwsADsa`C+0?LQC?PFwjua6{aq1mCf|e_de9yHVAA5#PfYa zY?R=LWyf_dN2Lzs;sLUgswcIkwx}{sL2I&Qb41Q-t zar3LY)=}lD3P-AN!t3o`EscY-t)_UY9PmiH~0{tK(?dcJGz z`RgmxThq>pJ*Aov}W?RYBBpz&XkpLc5fca?K;EG6ScH!i_*@po8RwWHBw05o*myIW_3w`k7IkAxQA*q(8yYYLQ3r z(ChsX`bg!Dg9C%>i9_qp^6%6O8C&y0O&KokX&(jWc1?N}#gA9*goZsJad(INldVbn!OTSS@-zL|4ydwtz zUM*EvrhlOLy}(^8;6b{9=$H0iN#Da}GgttscaZXRk+oQxni-;$P1&p+SE#jCi?n4* z5I2358@6X_*(I#U&6b;@Oq$K)NQXW*c)XwBdbBAcP^H^yWROUy)QMJW^bSvb-1k6E z8M^4eM&_SEuGlSYIrS>Wr*OL7fIG~sb-wuBsa6>&cHq7nqln;VzDlP9Dbl1l`Zp8Y z?MSSAHU#99C|Zd|$x#IE@EL1J$b}MaxxCvkZw%o-E_<0#o;H^=as|X?4>QA`FOzy}8ES!SHf$tGM1Ih7MasK)!VI9ipS!9CUBKT1+ z>$YDo`dFq-&J9bg?9&UoB)4vlgkYHyfLe&Z^SrX{|+<*%J5tWzU%Z&c#Kab_)4__=m zE2fLRc{7JuOvW$J_p%AjTegYd(%kodPD=M;*SlrU)p$O{41e=7D+TtRE^X5Fy2xyO z1km(w2hs1TX%C9UaoC?N^B+#KXa6lHmV5s%6EgqwyZ`IYS^)oFB?r+iq#ym$^Zn;< z9W@csNUO^I0TO^euKD`?$Tx$TuT$6O|HV%~);ZT3|L$KlY!_#2N*yNCU$oFZqI&-c1xS!=NVY~#8DsE1vOgttpNfo zo~fJKhEIelj0-c`w(An1n>`ph;ZMzALBFc!d^9?1aHOh9XOfq5b;e9e?rZd+8kN2klb8J3SUYx=LVFEJCx+sN`zwz<4R?q) zB&r1m+>y52@>{rPC|N^F$K6UGP8Av(N(p6-Ii-M@O6|i)HDa~?(^+4|G`Hk+RIKF_ z3QJ^eCUM7FO59s45hRheq-R7#sRg$jrfV?CSIsYpj15B2uRJ7pX+B&hxLfQfPm(QU z%bSt}y^ENqhSdVe1W-g!B)@5qx8i`5;cgppu;zkz-}6>!-uTAV8Jc!s`u+6t-=ikS zg5*f8WUlns-nIWjfauGiM5q39*HMoJvIMoBdDXm?X8yh*l>8J&Fv_dMMT+YfBMdx0 zUxopVt@2a%Q1_6zUOki^xkhtT^TAmHKIcEyc_or)W1A&Ck=i0u?v!VME>!SkTEI?f zYfI2n&W)Aw;pktGwMGW21-%)q!2abqHCFxdUno*l<-j?xeJ_$e<%aELB~2HO++i+S z!GYVGgG-`m(AyPopKb{hH4-X_X;{BSY5q&G9_nckm?eSv%hy=puUTjE=VreNauER= z<;KTlM#s?fU_M%nH@3cf3Jqm0^^Sy4VfVM5@N^tSYZ5g>&QfAeM1QRSjlI-kIw0+( zpEvnPUc6w)qyW^wGg`uuOrlbdBJUs%lC~^OaYJZ^1iPnRDNk>6q``9s!5{v&r_c(J zNJqV(HOgZd9DD)uIuKggm)4CeE#dl^EMF}W1fAz1ZQ4V9nQVz5cDd1>ESEXNUwOt; zQYc?SeUufk+6-A~;M6tm1V^+qg7}qh$Hb{O(C6u?;CC8{uwa*bny|V|rGmB*RZ!BS z1(HZS^C*(((!YLn*Xq) z?NlIO>y#p0yE^8={=e+uccG%EG07h`Vb?$0THyuoRP=_HJ#BrUi*p}Zj;+|xv$Nvv zSgBCf)_5@uxu@`wF({tpUou_Lm3+5z_4d0Ic-Es~#4O0((nXXf`U zA35zfv+BB>;xC9K+rYJ|&6+;#sd>n-m!|I*2t4SuH*!&%2)oG&@$I0=ED?OI?yTW(+goYd1K#J(#1}ypH$1rgVEZ}7gy~7= zE-su%fxIQVPHYqRCQ2Lo#SdyK3%Mn4^Pn2Ka7n^c^#n*IfK!dPlDH8@_OY1uU|J`h z>*hC9DBOFBV5XGcRK_)zf(ogONYX zhCae{`|kniBGZ$Sz=SOb#sK_iR@reuQ|Y>XS?p2qApiEEqa16(t;`enjF!dyr6RV;#FdQM>6_uu|N%8Bhp1paa6&3B>J|bK`6Mo2; zIZ%8!l3&(g@PTh}n1=_a8~#Y#VV>A>AosNv`<6#!`D(>`=xM#ri`;M6`fvF?fy%7Z zg=)LEK;M*S?I2oj14%B|LOo5^7SwDb34G|QQ?Mi~eM=-LvIgeCS96b(b1*h(ijc7; zo7D7ZGW! z_11f3;1|$>psBvSOOYyh>^8{j@RdNNl8F9>Q)HDyKl@=24^3OIJsm>Y%+_2v*Vfgy zWgDrtZ&3AeVM%Z7G~jdMrAx=~ZPwxAFYv4WqYk4ZEr#sxA)@edOpvgbW+env0mu1 z_+EaavQX049j_pU<`*BAjD705CyDL=7k#!}#$85%i@i}Z$w5<{o_e3VcQ@9NRhY*; z$_kyMi8bvfLgC_NW@K!LfDuGyt9sT7Jc}E>E}^m&x^Hu2*M6uiIS-4pd}yDjzbWJk z8G+zh;(h_@xFrZka=O;oujLK**d|1RCIz|;1@i)+U_3+S;Yh&5kK?`Xbna;` z>(ubE_i8uV%dpgPyCvnf9LvX?fJ;J4)_FoDcgIk^%9ne7xkqm241F!#)v~?Yo8T#SSUC-18Z^piGccP;`@fvb!yp3cf!XgvL5-u0as4sV6#bE$PAXRVsD0HfFPtH z&$ZimYh%i$BKs77B9epD!$^Kcu$G|yT%I?M@4j;&5-U{ zBPrc{ZEE_q9ALW&W^!1Ls18c$XbNF}_cA<`P^g}fC(w$L>U%M{ceEniexyA$rh z9^r*&L-`F&0P5~uT0H0Ljn9z~nMF$1mWjY+dlg>b#EF8W$fAADB8+?2`@sN60uzGicP}J!%gSEM-ie)HJMYnn^B3FpRv`W2R34+KfLa&vmN7Kh_A&|O$AbFb zv7lZ-iGojap@rUwTo!NZevpJdL>$ET8Nj`2(uG(v6 zxN1VbqeVjEBQ3Rpst0mlE$nQXiRf_?(lSSZ$w@{ZC#wmqU-L@f$Gt?}nl8_pmbdqTNerlj$BvR%tCE7{xDNWDnR>u@qC6m|HqM2~a z1KHF=%!*hlB!uQCV&?$$mI(3N%~w9bk_gZO3Abh$Dz%Pe`En7w=38U6%E z>28tt*nUbyr&?E?a1d1mYSuiXdu4WX6!3zP(~4=smc#1!{KsX64d^^FA1IGoUQ?ed zE-2Aj36LxOnbz;C3B}b$fcfxFM70+L0*YV;;D(yaSnYmE9nVoHq^3)QQn=(yH1xdG zj4V|)CcMl_FVGL5JrA`ZQUvP0{#2YE4sZ*zGy3?2xwi&NCWU0*tjyOpY(t~2&t_s7 z!96reqC(c(q7J#f|3cu*jfKbdnHhWgU9=MIUD8vC)l{)3iRHDW`*nEg3<>T|IGA~RV9|B^Yne9JdX8>CJv*q)9J zlyie5UW9JwP1y80mFKCg-8(HYN%Hc#)*Q(b z57~RB$dUg$M_}om^Dl2{h|%dyn?dVR5UV#kvQoqw#BgI8#vL8&1?ZkHcD0hI_um}pp+1qGZ0!wdVP7j|qDcbU5hu|%7@9$+^^`)K zm~*MDOVphL!LvY`2F^NzN4^y))&3FV*Ruz5F_nh2C8CY=Q&13|i4x5kp3V?YigiGgA|Yp{Fx8j894uwHgE(@Cee#)om8dzEVxEVi#EzBlV_cin(`+9Z7)L>&kE) zMReAL$h?K?aak~Q-EAKxT0QGpNYapm>txf6M=s#a5_Mg)9%kQcw^Rcc(zd2Wj~v(m z4myQvJ>2uwqPvckJl^{WbDv?ylX`S16;yTGP-#TkE5f&IiZx67t3pw$F5eb=U(udS z3!LDpBP!*C{ti9>Q?(#@cjeYEfYs8YH-l-*Mgh>JTQJ2C>Up+jB;GEd_aW}cYYsTR zw4;3ULgFOvV7w5hr)v>#(G-JyRBD_=e>t+XOy3O}!Bn;f{rysGS-_4)4X#T^U*!%? zO%bLyt`%GBU+;|bcEf)_#cSGZgm~lKb9_`1zrDUYeZw*5 zqqcGoTaZ+<#ea0GyO_gi)N#;!gF`)nQAX6L=!zZQq?x0ZcLUtW2!lZ2y-t2j$*+{G zCYXRoxtvJZZ{r~e8wLSb@3}MNOgr1#(Hhxj5xkX7f2xdW)8WFo_P?YCqWu{K!c$d! z<)7uoNI-LXik%j07i{M|ZTRa3BD03Gnntbopn)f8lnpx29Kx;ljtaaAIAL>%Q7G9q z`9bpF9@u2ht_azQ#xNtes0#q?Yxg${!dW?tA^UzTyZ>d&E=5A+SN{s7UifwAx_vWH z4mBm4N(fe@GH*+Zv1lz4br<6*pzKCfv7Eo52mg_!LyJ#+eNy1-(sqU`Y*aJXgI;%~ zS4S*uv~nQP+TP=rat_KG9HG@xL!^hP+?Ce7VA>Nk3$Fl)ypV<4nF$B7U6;y``*&!M z;8DlN0=4ZZ>-du?E{_|rCV&B4Iuobo#@kTn^Jd)WJ7`jTHGwMYUT=ZsIi2`+Zz2;%NvYW12e`Gl#!#SKdhxuoOunhe%5bBKPDdI0%Ki zMAs*a76>kxPgZGNnxkcCKbdu~Jui){AlnuPtet0Sb*ZK2nKnV}pRONG&Wk6!(+rhv zKCIec4}2)tyj`r&tWAFF(3Ge0v7Vh8rM__PB9XpO)~E?FtkfWMFgq){jf!<}`w-J~ zIXY_Cj76Rc@XlvK`a|>|{AYpEHun?b%znNkLrxk}OB87>{LBVyGI+3Qcd0+?gd}8z zthZ~}z$BM?caf%!h)OlSgzs`NwPK;VoB*NXfx{X?Mi!EoyZk|FM+(jQarfayKYd21;RGQ=7M9u!KYG9s> zI~Z5kVZ%F)rZhChKxo_Tw9Q03JPJ9~SLY}BL(;zOv2`^1P)YENg7cVq_PnQCK1x_r z;4nm^e(*vtu=zX?d(TR)?xLkCAR9-0aaoJnXww%^yR};iY}!!$SPK!Rwid<@b%u!t zie1%64)$O}!9|B>#Mf3A^wgp>LL8FJ(Wsip_(#PpGgaIs-qu^~_LP4Xlbb3Frrciy zhY$j|eHrUIlV;Zsu#%_H_XaDyqIa9r;2IhaLrBa)PSR~C2kURZLgE0mA6Wpoc_ z8iJ8o=zT>j(vKEkQweZJ#yMEkH@ijxTQozOwfpwakm#atHPX#M>K`&H1o%i7+HpQs zHbw#hBWVV%dZ-^b9(J2}`m)YEvl93xLYONqmQQvkBjq>fND+G7b0z2O;W~JgUbDlK zDIljIirjs#k`{qNMlujRH9|C1R%Dih*xp{LStCu6CQQtB^g+wS^f`A7UQAq_O0uTV zjtrn-4o``Ks(h=dGWHg=g1SO>y+FW;?^upb0K}wQ*`pQ1CUlQJnL8)VaSR|zQGUe~ zDRy_CN8`%fEAo(o^5+{~`9I$nvA??ITV07yqx>C^3d zn>Z;63QGh~UaR9=XlTK60~=jRjs4QA5UKcK3#sE2V)967b6y6YrOvUlEx7(7^(P>) zK895!XC!Hl0Ms@VYbgR^ZSz(VffjL5(x&%g69qYY;V$rZ)$OxL<$6h>Tb9wgXw5XP zEK9eIs-~6;*r=FU>3bWujjAq*(F95~T z3*S<%^+w~#WDMo5yWGp&o>O(O5fRqz#c9-9NU1{IK6TJ69h_UpemFZPW4yXY-Q(Y? zO?a!vn7)XUpNLO!*G9&uD*X5e=$(OBu9I=*G!<189p8*c zA$3v+lx=BTS9!TQsommIRW3Q*H$eaANz7|GwoW>P|5H~G%4=jP*hF^0O&+QuLbq-! z2sq7>kgBF28ser4q|QG*x+U~9O{`w5!-4OM2%IOoTUD1R;MoOf$K1ENrIalez#%57 zHgv9m4h2xt*~qC!LXorw=tMbWq~4~^KRtUgX;Xghp7Ew%%zP6~N07(8!}f$KK91u< zY#7jte?y@65XOedv=8)EpeKJ%sa}k}XGTwB`U&AfY$!YpEVepc!Mx10QX4OpAfx|7 zs#|$-f^mX=bIJvpq`@FH_+LZ}S?mhq%4E!(EH(d>1G2gMhhhvSUs(m;A53goPE~JS zCz(OpUJXWvr{2b+Ig}@f?}YPKLj!65Lzu1=7f$aEB9$U!7HR!Cc;X0p5q zAQz@i}ea7UI%QvRtGMW_<8`6#xKjr(1}-2p@rl3(5WeBjiIm5kekb&o%Fs%L&__e*^@C9y=uhpB2LP{bE2 z?Q{C4oNd}C55Yd)xvKRS73~%5^`@>B`c=3ddy%2r@yFR4TBSoW)hpppFhJ;fwcCUy zrUyBiyR7kAEalkg`G@ntvo-k5XOHk!53|D$GSB1Mg>BN4 zhY70vtvgqu_w}>th_7$yH=V&iEb@)Qld0$D5$niF=R3~v_75MASVx*P@UU~-iYvh6 zNSLOdv}!-e%P#-G_Io6uKcME_JHv%0$dvnKABZp7Q-@^g%e|q~yV~*sdHC0JDC7b0 z_LZ-Jm9B~tD%(^7F=ELEj=LhJ%InDsZ+uv+n1En$Jbn3uS+uRQF1dJU_Xp&?s2@oW zcK)OL`|_0~2xyE>`q)aet5 z&@mJA{FY`eIG--(Pxqiv1b(8oq;7MK=K&n!p;7n#VWOMqR*vzuo0;=NW56;{roipL zAg8qN6Dt>2w@I%Rfb{D-&yh;n8|e)2iJ_rk=rR3w;2m5vCH%Jm*bp4@G|`(bRDBpo z$<19#&u(Qzk%8;K-{@Xq?CcY-+1X1FiqL#wH>do6egJ|&Ag2YNXtH-*@O%|ac|`z1 z-7tP7V*e)eIMXs7!S#nXSGism#xy95y{ew$_@=Bi;3a2@Iu*ZTdchESq7Rh;Rz-Qm z^8;TLqrL`D03Hvd{3F8L%@sxIt`EC&PCdG1cDjj1k}umfmG(Ru9_;nz?$e05;ZrW* zob!40?4=Cc#FYyp#1NesOtEwEuX~gLzVFFmYbv@JRnJ*3inR&%lswwG^g>loQv!|N zT}lbNxnob`_piKt({Eh-F9*oj_T4j|XnCgH7cGEyZ20F)eFy}0@y)0uScOu9xMhoXBmhDpw zWKWOP5H_*#2bp)8V4>Ow|BN61XJI&B@(~RP-}xWGzI#@iobVd3L+#P8%4o59U0TTK zIW5&(2xgkO+fy~Y_uZ)_Bv(YHr|A<8f`9k@Zq1Vp@$~_XFv9jmth=j_sWc9wWrl8F zgmuaj8p5$bnw`E+u@;_6`5v@*q6Jz$d#NVEL!U7rK%+=h&^*|jnZ&neFt+B71IA@L z<-3;S`tt;L6h+kG3~b|v;<+|&E|qo#zg>VINF=N+vu`l$5Ysukc#xM;Xh19SaY2~p zx=d=J)?OUwd?`E<{<|KcDKRDGogT1aI2OwrHU^zS;%V6PV_*yCc4BbZ6Ti|jZ6;ew zZp>J0^6q_IXi_^%Qjnqo1)daCwAP|@zJNZN)lIl@ z(QTgH@!96QhZgSNtASMJ-CZ8}GBQ=0*wpDXDYHo>Srl0-I#D3W5hr$PXeE*PMVawu zqKGA_D5vNk{Q*JpF79Y0Fbi-N?Z?OmGrT+;(eN`U5jH z&uI~P4puznNG0YU$&9gdvkT;5wU6;b@%diaKq=3tJF*qKMxC9jdNP#K+2^=FA#%Up z!D=VnRDjBhzDPmOygoAaROvL!<~rRnaufTh(+XCKuA|X}9+;2!ZD~hSu{^^2Xp{(p&suqEsk2EAZ zs6;%w57r2ds}h^052bq)kyhZY{5ze{ch7ih?v*RHDS2DesuqHGn9g%O_U2Y-;9rdg?ZP==`-=g`= zv{$H}uLg1zg>oqYfQ;v~Gw8q0UaAVH>5p7Y&aJCzl3f6ESIlMB2_in}F8MY`EaN=L zL)k3{@K&XdcW2yU((wbAt=!)&vF|P(@`W*+j>ykbi@(OWs|h#kVQAarm58lbCa3b& z?4^4uT63~j%B^~VuLCr9d2c%k#BgKWdgQbLo==zM$(;$;EiG?S^m!TYP62)oorm#2 zk3BMxDWyn)<9NtfnHv!@{9t9Ncc@&q>b8azu&ph_?5FY5OE0W*N#tJW<-!6f?Iz;h zA?VXLaXrfldfPM3BC?om6g`6;yV`l6z*^IG9KY34)2#W8=ap9J_JaqP-O-SMU&=nk z7}|rxa&UC~Cm6#$ia+-?1=p5&{%{Wy@7hY$rmFc*0;Sm+F(VKj`xzrxjJ`w7$nq+*5#~3tU>R&$&`$AcTnOd7eR@cg<;o-Bvr-9T6_U45ox ze%L-2eC>zydWo}+8G-#>g5g@l#xC{tj!o0y3R>a$K__(9#!ZK%aHW#OinHy5hAq3N z)gWN*;L?u5J^KyQLIFcd^gS)6Y>ypWiQ5-(0~l1={Ur@>i-DudrS{ecm6x?u^B!3% zTYKu=%sljdg}nnK!3PUSu_4Mp^p~31#36Baj#(+-R7`hTJCJr>IkNZF5jzGGSGLo2qMu!H9WabP|W5dcg*kSkD#ml{PfWx)qbNWBP$pcku_;R+KS(C@%oIu#FiZ8IVtRWjT+_x*V!iI?)16JheDW7xh7J&$AYz1{iB{*+ayC)fi!vW&wI-!b>mNEy+0YrbwH7&Ha57OawJ$znQF83GE^@il54*>O8AKa{fBR8BkSdv!CMBoDN2RNt(w7FG%^xj_HH;?#EfT9k!In;5tELQA?fSMMk?WH3wvKJ^+PnqaWB z=%(N)DmOix8?P_WPYt~MR9%MFz?U3<(h=y!3e1=J^!?fH=sRHzy$Q+#-N{m+4+i{j zR;L1(3iEjlww8bieCh#Jxx7=r@>x20c>^+!^2r?a6_Y+{P|Q_LT;P8REEND<2=^?Q z!CPZ@x);Abcs2J_?p{Twv}BJEt?$7GoN*FcQ@A5Ls_4rScs3HJi(EaiLqO95N5ZbA zd1!(Vv|RDbFq1`dz5G-RF_o9(4Oh~J6#NvvDxs@neK95dE;(woDpLs?DYwV7N|1EZ z?ZB5ChKv>1Aprc`SQV;Q*CXz3QbTm`S&uk)s6()#5Ico)v`Y@`N_;#DTofj}nm=fX zOO;HaXhc|Zp?^((;Y__aoS%yr2KfU*7jYhTzQKCpn5a(yVUgpWvr4=0(L7CE!rQOv z(x!Db-1HxDj0V-Ym!C>aEh-mcKWS0V+Y_N!=RBsx{b8MCeK3= zw_X~*yXbph>1QsaB|e6XZFGquAMt<)*ok zGlp}e={Ks!Zcs?fOZdn=-G`WwXQ}%M)x$D&bzGRR1$W0|E!hk2FW=A(B0YhHs)_FZ zK2pmiAlz~cw=P2rRf1^(TIDVGv!3@FY2ej zQ^Rtc-t%ET`d}H#{{9$t*^ytUz9HWdxIoJ#w7WNgp=wk}{lc#$qJw}P^K7uw$a+JR zDNVdHeyLO~Ufjf)YZhL~I|WqRAl8?PrSU}!BzK4wgBkcIZL9a?gT1t$;I;4{+B{(> zZik~ZB2y^cEOD5gQnqK8_(rz%^Z@tXjAlVE!m6vG4@To}h;URujW8eM7^ifHW6L-2 z!w*}|<7(Am#YrmlJOGO!Z5ask&rb;}$39?wDBq8cg5H%=1e}I7Tvposq?v&01I(a% z4MiQ1U*;9;g-Wk(ma_4)mC>GTeAqI{ zdn`=@Lr1qSq>lI<{KeIz!vvs&q;4!>PPEjPR{(cu?5pUJbY%Lmv)&(iCy%Nr*&h-= zjkYU<`T%BM>iL%$>!_1#H*L9AlO@^pD3yav`F`EY%er)V@oUN*Ttjbn+t~% zhC9o6l$ua@qS;fw>V-U8h(2-r>Cvdw68waz@_yp*631awa?<+sAj0P#lzfLOG1y!j&y+U(ELS|r<%3JwdFJA+jH!X4@XLBdj0w-+4V`<^ zRay?xbK8mU^=}2DtTVV<@dq2Q+ckFq-F-EmR|LR;Fo_ViH6KY9ZrU=tLwzWn3A(95 zYI~P99(F^b!x;(HW2d`&nc02JbY)<=&`P>6+UbQpYk9f_Tb|Xl`85;imRY8{COW14 zMv&HgCJ?;1C%$|8YuHUX8v9TZE!7Z2a(&FC5G3!Fm7Ifta#M6X^y~n(pWfu|mh#u6 z070UmRA}haO9w!Dey8IcnL29E%T`kNhuX-5MsBt5OKol{QP0iZ0d!Or<;#pw`tObm z3)#9vL7tS0(E?NKklWzH>9dzuH*|)wjF-}byXb@To09eCimbk$Wb{@M1`550)^tkt zOUSI(Pjm6Z3Omr`med}^%9P` zybpo@$)NJF zHKX0{`gZIy43IXUmG6b~_`tONhjjob^+o<(C{kpXh;4n4-gWc>SX6|wN zW8J1g;vIrKe37yi`5J+eKSR=AE#r(2pP3U8yJvRsCP{FjT$Al6b|C&`v{3#WP@0Zu{WNhDVi@)>JB($GC^NvF;&o83TJ*~8yT!#|mD%kCXmc;I1wBjUs^ zd31}6Y#is_fz&ETXQOzkZJ8idqX}7QlL;pExt8z(>Ob}7EXgkXlD0>*OJ=Vql(o5B zC2G{xx~((2C4=j`%|Vz;y8K0}s~j6IdoDUJVQw`%>J`;c$l9zDHeFpHCkaAQmfoTlyFZuUQDCi1sBfK7KTPX!dWuuE*fi(AYI>K-bt8?JmD%Na(p#Vw%4)f&X) z`aP~t2=q4FObwjyvsS9HK$F;0h7AIJwPkAi#O?K|2b??M?)mU1RwX#!)N?zfF*Nb$ zl*P69DQ(>eGqzQ8=~WH8)Ax!%m>LhQk{>BzNB`dF^NN~x;d)|o&^!*wrxi6ah)3$~ zpA7X}7qAfqrO)%7Z)b0Of{INUMh=u~)@q#YXI^q-qPez0v$j(w=JvF(2N|s_%4-5o z=wC3MI%3H9zGo26TGY$uGO6k7-L0`5h_9JKJG%dMzx6v>qP{UB`HXM zGBQt(f2&xj^Z+&L4_=|-P0**>9sK$DX>xBCo^xZa2{PQfg0XQTi6xAnU6D1U#BM2Y z4g=Aemta5nWW)2OD+jnfpaAHe-IzyRK@HU(hh*Rt+YkO@Iz%Ga-c?U4^(DAd+6eRM za+4FV-L6Ka#U*hUIdV?Uw@m1hKuz!0a>dqLe=P`8ZgGzel^lcu!w0&uu%7v}mVbA4 zsgV1utOY>Uui&nKD$n*LzICkEHm2^&4*XB8IYr^0p*HR2-6Mr1l(wF}&KPzCd)80S9>Z<-g4%X}C{DWglzjSBo%R#Ncf_%8@Vub^gd_)Iisr zPO05bvnvl)7c;AEvHF|D(9%A}X2ftoFu7rdl*LP_Mjn#@8YM)B9P4}H z_mvU)Gpo{EHYI$kF+Y<t(OHk+ z$jYgRHg>Qi6(^{(Cvv7OvC#I00FkZEDSh`)rx0e3Cm z-jP5zVy8*HDjk#d+#H)Q%y3ypJ~y=Cu>Jp)y?2jp;?B}V&rGI6ry+RK47dr7yzb;A zo&dH;Y>z6qCk^pYj7+*0VZ8hyxC|(*%TH(j)}bAZ(GywruNB z!NRDqkQ6Yo@Jod(Bw@=^St{!-Rh@$L%$+lL*8Fpy>z-cAe|WK2Roi>--=p^a_V@X# zEUeLS=P%sm{2DW6%fQRfJnCfQ!iC1`k*WD@i9ItxP0tdItg)1S zhBZExgns!fmEax0LcEpFFG(st{jU=#uKZIX{eLf!00$NYu`q^$FI|-Xrv95-c7(Xdf`_?8c3D0xj-zZZX{KuD$;*1l(2Yr?jHSv+WBSV;`4SFTi&(_0L zkyN&DBrYAF2M^Qb#}3?E7mM9Enro{v^!0)l=hTS_)hPB=yrZ2i&R}%a6P#1F4<5!Q zM>7O3olUK)O*#0P%0Nv$2ipSG(~L0Mg85sto#lbtOf6&q!%BP{x821s2j^|E&hR4Y zZ_kHD9=~FvwpiL6PhjC#t#ntGE>%<+=^8Wg{M$Zep`}*R3PP_AJ*3imCFd=+8 z?O%XJdmkciusEnQOwPC7=oet`*Q?2)!|y4(zTrNkBl46k+|;KN<*>Cgnq0izbFK+V z>p47}ee0uI4b?zoQF^he)=c0VgMf>QB-R**i2MZL0*`XZFkc&F!KPE~y42^*8S@L= z8@c$P{?{GKITEesnQQUEQAq*NGG$A5PaYm5V*#GHxB3uHh`!Jod}>1rN(!90QyJI} z$8aKxWD?1m3!C$Q)IqN+f@2R56!~-?@Mf!Rv0fK^A7>j&yd!A|=Cog?rxv$5xqpNw zrDVbpb}*@p2)y%)OPUdQa-o%cIw#mNKN^io(hc((Zz3eRQth|+_}RM0!>dbPV!B+5 zyb0{&UjQFEg`)t{?s1m{egeAb>1RJkVN;=)lI^}VZeM!>*Xg;qEloMc9TTtmFI3x( za;~*!sv9*B1mZuowhQcp3OAh>(;nXy7d-tVgtXloz&ChxG>~Dc=dd206EZJ5J`f(- zS6X8~?@8h@LD3*};Hk%>Or6QG82_mjlK$~|=WH*4S8ZE@TB4>PQ=@Il#1bn-iR4Y` zPr<*D!{P2{nb&gLL=2l#28QFa|M;J0o-a(yD&vUxm1CSQig_L79-2ptw`R(Q2Puc% z^kv0M-qrF9@?$`6t##ozKGINeF-=saNje>!jGX_2S6Jz)C0)bn{}gO}Vh269ZY20I zWzmsoRgVYWdlnI4fe?%1goLOy-xj~OB=E|KG?D3CBgkS^0CGTv{+(ZGQvxt zA?0Bday{}uk(`19sAPbR()dk|!%>)zE8{{T`)WfEhMxeiYb-js(a7kJ9zWXCpARHk zvsl5#uGSl_3$livBkg@5|Lx0fEEF_^QLpoqzKuTEbZC2GDQGvY!;?3Tp5VB@Wv)tL zMwg`}lnLLPMEvWton{ymQ?9m`dw9t#wkHtr5hc7750iSG>qc%DI%F({xzJy7=G87n&0q&9 zYyV5wDOH$7q>-s=9C~}yPM70ZjIR$fgqfJ;dn3(fOL@Lv4=j2jPl4|RR$H%zqiwZV zYzjYM(E;%)-XII5GGTiqb-T|*LQFStG;*adjW@y%_F@}==0Io&!3BARvu%@le@W^# zF#HO;0cAXb(w|x;{J~ihlf)mqb=+B%b`M9O3Dgahrz5mE4Z!0p`0YjBv`uS4u3#96 z;wuJ4*;L+HQ(x2aOq1Nr2Y(I-T01UC_4_pDf||Hhi9>u=q`|MvP;wB=eHOw7wziYK zUW=Z=k!TMMP8pn#L}cfb%3e6(L1w8v)U)oT&>j-fk%5f`$-aeO}Np^Jqa znP~FXiObvQj!#{w#a_pmeTBDx1z&R3u%RPGUgf@V2#53HRNXkn5($IIbkp&=-Vdx| z9>pDhE#}ej2FR4MB>`GK3u^IuQd>b^h5+@+ljGC8)~=Lx6=GC3tpuM&QeT#Zk4<5> z7`9uUUMl$&;oE&3W=5;ys+I;gWOF|4%TIGK&um z;yAZNC1nv|174!Zrkms+n!{ngy(i>=V=|E&YK$)7Nro;x_SU-du~=d#McUyQ$vP;6 z^L+~m@H?>JE}r{|Te+odGPLSaQFLjvtJ-I`03KUxLp&g#x!6I@wI# z_D#ZItlo{_AmBt2=7-XHi`@?g-DT#e@Dv(bA!O1zL|h5*FeGQ;*Ihf!^Ns|JR|5?p zg4m^7z_(*Kji20tUpv1M8R!rWnWks3Soshxu&os23ewEY-voG2L#iA55t=N=CBEGm zw--kdtDKB0P!px6*6gGA-+swR9GcN@5ncHd!<%?YQ3fHs3`cl>vm&#$U3`te2JAC4mza97nt@{T;TgU!dIAkppqqsD8CTX8A zzT};CA9dn0lg37d{YHiyR}fiCC+fF9bY8p)e!lCB=>530n&(`!;!A|-KU^cgXV!L} zsQU(QjeAs_MCm+8{BFVN@qrI*NQNv??Time&O+WAx)`THgOtgoy;%>!`$yco_0P9^|i7DBAs6Uz#x0H@gp zdx9259~ye!Kc@2W6T{A&fVX>1VJcl2Z0tY#y#C$bo|&8<4oVj6*Jev_{+$^uz5QOD zgj5#vLfoCfWgeye7OBHK3mt8IbG`gVZ-=5GJdjuWxqCLzj+pULRm1$@z$~2wZl3Zv zYpJM4UjHyAn!KnGXnM~`rP{RYAnE=Ud`&++!1EVg@e6<7{`5UBm(GoUs5Ebp$3iSk z7dNCKj?KoSA`sFNOR<~mblt~jfG9gt}-FdN3Uu* zH4wV#Tzf<7NiVD8J zCHO;pjnDAb66huP)9~A+iKp**vXHe$C9t(xlz_+bKmiB8dkG>Bv4HkFzX*SAi{5zp z8ppD@?pYpPF(h@8h2D)!m<|laW>1W-g+~#8@5cSP+bKQt1`!&o1xr#6;F+QMeAf>z zgJyYZ_^vc;Pz}MBqXV<3jC1vfrHXBDZDQWU>5;SRh|>Hsbn55HEf=YcwNhYOBRxLtuuF^OPXo2rTubqkjco z&*gzJnFS(jFKe~-cEHy^94lY6t52&|t*p3{TmSN4=Mw%h6!VAS0-O*m?&>Z~pTH(&b&y#`=`Aek);c#=flto!No%lHgK}IP(^&ZnY zMlXM-%+gky%*gA#c*PKHQ>EtlZs%-5P4e(@d5+;c@^w2-hVeHx#LB~o387A>@ViaG z0+K2sTC-)Nw$h+Z<%>G*_t7b>zv@Ww?n#XM65L*?;!r=|ZFlRc!++huM32_Tg^pXQ zwaPy5&H$?W@Zb8f;qo; zexS{s73WoE3WRoAwCbR0j^xeg5nW`6kQ6qtaqf(&AfZx9dCqT2@@S*Ow4Ze>Pyh|i z*16Jq*w;x!Z@GzCjDF_9W{qm8jg41NE*HzWD_;@PXU;_0=cB==cSV4Q<*VY`$s#Um z+Zp#z)QM~gYA_4`F@6{xijmtrA1Q^yTo+H&x-@w$Xm!7lqViPUJ~wq27oy4*Sd(a{ z+40UAg?xS=Wv1O){BBvzz4Ha-_9+SwIk%S*F>S}5USR0G*s}|2G%J#|F&tmW|0^K~ z%*vp^D_K^z6!2SaRgNDneK-aDPC9-5%2TebcpP5W-WM+kEl-Gu`Y*>%w2PUeJT#Y` zo(gsH>vshXFXMs24+wMkI`WWtsMgC_m}CB#lykarlng|jfla|A`kp)#SkYz1b(t+s zFUVmmoWgX!oBzQG((D@_e>}daG`e9^9S5zf_fR<7wb=#=GA@aft1b|&z^pDbd7OiJ zD2tog&+U2OKrFfGk+ssbjCp+dhNJmJrpkS=pK*3W=nK5n{KHFs@SRLUPSksRgEsD? zjnPwFm%EvlYoF@ftlf>rP?jt6yY6`amCAO2Q?BlR>|%z89DTBY4t`{%1+UqtSsl+3uIz2#);lx;puImYMI*paKoiMvCH^XTGQa z$4nPw&2ud$QiGB2>u%v=!*VNUce`_fO%PJmEjZh{i}<_}CLK_#>f6brjugC+>6~cq zJKha^AWOT746g z0fgTlk@S!9{eAXT$?=9PXzefL*d6yIpE~ZmDJPmRkp`S^`0wxZ50(CSH}XRT_zZ1>``m%4!265+*1!xr^De=qUbXPD zaB;(+%K%Q#It*o{550chazM;IT)`oiw=1!Mz{Cl6a1!~{>Onue@91OxEM48(J)X^i z-dZcI1Q2i<<1=ugX&klrnpivGE~Ku1C99w*d5(24x+k;Ne&L_Y4M8|4LfUx(0U4$*}EN1hGZ zYNo0KdB8BY(jG2&3;G%ZtrPq7lD+D(Fy0+zQLJlN?(T9e)vK$Vf%u6&&uh;Ol~q)- z&7OCfkcJNK0~^~^hN zuF9$*wbiJHM$0@Kn3}tfJom)rsygcW%q-UbgKjBE#-$ELo=SgWk?!uHMI*)5YQe&F z(Plnn203h`!Db#MLL7>BpOP<3Az*f-Q4)C?B(ix){5Gt{TBuMJbA%J-=i;~$RR?VY z`c6hQ=f-h-=-11xeLbbAEVe{RHEz&y5ht|l^&gXGEr(j!EgYI=yMipfF+K|%;W%$1 zu|>`;PjC_hc2m0*Jn}_hv$s1u`X9|P;=7=;wjT(*n2jGpyNc1?()6Zb6he~?Lya?r z;*ypiWWvSt+TgqyM{b6#xO9IHZTDfr2@W;j)I>8o^i|>=$hBzDjdz3{E7Ry5B7rX$ zV|#1D4dR$*GyFoaIw>tWK%j9JBTsW#3Sh_iyO`nD9m%C01m8L#-^-)Q zaI`K*z6Kj_0kZu?b9l4jd4_KThFkNw`|y0zlio07au<8IlVEX*J21rz<81N;i@(lH zx!~hw%9H)Z$K|Gd42}CM4nD-DO>}E0+GWehc>-+8g0G5>UC?hBYK_yj$;qu{1(c3f zjW8Cb>6uL}9cw1#{Q{(n^dHO_iRKOrtBpaLw%kSI+bRs8!t=p;D>e%jm<}G`aoP?2 zIHu5}iLOxg^3vS5crw{3$XJ2D zQUNx7o@(uu>thcg{^(XOcWk94^mX(WEsn8Jie5@C!9{Tb4J||L#4V|lQR+1r=P*<3 zIoouGWFTA;Nfk}1MeA_h`nl;~_6bM~jeB_Wd@3tUa_iIkvC?Fzut}_P^AP(|Re4cs zJR=3?KPVK&O0DhYartee%|SQLAS$xvwBB6^WCspu1(D#|>e3R7l5|QTPF(Zq*{#6N z9X-7#J9R-?0(cdR2`6-Yx3@jD%9V9Iw^*c5w=>ST!Pa;Z#m7P`h44p!f4I-3dF%ja zAXLeIUWZ$TZXo)MZlnch%1hW|kY!a8==RT1pc}O6LBokQ3g;r6lmx8Eopy8K^R?M# z;7wr#Ey~i8!i8Wofy=RwE#u;Ps__Ubf&aUG6Yi<{mQ5Awtp$GUOu`d?BSrbLJYmpJ zcdEX(*OZz9S;C##589Ow3?wrot}r2z+A&*Y+ebyit2mt~a|by);w|tm*q%8{qyUU#oQV;z%O?y67X$@&LSD+$!g{1YI*r*~xSE2b&uc6fpA$j5WKhx~~-nsF8dmk-(&GlWLW8jfd927)hAM)(i&(2Ld z;Y4ggcNGki91Ng2m+jhaH#G_RhZ0aUU#j-}YL8q)>`#!Vm~K|oZm0%@`Me2WH?8X+ ze?$~EMuNUH@V5;2%3WtZR0!a0HPoVPZuURU;mzo$r=`Lq$1ZDc^S-6xh+nKjG#RMN z(eJj{-#d1Tkxr2e2bQD4SOOoiNCu`8o)0#`;x@TiBJa9#at&Q))N#Fe>xSrS`^iD*7sV!9Djmh;nmd9! z>CxYt{x1FncAT);Ur9{ad;YR~cN;S+9eu!%a3vU;RdXONTYGMDxst{VU1eYf;QmSP zSJR4|a7}$TO!1S_*%bMD>DE`#*puk3^GtJi(w)w1_K3_bM!KRkOy&zvz9lD0o$c%-TJYADE2>HPm1jl_|m9t<6l+Pkm(5sp7%M^0v;Ib;Rq* zteM7;b~qq6n>g3yBNKa@*Uv~3QsfVx(s-QQYug2uJaSWXMT*8A#1mn5dD9G|^kPp1 zjkjAtOU4-JxvZL0qxkX&^TaG4J_SaHJ)Gv;qRoEmUUNo2nWvRdF?<9FoK@2Sp$-o1PHGX~wSjxEYe_D(}vLC`9- zxj}Gk_awSB_B0_TI|WNtEFd{vuKF;v-ALIo=i<>4Mt!MSrn@@vDM;l~8=TWfay5!i zRK=W%s8zq+MoD2v3K%>0uTAOyq`NIR)8xA=bQ_>1WWL8DIEe-;d}k9aLIGZX(qKzo z`TDZ?PQ}Oh9Zd@dGozmJE4y@StHJi6o~KFdQ8W=e)%}5A^_~d5fi05XT9_;&oZY&Q z(Y)SVLQPx+sX;21EPdD$qNlztot_k%mJ2~tgnhks_7@6frEmJtE{KP7?)tc8uN)}a zlL+2JPHi)bVX3*mv@}JO7(r@<-^Yo>647gwM_TK5&XKQM#ZAmmJ_8kZ!>;STZL4xp z6Z^3e@$dvoaFWgfnpc)gJ+IAidNwGl?l4la2RD};ikA*Jmjw+@hNKrc#ArI-v6MDI zi_+Ymza$9->fbvYyVlg|3fO5$yk{JR;W5_$IJzUxC=MO3ki>#uBBS(SRu^SollggN z)V2XY8m!1t{k69i+og&7^j=-IC842vV(9V#)st?>LyfMAusFrjeA7m*IdXwbk!K~^944+eXH+Cz^Z$<_LI~p zVQOt2k5Lk}GTr1UYl-vH?loQ`kdVCf>!H6}S57#Z+q7}-uy$fi>Kg6byd!guPPSRx zlnGM!gDYDF@hPX^5~%%0k8)>n`2jWO>HD`_Cy(>V@EuLP@{?bfnoA>7c}&vndxWE zTgvb|%Ot;HG>6ujpj9gt{KG=eM<*D`TMRE8@|;l}ihCO#TUF<#rv_;4t~G$F6;1KS?pRGURDO}$7#{ZCyvsN9Ze-^tv%9{%IufRj4NH!4C59cnA81d zy6V^Wj^CpL-}(+i$6I|Xx107%8yqiHV7E^6rKU#>(*h*JWC5KzKS$>=iW|F#2SlzH zIy6;Tt3aNLh2p#vN`5Yt)vB2;Jb;WZ-p8vN1%1ZTdPl5p&3a*Q z1272A%1OSXUZwtX27I8Rc#@jgl>u974p5I<&)vp*xN;zte6x_VC~JIQ^a1+GB*iKH z64z56yW7z4s6o8RX8N#or>?pJ*vU#*CTpHwC+|$#xR;TGfnN zH{hASQ&T-7{RQ$^(`CHV=HuSK2%&)>4J@eGN)!~WUv9h$)sIROIjjEuy%+Pc){{+> zW3!uIlvlJGm*uWAAh*l-8~e_4mlmGL3J!;_vv!l&t&Y4)%TE7~6~MyHsrHV9b6Fe3 zDK(&gJ)*V;D`r9SzB;=hlF+Q{W8bwQga56Pk7WLC(%l^i@hW8PA2Qc4efGdfxd!7&ll8 zaE+R)>eZsW8-_Ol-J&=!`Mq96D0dC#uH@3zvY0vQF8fXe*hRusYIi;NiS^yHr!UFT zU(YMFiz{>XGw#p673p8Si=J9jOr!=x3VdJakpTuw4nEHSKBB$OTJw|exElM5%euVZ zlr{f$)r-YJZ1xGD9l)Nu>tegxM|&Wrex4tGi4*j^qL0GK#RoD6_BCw-ILPgyA-#6D zlW!%hU&p8rxT`aVct{ZBG<3-iR9sBbzlRRr7{J*QFCq^}ES#=m{HoSTnjJ)CBkuMv zaEHB1_^mwF5s30)s7gyKWqIu2~z`GkE%!vtUFa2 zUHbJW(=6)t+B7uRMGhKgagvCJYpkfTr4Os}MHiBcK<^nz%`jiXNle*DK4)o7a+y<> zsh()tbNTARBWr#-)ofq`!q(&U$=Rf{PdqhpjZ^?R`v~A@)K4eOao$6iJ`8uj*K9bCZF}MT_1IKE`#FQ-3izU9JiNvCR`kwE!(_LfRa-V^P(6%I zBkCiq=Tpx7vT*#SoK5A6MKGFJdGaWxj2nt6eN9Cyp%(u|*o-(>;_1LFJhqtdVhJ=E zO(Mya-s|D;4M<)Or9(xU=?&?r($T}gKBwSSFmTs7kDLt0Xvnd^xwRrGsRNo(|DW?Z z5_iY#`G;Y+9AwzF1zH(bkwMKm(5zT0HpKS`ot*}ido7IjehrT^QnP3*0yxNNAi_sI zOfyntFQVpb-M?`SXp63J%CvDrcj<%&^5OmP0aKAC8pUA*5sR?{~C$5P6&<(06raG?);LTr3#DkLikK#B3r~Zr`m8bGSMAcR*Bd~7FHt*Ww!At zv)FAJlkq=%uWRdip$4%dYJS+=ws(ycoX1!D6Bs=Vl|GlavgTpQes$T%&I9 zlTggEll18Kzt1U3OW<^rZcfx^PU%?R52!%3WpXz?=yI#n76+YFfVw&}!DLpC2|~>< zB!LQ`6zEP2dy;-PaCzdp^gZ#igAw6jdnKt=Q$Mxl%5At=W4I(kb0lXaWdvH%*uk=E zodxqdlNwsgU=dlUXVp90pIF!#?%DXXR52yln;jcp2t4GZF$=quaGP{yOd;>OxoU}! z(&aN-*R+9Xw||?CoVM3?^th!L?nEIh4q#1GZLx%WxBHHMmbY9&&78--H+p`>&=AV` zcQ;i7bh53|sh2UpUO0SNL+0oC@EHUcb>+8Z2m1Q!!lEWcL8ViAxO6zbAZnn~RdLJi zy%XAi1V1yPo9=696c3!BmK%o1!{m@r3S(7-NT%LdxIEv7^v6 zKLS1Sq1iVC*RptU|brTkKSQuM`z~cQ+fAGSmw+FF$peiH)+r? z-{2vR;$c>l#@-JKIhVl_0TOC>d@_%8U7Mc=+04}5L6qEekGM&sH#u^oc@cj`-7pxJj8d` z?};rfwE%gf__>3^F3U+3at`D-52_e_O<#}L#Kk?U1-O!zRKzp?Q^=)P)D6ssl*#a8Yi^l#BwBee)n}ri0gJ^a95j9I;_~Vm?qkn( z6dz^Zbay&5CNKb_)v=&qThh7It?YP}cz2{cIDaP^5{4G92i^B@;n87o3qe2qz~#lS z695)jqX^wt|KAGNR(s2r?A~JDm#oKe0f*eO{*u1Uu|zbN?6e{>-(Bk5x;@30S)Z`| z&e_RY5Dobw6aS!S5~OR*i!ld_P+Ii-d>~a7H%t;cFxMcoQL>94%rE8#bI2?8S;DyS zU#{ME1P9z3*b+ccJ&2Q(#K)mP0cUQy5UnUfL*8(fsco{xZD$KcbsN~<(2gj&L1xV- zN^NMEMHp~J7H8wC1?j>(KbOGJjFJfzML(lZ)93)lb!|kb(7w>S0FTv=PeQr7LFe=13_= zniBXWEP+x0R6Hp_+vDqox^zpF_>Ope_GWfJginXKQB&l-cmIIEa5UBuqFa zcUH4fCya3W(KqmU4xpJYz%D2`tul!6igBu9*sdCD&>1Bw75L7q#VkGXyCII&8y?BZ zNO(u?KeEQtih8_ZMYj7J@}V@S0D1cVgcMk;r(&_v3L5@GEOa>YfKDY0yV@a6vOn1) zYG)%lkunx6J&P|ufoV+>dJ(OjebbqV1AlI|@f{3gg^5B;NIdoo3H&~!H z*Gu_zcw9*1v$fivBcCXq+DR2)t+!Z^0m8T!<*BuUgW<@ZyJ`g@5CH6&$nR@fo|pAQ z8_puDVcI^NOq0bKRtC7c!!aCzH-v*=hFBfdrVltba%o}w@MUWv*Y)Ff#arc+YW4Wj zkDZv7w@ch$z9WCM+ig|ytWZcsaL9Oo~+(8k*)4~jHe*`<$aUr+Dx&N{k~ zLxk<7$z(XHFC|hv4R0!>6V>LIS^lT!0WB;(!<=jS7ILqp8_D!!m8dd;3e>OLx25s>;Ug|J!WM zNXUca3!C`O3iKR5#sl07GP!U9Ea;D{CIUCccBS|4zNFA5U$&2A-WD! z_88Qi6!UBwamu#vqN7c|KyT=u!k=b!yX^kkbYpO*@ZcD}NuZ^gx1|nZfpv!k67| zu`0|+$lgAvY}G~VvPe;nY$yJ};0UKx?JsK5oM!d2cSVwkN#)8A%bc#~$7O=9lY>+E zw_{MK5y8mqvh--A=wYzr6=KlzAu^in{s>abZqB+>X8AmBnniuONnyND4N|?CgjiJ* ze*ZtWpd43ZiVpP4X7N9qbN~!)=Mp-WDSsqT>7QU44($oE`Td5Q= z0k%PjK=j_#RxyBY(4H4(`6Wf4;Hg-5`%kI(zicWp;&^S8W(R%)t~oXK9xacR0bWk$Ga$bh6c zn!>?w(~H%~9Lyz@fr7B)<#lY-l3U!I=hd~Udy##sBx~9EjJM^tXE(pXXNC-%8T}=U zrp44YQ>X>tEIuwHGTmpkz~|s4TkE%VXTWecZy`^)E+T%BX?~Hnpt}~BoxIL&-G?@c zZ}5NwOT>WRdaQSZk9YJY8>3XKY58f@mz~!>T_}86ZIOOHvO7&2lRh(d@xL?|0s-Ep zJf3`BA7mpf2RIGz!fS={I^o0q99&F}?CrfY3Sdz~(WK!~FlQ|fuWRKd`bFz(!+vVC z-*+a%GZo$wZBqvQ9FBOXth-`D}`Nn`7EU!4VjXmq@FG@RUK@uyO>RO5;JTzfa&c;@OskadrFoC`4yM} zq9=ZP8^4hqIzp!A&N?W@CqN*vNMfu{?^&7mh(JWiKkNZVJfZ@CjV0Le0Vd#@<%muyF#+2lJ6-U7gT7GD`g@&d<7X){%ZrhmfmOb1f6ykx*A(}WJ>?|YT*yfgv1 zC2h^kF-t9VzK_N%J=>(~`8z^MT{6RL!5BY87)2$4gq-8k#?Q{Rb;2J#U(dFY)nKkyC(p>-pJ=~47_om0mw|kwO0JnS-B08I5`eHN>Ftes;~jEp zujTsE+zw{z1ml2OgPCUX-O_~dmzP-3HTNYU4NZjq&&qs8(t`sKZ{1CiwW^KDo7%(>0- z@%!JABw}}XFcU}2+2C$PFA#{(kZ3>iA{;fgO?qFcPi+zhfrU;zFhK&F6fW8oF`jq2D~jsm(30e>75}wXuTeJxbw=Sp80B-Oilff)uxnmi*YI$v zoAo-A$Ns3u;hpa3MO`c)Zx$|F|L;uPtmz7lcD5FgaiZ#q;o@-G;)l*|1pB(SrMaAM zlx@PexId8#*vD;N_6gSJ`q3Z!nJx{!zWED}JDItDmWvo4*T7jf zs??Nj#UzyQ5}EONgS`|G+)0OgtFJuurewg_pY@rX zV_9Hyq_zlb0m;gZWZg>Ua|e`B(~U!FuVa8}H$HwOJVmhehm$Diyu~y8mWBf-GpE*R zqpL>0zh!FfC-5M%+7(X$g)(5`JH2dSkd#slFkPSliX+a$ETSpss$IFXZ+Rh&D z{ErTvQQ|QFST_z~ssVXQgq<6j zww(0ulpjfW{A2y*Vsryx2zpU_?7PKX(B@6;Nm@cHcsa%&k@5HnDMf5!cHSDUv?tNW62lO2|KpQ4YS$PCwhqG~pOe)ga?52MXg z&{J<))m47Eeyxg%cPsG~Pl{alGwCd!d1$*W)NlkZ<~G)YKTly<<9IE!aY1wJ4^kY! zx2gJhh#zxBTJx))u6V^xB-zFQEd|FOIg0!<-ED(lHUc@}WHfMH88EcNMipg#;YJ?` zde;>4{kiP+tRgQzX@t8j^UyeARzp-BF%e#MXg5<{D znO$BQi*(U5(O_%2)t!mGkTMHD554v1csD*gI6g}~;CZ??`9x3bUM}7fDn6iAu8R&7 z?Xw*bRA#4wTy>gv1+71S=&CarvA>yo5Te7iydrc z`9gQCFnjG@#>wDsmO0DhhgaXlSnQ5?j#AH_=$EW5^r{H(%Dd{op zAsdUET@p)h@{2d7e1d#ZP&w9poL^5G@4UC zYhI724u))b{@xe*-ET8e4DtP}PxeU)SWMZ%&3fBP#{P@Q*VRDKP|3R2Oyv<8aIU!H z1=&Y5Jyj*hK&B>$CV;f<5isZOzdOsk%wpit7*aV1aU?1Dd|UZ}%o(%X3{89NqLaqjvYc zvx<8+7aj68#2{rr5iKA)bAq_$bw=_Xlv^X@MH9v%_snRCyS{7`r^s;MV!u8tP7zSH z!z9h-ECH(S?K{0j$I(f0%1!6`lNO>>^9yTqnR5%LHk^E#(v8;|C`|2Y7$La}SrXC6 zgmrl_ZMdQJj#PAFmfSDm5L7GCU288vZq=xB^5fD1YJ{y7tDyM39Jitb>Alw$Jbmd( zbC#L7POpx&0G+F{{meTJyLRUa62W?5bk(y33bO_qR-E5GmKEG#bQoDg2{^J;QY`YM znf58eEVw6P`U@-arM%6Vyh74lHcONWeBaMyMb5o`mves*mnRxfKG`jybl^07oKeZ< zzOn;5``vd%s1SAWm%PYZ^k^5Q_c_vfVsy2!zFQxB%lttq6{>i)43+$@8y@`{%w%l} z^9s6L{0r6E?AVR6h6e*CXY{1~A{~cVof8f&ZqGCAStIQL2_~XMC~(BlzFq6JX&3py zjHu_EsMm>*=)KjR#$Fv~F@$=1H$a__xYX6)4K=h{F}xZ@T86d~*12BIQx>taP@YuCwd<;Lp?N&pv<+Ep^!E`x@~_=QntPh87^~imdD() z+dmUZ;H3++4K2yYBPh!C3E{nyJ?2Iudr$h*wzFMRBV=$#8nQH-Ja%8ctM@hi^pi)c zeyc9(oRqWp5NNr5Q}o<9Ir`rL3O+u|M_t#NYD@c@a*6Xc{Bvm`e?y76O-r~C?zXKH zQ30Fj;P?r<+D_}*;eN-8E{P^>UwQZ;@&e8(xhSj{;O1F|#o3HlJlc(1RhkVY&g#(9 z?N0spkJ}x&qcp%c zflX_GZk?PakQ3&(3s%#&eOagBHsPn>bYJ^e}3_B)AwJ|IQtN22)*Q}?s z>IGv{uWFcaRa{O?iOw@FOc!bhIne>@WIu4EiE6|@>wXO`sJEZsVi2`1zEx(lSbEBKLUxZk&+4gkUjQMxzFejq%SQWLwSUg~)O%yy}XF^*m3|g5fM5 z)7k`?OBKHWyJ&}o&)XEq`J|N{v_EZ(CRzM2nanmXQdRkI)1jI$`I=R#wF*&#F1%Sz z=Rr`Ydn8`br+$RDVSR4aS+E;U0>&d~T#RdJB|G5jN zah&N>7d~rVf*3_0-K3EF!b&ZC@2HAZ7Zui}PeJ;smG^*x;+lfVi%2gDvJ)FFON>^>kb)40`Pa8G6V!RgoJ7Ab!h56wEdB=hoIr?oCF!*UAqGqE z+A6o^0FPpfNq4#({J5mRkR6U9rJBRG`aF`P?DEYNh)>qWoNeb74}F!-oR60iaEobB zXFLhS@CO^q!O3nIf`kmOT&~^f$%rN%1dxYt0i3H&z0`LFn}+~(E{za))}_U;)gE$K zTgJ z1OqQeHeBCqvE#@Wu2E?P;~ z(gy5>V&g2eRQ|0b5WTPeC^P*NX;#L&7c?)kG&;Hg$jk4*RD*Z=Rqu+=t}GsFm@0bqFH6j zczu7h;eA7!{i@-GbI0Vji{TYZfMGH@u)4mzB?1eaay^QJf8Y1d;Leh?pCEkp%9f?hg+z${uE! z9UDZcubdHjW|N|(u;~^ZepeD`5b2mrEAP|NvPW_x!#S1=bi+`WQZQO}tiXv}?s%@4 zx{g+Q;No`PP8+vPegSK2AzI==O$iZRmm-yCa)kT9&-!TaIay$pX&3zyld;INIm09F-;mV=WwlWLW*= z!_{KQ2lo6A_TK%gtt-zLyw&N7+vNvS;}zoS|U9;}oS*!j5oxS(>ySMiKem@Tx<1J-VS@`QV*&b5&`3}Bh{ju_Pm{+K5@g4EL5a#BrsA0?7__7EMZS3KrE zb{tFCFv8v;81Ffd7pRc?x6<}ww$;oiG~M*TNJXRfy6Cx_P1_}kPDu>62 z%=fW(C~Dbz)9sEM;&J z=Wpnb%oVv8q$ZJTJMOH{uuwDiM04^)6# zIK&L^w1f}QGK-$AWJ*d0dO2@mYzJ^|=h|)m-VNK8j#HM{^1F@I@wHRTeOr&6mo_!Z zZ5Q+F?TGy2(VP%&D5zaJ&@-SpujXk!_eHMjq01CP9p^C40Bg%u$R|S+Bi;+lXzdh^ zVi;}~Yu%B+%r(ou$c+8JpbI4he!GkknHJb~hqxjjswvmE#l*!I=wqPr_*f--hh(MK zH~G!yR&Xqy&Wf){mix~r8|Al+%p&cn4CMW2NXK&?Tqt(tY~9D!56cNpKl3bPKELWa zxu@fGx__-vvqk!13T94Ji@n9`O$~OoS64EnA1ql{I zW)eGepvaivXgTtl8mP;%1Tt|lt8<3!X)G4|&eu)?h$O|7f0ms} zBB%Sk+Z`KBk7Mm2&AT{wWjcQFunZ?RwKW}c=ML?abCk8lZis|4ZaQ#WYHu`55M_}` z^^Mh8WVwi05cC$y`xv^|=GR+!jwZQ_`K@+sS`u3F+|P9|51nzX?hfH9cmtZ>HV;tK zZm(s{c$NQfZSuVDzns>ct~rT!msQsN#Q8ragN~o81|By*ah7jy#^n&=Go$%idmM=z zE}h-f=^P4G$NeE-Rip2fDfOE!=3j}qHe=YgRW&=F z*%*=TN!8;jn3mxB!I?7OVleXJM@@cD!r6CdR~-a(4-OPzjn1v==)A0z{bTvsJ{$-0 zIESu89?)HRxEUrR?8F~Kk>C%D6aL7Wz+SVcY4-G4(r9~jrAB+5o)O14IMf%gx2QMe z_d1OI!$b7vLMS3ldM$pW$ae2OT%bYz?(+5+-I3O`w#i}~U=V|=!&bNG*uvP&(!B}q zOGJ5laEu*uEl5wR76{iv3eR%Mpx&G?n};S9w5BYfZx%ZwIP}XM4eD(~tSJ z(yp9Em+y+$!iK*D=Z4sCg3$U5FU=M5e4{$=3@v79t@rsc)*MBhGBu?-k}+eg)E}w5 zDCKHn+hRx3_2RrUW#IQ@FhnnWJ@c&M@#hzyu@3mXUHjvEn)lSjx2T>j48+IN#}>Eu zhDd}RReoIB$Y1|A?;pe8EpJpQYC4+Vj09>_U1aU2w?@T7lE-jSq$0EfgTUYm!voZNGJ1k9Igjc`K4Y z;!ePq-^L;gX|*ww%IJeFK&Y6qsZF0R%yrvHp`}5ca&Ot47HD6z-I3M8RSXVx+V<2p z`6#2wlQ&er)lfIV+_W?}^9cnPi`j^L&2v!VLxmQ*;rofd4C*f{^_QIb|6=!1AJVYr z)3l)EKmF=M_l2o#(zQ7PgXwIe7Xd!@DLZJEz+&PU?xZ-BVh==fN?M3@t;EdiW3R`X zb;^I{0sGswGnni(?LyNVbO(NA@f_xr$$)q#-UI9=$@vbTD4?|sv<+DoUl@&q5xf*B ziS4nMD|bXcDJK-+Dg|7h(~7g|tuJ_LoLhN}1mY&Oi{9mh?z%L-7|1Nb9i`A(KCdQH zk?i=$<8;lmMRn`!L9BNMJ{3Ko)5;>wJ82C2ht6f6D7oEt(fa7#wf5nx{$1I!Mr3;& zNMDZ~qgi^LW=`Ys7oF1v2c_&S#};+_=SLIIuudN8Y48O0rz^o11RO^Cud#sQEy`*I~33qMkhUDZO@5GiIheTXBd2AxPb_GCPYai zLSBj5K92(iM0%m_L*4Gy#Mj!grvtYuQe8`~{CYNCA{i~3ytWCyhA2WACe(it6Rug- z7ZsV9|2ujTozoK+b5t_Oy<^rmc#4G-if?i)_87~9%Q$$uX$g)6+}0M$P%-CY5Rm!6zPPZey=OwTi^ z`WElDNa;^J==;3IrZ?J>@Qa4u4xNQ(PNTg0EJHKwjm&72V{(5@L*^dEczCjbAjJH? zGh}LGRkVFBT>Xpln9k+&oX5>-Q7CBlupT*B&Tc{hDUMy2nYFTMC(gyE!CMj8|%LtY0goV$I`(+T9M1q z`~JQ0g{hm%oLX?!jcb=-U%)qGAX`Yn=hQKs*44(;rgQ!lR}l$w{#?ZD!rfU;;sTy< z_-ouFI~Awhr-ng~)(Za%Zg)YXjk42&_5z)4h0r!L$)^MJHrgIwZYnJ&(uDZ00m)fH zC(q$mbYNfC`I4}vv%20iLsK}iJoQ|@*m!X5#ix}q;){kPi}F1+yc@mX%*ht~N=EpWd#}h0XpTqB`PxbvRd(*naGS~9Mby{I+(NH0Nubk;sS-U(j$;ABr&P~=s zyi@DA%)iIf>|e=yF7p|iy9vs%Se~=oA|S^V;VaIrP~0fSOHPiqHe}kzr_m|9N5c3AR(~fsS{JM}K@I?S>!E~&&k5u<6QNYd zAcShWpx^oCXH97JXY;3PLX;@G+uwvBDyz6E>8z84;o=$syF6-OJAO^kkf-L)-YKPn zSflL4jGk14q$&bF$DO9Jl=V@gjkof0mt5GPyWWUnvxAwICdb#0$fU|=D>XUs`F!jP!ZZ#<=R_NIO9lBgBT3{)pk>xE zdn{@~7cvd`%jEsL9BSJ}sy6h{`H}*IBy*4`t7?S=+(y{AB#i^Rj{6@8gWkS!DOM3} zGC{!5x2eY4MX*m@KH^-q*fDaz-Eg#Z_510RzcyokPt>g)_b#6*scrjozG_G3EaV4p@oCKj1W049u{5MNcGej{2?CL<~28x-OM;F&vUbbsHL$wfy?T7H1s~OQ~TA1iOK`@Lf(OZ`_yyv04x} z%9{g1G8!PW73fXerk(UUW?Y8Uu_d28u#2b1U7`rN_>Xe1diTG8MOR9lD=J8SRk=zE z;F2sQc7{a|qqnAQm*QsRRRux>1q(X!0V|A(6gU%nD$z1%oM`OhGbFa>K&Y_~&rLaN z)mAwz62~})0Nzfgl;12I84pvE^(KUWWJV`KHBNDa*)Z6={4%_2ecSYo_?iRhenZr6 zlhT0B+Chg4rVy-^4U`O<=+!v)o_4MX*CtnB7=VPj!ud1rXs3LCufz%B8^T( zvZIt{HCkSBKSw@a&xuA*B$V+oIq54(JUO{A3gMMAY#AjlyTo>L=uFUa8o=CteEN|p zJP(qO&kID3hmsLeWrAKvV`2tbf55vB4 z%p2az6ZATZUxt?~UwPmgJG$pmHphg8$y5L9-S-vmm4DoKVXrp7uu!oFiM^IXF0byU zLb0o);&5%~$Dr|tTz}|k{WSdZNcdN0cxz1~G;k@5>k+D~OjDZ_w!~{P%C9OkGpceIZ|VM1*CMSyT8a5ZW(06iX6{gQy6*PFTCY>W zOV4zB>}}8ks0gRqAgC;Zihb?79;2BVLx6h;=bHa!25KPxX7 zI^xTvQVEHQ*OJA;l++>wwP-#6b#WW?I)B_LL^VCc=@}X&>7od_3F;4Q3i?%C_#2rL zQeu;yv(bD32axfGG|#1C=DRGur1{m_-Y}_vlPK;9LXp8dlW_2~u&0-pSlMNpp<(rn z^HyyF_$8=_7)da~VBmyE#|H@=k~*08Ihp$`0sPGj{9YvNX^81^vbtQ~ZzBvb$4Z;+ z1A~J_*-aZtbMah|2M|TK)o=6O@`%3~Sn;{=T*|l`XdWm-Qp;*MJt&OCTJl`6YtClW zeT2aQIarHzHX_YLxD2e6|AX0m4Seg=*5vRG3TA zNPy__+NipltlS2$LSp=={r8!0o2L6l!(76Mz-8^3^w$JHh}Kv(OuHvZ2*_|D zEe?zlTFZQ(clG5iD|`zm)V9pZ*jYW((Zr;E=J@F33K*dA<`kGIS|5izUzMko8}X?5w}ee7y|)Wou86M3EyV-%CJolk185$9aj>TX4<5z9|}Oj*`tESPOaup zMhgAhIe+cbi~~dA56)YMLCCyELf}&_)3#LR28Gdar=!OsM4wj$PM)Dw4(Lwg`epu>L{Q;KF= zGd%~p`DYqFv#hMF*se1^F7>y+u08{Rva}*vl5iKWYp#z3x@X6fN6zq`HI1~@ZJ$xk z@&MjquaWyRfcp%>mA7F0Uouso28==2fitT8Z#0bA75|6g*oudE#-lC75t5CW zZ6R+!4ToR=L!~kg{JW(PqzHPntU>NrI1yvSlk!UB%!L%UwDBZN%Z4_2L6VT*_M4!c zKL$uOZr=k>?()ZQw0cgfIYXXDwayubhuvcIsrids@9J|Yw({H(eooWcpD{xz0TwMK zvvy%`4>%>&3(J_CLqO+DtA9d}GCJVG@7#e!pCSt@trAN0+MAynKFU};Fju-GA-j;b zL(jqRS0WO^@IN(Nm7W#gj6!;ZgJdm|@qd$%5%_HbM=54)Zq99NesWk9tX>JL8r=vG)|m8|1MfluJj)QI;_xhx3EGG) zBb1?G1*H>TnLXa`?E%(2DCctGp|U$o(cr>ZGoG6nqK>3B6p=2Y zme?(Adq#iZAo^TBM_v(4OScc7=G;!)QgsHwA90)@o2~~sO%7MxQ29cNF+26r$j*n& zCuR~J)`6IjX5mK3yq7KjJ^?4ejrh1AmlC9aysiNk=W)F-(H&+eVVc`radFlfwfmjE zM)IpDeKqo?KAVe3+?w?@>m%Sh?H!-Dd=*xH*7*EhPAbre(^U1|a0OnxjC0~Hz18_9 z0@k#ua^}aQ=vKr1;=9@dq@MBU0Ra+~M7;qY7D8~F0U^AKRD(ho*PFPH zx9$yRE1?rNk<6MI0M}ryWl)o+;$fnMCR8JN{Q|P`(%m>_gV)46N4wdaK#5+dZ0+S! zP6P0Jsy8ha-iTd!4K z^eq19Z}!Z?JU?G5#PlG5LmuR1U^5bxgHmu?)Bp=h&#;6C&5kc+(OwAU%Vb@}fl+{o zhBGbtPy7*2$#vKFL+xNxj2z60GsICLU5J9PD?Y9I4ISNXa_EQT$}Vu~j5_== zW!L<40DsXUYaxq(mn_wr9HoYP<$b-?J1Ube#fS#UmmEq=49L+4504UxII zokV}bBbH{ zoea!cdivGV%{aczo6dL0Q>fKe2QdiwQ*TDTC@y$!q+#$t^eO}qa;j(jt@8@!YxriC} ziuGIVDF&K3JVQ-rhAlzc4d-=h-oC9xgk}rt5AEH$s)9G@M^8FFICJzA331(c`%QBN z;pmAgQkF^sZA(Zz@0OvpvJI3mZT_J+!BSoDbZ>A9z#ecLxk z_(!0uA08bqBM$yv`ewiH`tY0kg=paE*I!i)^RL}{Y*H-RUadZC=8l=qi{|YE^|Xc1 zuQc@R2AF?d^7yzK@Z3#3gv-^Z)s&`RiRzY%jrOe3$tobDBr~-7-Fbb+Nxf1U@H{)- zJ=o?D6)H&D-*;CCDABbxI=GriLRx+L@C6oyhXgHBGCqZfC z!pPt8(9tyQI#n9=8`X;nBA2w>EH`)5&3GOw}C|l)aNelC3WIwoVU0 z1DwnT!%e3(RL+;QNrms1Mrs>=$T53r<%YhNffq>nAHKFsknd~r^2x8b^N z2rTM4_|v{+%82p^$y0Oih0;Wjvev#f$*;IKWs*M&X&RKqyR% z(|=O4)|9qxd98Q8zQNkpm~lUyaw_Agca}~#zH>R3mDbfKH}5Xu3WKRT>p>Ual-2mS z((-Hg=YoX05&NeMURtnkzCN;>(sIJ^AoTUNvYRKCp`Q5MO3V5D)qw28!*+dAMo@kp zchNeN&}P279B$;!*_>9F=&PMTPh5QtL%xST+S@&>|Cv3XWf8-740760UH( z{Z8aEK-&}5Zn5&;n~`&ThDG2MOORO{^gEe{eIF2-m5-0Kna=JiIHYWY65Qb_;%iE! zctWw*{j1lKHKYEOt{LA$!XTf6YNH@6|-OTh$f7TMsBvA9Fhb|3yEB` zX-><2Dq{J5(3~>clY|dpdJTt^Mtm*X#6C1iWG8?2ap_KJk=cyBTrWk2t#Hf0W1ksr zm0~^S9TOV}!Ta z!}t5D$8AcdFW7v0j(e+Dgx1HqE6IZBGMA31YMipp62^?E?4&SbzU$@`j^RflnRiS5 zmE&e>eQPGkcIpLFLZE()j?7r|;3SV+tU!b*%UJ;Q zYm&t|b}DLIHn@RpqYksIO4w>=gyr86)yelh?aB$3u31oup7IU_{X%p{&sFY)%n26U zU$8=Wa0y$!V+{vFwmFJSKMVu%yw(c8vl7ZCdHqfT}XV(74ou_vP|;75GIQt_kA-2+VQd6*pP{Og zgK$BE7oWVjf#P2uJ^G==^&G-{ie@DNxRPwz3`o z*?D~*D*Mp#Y3xVIVa1+Q%DiF1XGWc#e!NCl=Xdj-UiZCv`-C7KCn24~U?*_@j?8m6 zp3MI0&sqSCNq8E*q=PqSGnhV`N`+6~I$b83s$g(5C(S2l4S1>h7U*zXJ0zwfo)vrZ zA&p$`ze_%Qt_h(l6|V;1K5+r$4v+4gkKPuY=b3h%=qjb2H% zaAXQ$+ZE10sGKX(pK;h5U%&d{&@aHv78$l2D!1JduB8NK^;DYzQ6a0WLf47+Bjl`x z0+0k0Am#8_Aj&6d-lc-ChUh2_M)$vke8NbQO(}RNi5xSK$1$~0vzp63>)3dWgBQWl z6)2I`vA11P!Rzvq{o><<4Z3Y`{TiErHD$iDrFEv@ReEP)LR@+)iqOF3Y%mUN7Jjc6 zB847>KkJ$=>%5`R!Vaz77NLuy{@J&O<_f`sx$uwt!qNoR3LFakl(6HWV(mewE(@;{ z_FAIdbjiz)0?0>;QriB(Ur5QT%L`yYq8@S=E-|UBm$}3Gx4E<5M-nojaSpc&T=vb4 zr3rramZASX@jUG2HE~ZdR}wQXa{|5`CKO#GAw^W=>tAA&wzwIoo-o6m;|wY=o3?h! zD19}=v7JiXWmEaASCdo+(Ez>v$eCO)V9n7l?(8bL|C#Vl+x}I0&k5~3l>7w^{LlaA z&+=!!k8J;ExcR8=#QXCih0`dp99ifSx+i7ImO@@9B@C^J<}+JAOmBQ+!x{W?H7^zGw`N7p8B?x#?GyYJHE>e&2J(@w3shEu-Ah;iX!^>%4i$=TLbcFPPSx)Ce6 znsD%NV!z%13{@jP;xD4H>6@S9WRyvUes}hp*D7LGE0&OX$MYLtPg5{IsRvr|F!Vav z(XCMnV>rb~VOcY}72!$VUY^}GXk6pof7*|$?P_ikO(hL_VvkTaB`IS2+$es5Akvev z%=Q~Y&L!~-U6HZ$X<=0jrwNf>gl1V2v8H&yUkMt|>MXpPJnRcF%YSgi_JyArW^B(E zB{d-00qFYja~g`*3y(fqk~y}BzWU8^nWJKLO#kQ@kS3!Y?#;8YtdO9W(Y7a|z!eDl zgn@^Q!z_Ob_EFRUojD{I-cIq{1!UNYwxJU@cmj~A$jT%UvS1b6z5a>5YK0;Pe}EaN zP~Mj8X&Zj!y2BIiI|t!r;huV4WG;hca;7ewvL!U?qZG+18o7m~yah87{aiM|$Mz-6vxBoU&AKHxFKwvz{+N9O|(X=v|_6XjV*%h`eMT zO}vPHapOx7&cUJ5M>MMfdeB^ErxKJ*I7&6G_Q&L2aJmMT8e#;>CVfTqcS+JwQX86I za*HKNT>VlcR=Q+e+F68< z*(!*X3^aMPG8mXEE#utYTR^A3fxnz^3&Y&=?dQfO{mfNx?=dqgtC*5m`2P$j1^)aB zx{l)*OtNP#Tsj+%=NA%O+0OIk*_tRN_41{Pa2EAVh?Gb`?LVqYz@0kyA()i`#is>X zpz-NPWY=ZrY+xl8yA{!cGZl^G;_{_(9s@IW^lSDH>Q7_2c`Fv@M%L1D9~~JitqVk3G~vXEn>ilSzbe9!MxbS~iWXnU zNj#3*G13;=5{g@Vy!+*!eq?~gb}`{J<}y(fpM>bDmBgrfmI;490V0DPH^b$0cG(aW z2vTgks4`cDY&^D&@{$2&Im@5T0@q~vKktH(*}R1QU(A^DC-EW?$1gB0yxIlvi1hJ4 z!9|p3+bC3yiE*fV2&NTGlNT9!1LxxsGKxcH0{9;AzF5g9PhS+jY^427eh;<{-=SSx zz43e5t3BYao@HG0DgGN96t8m)@3K%%b~Vm{W}d%PHsuao1UaQ#|57&t;tgwc;g54h zEtb9bGk#eN_rIR#tfgU;oo}65I^LthJ~``OOuBV3t$59kx3|}H?SZDxB++*kX4(+o zpRSqvwVz|{sMu`wgNh-e)KvIsuK9yP3c9;hrFk9$?TdfEEt%CpFhow`OddCaUEd}} zmLYDcUNp|Er*r4(%LjE?eXPN%G-%(J1hm(uD2`N|O7r*1`7!6Qk5C)S^d43iJz)`{ z6z0J`ip4)V)3mafukyK(7*o5lj#03BY~8BPpLU!3*)>7i$KM(M?I2Nj1A#SkcteyD zkW6p&%NXxdE2XmU=Vjxjrr-- zbewNrnZGvfSm`ij_@01i;O>sZ?Bnlc3b~AJ*x}beE+A7!pqSXS* zIo}IQjZSpG8tuGW1R#r< z!WH`yMX20xV=Nv1);%_ElMkh^*BLtaqDNeA`;p--B5jVI@bjU{SdFoglK?a{X+ z=8Uz-d8?VeMK6QMXDMNwx#kYxNm~LvPsSMXPA>A#Kgv~QQ0AQ9D8drFy%qoy|K&YUj$~=fp11LCcVh2UgNZ^PNznOj zRmGdTg@+5f#C2^e0&#v7G4Glyj)Ohg)0?GF}9zPrfSPRnWqhuEEVb@)8-)o4e}6dtT% zl8oAGET7@#vAT2a-+G3>|9^ZnVE7&_Cq7?#YN(w_>p_hciCfa|) z@eZmL(=KkdnQ=#m03Tb{V{=T`K|#fwY8`S8`=jhG6Z*LjbUz6BM@;}tUVdv=S_Jgqv4J@6E2&41s5|G%<2WY!aIB}Pf_q{(=ZAVRxJ zTfIQ69-I6*)lg7%CrpBQdH?&HRr=EX8=5I5+(#crI2BG^UEmbP}g z1ei15nP2Mu%3j-IghRj_Emxh5Ma^%s;bw4W?v*!Vr{~oQ`ongv!mqRM%f)0!sLCIy zU4pCZoYw9qa&Cm=3wRm|BCX&RWxMz04f;XOPQ%6Xl_RB_;3?73_KIEM=%?(kW?R?2`sd zuaC`t;^#yq0lx7LZavHR1&A&(F6P+2zi`R|^H63aJ*?v43bE>qMvZBXT~21`A*$6w0i z@*oL@v73&e^SXHU(2>(cm8gy~$F4r5R1hy`8I45IMw4M*nI|kZ$7%K}ca|qfPjZBq z7%e%sx(YH^J2)H>BrGChH= zo&+>sp@sY56CJL|``GBwea6%7mX?pxL<(ywzem{_+$&*Jb80y*<`ukm){kfn6tKj9uWuOQ{ zv}R7=mYvLL{Y%>YCGEZ%h&qqn1AzfxNA>3&-+s^$8@M&d$Ckf4cvwiaNgkg>z5cBO zpScX`#S^;%(UX*fnB)2_{2x?ha$_*jwHqkHc)vrKI7_?bO&u-VB8m_guzEQ z@95_R2a<89)XKUMiOJh~S)LdvCxa`Jq%Al_@{z7DbB7}D%2*xRjhi3}4j^=$zl*%A z;kUOsmQohs?_($ohnQ&aoIO62sTXx|A*KUY1~_%dHT(*qK;1=Tgw~`w{%NN%aoJBr9gkFhxZiAK75&D4}8(-!A~QRB#O7x zC4k~P%OmA6sN&9M$~XnUyASf6-dMym$=y=Biy;j0SINIf&`&?mV9lYQjly!@@LAG8 zS3`*6!{v)#HY^ubPi0SkvRuyRTjSjQRC>|ql7^6QxZIjD{*2?D>}nRr-qU zSRx92ir0y%C|7r4BfN9rl~<*SsJ|Bnv$$E$kt^I`#?2E%Veavvh$ye<986H6?%$e* zd-^Az8j=W!n-ktYFR^4^eSGaAIga(>`F-EQ3ZY8b)f?JwZ7~gXO=2Hl8M7&YPSdv1 zhk%RLs|@3a3j8CSGIpX8i4Spa&|JOCKWarehJ9Fh2lfA@Rdhf!a3}aBq&%vmEmK)# z>F0dq#uN>&%a+5ymQ2vr(L&9mQ~R=9-rD|Y*Wsu z6R!WR3!z;e$7z@9ZP#V#LsbB|h z4vDHhb1EFSapYUDSHev;beNW-NEEmiT2wY1y<$Wj;ncwXlE-Fq*bGJGMeQ+lSamoR{+97HqcK{_P4Ajqe*6JrOcbeqnL&P`5NUPu zqAZDJKNmxTitj%-)|QMQT##2Z7glc2at_naEi#m0?T1dph?lDo+Gta$y;nzDquTAYHLb3Db2k6vqpjjGRePfOL+qx@T-|BXre?mkN8T;2FcW zK|d7t{3D197bpsPB1pt`ZmC=%-C3qKAcVvoWnQl0#KrRr;7`LHV_a)9u#^ZyXEt3e ztJKjrO}u*d1VJ+XG6~dRvz%1ZTRL8mz#S7nN*;H-ui#_|Mkr+ju8<7IGwOIdz1j+f{KP>0X?8+`bYhuF^GI=#KPLD(E#JO zGiYe(&HYl`tpVkI?o*Lu*B-Bgd`;ZcGygs`maHCoWUaonNQtO?KO*QfyiwgL?p(perP zg7i?^@_Ai<-kkD?coWVAp_k6pW|(;(7Mn_59m@DiaQ-I=4i^4Z#6OUB^HMM8&hI`V z^xtd!xh#_%vPXKIF|r~AYw#q*JpBqe6bTlSpsmcrjV7DAJ6WS>XSjG%JZ5p(P-M`c&xWAxB z{Wo!2C=09EED_x)a~v2KA+tiew|2g{Lx)foSurx=X=bMpA3ozV>iEG=4c}{LHj0u} zQ%1aG?QQU0k+MfmQ-_D})>3%c>i$3mEtg};=BB1RP4ksJU3(Hcd7wF*9y<7&MV6P}Zt%g5ccW8#uRvoQQWcwsU++fge$ynuPUCzpAev)O@ zM^o^d66tQe1^5NXdZyT^(exMbo+*yVo?iLe?)R&d*{QudO9#1dlrL?U$Ze`PSzoWe zOFTnKU{K~b6bb@o{b|O{1aA#k(9}kf=qY&F8!~ zz}MP$Q%>u3Vi`yub5R(~w0a{7JHX420r*=W?Wd3X=V%wt?ivfFFV>e{9XnO3j^Y%U zn2<*Gw9##2iW^+$y2s5z#rU7?0Bc<1*J!B}LRsi`#KnGk;UzG023BRjTUlfahAIw; zuKBrIZbBs3eZ;|d&jG&$g)IS%^@Od9UZhMN)B4SC_K@c{@?&|5Ww%cPTZ&<4`RZ)i zCHFEnAR3eJfxo%oi{=C^D!2AzQK>(ya>vbG8QeUZQtQJn5K{;0{CK@w-pjV_PjElW zarNVkE^c^~_0-L3nggJ31Vz){;*t*E^-V9ahPIoEK$<1-6YM7jjNf?uNU`raRzr~)j?V%;WLn^jR87o$H%kE&4$83T9vY?DNWOCqdWeTGs*h@i9*o8tE34a3u#7dyou-Y|1Le+TEws0S;`6!sOrL2Yht z01bvHC&s`2T}RA2L%7Uj@Ta>s4!wfDfc^^v8sL4D)Jjm|JYEN2#l7rh_}=q}hG#>* z6*rt;g%}Epwicel&=BLA7s^_p>wfyUBEbJQS=%vt2g6A~N22&aAYd^qeT6JCM~)O> z6;E9sI0f!n{3I|MGYmr%rxhxh$z2&Uus!r#>-!QLTP8!k5wJIq1QrJmhCVKZ|Ivypm zbAr;kwbZecU^QA%+{o>+6(i_*Pa&!cJKyE?$z9Ajy$t@=(IQcc+4;e5bF zpFdqt`NbC&L**UKE;!~P!=K@ls3W($BaU)1WVt3FDB~sGN?RVbVtNS+*AwlE#xf+n z=C-jQ=`z^%xLIsBftdErYs#Ubs$Dx2g?3`m#b48P@E40>3j0|i#E?h2E?b{`QZ(1?Z?i?%t*FhbcphB1zz$F&wx#2;66RI|{5d=tUxW|~*9DnVaR1mD>F7sHlkcvO0sTfFOKYQsM!fwz|DO*!ei-GZK#YMgE6ZQk1hc*2Y?7-z zU%`H6;67UcRBN&gBWWI-a3%jeIG$%R;2Kq#(rD)8kY0h#r4@5II1FVm` zw?Pm7TT>B4qicA!HKk?RDOZSk1GlJi*%?|Y_SgI2wSS!p14u^De>Oq82B0e;JZGF4 zq32irre8Rw}zrUfTh+U9?z-|9a<)O=Q@>sCP zdB|5~32)aQ(MxVRe;}J(722G!5V9UQSW*~ANp*FD2LLOL|LTiU2_ zEL?lnrwsjhoFaqa+q?F@`B4&vtACYNx=#R%Zvn(?Tbc3*-Y9)|!Bm(Kt^aJAfqSbB zH%q2)%lUjsh6`uP-Y}sW6_ZNi)nq1FAR5ImkC$K135Bg#E|cErr6!&p@~m5a<`P9T zR~ADxUe{gRXv!0o^03-zNat*)DjcN`Kv+LCN6D+fi=$l3cB2OD-U9AXR*b4-OlN*( zOct=W-4Z8Qzbnrf|Bps!%Z*D;nsWbPHdH(6xNRGDQccrF8wehZof0z*aZDHa3X4ZycS6fHO#%405mFqH|veYd&Nfo z{%rAh%UBaguKIVYh?;zwMUHR3pjkjWKJyJlB>GJ`9_<=V^yN`BH!tEs|Hy-78e^w5 z>z%1fo1`*QWci1FC>otP6GQ97))8qDV-5|Qk4X`Jvu{utU1}_lg8+Wqn<|rZlJ1U>`xv9L39a-|@J`=Wnuy-a=(xlh^GfrDA8y0@I6duL( z%r(cXO5$#18rxXi%CKi9c8MIrDpR&&AgHmAv^1jeG+S1|c$NX(3kOso>zN5c{hzcMTp9W>c;` z?Go2o!x3D-uX}imf?B?bx*2?NvYM59b!Ti9gA+7-lLw-xWF}sD5L<@n3in;aFXLCi zgcwI52c7hcHUhk?<8^qOVw%HEkLKGHC68&nm$VNJtPOXCUIO)^L;XlJ=cY!hWlkJf@vm`CdlhH+*?)hWqpd&WP+x1#nUSUrtR&f2IM}GMgBcTb10YYS zh^5ctsh}q`!`fG2K2+FD>J_|y;}F&M&>zC@Y8le?UPfq0nCIBv=1>FFwAo)sv^gRk^OQXiec|}0_Gb2QP zkup=~_iz^a*wHoPqO_``$8WIg*_BC8b_?D78_E)QYg0N)f^8A`qFN%foOZZffC)cJ zYsh5s|8Mr*HM*%QOBX$LxgA$E1Q$ht!^`SUy2_OTTS*KUuqEB@6rpnnR;L^+K(-X1 zVq+c_e(EiCihvUYsAwk${E#|vKmlP3;)iVOv4f3pK$cWS$ikK-VabxPWNBO4-jem) zXPc@zr~Ahp_l$eSxug4zjIn?Cmo@iX-*>tm72TcQO~JUl{0T4$YHi zXC6$%ZY(#Bl)Okjko<>HTOa}3BWhnPqIUK@&aK#kwpS=o4<(`*K=uwk2h%^u;V$~- z$pw3h4~&%Y>y9~hk(Mhp*iiCQzDe~_g(FojxE@@>Uw3% zX`Y*ZJ|AeZqRMW^2FJB}VvhJ7L!5c6ah$~TTlm}%+v(U!yA}(4BPGw#=eM>K(2=-g z%3nB>a3vNXYsg|uiK~gBnWnLm>cXl3kWXV^b~VIU{To$-oD_YR#&_JkMNZu`=SwBd zP&3;In#?kE9EQ_?ra-^QxqY+?*txZ)U3RwIA!6|E16B67x z7P|&O3yBS}qT)l2&4aLfC0aX2$G3lHvaLsMFm+pwMoqa_JcUL3yf4nR-96D72N_Cj z!m0f^w^e9y{eg90(tNf6LYW^E(WMHvAYq#TFM{t4N>>wKt4tMbE%eJ&upbGh7DEc; z@Rgc zKdYZ+m3@J)X0N{*t0+r1SF1V11M36@gxM^)qb^l*xb}lV9}js(svM#3Xy2F!9B3>3 z<*9}@2OT$2TK&XT+Bk00fM`;i$^bVSC6j-n6mO@yfmxwMn0O&5qBxO5NAbf zHc_N@^(ZBDzpav@FF{_|^wIx&n+m3Xu<3th?SAmn{~X4D@YDajpMZHJCP8BS%iQ?S zR<%TzlYXVq5R=ZcyH2msm<>{Hbgz0R%$?*ngk6PxYXTeX;d6V;#Vl3j;=^Qefc=;$ zL>uOx8Y?|IXa-JlzHR+T*59gC8t?Mrt){88z=5l;&2w}qh2yqSm5gu27!=_9@0jyN zbYM>b-HUdvq#TJsX}gXP7$L+a6_rr}j;h)?P|#5{#Z4FL>N3zy@Ac99)`2OT-?cfpoUUT)wY+(=0q)kr;Z!dQ@K2j?RaZ1DwgMXkkKL%wrcS`RM%)%F;4cS~wdL zPv=08H~6l1r!V^b9f@&N7(|sqAh``wmYyHoWloz{<0Q^@qM5v8gw-j)uFETg1+)jiR;(9#mAeWb`%PCZ3OY(sV&$+JcBTmv z8c1k2Cu;AHNH*MTQIopotvPQ#be$hYZ(T*5lg#e9KUuq_Bb5cPowz-zY`c=EQC?$` zu*;;A`+G4`mM82Z(d+14qRkznY-+TJhBC?~LPSj@Fp*-@S{OTPY403*;oQXM!V;*A z+SabKaqapFW-(esjGp8bIm{E6DUt^&joNRcIXotrZuY;swh?u$1NQ<5wVI_Ok}$fW z-?!x2x$9pXCP+|alIDW+Dd42p(E5?r^GT z+JORr1Prz+>(piIKC+`g;GzVmlR|#Dmu3t)*rxls%k2Ee&LHGCXqR%@TD)=RTv;#( zRd3hTJv!9|R6?#;m*LVve5(fzl!Ls)cCGjEAwED-y9$&a6a*UfO>oYqW1EEXX;@g$s4Z5G^SFGY*=;>I%DA_ub9L z{eh92;sI6MY@2HLyC3}uvRiNgGX8>vmu!}E*^P+3^_P@OQ>~ZR(j|x?jM7FwDY9f$ zdTZ$tdiOzbNp)Qc*NQ=PWE#J=NZ*vxKvvYMh%NYPStvV`Hf2c5nr(IidS|4=1*noX zIZEsD*o9lxHHhx9mF%jImiE|QWac8@iY50#6%zwH5Bp_~gYP7;yy$)Qr8rJSmvHF$ zP#5K;;$GQtLNPq*Hp_#aU>TP5&b6o}Smi+ZdLu3gCt&SPMD1HcwKMh$J^hI!{Yvz8 zjMOur*-lU-hJ!MXT+Rm9oi^K=4RufVZXV|0QE7}ETGGm!xYb^uGw6Rprlt&UP4Yv^9DCgp za9W+1QMO*A!*89wRlYw_bE`5>&TBve0&C!{N2+K8F>xi+)r&!9PB_FiAbR67(QDC) zueCNW(5)iIc5GWxnnxpo*LL!X_j79*-{={E%G=R^P&MkeD($JrDZF~H&5lN}8lW5T z{Z66iPS~JYlJWen}hF?*CvlQ3hgWN+0c0Q6ftr0v2NXv5Sm7B)4(W5U$(b>dt2K-s1C1pTb+Z`0TVaRaC1qni9ZZdjQ(vL8*|^J*2G2C#LCJ z?0LZ{fHf(--Jf&n;Jj=C$0{6EH9q>M*;`e1JAt4sgRGPy#5^r)9oV&KXU6pXIND+k zaS*@NCsl!OSrQ8=D>uSM^u*Y_p0dfF(wpz#-rEYRTrDa?Es`v!Hi_|JR@PQ-r^sC-Is=}9(iqZ$amjqjj zJ*yw}L3J9|fR=w7j}9F{M+r#BGv@Zw~0cHj*7V$Rk|}&z0G_w z8%N`RCI!86?lPNoQ8Z-hNBP*tV0RbkeMY2raq6Bdsq?;UuoolKqn|B%rB9PX>t0I)RVACBMOoO4Yj(*lN$+J$O6E@2f&9OyVB*J-H`%yl>ga3F(S2 zx>`Je6lBtE0|Huzx=Ay5O?C!s7db9ip>zE3*Z#LVc#jf!b!wsmuvG$4NAmMb$DDcE z<|upF-{H7$2OptU)1OGo=M2=DiA7r9G8Z06l#TL(??CJ!lz`I2nG1wuo=De(dTkIrm>t+0zJm z`|fUWM4U1CN~&$td@pLy(H@{YYXs(F_{;YRZmwv+E(IOIZbyQ~d(=dW_~wJOu5<7h z?VSUd1XfY#GvzgUv9-MWO4E1z6CZ6^oYl7i#r1b|^_| zl2?0t&)8l!l=e40_fvoO(L-M7aNOdKjAO)h~X9WiwmEP467|RcS%f`mtZ>fIUNYJtyd(a+ z;HX-lbXa)<0TUq>_`L2fmWvu31dNbN%jXW_>wQOh_9twjOSE3A)X$(M55Kig<LvO4{3FyVFG1y9`|TAGT>FZ7{f zgpWg=jfwhApn&k+Is87(HBLAXO(GaJ|6e!g?*5&><+&9^zQ367&w=4@1CRbrRR8gh zJS&!cUrVpchd%x0cfIR>+7r8esvK{tj7GiTnFTXSb#xn z@Ku_4ojI2$+dM)pBJ}qkm^xnLrBa~bM!Yfe41ixWH(LhFa61qJjvsFi)f0B;v1oLa zS!2wrL}iK-NpcFR3Bq#!%@IECSfeD$kquLY=Dcb?4T^0iroS#|Hrg;3QK882K8Z!m z-?bjHA5SuH4Cj&l-B2J)SUu1>a$*1*eBo<~(4z~|*pn&w4+5e`aDE}5YSxUO3VDL`Y-0e3z4S>qi6yS(4FY&qavK)EC z0PA#`&q^;8x@LK&Tc~zZnxufBHzbXT*jy}DJ;lpbj+Y1#)*t8aV63zW$d;8)rR^T* zlsNe=?UxcIVLhsCI@5}mvyu9(9<_Nf#G1daJuUE9vDvoT0->drx^TE?rpD)ecf`T* zdPRK=v3iNkA<;FPNPLuc%OjoOP6{D6+|yK87xP$&W4A0vHOz_+6pNi*8)>2BGv|>S znYNwJ)Mr{_MT8aU_%jlb;;)6DB~gCUS^5K0>e*I6B~8hzz23w4Km=7lglzq(qQ*{X zHUj_a1lJCAuH@rNmHjET-fJz2HQV3A)A?IHxyZu;E+v|tJvPdgg{g?K8O~8(;{?;kM#<@BT3i)O znZ~Y0OI;)Wd#kgCb6aQtqh4n#qUg9|O`$)G+?3>O;zR8c>g2fF#BJpB^N7XN6w1uh zBB_X05ey=WDLXjoZlw`+%P7K_=i2)=r(&>HrG?H21lrEE^t5{$;iMNzzOm>(L&Y&W zb>=e=VuGZOb;RfyQ!*@$pt+Z%Db`~(RvL|TR|I<6D`q7vXDXshqhePQJ`iw5qT3}j zXokqjk4>ePIAx(s-qvz}QfgffJ$uw=8Jc@0I8-CbKYkL0inD^t7tzHZA zo1>k=Gp3d`#YCk&Ua?={>>0fbeUmoDYRE-8=zS}Zv6ohPwg9_A0}Z#W6ML#cW5eDJ z)wIKKZky8|at_SsII%+UQbUX4fkD?V?%j?|xHctoZwI$o^)#$|(AM@a2Aa6NgYr+`@o?+<+L z?P3E)Bz}+vw2ELx?!Y77wuCFnlm|yb&`yIDAK}=KsaU zNQp}2D-v{q9!PlNoq>aKV&$imyq(+{uWLfE%Z>w>9COv=+x{cwNb4nUM$9ten@QHp zR?Q)XAu45~N*b%d8YEO0o)}C`9NodSR}4eR7)sEZ^4pFvz3QC9cFa=^8J3L4Z;SV! zLu+cmVVoTm6(PxqspAJO(>ea|t=8@|RqvHZ*10QY3C#QXK%1r?3Qe8eB`%ykYVS1l zG_5Tj;GUmljMF-oT$C;eB@zSO^P;Q_u!=V&ASo6njPcvFMEA()c+s(E%ycrHN~YoJ z9u;J7egn)r>FA6TPjE|(uc1?jcI};P5EWpNS){yex4$pcG%(HjgNWP%8I2ceyB8!y z&TG_S>Qsyo{D)1(_W3u#anu9LrBirqeUV>Ln&TDjMQ$#pQd0*Pb%Ha|t%RUfMo!LE za>o@fe2~3$zKG95csztvaLCRC-@SScWheX#7eF+l4=hbdd+{>w<#R$Fc;tYPjtbY9 z{UyNq(wR+;L6y&Q8zDh4Z{>^i$PSHSrPv^+i2mgzZ}H+)x_@in%d;ibk|VpsFj>|N zja)}QNTzwg{{b5G>k{e4`>pA@H{0-;>ltDKz(*hThFnk;{kze`GAmt{HXV|fp?@6S z1JK{RJ)+E}B~Xn*>dTwMmuTfEjn_CLizT7_j;SrF9N}M3tNf>tx*X1^vY{pN$D!91 z#5Xq?*)@M@|AH{xlqA{<4@%0)-XpDc_Xi%Wa;b#Z$s7mdFgv+cA)87me_cBGU5BlqBmE5?Orq zfwi^H`KeBe9n$y5=d;0Wfb@IUP5Rw_W!E@<2>y^nDo4+91bwHaW9mYV%5I9uJ>wjU ziT7dEZ5Ar`)5jd_)XhFq?dHPaMh)*xgDD1|uR`=GWHyQ{nd)3_> zVNMtK$!160w44+h-=QrRq3jfmpzI!^hyoP7JKB?Rpba!2GjQWe8fsM|wGcV(sQCKk zNF~#9^n}VBIz-vIlEbv*TuMDZ8#-{Zh8YFY(+N}+;Uq3rKGz(J#rlMU9_J@+_=DD( zZNwd02m)_}G5u*4u#NIQ`1&}?S=M#B<#cLZjm(Qvh0_B(hubgQ&=`F`Q&YqYRi#@! zwSm_pVO$mn|Jt!$+V8KuB^eJ^Zd-)WuplSZ#c+Wit@SD)0#n`oF-U5$Sq#9WVqKLl zbkGhzT~BLJT_IgsMzzDA9VM_17p*0irJ+PLmU+(B)EnK@ctRDJK8bex4AX7kdxWGT znd*#|Xwq>dDRDc4DpvKEExxdzJchPb)pSMSnchXi-4Unzn~)4Oz<~=}Cklj+EoLgi zvd68H7Yg*wLP_vpzIa_Ne%=fnSg~Y5^y_le08C#S{9WdWYgpt(;=^XqBkBqIjc5hi z+?gYs*Okk|XzP)y4D`p)V5clqYTTW1^m`2O!NF!W(Kco$wJ8^-gPRP?E|Knkyx;Yi zjv0PDLY3?Pltn~RJ{#kfI$xV8KC7)?R}#~ ztFsZxL#*mtY~Ld9=g^m#LuW|P(5jlg8(AV~=DHA|v?4FEBU^O-X2kGwuy9S}#y}bP zi;DnZkt-UOFS%j|z*6SzxkybxMm~TrWlEIZALIs7k6<$~I=Xz1YSLYf>VWHh;`$gf z{(Ie@%oN+(xwJ_8tQw^O^*?+qS!y1BE}+fLEebI}hu=eBCKhl#-T~ z3w;)XbL?*LJ@Ai_TV!JPv`9&Dqpm^FHlxI1R(Jfj@usOGM&9c_XIJX?SU$5hU7vgs zr|NZrYUInJsqBT}#!x1CvB7Wa5Q>AnKhKa^9;E|#fM z=2JZH*NXJRSRkZ~C9(YISQ0)M48BaeYreK$l2QFWVD~Ky1(r8a%BOnqNk29FWt4%w zH%)@Z2^!?+y6Q}heoc&o&8Ws$JKUX@ATx)uxV!EV{lSK8P}U29DjTi)mZ%$=j@-pT za_WvvhKpP2Y4a&{w_Hpx__mLbxmO`vP2e&;DI-|~3Y5#iU+cfN*=a@PBrVvkck=9M z-*%wxF&UXjMiyjFZql@B0 zh>YpSAm}PZk?v>c7*B%xfzqpfdkSUyo>q2I)iAlM?LqW2Y@X4sWs!u!ZhWh&6F(Xg z_eZ`jOq*qXtrDd6Hw;XB&i6<5t07n*yDU%ugL<%SVVtlN!0`$sh#SPW0C=5EJ)PUP ztJ?>Cm+P~T+bR9r=|9Q@%JC+CO4l(>Y?6*6$L;ZvKW!p^`}|6#<-^_JwW$BI#DYOf zRjz$`tZUf-wrzdk z$l$1+83vNJJyYg9k#Pg+$j8r2S+Kve7(1mo{oJfA_YVVU_t?C2xWv!jMoYQ=w9VmS zMw9Bqov)&!3HUyj<#l#aURHvRjF?=gdwKg3(2ujtt4XhAxlR_>x!Ri_#B;ogk@kU| z#3dAcs+@F(nZu=(rRzEIuXt+n>{)BpO7&p>3GSi=C_*PY8OKv{PbWW#X7>miZAJ!#JwwqLcD{m4}m%X`P0tP-ykr+yCF zO(D;hH(YfCjQUsGTkM#V+(}k#lH4?W{|=j1=fmYre#P-N^)4`OV~d~CA(2uujf*P3 z!+L8spFbl!oz!jZW1 z6K(;2z`wy>2P{t>Nf%lur+w4+PT!XSQ5s&u;9B-zyCA<6W#^5E!#UK%uY)Vt2j?#C zwT>?0qDjvA$d%$^l77$BfR2iuXVj`fz-}Ywqx@ha$JaX4wy6t?tRB|xXlXW4=;@?T zC-3ML6wJmq#gK^5sg(54!P)UT|NL4>z^0n~s>I{~fO#=`+q-+?n{#56qKqi$`;{Yh zI2V`g7p#uhlI|`V!Gbi(Brb-zJQLphwS>__P3t*k$P z?xVW}d8hJS(J2UeeUiLuXZbcvjW>@U^7q2wV3I|r>HDK-A@U$6+E|zG^rJYnk(ouf z76pr2HN4%y;-0?GFi_JyLEdA#T1qx{4wE^3bm+LCcpnP*AvUT`nN{-xP=5gGzXfVy zECG+jsjvRS)&0S5hi{20PvaP|uJ%H1sx|^RN>O#7 z=+(|26RBN!eRGK_UW&U)MlRY;T|qf{ZPmz>(SU|YPNio3p;hwlGb*U)1w+9y>d6Nl z#SIms@O|65 z(3Q89uV4q&NFd~_@fZ0&>v?tKp7N92ZGZ+uBnB^#KeX0ir+bBozPZltGsab6vD{rX0psz9h?X@9rXhv(s&)n;&PH31zb_|cq` z|CLpJ?fsLTn9h(K^#csDUzq~oA5aPU3~S^a9@^TIjtf2 z8?|gK%kMg8i)ASXaY*EOkkbo&+Vkp^{fV}eVKgP<8a_0{IH`F>_4KXRE)7W99cpQ; zg7R|br=*!>-EyDY)A})X`%#E&asyCc-%>#{MSZU^XLr<-y?Y}lnT#GdnTt86K1T<}emQ2W{u_JFwDH_V<$}yHRc!8n&viw4pP0VMj z7*o59EOfm`-p?Xa^>Q$QNTC>b;f_`jwZ&YTT=wSh$J^v8G^dT6#cr=djk$I>ZS$jb zEF(w-A8D}m%S#!zN(Q^NYg2pP#K1LJ8he&G-C4bb@LRQv>6{L0zvND`)nXjdd?|zW z!UsjXfx)ML4KiD(OKG1sYAiG*{umB&N+lBeYq(XFeB`i}Fcwg*<43#ee75UEDLVHr zU00(<>Zw}zemChq2s|X<`%ksVZxrnOj;DtRSFc&6{~pJ^=qCh+{Anpbrv6vsBb^i! z$~nb*)k&kloAd9`jADcl>TeLkzd5w(Qb%5&riJQ=B1A9bSa(=J1C`JSmmDdbS$2ZL zG?Jjea_UJBy6f_XlS&Jk_ec;#LI22+1^y#w&=lCs@$eBry5p)a-Y-(97gY151y?XP z?dGD;X;k|iA5c?_V&vVCGm1$j`g7SpS^3Gc(IP!M*yaZve$@M%C3yOPZfh0gV3YgxwxR8;v|STD74-4wrh(jly`|J(-g%S znxhA58dO7iKGf0iK2`*2XY$iMM zjz2}h0voG&Pd#Sk6mrCEIPGl$Cz;dc9q1|NG@G_)zD>i~Ey7D!3gf?98%+iY8|4h# zDDpS@k#-<|Jcq+hf}C+q=$5KZMBHti^Ab{jOK**EXno!taUh`o+fo`UX9~M#T06?Uur1jYOa9B6(X*xww z>r&X#;0ii#v8z3caa*mBviESA8vYK#dhaK$&VuSUlb@}QJjs_J56o9bHh|8GKi@4R z5VH>3)Qah2!g*2Pz(D>~Y+Bh!VQjlZ>BmjkH}JOk$-*ey;SyxohmhNN0yYC1!~u!S zkpOqYwwJYyL01q;~N`M4DmxB?qkVnc-zk}4;YTj!i0K0SVA14tYXdiMcP_;z0~yAOyC)*Y*ft~ji?(MuRR znSyhvV#?Lj(%C&NI%gw>?1(jr(1HYXaxd|I5XVetH~^hGUqoJr=t!W?fts`tHK{^* zhJngvx&-}Xk>dGML5?rAL3SZK+FnnK3(oR;#X-b}cB+XZU*^Tr>6w&E9WQibw-dLL z`M5_SX;#HjAq0Jh;HBtr!oLZol$w|sYN}S2Ih-|o=+FN)4bd3jh&oX`Sdh{V0f&gF z5*5)wASV7Pi_5o5?zESj3YBJooI~E#`f;i-?4CV4f#xeqk4foD&8Jy=)FN}e{qI3i z$T$2K7cLbKk{j%a8c@?5+{eE=FCRCdI!>mj(S(1p8x`8hIqCg?tTJm0CF8N*bi6o-JEi}I$F;MZ&ubxTqP z*CQlU3JU7UY#2jjs(xbKXV^B!%VYGxsSE9ypq&1MeQ=+5(*kde z9KV9P;>4+P`&UavDkCth#zcdKv-X9o<;ZcI4KWkANKxSJ@`V(WKh#*-82nMRG^BKQXLfaq-b~7M2Lq&AlekyYl4msLtAP0##fwVr7G zJ#_O5|1C|rEM=}v(EvoMzB*7SP(TZ(k%e?<^m>*fo%ThaNPC;Uf*gsFHx(?{bDorm z7DFv$Icw3~DNP?){3_-niX8lIl1$^3TD-1o@%#=wQ3l{!N6IO%>8q-)ZuiRt-glJ; z;#*NXOOS`A;Db$95)|8AyV^0Y)i~XWO(M!x!l~s3>7n$)#dsY|QZ{&Lp|t}_OdG6S z1wWAuX!?`w7+#EVy68=Atc0M_*n`HH-a#1{aLWovDi)(f58b3-4~(&V*aszBscJmk zJ|0aj6mG^w=RdK~((x{%r$$6d^&D&QpVXtA%tg#kt`nCk_fW#SX(DP&fZU(esH0|w zns47XX)dFdrR^xivFl#wz5)Q^IJk<=H_+0NNBUfW0bST8IE2W#$qxrp^+|S25%CTi8>ynAXQh#eEK!=Y;gt3lWbXD+9Qq&LO<7& zUdj3cBBk94@AX}A^8_`8`??)`+^7SAqn_cR?t%sxD8O1{`W%sr75lx9nQQwDNj zIw+wxH*T|Ji2(Y>7j6v&Ksk@dowP}yRzO`_rz6q+1V?X)nsVnW_zCrb^caf6psEv$ z&C*LL!RepK9Z9(Sf535~1*LmugnztO;`#Gg=37*n&yn~$CkvDTY(&-C^I{>@u6fFv>DXx(Sbcbs*iHwv- z4#rPr)0t+X;KqPq{N$o-qrDcv&2@S%JxdF2W!(i{B>+pfz!IH_!SQO&XE&rbG$%a zJ;p8NTZTo-{6%OY`{fmtIGTJtG1IXHj+>s3X;ROgxyCxZN9LW)FVVRLQof0&?GzQy zeB^1(v6Hyj8zhk-e;`Fw7h%|aO$9XWr1X3L%?x%J9meTUwiU_-M`E+{=R4upUw34Y zvL29t^=qRKTf08(UQgKogeP!Xe+_T2{TE*JjzJ-%6c2W~KDnpJ*xc7g>f}SdwYEx_ zj^hjzo*_sAW8a+~ha$H^3-kKl$_W><1L)Vq;rIo8VXf_Y;Rjg`JCY+`#Kp?wiul8f z2YXXLclC@@HJqZS?x}-joPmhmVs;uyuc-S6-_XR(clwF;`rU2j`N_pEjKS9_LdX=@ zvXkEi58zNy)l-{tR%mbs?)IvWr&>vh=Xe?5pVrydC1WRrFP-ZaD@YfmO|&blRMo;U z^s}2z=M8iyp6A)V99)c~2}~{c(92SriTF1tKItpc-gFq<;CWudtzZprm+Hs~u4d@D z)_gW(mY>sd!#6fNZ=bU~kaHS|Ay%8Dx)SZJxor&G6g5}-cO0G%+&kYH*zb3!26smf zrphy^LBlg+C41`|ZLmsxya>nXe&Q!~>`9<8CQ5&}NxhpsyV8u76Of0Sc|^R$-^mMq z9QrLmyQ32pp}W3uC%v=*ecS0ZWIwd#9c)+L1vziqmSA&1`Kroos_i^?H~YNBm8>t^ zYrs@;tBLBidh*Cm&d@STPo9z=LOkZ&L8A|3E!NUs;^VCyA5Y)*2KKvVr(3U6`0H_# zXy5^Wy}{?XgL~=U+D^?{l zW-VtAr0yx+`tY|GX(fkqH}+3vj@07+Pqa6ed^;I`4!JUc%e)k+Lz2f~9ww&d*J_f> zlK!I&fA3G^K(o8C=hqqJYb_f}%hI)rBQ@dxN>76Pmviz=$M?YZbnb`o4VIA=JfCjN zD+7~B8s?I5Px%yArl6+39)6dGxpR?DgvV)KEB0k^3s%)a`D9J(3-qR!%LR8X%s#0i zCubKz@U-NXG1^zeVJ|WqyOS4XA2$WsBFo7ef&S$gU5(Wg+3ViuCrzO-FTI94h9Bo| zi-(3qS&=81v}qmTI{;sr)uZ9RC7~=8<&247aWq>-4*DZ1tftA@#2-vX-p?}4lV|`Z zp%B^e)$(}o^^>VaP3rNpo2I^J?uA!xe=k?{4*L9TBg!07Y;_W)LU|@CMvzPoNTlqa zDErx~XKl2_;|tTeI{n+|0b8v^;ROxR(}{UB zBf6tZf0(cz z{e}d+vy`E{p#3+j=myPt?qYaI9G~vwELgg;RjOW%t~{G?xoZ*K)RL&JeGXTunDPc< zN(eWFPnz5c;b6Z*z)HA1RMjpuR|R7=yg~=BeHl@oLD`2LI-h(*mdP}l=*D=xuO~NM zA76~m6U|0Yl3)&s?g*3xm+h%@@^>&A)g391u^E$sZ)ad>onWnKg!uL5rOo5z(sS5C zb8eK$P6s)eicF+F7U;+eM!&N224Y$AVw5^NC6GG|3aaj)Wf`V~;XvUC0k=b8CG?b7lS zD5R2E-5ZmEuYCT7k8#o8mu;b}-z#S&rp>SNE?30jEOYz~UO%x{JRmbGR}~~Zha+E7 zPhJC3MgvX4&zEF4;6Jnq$xp1@+`cKd$Z=4lY_sMsGsp(T>xmbIC3B(lw5xp6Mq1*q z`PJ%BSk$3N`elkmSS^nH4170(+`iMXo9$VJ2CkXp72?}X-Jvin=2-SzqI3JO-f~qk z5K5k><4E0uXm_Gy=OQujN3tY5zxXOv?Ucl?-4j|$IxB<6;p+P@1I(wvW(+5Gc_gaUqaCzlxh9ho&iCV=vUeqwPw)pNyq6v8zCsJSG)^II# zp&WcL@~G1ciq{HdSv=g~khuPiS(|F^tqa9Y5-%OSF^J!E(&hH!VqLb%U zE4Bt?byYM>QX!+D&0;32^=yj9hxiIA!+PKHb2B?$~k&i{ardJJPIY zpZ1#<-COU-4a!4BHR?yX8Z&*Z;hi?^Ba4*9gr6{c{kd&Ngwaf-8J1|?h&$t5UMG<= z75IWIbKr8bN!TQ7$cdZ%P$o#^obWoK3Gv2}_Zqmno<7i7*x_=_PCGoIX`_e2iVmT5r2zX-Q5R(q z{zS`ue6KVsN*p(6z1_H-m#+EZ^>;3cUsZ9 z1ktb0bmj#mx7*QjAG>yAz8RkVa08YKKBRMJ7?#RJtzD~gWEb_VIm zRKu@l3bEnGo6|QX>(D6|Gt1Le3cfQn-`W(w$L@(R7574xWqa;-KEO&p<~G>P&d>b& zt3#cd?$g_yTS_%}vrZ;`P%?6A`se7PEJ|)83uni&EOcBJ-|4EBPaR4Ht3v&(Y0K)h zOS`0eig2(nYiX10sJP`f-P=yl*qg!l_n|Ih#H|vD0GyZ_>hc~h&9b{v`58zRhUG8G z&Zf>>CnZY=`RFvuEqJuN(|)mkx**fa4WGdhMt|>;XI%P}e34qbEa6khw5u($DJPj* zIeqf}!P^|}EfI-$QF_Tb^m>GW%o7eGv&%cMT_7tjeSgG88R(7MOwJm3NS?FB-n_DJ zu%G{JV;)`-cvv&~fkk@el!~Lyaln^d<&uDonT6%EivVZ2(R@2kHIk@YnKt1U#-&9? zn(z0@7p1(4c^CYF|C;iUdPB`HExRutXcck8 z(8QCuf~FI0hZ$T}?YHPDv56xDfP93l8yWhe`?pE z#G8Akc(L#k!571UhbmSscL0NONU3M@vZKVc{J1Y0hJVcW4WD0I4YxYNvqS0GnEn8u zxK<<@)ZDX)7g{>YQ4*&<-78PeNS)g z5ulw&HR6hW;$H(xJY{oXI#0b8F#4i7ax0LnYbM0Tm6JK* zP4jOdoezZ38DbWA(?f92lQ%OrAL=*Lcsl9wgw$JbG-a=NP@aA2?tbA~Vkd%f z@cxK;(Ow%`SiA)fTb5rMfqr7y>?7z0p1Q##E0-rhZ)+$DKJH2mKio<0B^DJv`zTGm zhyfo;^6VuNg2df4i>)4y%xc}P+(xdM7!SBZM33o4M=z%Pen5mJst@d(5|7F(k41X3e@eGXTF)8|ueD`7rrnKj@%z=KEvLZwy?Ll0vzo0CdJR-}^MLXEeEc%ye)~nsl z+0cG}lRRsq(7U>e^n~A1cUR|#!H1G~nM0zgMp#>j=@~M3T*7GlPM1`yC)k?_Rzg?L$h|8 z$UQJN)X9U$`0}R&9I(zG-JTx|9}{%4deFYDOs6~(O>?gZq$8wGjD~W$NKEXfypL2F zw0V55oS20&<3gu{kf7VZgEY`9g%=^K6KVa`a(bhnMF4E&T_2pOJyZFBk)e&ts4Inc!qSG`t&xxvn%#aS;ndNu3FOkXSy-xVoN*+MHc&E>Pdw)Z zA{U*Io5pD6nS)1!yqNV-vq3G>cc}41F0V!}1;#e^$IL3MR1A&WTkhx`43BRR890YH ztfF3M+Mks*Y@t$P$LBii@jn9X7{$}>M2D@vn~ul4@-mNmBFbnGA*E1lHC_b+CX*ID z{F$+(>FtudVt*jLG$u=g6jUC!YOVu+vX_oGJP0d5M;XU{ye1SjpSqZH18tubju20E z^)q&&lju}R8=>83DvEY(r=cQTWRoqXo7jk{;Pp<3N{lhrv$No#a;E>{-b#Ef9w(km zxqdM52QU7B#s4JRg|HR)6vO|K=%0U8vGBKxy*IC1ly<+*eVgzpdN}Jc){1MB)-!-! z?tmOf%7J+^MXD?V3QwFU%9<0L0n0xzVQ~bw)efutTrOH2?MN1i@eXHma9I*Y2isBu zai5rtc3fQ4;96hP#0o0Ct?Z*4>0f4fn27`p@$+$v&uYjFJK_@uM6S+sctLZXgUv{9 z2Y5zn37K^a(%#X-M_{Y>@xE6l=iDGTyzhvX{6mj1WYcdD_-`IN- z@20LaU-VYf9VeZ{sx%2^u;tg`R=HAuMT)_Lrk6(%I-QEuX$KUrEfvs(F~pW<%~GWy zIKg0bnt;KBRKWxVge|xR%eICC2%!WaDYlShtO;32!V=PvEFaC%xrbB_@4k0?t-fpZ zy6?Wb_ya8O{q1k>v-kJ?hF4_2&`#WlxLWRnOG=B|B4rnql)b}d{+oRG#5R%}TNm?u zNhjwR_8G69@2nS^CIhHTDy(n`|XtyD@ht)%tR8vEpMI_yxhH z8a(WaGUkU3C(b8RxJB?1Rf;@(kB3k8OX&=qO)$^7GPVNGS=fsYeT_a*_28eTApYkm zu$CCxYg12L@+ZIbvth`xytpd9wb;qwB&roQzho0APm9@$wuh1X$>WmxkU5A`4vwZY zWdhSEMTHnIRjpQ-#S84lMtB(_0YmbbINaBym8w2|^i2Al1Qa>CaIWTlm#oquTw5qc zEAgL5dF!fP_6;Qh$lcS_zg#~tjiJyED{y-_?(6q0@PFcS?*uMUjp$O0in*qYsvkV; zxNAOUQe(<&_y-b7snT&*7R8j{Ntx7);r6=uX)VfmgZ(nunU>0g=3V7=6ZJlftgtxu zdbGh6D$ERih8kLTucb+k!SyhF?#RLkow$a-vato~rlGsaPGXgc!QK~WP(vo$$X6zg z;`Nq-$Yr-AiNwD6D7Bb$Ryd*IFeL6^#qAdVlvN$`BQi71gyR6gKTK3sObx8d&O>8& zbwir6Djg?_3R`w4gemB$YjM6`hB$ZHCcKTcjpg`EtJ=Oz>GwN|qg<%>u>8#9#@Gj9^r!!{hCe1!yg6B){zxgi6!Hc}QAGE+(&D9rN@IUg- zab-^$Uj#6}y{32Db{Cj{+@Utdn^|jZ7Frko#z`p7)L0Q601~IXboiWkv4oqIyn5JW z;-BaHoV*T%n5kST{#|ak*Ei6MDuAMUs7$U>>WwhxyLNkzhZTeTx08!>8U(6BY2y&% z1`GFqge$~D=A-Th>LUx7Qh>75;4CkY_R!Fz#7w`tn?w6xts^&hgnU9`Bo^*Ml)iT3 z`P0-;Hb;XE_qcB-AuJ}=+Qb`LqP0O5sV&VnLF_#eKV;S@BVIS#;#&i@m$ zQ}=USi;k|T6QYSX#`BIxFPdva?0>-NslwfwK^cSDm$H;8#L8jN<7x5rlchIOq{ngb zD&R}w`dS)9iUz>@9;)+@je!q|3@3u$NM>q^eJJ)G4sv|VEwAdsBIb;zfZ$=}z2K4j zUG~we*jA|GJd(Ih%C`)j^LsjH&VUy)jXh}qQH-1vMwkwKZ4+Uy?o@Omzy1uuM|5p2 zD?8jmk-XH+1{-|eNlS58R$;}Nh0J*74z{>SxaU5w6R3~(j4Gjt^a)ySG4VRxG4E;c zQ=M>GRKF?ENcF-19@v!mUQr&C)n6~jT1`Ow^-xYHnxXrQCgBs2x2&GIIPUS@L=;CZ zk=T&#w0m(&UXKiE%y2eEdab)_(oG6|3rx?YPE(Bu9EdLM(WjkT@(dHn_DXPqXPA$O69!&F~fg8uGka(aiB4PN3TMYqAqW@YZ2nzb63)f z(M~-LvlAvSi6s4}KxvJJAn1irlkWvJ$;7w#}fUB=ja=?E|S zq6}j&N4toT`J>X}q5*W(vI3c)`hhdqnyu-g-P-RT4{gD4Lkv+Ze2DwCAU7+-t`?}t*$>fj1ki2b?(T6IdzJkEV zs?nB-bU4vuFs+~D$Y?W2OuRJF#V3^CCK|BqkVj-NiX_e|hM-Z@^ipSk8kGHjtN!2n*Lz<9j~kqPCmg)XK=N1^YpV>sqW2f`Qw42ra4eHv9h6k?8Br=E}DnCfBHP zyj$YL-41rQK^YfGQSJ)t$P;&&Zfb(=*CD#97M^hph9y8ERtEnn5peG_V+Er0g(I{L zB!N*k;Q313OU@Szbx8q+vM0OH@}PLeC~RkG%-=^IYzLV)ysqgLfchyv8ydg~y=r}d z+7rlrrR@k2aH{_3=I&Bw5WyP_oKITCZ%r1gC1 z=He#R%2FyQ#*MVaT@m|$cz1iU$$15diQY;0U`ly2Z0daC*AWLrL^3cKMz<|J!fDC| zs!qh)6Q5v0^ZqhHb9%lO&rdAJR3%bVw-#KRn_JT5+p~ih3(&zR$@npV zGPr$&g-10ylRNsW`U+3jb6V|w;tF6W(*1l^A=CwpmJCu_I$CiZQ*6pGbNspn+?b{U z*b;#_*&Nk0Cs{;K%b*-30KGWUwrd0U2N(wHEmNNwtX4a@!)vuR@7G?M99bKggNL4Xd#(GCvZe<$f2o zXf>DVXkz@mJm(%ETGU&id#ej0Eky4?QTY*8QQGAGmUu;kUsyUWIpx08?T8-ItH0U6 z>v{;M>=jI$zN;T|OlL{IB?#EK3{IJ^VMU$Fiom(bw?}29>UPY=%=Mzl)FR2}Gn#27 z3T+|2oD_Lgyxfg1A_(BUGkt51osLtF-TIXy)9^PR_ZeDs%o*!;PvT8- z4Y5bZG#asUe6j?MqOT~yD;S5*R&dl<1;H$cYrCYhi5$dscUkFMI0=*6MnLfph~1~l zd=sldX_tHte$xEN`f_}p#)}+Gb~m@+ACGURv?}eti@RS|i=8>vSKyU|?i)J3x4F$XG`@s_9_#p0yCm^5G5dCoGam3EKOjYvHmXcw7;?4wP zrNg^fBTl*k@e6idhV7Rc(2ON>DBz`ajE@pFjyBPJk5(X}n%@H8hj!*-uALx)$TFUe zE$0semK8WT3z=Mmc76XfHL2*>Xm&B*;lHP5-=_)$i_w=bod=0_qc63dQkCb#Gn@`{ z@Ha^)f>t=Zi2AaWS_qlqz~s2>*c-{GguP~bOob+Kc)AVFR0Cxac?}oCWRR9q?byQ( ze?gDf*=>D@nsXRpPd5>Bc!(SyqgBQ`qOwZcwXVs7Gr{11POEXfMsps?rz$ypW;?-d z%?5ne2+a|FuK|1ke%GPNCw8nf#B^AOWE~28n~x{lGnOc3zs|N3MS)R9MG+_dh|4C+ zHhC;sc9_*K&kh2-mIov!?4Nfa%H^Z!qdViXX%;S$+#urw#LR_Q#=yx?l|V9$ZV28g zacJnEzTr42s9eC9o#5hFO5kJlI=q#ek27M{o*l21@*bC<^cEikY&U5#zk4J#0S`57yZY zUr~#}TY<(<40-iyK17)Ll5Y0lkH0jAmOoqkK;({3W?LKcM^S;2V9f2T=6BH27u%?1e2Kb<{cZOF#CU9iQ(K6R#PCnTW}SGqJ!n$e z0Ur9FR=p`qdtCQ4T;1jR1W+82O)iGfQHy&h!@1pEG)Ia@CkWlWrdxEBLq`8GPZfDm z*@V@Z3>56hE@csc&f&e=33AfM9Rj6PyIkaK)ya5$y-h~&z7{s8`vLIF88m0UjuUqb zTuf{xazmQfOxS8u+qVMbd z>%y~>=vQcgtA@cF15oNJpW$~&BF9ey?(QxreOLY^f7Vcqp|@48ZmDRMeuMb= zvzl7P$RlU|ATpMmIKbop{oA_aEM<3H2qKHSC5Y=Xtnp}we3(%7IA^oew9^y*1j(6K ztT2CeNuxPfw)m2j>Gw2M?O0p7qp8<#Zmi=mYb+o`6c~zc??a(`rD#7XTHv&0x_8oO zzI!dluiBR#BM(dK@6NX>1Ee*fAHMC@J(Ho(y#ziwUc3}d9-Ue*0O@T{n#of7HJ$SR z7N>*{bo!3jL}`TWn@=r*7t)WAgJ9#0@s+`M345_5rA@zZ@Q&xZ;NL0{-F^%$kSYS( zxJ#PTu(qP=wK4Y1@MQ?P|8eaIJ=>rzTHVpY4D3YlD_ljj zks~~UXk(uzl5NT_3i+YZ&It>3uymv^G?OXlEr2uGwCx|#ZB*Kn9Z?1&a*H|PT?H3c z6b#wFLqt_B^~x)XPL3B&)LkaaI+C8oI>5~x5jYAO2#i`4>sz9p%4v&Yb}5yE>$Gp( z?nJGm+)xQub?cxJV&nL>q0&;C((l5QD2}Y-{b2Mhe|Hq8a_YZU*C`#E(s)W@((E+Z z`{4P-c@d(-v8I(D3T&9fayl|%@CeG`zx`l--}N=gqd^?hS|%QPt#_^LeaJsn3MhsH zbcGR`O24Vk6X?h&NSy4ZA*9dC$S1;6zI`_I6SZWvgs-!VCUXtE|st)*n5aj`+d2IHj*nnIF;XfsdhB=SZRW zMJxWd40DQgV121Yp1bbKKRG$BfG&3d1L6FU#5+V0X{CNK!7J;^r$ej)xh){ADj29Rw%We_u%K5)fx<1S zochY~)!!jt+uu}X3--FQU;j3?knz>qvPb>`5sdNiRqY;Z$qing(0dd3M}V;SST`iB ziyUWoWK>Kxb|2Fxh;GlM_s9RyGHDx}VAe)W;eY6Mg)kqK6cvIdrcg>gfyfg96G8#I!-Hs4yZc1Px@upc3GfS#7%4M5aoZ2~r;Wx_y4eT0<%&Bm-sWC+oCxKt{fz>QJSGy!i;*p4say=gS}QVA#W z;f7o+ETu9&HioE5dHSc@Wh)>5cwb*OhYXu9NIT;nYOTwi>C-0nLYXNoMuB&tKLoh18M^3y8kJJA zgH*7Qr}RWu^#7RNi;sRLb)?8v#2(z4JXiF`sTEuBV;y3+m21v$D`ds2qbe1tf5 zrT6oHJNnb7)xFiZ$C{cuy9K!54TdoOG##CDS`6>i)B$$(^gr#;HONfKbK#AE*l%Y`BqR1LHeQI5vAKzeh|}c44mMfC)H*V=@!YCq*tV*|Z{fiP{d2YZ$%7 zD)G6ZRDx8me2jGt%(D=jsoss~$$N*8q0fNng{L{Mc1Vg6826_=k=PS)@I8ykRkB$7 zZza!vclfFQZt91?LyRu^yv|HTYzKA$%*Lo?Tj|AzpeVm59v_Ff#T^QKL`ki{3wfKA z{8YFKhf+EUTpY%Zjj-R0(E1!+OAUc`?Z*j}peT!erAWhkTr7lHZb!0RlRz?PIJs92 zR79Te>v=W?`$_ca_oL$dJqM-#W7+c`p8V8Vs>UKy{U6KT-cSAM=v9OA>Q%+BfC<)G zWfGbmArc3I{cGfqXaCKddJ;zSaC8$T+f@cqpG5torMES z$*1^*I{v2aer+7RZ>7Pzm;IpqO@pc!IGk_*-L*c+sprLZ#9xmT)!%wgWOSTzKxL!jOb+;$$6TMF$98;BGXFFkS$7X38u^?Y z%H9L84V9e!;uvzBipGKM2lFfOZ4dp~bs&5&t6HDe}lQ{=S>1l7SSMgs!gW7t;HhSI2RM4{=3 z38yd1E8!B@B$mZ_f8HBWcC9=%%A7@S8T@<{)JlH=a3V{cX}Lo4D+0SMg(dGBq-Uow~L<2S8)=h7UZtf@$^Q9 z!PzQMZ@WO&z9-M&n#X88E5-F(sFQG_UYVakB&ZYRW<%;J0@M^}ha+1j;j4)TL>^ji z;xCbX0N`QCDbasQ#|i}Extb9_-JUN?W54J?9HefdsrS2mfBXSgc+ zH*z{?4lTXsMxMS&Zb2r~)G|V_c)+g^uU^sX+ zdxe$5WqiWF78u==^n8Q}Pk2t31rFU-#~$74)Nagl2X5*25KhGJQX^yV1$k5w{CirC z^?l29?Ncmfax)$QPBbDtrz@Tiz_$fW!I8xhN~VN!&Av@lIeX~ohfnV$Ls{Y#W4#U9 z19M@|*;``tpfFjUA`!@Iqnk_`V;yqYG52~yW&wZXqh)?Y0@MX zm@7?qrM-nEdW|Z2{(X}>_e>W2b^V@DF0DoCZ=qizZ94w#0xSNpl7Wt2q9tg>!--_;DN5a69HC;(?N4q$K#?#8Uy(mBM89VUhyTwf;)z z6Zi;+z=Us>vvzkg-KR#?eRq}G=R+u|>Z ztq!klf?z%{_2{MqTA`K{s0u5pBJWwbw~{~HG;dc~ht|cGisq;0G4V_Ew;}qM^@Yx7 z&Z5y=Fn;liw8TLNdno`%kld?hq_W`CK(!#B=JYJm$Ic}1F4D4#o^3wZEDCGxnU)fIn$Wns_<#T@%QLl2*UhAfH2f{^$z}c5FT1P1 za<2ftFfpS)$Q4k}kbr+pgVaorCNGm^B*nG9Q!^lq`wL+LyNu@RO>cNoz}!IQvkR*E z1@~qEd*U&OT+JaeK$hhIy z$58aH)xJe&00F@BiJ=ROb@C>hf1)=~MhF;(PMa)UJmF4LrQyN9)Jj84)1CBAfw)fP z_W5jS7^&ePW8$sh?ckO0NO5}S1P>;YgJp*OHsb$g` zwPxyNY7d7=noEPUivFleuDt5sXGHFBMAggjvG|{@bNtKi7UVuSO}~ug?Ld$+$p0}G zO-QBhr_*ZthE6!Up}uXk%Gw5Ngh;V5m&wY3<-lve+9^=#G_5HqB~G4qKJq_KluOoG zFxuTuU!^uN`_MpAFU=zeQW4kn?q0gTgI?z3^5%y$-Yq z=V%dZPV0&`@OJhQ;WTK3bJ3b`|KAqu<<+yofBeU3BnnzMw*;Q&myoo;5Q6J*nl&wq z=!1%9zjP>fvV&Qu#{krEmj8IPP-zImLK*ym|rWxQLBzAsRtT4=XIvA=B2FScd* z9}(Nl-XA`TymhaoJAP+D!F*EZU}>kc!0f!$I^imE;FLab+8uq54ac>uTYdj!(~3=_ zD(BzxzO>k(*uk*bxn0=8fnyikvf2y_FG)&)6THm(aQ7Ei-@V`6t&ecS39aK2Xp9r=ZGz*UAIcpsC=ea@B zKng4Bf$6F8UU;iWbWXCx{YBd~EQz|Ax`AR>MNOParNrV)$Zdmz!jX);f?U8yiExio z0ZCpBwZd=;9edqQq!seyYkJPLcoIwPlBsp2rA`81eHlzXs|(hIwA=}GxceFC2?g{8 z&ETDha{HRxhq<#76##&o#StLt^kz$QTb;ZEyQ0_K%YFMchu7$VggJ;M>ctj0D|-^q z*&i+}+ynaCIwJA#_uEDQ73(T=+KpS-OPb0?@494i*V$F%9ui5mS~)+z7>vr5;b+-I zka>8vUhFHtSp?6r7?wPwWUB_cO-fg>M=;?}r_+WKFolI19pF4tN~%Awg@h%vl)k$R zn96ihe+&TYc>tbg!2gUba0_-5@BeD$t()DFZtPF_5G~1CUs8Kg{Y*$G>S9=H1Uhv= z3!>u__6Ijmq?jLwcRlmNV>xNQeNl)D`@biz6)OwN9W_MGM6V2li%6iKpQpVRxXU8N zfdO$Q)KY;REu`LY#!)qOTL`sv-~ukvNqCh4v2GU(y_GZZGHBkLqIn0fJ9X$wN_NEp zB0+a+;WGR^XR?e~PKh)S9Kj7LbOG6Ii%+ARtHS16Gs}+A*Om%bqbN!xA|95_MRu)$ z$z4rM5}E-$mV9ZVR9nD4^ouWKBq@+kP^p~u&ImucC7E=+te zmId4kby@IHd8hqj8XtDHkm>PRN;378yE~E2k;x~Gq!0M+d~%>@CqDo-py z)Q%P$nMVu+Zo!br60F+VlWorTiJbbI%;`BWH znULdC&+JeU^z!r%GlB4i#hY(aGr!=e3eYXAPzKV}6=&^j>CKT$%UsrPQt7G0xsBj< zvTdk%EQ%D^B}q(4SDB93NFpngAF$DcE@ zr*`#%cuF0Fj`nu#&)t;_UqqD9HVApl9UFK*6pLIvtNbSq)QS!%6Ddyg>4NHb92Y4S z&z%r6A%{vZ2;k(ivQ@FK3h2aS>dv(_1kj)Fd=pg|)d-q@(%SmZS^)FD3EcdWEg9&R z6H;4JK)cQ{68V9p9lGWp&-+ua2(#Z!d;~LdFtwxqr;sA5W=Xy| zvVr*YP^qZuPFZvjVggDcK1U}o7u=X#jtTrGg55{zD}i@DQO7{k335lK#@$$Jm|w&e zAZlPYYXA*o!Wabkq+xywx>;d9ozA%uOU*1UbW*3~E?$n`L4bOyO^n-&n`Wp$9`%ET zwlF?WkXt9rv1mE(2V&BGRc<&!y8w(&@&sTpZ;08<{uXli_kAp=rQK-1>glS}drV&> z4p3ACP!<;>o@FH%ZbowtE33aNPG{bWJ_i1rJDbaX8oAuVM;dUt-L*X5Z8{Il2*}2H zh{ofT>k@=P%-dy?txjU02wf$Ws#=ocBnl)PPr7vU7f35n^v9Q!|-vVsOom?s)Tfj(GP1}rWLft^FyRQVk3=E&iAIn^oOmHe+bKcikeA!rT zDd9{$b8-Ke>5JV@w2O!h!VLLqlocRuq?jYLld_hIZXH;gFc_E7vMVekpq%*3i(JFJ z8QDb+rMuiF^#WurD=m(HFL5j{BXW|4M=!a5Lbgz!8YDnlvpRl-nvnjuvi)U)gp@M(SZr-25tN4kN-dn-1XSyWad-1JG^YpDV#hqJvNhS0B%w$U8bcmk$rzw^q1QY_Ls!sQyi)2|98_%jE3$CSAO_6OKa*zty4SeLC^- zh+e_rI%ptC01uKVsYLf_dXw=4DV{v#{ht3u>S{K<%)PS+o?)!%9UadYJ_9qj@C>ab zyVM;WLTt#X19^qC4i94dN5BtIs9g6V;z#4hw?x&w;48w7=;n^BCZtGV^U65J)MxIj zg?ds7+l&Pt9Q}jiFR#w8?gb03L5ChoUbXg)8dHsM129My?nrt1cGn`+pd(T$2ivkx zTF>=sYE*>+%1no{!?8uXY{EQf4tz$0K!rF>3NU2;#f<)ubVb7*yI=<|;USg4 zi60x{W=e25923QAs+fW-<5#aW}JDk+SNA@*$GNIg2cH~!c1 z{#(=y(}DIF%B5D|lasxLkuf~-0F&+LYE#sBBu&Yr1u>?cz87G<&gbVSj$ za^@PG5^LO}+4k^0W2_-r0J&$x)Fwr~LCnh4Dhs1}^GH** zDW)3BZRF*yFW<~R%blU6>Ame(DNeAY^YD|w@MD3LW)ZKX*KerjGB!|qw7!|ZZWR|D z_A3E1i`-_5&qT=50yHq1#exet;MaWqta3VZATtDSJe;@Y(Px)8ZF$ttvaO+8UdT;w zFEJFByw3fpt2x&j*Z?p~jxOnMc2|eG|L~Gp^Ki8>9hMgoWWbhu<31HLqJ9aSjgzBN z<8U;%8_4Lll7BfVQZ-aMe}+ayHEA(N0AfP@q=i;Yy5c-Sq5=~LM=_NM zze$MuyLS3dWT>0FN)PaX<(WsAcvnLnSApqDoInN4m$_aWd zzb!z2_HzmpF_&t8HiZw6%DZ|Z4iYRN7O5g!cZm3H?E7y7dYx(KIZw;4DdqsR@fat~ z(llf5c0B#&qE^YpUE`q$+^oG{Kp-e)Uvs7wEOh7FczBVuk0DGUmrK($e^nN0@oB+_ zgY&naG;t%TqBisM;XjZ5^W=HHb^qNb4;+E-HNWSHZ=CyGY5ig3<*BBB88n^!P^uWk z_bL+w3$7y+9S6D_3@S8k=jt&EsSTo`RGaqB$2tjxq)gM@*e+@)59vKbFN;E=5&%4; zRK#kB(Td8TJx@Ar)08=rI-flIOm{#7?ar|3HVnr9njMAKQ3YlUDt}aa2>SJETQ}Ka z1>si5_2#JlJmwhEAPFzJelldAQ)up4x$J&oa@rbiBnUs3uF%g;Sl5+pqdX?lz+$v- z!B*iVw#c-W(!eN=knnrD8sXT%W?{;@PWx%}r;vI6ka`z27faUw;nR-q-k(S-*DX8#wP#|xw*GAHa&G`PI| z+o`Xx(^;2Cz3g524QBUg7{M22fugt<@iYTrT{arPZXDtu(inU;wiszhkkBs4&H^mt z;PC@8hR?3C8U2*17x%PQW(1>RPPrUCFW1b;^ExsykK>0kQKG(PN8Y+ zz-R)R+%w6bB~z!R+CyjZx*qPo!Fu!6kVX;+#`zVrJ>$s(Qw3^dK8$4e_ft)cj(whI zbOe~DRVERKwKUucXHxn1f8jh5ec*H$x}>D!sU3+!W=)k+=5(flpp%nzUTPs$^Es5^ zd_`p=^v89u^n)?c64JjDX`~kOw1%y-NICdjqqy?>Xo-1wLo*GtJRDuI?ir#X&BuoH@o2jf?oInF^xwXlL{utrNS<=I_e8kcWJzhKABo}& z(!%lv;Hs19b18T9P{$*4gM{ySC;d8E?%>Ga3tFoqwVtOOIaBJWQSm&1Yki(udt)CD z3;*f}JK|@hvs6R>iYC?WCCyctvzS7_{q}lIzwF~Ag6D9;))tydBu?i58xc?~+jKAf z2nWezh?qSBu76Fnr{h{R7>vt!>2w(trXR8y9~6tol4a7Wn(R8%oOpZ=^2)O%ct>oe zJ`(7-(H?Ou{bBWAc5EGTce-}9UcOPbp5{RS(@u$9->nY}=&sk+N^m}!$G3;h$w3kB z{%7BO7X7e4Iru`?*tnyc>I|Oyi5z_$5*?U+qapHu6@m_(5qTG9^5}R+>*Qw7n>;AD z_s_*|0iz5A>eHtoljJrrcT8kqU7;tT4Dy1U%9tZpz^7Fb=KS>QWO9i8nGae5Y4Nu) zfJVZPZ#HJ;Q#f-#UYjuAq@A!t@)f13$-oDr1F`{W?ojf0Inw5Jnoi{frRTYe8w<{? zFzjgb(pMMG&9g8(uB`rrr>q}l_& z)AjQiYBT4U~Q`@i{e%V9ya_*LaV8f83j2 zHfdag%r@O6hX={D!)^Cfn|NZwAJ@Vc`V(Mv;^ZIKf=pL7oQa-^nyDM8ulbPELByw# z=r3B+?ff+uQjypO!iN%fne)S_5KG}{Z@9NT<3}JMxo8@oKSj&S=;Kpd$M~~?qAd$5 zST+6oV}lWFhtNxf#VkC%;NJ=>5|?a-&7Ryg>ky}{45q)_gJ7f7WrpQ6ZnMR`LHvGo z={)(_fhlsr%KhWF7g=GsKL~X*CtyjuGt6ySi#E0$u`Et6GGNz!5o`R#Dg2`WlczrjBT< zgGF*}NMF>{E-D)tvBgnz7%O$mc+Ya{GgX7)qy@f2G1~u(wTx)hYk4GPK-!aTzc1-h7ayy>^BQzU zu0*UYgcsFrf2RNy9bL;wLV$#Z(6zQ>o34mU;Syeu4SzhmBZ+Pcu`ff`cdCFJ9G~`O zkkKWb2L-_?^;lJUGhg|*y{6ZM*gxZ)tCmMJg`~ z`mG4lXR2pS;F1phf||}Dsq2o*oH7phApWwvFsnLZeZTFR5)Kj<8X%5w;r_|xDrKrj zsR#PupH&un{}g;>d=>O~{n#0hvy%7rmHjh=QFA8kZt%vKx8^}4JQST$S<;ggvMki1 z_`+E-s*CuF`17^?4Rp3gV#R&Xr8Ni9#oqcIiNye)>~t(LyE|DF?_vPR zsyuA5iaP6g5-+k*`nrQz8vGtf;$v6UHw}alAlZ|~oIQh?N^UG+)Zf&9TT*`wS#bnv zwzp_BG$8dli%FXhUiJ#Uuge|Y6AI#6p2i=@bN+FXR>3OI>@DA3_#q9sa#8KxhDzK> zQ#`Seh`rrQh2^Q(8Dq_L_g$8Mkw0%yJ=_0@Y%spTiG{MaOLqX^qu6xqCmt4q6oS^1m>2RoucZYkC)7(LL>{ z&rq_A*_SVnSn-7W#-6ap0*|PkvGjuD*MyT9QQ`*p>?Gmw(_CG=iVIxTO@Y{P<>mrw z+L=2g++~ap7;NRP|JTm?kYw0*7};5_0`;?2>Ld^+v^YQZYj#e32HK{kXGivRj$X;IOQ4ElyL%|Iq*+K0|=z%8?H^J++VXBvQ zfQ_ybvCQA4;+kQ>pLM>wdJ?+*>Lz}=-z25U$5+gdQsfFOgcj1C1MSVvbgR3 zl3_XT?M^jXNsAodR|GDRfQi)bLI@xHB5(m* zubQnU(a6!*@3Kp2qjiFPZ+0LhA36ta@Xkcz_%G@^`oAIVSknnI!N_Lcsr`U*$=n{ht3LSn+lF1nYWudev`uoteFgRDC9zDxO#c^ND(ef{@W1<{Dr=v*A3wL4e9!tg+3OS% zNm|3@!anHxx~5IH)2BW~wD%WucF@WGYIIUREgpJR9#_N}ebMi)IVq__m2CIk&8-hM zOMI6?UwX2nu4hn%(1IursjqnanvPtau$^~pUCicK&H7mHgiP>DVGbH@g zR&g$L(3}2EGIODEF{7gyMdJPSJM;Ca$EC7WuI%?W5jVgkPbd!J@9nl9STIc;v$Gv+ zoId$@mWJVO8B|6#uC6%LXO4ap|KYouDsbX{z%^R1qozZvSz2m+WQM*+ISD7@USa<^ z2lF=OfcMh9&%SAq*{SejU$s=0loY1R*qd(K-@9>m9n6ZyG4*(8p^OY{u`9*+mcgY# zO#$1#5Ip2iT@mqMCYDZG)nCo0Z;o;=a(L5QnK_RP(R95w`pd2Z+}2*}iE!@k9wGeD zRBJpPM|-X`jV>)5REO{&Ug+htK9%*V`V0=n%9Dj#^nT`L_QA&+#PM1$6n@w}G(73v z$6{54{i(-YG|^pln^FH85a%k`6#d9^dwSd&lJXa$mn_!I&Yo<)a+ND|VeZChzA~Ne z9TldQ`X$c3ki#S#uSyx_yYbLc=N1}uh6KQhLAm$@a>K;-B?;98VnaU;UbIGi3$wdV zZyO~{=o;T;@PE~ehz4>e(pk2kb(d^+s{Q)jxG;_;wGk>}*7vC&)YEV$-tFl-0O8E| z&5LJD?9wPJ@l-Rl%ii)fURlWK;4Z3VB)4+Hcieb5P2#5XX4(gIuz^%t!mW>Jge;c4PlgGI5wmiGz51^AfwM@@ z5xpf6UH?Fc)RL3Y_NQ0weZ5;`^K4zKAg)5(KZPn=HmBTCA+fIKR?b~z8`+4vjHoaj z{6>0lv<&_3+8rN^vV?y0YNl=h-^;{vV)F+jq4BdqO1@%}kaSta5r?g9lL<>oXzt^7 zPF&p_8cPR68IB*?%0ImyK0teS9DAv=(L)7uInNa_A?x+aF3RKAOGZwqMicu;cx9d5 z+6$RLBFz_iYk!*`>^Yz^eq|)h{oDv-Vi{&-=Pu6=S4g4O{?{C$R}eQ<5;eqw9YX`= z#xsPX##yCLsWlCdda|);vgzR()XM^a#);C@n6ru%&HePZWOvnN`9}@Cr-mqo+MsdM6j_Z;<2c24l8IBk-s+$< zYwqz?M2gosN#lCCY7mm}@1cgwWP4oh6T2ab&gOI8XO-APPQ_-O85?_gMVg~!a!;+; z4P*4fK7*Ay!ZeyoWgtJ2;`GG7zMFOCa=PZSiFlnt&k2c-(YJ!@HXtsxH`1=1gxSG{ zkHBBn?Fgyh{&(alR8%T}Pdcf)>EcXD&)A%(ep2Y=iZ~Jz{C!mSFbfrd)uCM~%~G#b zQDQ*b{J(Sj^%@@J!~i-S?v&H1nFy^C90SC%I_HR+BkNss014-MGWR8O@eKeEkL$;2+-ri zU`&hACltukZctH5}B z^AUs;MhQ6Wwp=Mb1LgTpGqEy9*z59N8*w}3BwUwZRxars&;frD34PZr&38=}k9>r6 z{iaXS17U@aZgfbXrLYSoP}T7n_*hs@Vo|r>-rOx>nd8kX>wqUxUIp;Ryx$wgrB~7N zR`~wxxg5nrPVtBYmD#2BdQO5}1__H`Mr^FDbix0Gd4ep$+RZ{KRdOekD~b%{S|06ycGUVlVd_6*j56BBLe$<;1ZXzFjeJ8 zxvd>^lCi6Ifrc5qP{qTWeyN7;FKJEd-Ro;WmI{j7Z>L#qVQ+wxpub6W6tPaw%dD$| zb5=h>$cGYrrkdAbARH!)7?;@Ou(?oK$r=7fBiXFI-f5LF_4L)1yn96b^Oekb5jlV> zu>Mb%vOUaSq6If=>7`!5Ud|bD6Knfv{Midf{BE|y8VQ?00K)(w|6~C_9$!0tD|O$z zZ#UhA`vS|l=IE7pjS#kf-Eqzofu6rB%@~hj%J41A?$Jv@;lD%&5A(bCG(E=OX-F6b z0V>$H6Kv?B9s||!+gza*0<-9KpBY0Dw9Ak8D58kg32S9828N7*?IP%+zg*pJgs)k1 z{&n|h%w@;ojqPPR>@o(^P*d@pkg6G6^b346SwxAA20u2{9J>K%lO5j}hV~s}a;6pn zRi;=%&k&1VTqbU+Nn$AG+qD;OnqKYXwezr)b9=V&cy_=7(ufa9D?MjzN*tNcCLJ1e39^C zP1pNa=H~PSdx-scd#yRhAg~4d`MN0PgDW-Xc598iN)wfIRdq#$ntDaU0Nh7HP_ z6Qzmnm+c0RoAW3LB64Ie%~{i_gT+cV8o(renO#9kYZnhz>^rI`>SBH@v$LlXrzb>` z8?#%F_Eij0*Jtf8lf*=q!%V5vJ~N+OSu2Ccwewa%D5X6QX4-;y`OMeoh+22ay`R9T zPHcsix1>ptUb3Y;BXrwks9 z0hKl(ifVm3%Dq+NvhWDL$t#b`t=E?ES!=Ld6K?hgS-Y9(e<@~;u{ZQ{y5pUnsJWq% z7WLWH=mk!6rhHoy8mjZ>eetgH~1$z&CPZ&pwQ=Z8~Vs7u#ctap^C(K&K)8(tbK$(4>Or#@!^M*G6D9m#}txn0(HjuBGTTFEj}+2Y5_uF zs=nuYwc%~Z6^$Q^+AHqHh8tc{*ytrgMRRt$Za($ZPSZBWwi(x;ptp9ncUfG#XG4}V z*R_e~XJPsZdu0Jaa)N0l!KW44M+u4IpI{~S6?0{k5hxO1i*P<;uu3cQPS&zw$@qdt zH}$;^4{mLXGv|Vu!M4>=579~8FT62AGj0>E#$)$cXuO8)fYKvb%nG6J>9ba0rQ2~5 zU4|%mnxCgIL~5!Y zId$qI`=tY&??lAyVn9247HemrwPudOI(Gz`Oe5G>fmLuXId{5b-d=u&&#gen_VT+i zDsM046<$je{VbDvR~Xr34+@EnE-=lVV^s5|&vh{PQ=<||Py}L?q}q9TyT^sD35k@v zEsWISeZY{J1bO*4c>H{Id&a#L;~mrIPJ!c~>}Zlu*-}{Xv2M~zeq1Dk0TMGkX4x1M~d{wp8D=Gg-%BNJw{eh3gid zEfkWW=={_6X`CbILWWsBUF*YmM$sIXGvq+io3xyCuT2(n>Bdkv#w;kjqaG$q^N7*% z55)PCxcmnKx!970kzik z@Eb2RWT3QJ8GX7dxmJZ|ux#+A7bR1-nv(2z0D=5Fe53+hkn$366j(L~)>V1V_LP6c zHuQhRHvF=VydT+fi%;uaslJfhgYV9nS`HCn<5UZC5 z7t|$0=gM%q$ATiz^XuRHhTHJR5c0$l;|;%bj#jKwHN)@`L*j;hjLg!m)%cpw%T#b) zXJUCFKKu_(jW!!+s(rM)hk}@T2KUR_?DgifM-OV6p!*M>0tS%FH>sn|Mqjm#yqj9& zHSTUJWwCSd`4lN)cdvLObG-g}z=4OQ8peG_#|oTLPoIF|U(UatNhmUzQ%=ja&Y;WTSEHYA|d()JLHf;l!xRfWM`Md}mJ29+=x^VM%U5oSKldEM!9PPd z{Dj!9X6nxjS(nT3IUlCZ2ioq$`L`*q=MhcVOu>71FW)j#N&I&~;m+zSS&B9mVD5F6 ze;kGyQeOGrYmu=KUdr%+?}`ucnIFbv<;e+kDU;{e&EZjkW`8{Gf>&kbj4yV%ke1-m zeO28#?I`nvAaGkbK&reY*FE7VL&-F0`1s>23xw*HA;ep?S`qDy4-2uK*Ps4ihC%a9A>R7?5xNggL8nv+J`@8dTKB{u(!i@M9u>g zGLvjY5lZAzB5>LX7eR2~{r?qL0GP5SY!cW^sgaNz2uu@|k~Q^jMkXRkvrUzE_(jHU zAb{_E4j(XS46t72P>4-k&@em#fah%JBI~mN|CXM*opR*0`PhnxcGjMg0B{G8|GO3V z;j{mrI=Kx3`9Bh3WB>7IqW59@#(nFS@3ntNU+-9pIf3NY#YaUo^yJQXnBX=!^(@jP z-JZKy(Hy_^{c|~ZZ$?#&ntDg4S5?JDvRXz1aZ}_Fg-LZE}|M+d=qx zSsZ+dukE%Sj29n6)t^gT2Ya}wce6H%s~S%}&@)Yy!d1K7w|2n{U^H3K7Z7o-aLQzf z{GKXmY?0e(X|*l}p4xJ>FjI)FRN3AR#|K&3!8fQ$TMISi5!FJljN!9M(zA~8YD|$I zp%+F@oXOm}TC#|}{gyT=weTN}WB$R{4n04-5zeZD4Vc_a=v@U29=j^Hu4bZ3SBF>FT23EjqTkKh>7aBmsxgO`~@budN^(AsynB6vkWmEoMtMYhY>Jz2gbVv z$IObcbrV)n;A!kBx|7n*A+kPZK_Czgrhu^^^Y=8xUe{vENqDJjvze^SPOOVARqo~i za8OcOB)ALwL737mb0?1!_;-wfTLp1&76V=R?1GN@Oda=>zW36Lw9$LrZ=u3Zb~%6l z=>x{~>{UM}KHD68erKD(F_Rd!Zv)_1Ee8`{c$hOO7&TS8+)JNZ6&UKYn6iJw z#erILr?Fuyn;Q-k4(=rn1gF;#qa7S-XN{u=`S?#BXkV_G?b(WzSM%p{6hU#rt6Ao6 zQh?t83p-!WeRYGZB>;T+uy=pm7Vt{p9Rt+<8PERw@&>S2j>IHnMvR=p5F*+979*9j znWG&XYuL~TqhYBK@H*U_4J=))8q@3QwIFypSnAj_)u#OGeR%$bsG7FM}!lW*YkdwpaXMGnUO zUAPrN!a1ENnZoxDyG*iAL3l5F2=dJRG6!U-jPnCgh|&9y&o5PO-R<(EF(&;H8T_!u zJe2ASE;UOY94^w^N+;g{DqLi!A^l2GRWz#D&^Z(^)tf=Ew_S!8ane+pS}}8NWznbK zPcv4W-5cUSDmrEx3-Ks-vl!IWo8`AJEYZStXN z#P=u@&fQjrn!+AE7%Zc!?+R|=ZMlNlD_UNf2}H`t-_zr$rh#~*#9bW2aLL_%3rj6@ znT6{=>jh`=|310`c`Ye~RhJ^o&#CVag%c&)dVQ_ZdG%$-BQxpwF>h0SXh{UUwo@9A zBjg6US~G-HL9k?^vg)+UCU>XUU0(9?N325lshRWLty%~#N{0^_2JvD7*b|Wtus28& z^8r$&jzp{J0Ab}np|k`H_1ZtNR+{Tz2G|zu(T_ExxDJBHxO1beX$(11osTDS;CSAT zoeVz=G46!Ik$`%mj04sE0Mq}|Vah?wSKmAF?zxR0`I2*Jxb&u4tOt)@lt393?M28nBAeXYzJ``7fpV~RNM@|v*ws*hCPHk^z; zl1a_Do^vWJo!319msdMiB+^;ZQnI57G)WJe)OpTDMsQam;edi!!uRm6+sg>eFa1m~ z{AVqI@9{O3x*n-q z@MV(JS)oxAJ9TAcc%LV$BCO+GjU|_w&Mh5!=BgyzfIPzL=928na_2WUSBh^{)}F>1 zWi5E}wLKH@?UB{A6(SyexbdNEP@ES@pg*u${|Kk6sV2!f(e;ar$x%@2rLm4Dh^RgC z=BCo^2(2ZaH`5@J#}g6Pw;2}bo9L#&*GQ9*EEWyCDi9{hmA6E*AAmDCgadhbM-P}v zO2MIM?Z}v#^Ly?~#&*}}dLFuokdaWE-c3r*Bpta@ddF!lr)6L_dU|ewrb77l+DFnW7*l*UJ{VxK(RU=B*7f4X6z|mO>(~e0YtbCf*YJ6f zIj^!LLRw$g71J@+Y<>q?iP3ts7xXk77RxalhxL!*jgIeg)cCOE0(M}475xXoH!`i_ zs!|0k9=~<`@x#8F8@EI^rxN;+99PNnyl<9IZ&-~jZ}F+M*74 zrm(;%??BVx)EF#XL$_Y(Ya^>Yh518W>-1v5dI4475v;AtYSS-+HRN2|C+mB?Io3Sn z6E=TnEp$szxE=X~q1bx%Y{52`co113AC8Vofqv=vMJ016M#~IR<%j!r>>Kny!ZDpW zG};fS@{S;_laselcB^rJdJjM7;Hj33^SVT|kznzZKjDaM@eqw23;*G5`=WU{D3;%C z)QYlA6NjW%(Cz95^6JA3(cQ_k5sI-`g4 zeepB_P%xV1t@v0Sv*&njejOWn5?Mk%&{*T3CGOje#)i%`*FLsPFs?9twadZfVTYLA(zRZz@RdK&T{yecW%G-}J4xJm`G$v0 zkBrOths{=sdzbF+v!%KH89MDp%bN{o0&};Iu`f*=a-6P;PF07j5;&oOSwWKpa+H@; zst=*|mgk26YyQxUwpu`Bmw3jHr3(vLNd#k7NRmtq-HxZSsMR6kdm{c4^7=ktsGL_4l z@u+c~n&GM&IhUX}mn8Mp1-wR=WfB7;EWGp*d8d6Sv~y^*fJo0&5<~H%e1Az9H%)6X zm9UVigVO#2DXIVly=5ru0RGEalyH*Jw$nXF(hZQR%qZBzvt2H=QWb1n#~*N z(TDRZ zSUJ!or(qYpi>;1e=DxGOg38*FYUM31YaJ)#uj&>9Rd_R$&J*gO(LgyuleYLw=tC@n zkxfO7ZV@+Rga-E%v8vOwCKlv*BH<^kTEFReA(~EzPKZ**UX|Oble(JGMIyCYkOC69 z{A?+{~co8O~0h6_2`|hwC|FtM7oMo6ibMN_XROP7RpIbXO3OS*XEvnYrThq-U+_ zhQe#I-lQXiGphYX8)B9DvB$P@Njq6;cj2)lWRxXXBQp4`K;*7~yY9alR7eX&z$diTN&5Eq4=#?4|FvN=J{`O5>FKkjRwen zhlY;EqSr=FTNR;{wit7+Mly9%9Nm$#^?^6js_MX78IDUfk4ckAuC7LXoMI?sb%H~> zPS{UHg=`hu1JzNiT8OXdOI3{+n*EcUCK2D)T0n?y-&P%9vrd$)`Mz7)J=R*RUXQV} zhQ0Ejb-|1O?y=!hTZ;Ju;4F1-=OuA;j&g9nG zfPOuL7Wck%?sRF`)G>+LmR)r1!j?A*aSm) z1zi!GIl6@w*Uzn}DIL7szP#BI{&CRpDJ#$rCA|W#n9t;MD@fo6qHgk~(z4eyv@3*q z^k99H;@DR6+RAf#hl zR1hnxo-R17-;CbVztEuHik}8rdYk?Zh~279R!-1^`zPOgFMlVx+A|9&L!1pJmV zzA}B_P47z9_9lP1Doh`Ii*Du3^|02%5ubIgq0swu#p7As?QOM4gd3ExZFzbElXP1& zUf+{6?;SJBeeP=;p-1N6xwd-sk0kalsM2bgNeMK=HU#+bQ*Dy(o(E?-ns1LtY4mP}e8W^sY5eV1g>QKec}@*?;ZWoI`1 z>J|wZK^Fy{k6k~rP;Z4LW5(y=nD=xB@$jw5m61K-S^iM#h3CU(oBCpjlWlyB$APQe ziPQwbDb~QY!u%w3(I$J-{6kz%AR0(jVo~}4E3o?s*1+BVM6r+0h`FLd2vFO;Mbg(GsgTggh zTT@IwaXuwqmomY5PWc9z9}!HE)jao@Ta@FLT)~?IX`zd^Tq~ zrtpCn$K}9tTz(&DSV0|SDQ1vVe8%U$b^BIN=(f6~U+5}acs_OZc-MydB$2r%62e6> zioL3hIkBZR&H78=K+yF){NREGf}nU#RSZJL_?Qby^p_^QK&aP5?sKB}u>tlO@%5e; zq~06|twv_fV<@&KEYc~qCpnbp3gDz$w$T;q_%KZ$gW=rk@6W_lzbc}>DHIgicMi#fCV}rl zvwKAg5nOLa+hTX2*M>0myc%XuU(Z!2-sxQFB%kVOaf)Qwf!=LH>}I=O@v8$@1!V z&d9WklAkqT2gY;asQcgwdzzsGbz)!ttYf9t_>1P&m~hEgs!}6i?)Z``m%wogU0^;_ z86FWvQOwgJ9woTU*eq1g-T=pT0E40GW;KIj@y}>lHQl;JKVo}ez?xC4Q-!=^aaw^LkCHC#LH%!^cCtPY+SpKo~ z;SOqgW}LFc#yR1vr&A-bUYv>JHIo=&r!B+DP{MgHkHu^F$8@B?Gkjdp?)DvNxAfT8 zaaAx~NQzXQ?lQwY@KaiFRWTPJ6$VwhG1aLmO-NFQ$b+lL;&uoMPabRWT_4=KV;*G( zGNN|8k{27V1Xay?O@{Tun4CO#bp~YbOM7;!HX+~aj(AM2?L|Sh^6rV1b{*jXPVjhp zLzZB|v-FW~L0qh?nMMP?`_Q|X)=a^ft%@mxKsuBT}q-tAx` z)L;P<^UaPh^v_+%iRNF?n8cUOpEiQIJo!W++=;FH$(6nzT=|15e?aBG$p-&)lCS_M zzuF3>FQW3-ekNSi3*|QhBjbOp%KanE&bhVn%6eD}RD#cslBpJ+?>^yNW&E?j4DaU89`=kQFJ@V^4upQ-4cxPFr zyMdUVj-NF7_INwf!LWjn8b&``&A+;X957+!$t#7Y>al|ga#&$j|60Z@QND)SS~7!$ zN+S*ADnKa!L>%W%BXy#@Je)VOrN7$bdpO4qiUub}9YX((Dv-jLsTmLefK*)M9QLD5 zbJ}d4Rf-*v#*!FGz>KK}QCFL!EubZqj)xK#5$gOV+m_XicR9G$4y>g$*%NAkchhd2 z$z~*JR`ADQxUmPKK5$)lxOfgi2nRawj`@J_iKE9HHeTw*GbXhQjPC3!44Z-H!>6!w z!tfYKo|%TK=X5%pXH-yY&l7fbH32QETsc~-`2-GIq=x^_hnf7axzh32yXOZN{@}v@ zZBPi@!h8U#!GgeF6iwyK*S-S(c4M~DU&dYYjWQP_qlSmxn<3;S^AHIaAAkr|cMMIB z7n-)%QWu968@we2!Os?j0$e7_Bmkh#z(^X!Nj2OtE0+4h#S{cD2F6b`Hi#0P17!0(+JJ-gaean`l| zGt_r)13m6Y8z@D3GqZD~OuLU*pi*^Bjlb;OTDD+1$LhPyT__1?y<<&gGv48YH?SBY zz1T>^F~W!c5bhTWC}tPVcKiBm*fp4hnOF+;EKNg8>}r{YZK06&%+D$jq1I`*q$c zhr~C03RV<8>rY%hQOUJFns2Fkx98F=*-e!dKYLeB5UG5Db7Ufu9oT^9RJ_M)@X_G) z5fiMQNBpK1NoV@^Z)csWf|f+#($xKI?mYKgcmq zbFTEAAcsEX;nNFf2-Afg}v`Kf+TO$}2fK=LY+Fvtim z2fa>I@xqbja!8Qoh1&JvCZ3OLow`-bV+cn0tjMjcN!#eD$|ERK_|HH zbxnh?D7>@cN-X+IG&IAVEua`RZ-Ou{i3uvCw(a7rvex4dFV`@-nAI%{w>aHzIOw9(YA_nuE6NI%$~G*NN?0w>z08}?ifFHkjc zbUuJL-O=h0hF6Q?{W{S&UD0LWvr(=Lfc`e)#=Oiv8R6J{E63?1`e1L#F>|Z^Ha+$S znEwFt{|U@7As*$t@t@73weMOI4B0}4&)~gq8fACqcMp+|UZHN@#_cnR9MJN{p+SdM zC1sF&F^tI<^o*!e%ts@oR%pW?sU1={)Y7DdlpGy2(sU8SsAmJn>1riE}bB%9C zm--`xv8ibc24yvi^E4%{6l6KrOBbBR^*|()o(-0I96@ zy$vO7*EHl$XKh($Qrc?B?Xk=|tyf&^YDnN1mBitBYgMLxgV^)%+jEkta3x|iWB9z) z90I^P8X0Z1EU*PC!!ON|$^e3%cv`-ID;_{(W^R4%Ya~i+=?$7C>_vl3SP7SS>Olje(>E7xcmRbuAmS>^1ishtMK2qEC0Hs zWGLRbLcT=jt~E)U{r5RHdq*Fep7qKA64#NgIUc|+&ok>n3 zb*vSonlN>WYPW$=&y>r}?<6`6Vax>=nQew`o2i>j!3Ja(xg7wYyH3%@n#WJ8D3?jp zIYjW8JQMZo(F&@emi`@ctzkd9ywqaewY(?{MVdDDfXW^db;+wu>8%GJH`CfSXITE9)H0QL>qq=$zBA~N|k?X4KILUg~`w?=OP5&{71BM(zC74j(1Yf z({+v+ZytufL)^Mp<~Ln)(MehpQYl}?mJlP-Xbc7)D)9O`c*f&TqW+SugSxJ7;kzkQrL+u_4JW z)$ERNwRl@I?G1adthelTh{W2bas<`O!=ZCG%lvv~WB6AnI><6F7pHJY97(cTtcd73 z`F&?XRb(f!>{V?)C*qgMT!^t2KY6IBw0O8=ByEjt+FAV?@yJ*YHyz~JMB^FLg(5}L zj``Bvr9CIa?KXy2qU>iR?LA@gCRHt)_jt&@0<_jNZrHRA%Rqd@@qPu3hwSnbG8>OREf)4 z-^+1!;*N++XuqIeHV#BTmeijK)8ZHue6ZWemcUNrfLFgEQhp{sZ3@vMuDo}DMuwePmOZuobJ@mtPq10E34C2v7WXYZZow}hoA}3w$aJ#1AXIOYLTS-6O*ptl)!~nxnRYVHu^wv(khL4>&#;@QW1$OS9#NRXJ z!tc$L6ex}4ER+;MS8lNSn!pyFWOKTCQly~p_^jh=PY9)Y1;}|!F?CbE4(yM$Ixl=kHpJI%C4U71r6wkOPMxnYZ9n2IAppC@^n^BLJCy^3BA)T5H|g`; z902|n52!LGbq^JDYf*AR%FD4YQnl_KLM=lWyy^M6Z?+hEd80JvvSG(uNzqy1_x2(| zdZc9a0q=Kw-gyHUsty;s*K@S@YnCZ3Ao*$2Iq%$8E?lZZqW&#%w!Qv8^oL&nJ&&e% zSF$Gytqb(XONR{Z$oij7xiC&d3aZ@&$h{|f@i<(?`#FHk%c1q&R)s)8Yq9C_(UL6i z*j@ySL>Ka|QMjwuul|G;5`L5;yS}-xgUT#2$)c4k_I#mRJ2TkA#T6K>WS!?T%kg9b z4XpMGTKCJ)^)vZOTpROQt0Si7N~T%3bsuL>{3*L*({S==aQ}K!I(XKL&nK^5Z8RM%}niY%5Pd6L* z``~xQ%s8%heL%e^x>=RggX@dxq#1%!uWwQNbp(^#ZhO>CA+A3={`ym&$4`LD~7kJdoEup46np6 zOcfO;^upLl73`ONL!}X@Ah!))xGX9BYbFo3p2z9Zz`h>#pCp_+4+Gq z34c(;?|a@>PQlbZr7LWL9?QI>7DZ7-ghmb}SJ`xy5m)zZPF5V;kA?8E#bAB5BK)*f zGCEHoI>%L~*wa2G~z>jBIH>>KAydXasNGWpsOo?0HVozBK5NvrXrts29c-W;=5! ztLzKLz6cwNK=Ww;G5lezK3d7fr;Y8Z&p4G(bShWqlF$^)XBP|T$5up zt-E2D>|Q-BovK9Gm1}_=4EU$eJ5?evS1*P{7FriHY)vH3JI*Ipgt1GTd( zWue4GZWVt0oNE*OSae|QWz(X8Q!_TGXx}bfL^6P$l&P11DIEZ39=afh5yNtC9v$mH5fjAjBb^<&N=cj};OsAWxeJ}stsOTGNX8FuBw(*&i0S>0wZ43=*@Mw64*U^A2rfE9;)&v4;13E!*E7RS9Wj^x$9h(VKhC`{`y zxuA!XOHDytQjc9q468Thr)$GWU|aQOzArRVo5w-ZYBy}RofTrmEvgsN$pfiwmFyY@8)vFBogIDxSO&r_+@HkT8&$(X0nNs$E7MF;>X#WOTN7fjq z%*#}gn1k6LngxPLtMe|JvFku^+n^_N>Ao?K(Qq zdKuhEIfX2Yc9Q@vnA{gOZ8otlh(6{@#~9J3ii zS@RqeinJb7c@6qW@868GnnnNQxIaPj|LQo1V*ZlxEp+{QV*lE>Z@f#XL--4$)+WZ0 zl+M1h!NpeKEBg)U>vJ%)qjV0JL`N>V8U3mAqpVePd^E{By4ksYf)B$?#Cb1rD0sG> zqcP)Nob!rWZO^~2muv}5LVlfFfXn^q0iW}$LSN#s0*IYV)G+PBtodo(%LarLta0xG z*@gZ{V-ctq-hhitry_ZQ0!K8V${B3c%jR@&P-tVZHw#LJ&L~GkUTun~s!_-G(_WEj zdIpHEgx~HLu<4iSQn`|Y{!tilcv&7`?od*KqWpDhLeVBAN;PXH_Y}p|in5(tPH8Or zJ-q1_=*jbgWIbIYnCe?Jc>%lm@IONCz=xA6B4VV}DYC}Iw*Am^)79i<$$=o7fp2O2 z>JtK3FpIm1M@Tq(=K`&pR_g0=!5ayQAot`@L06Y5#vG|7rYLlelt59L7Vof!QZ4~K z>V?F~PjLybXU&BE6QToN83^K#x6#KX9DL#YxbnGxVoYWV4t%KOs~<7>Qb`@Wjw@s0 z+p<1c%zXS4j=p1orA)(m7yG*lXa3tGMS&(ODBeN~G#s6SVG+i}uHOazT7E8eVxu8g zeTFS-_AtHGzMSQ+wc9l(k%`~2JiBQM$0Q@q{kNF;n{#Fe`Ie<_HW z^yaDEEfT+g$uH|+x!5W7p90HG-nZeyWzL6NFG&Vf24qjq*`PK!W+9N5?S0kkNbs6& zsQPT%dd~89iE!=OnOf<5JhpC`v5#{-j2nEt_81hxgN+K|ZT|-~6uvL7mN(~^Y-X{$ zeP09nz`ab62ACn^nDGTowVKDiF+fEf?zia#;%m-$jNQc!*lG>f`Bq*iob!sEsVPy6 zJI@x4K*V-mw1YI9)e$U#SoWBdR(m(oyVu{uPZgGH{-a(naWBv!lN%XHIZc#yfQT+O z@bha$V?ye&u3FmILGVh{YB~7hXz4#Wcj5=<{@XiOe0)dDpS1w~jN%_0{R4{s$45j= zSOZ+m{8arK_doO>eD|^^ub97L=}tM-w_dPfP3)KF|JMGSR>PK~@8;_#^GcEU&fusp zBGnKk&^>g8VXQ-n*p5+A$s{BTn!k6v{1g)SsL1l~xU15ZX}>FIv6P-F4Og;Jhgj+^ zH<2oms7j{5AF|BEPmbd0#|MzVMuy&g!yF`N1jB18l1hdOxd62#%yq;t^-MIR&TVHZ z))Mi#V-Fpi!Xfckv?Sy&Zl=+@m8{(;d-ar@Y6s3{5sqj8A8S4+!Y@{e`hrtVByeAI zz0Wzu4>kaS#89pEFU?ywymhfjI&sA=**uaHu=@HFLA#`0R_2>7LM-x}v`z7n_)b#; zWPNb5i&AH=ewQzdiL6*oM@oSKN3_iCs>M8;MBu722(pSiH}qj zd%I&y$IbelAwK)(rv}ZwGDz9o$j?vk(cJpe@L%=+SC_u>k1q9H_bp+`G5uaojxD{KkzLsy=MH7I>US=#b=?y~>0Z4W|(B%ky_1;qF;WoM8Hk+!% z=LGkmdj*!!055+HPwu;A$U-+|^?{6ls&ZZiQDeo7-)n}CV#UtG_}Uv}J?5Yzg?ZNG z8BfE_FU^$KWI{FSeDL)$l05s$I~7oG1ey4aYhtUF`=egbWVTp9Ubd z?nzmGbrX-SSqUwFaoft*k14`K$3m>WC-hOe)VP1fLvF`(*@|Q$rn8sX^-a?am=g z*uyKNV1B85I%KJ?i?P70d;el9LCOGu@opr<)D##rfcaBI)R$E3@}7n!`F4qUUdPgJ zgziF)>^utTr~UI#Xn;wl9im7YL*js=pY!7!lgJD16E|J7gCU|T5}IOrfR>F07HeN% z=lo@VZ^RRit>vx9s5UB7qYl4JU^H*n&=W37*Hn(vd3+5$j%iux(uBrX(yF)8^QlJ_ z@n(Fo^)Xb^^<1;wsdU(+IiB|6n~z7S8lhsn|Y5qF3bNNL!N6%jX0gROD&0ijN#;-oej& z`o)Shm2M4*r`O|o%zR9gK-%>xm$kj|K+o%Ey6At2zPYKcGiuL?PdVy2*R-`B_wrB8XPk4TF9u9Gxn~ zs*O9ueLq@p1(dR+Oa3osPOVVgMYxxwibJsD*`0jU_P&F1?2!#N0eMMgZQA+LI_4nRKe6~nbIXR*RB3pTjwH-{wSUlV3!5ExE(9ZNFIClR z@}EXlByzYP)Sg~f%7l@LgmhSi7OARJEheGZtO7*il)!o3P z#w{@8jM2mNiXM=SdRjiumA_Jd+d7W5X|4zS6FD+Xqb3bdI%v8OHL-PYOwi-xi?{4I z!SIhjsEK9NhgxNB6=P8KxT_4orrJ7pl*C+$N2~<@xH>oMcZnO+-xN;hL(Zkos~$XTgblYh&qVXXN45sr|G$c@7Ixd1r2D zmbBMF!A8eE+^G4Q&xAaLeCywgsBoRey;P{|wlf!qlxw_^*c`|~a%npBE^%;t_+gXo zHlYV5tX(~y)O$UYvb5%Y9cj|gu+tzU4<@&_jt%iw;!6e2BT9FGEEUri6OC(LqZkQb zUfcNWf^&RaHO9JSe(trMI1wYi4`^|^*?)4{{{T*l`oK50{`JCZ_YSRoFXK3|RqiOio z9rJ%BDwnh;&wKx&Jh~U`GDwi&XJy+!@j2{3%H5{1PS$fCT%wO?Qc)Y@HPniMs0{Wu z{tS}n^AsanBu3wrB`w3Ji*@fm>MJFNcHjn(8m@U&*|Rbd`Lrw5{Q&B6sXNIgYfyw) zm;V3My6|(X7jcF>&GL+B z%`hEer_1w{PX18LJ2(b!YFxAPR$Iel$;zdQM_Y)O$~U zl2+L%VsINrsivL5z2JD?!o*Ty;nDrQXGRFTqfRV^WDiPdW?q6+Y5`1ntax=k$Z~GjX*s3}=lZ{tuR5v%fj2V?%R1GNT?$ zXTH&yfLY|(Flp9HlCLe8(_(!KDh}p(Jm7xM%$x7{_9jUMOpebcSZ76X)KesquW>`z zv>X0f*;Otu`KK3nO!5*VYCBWuY@%mXNE#j+!kZP6=lB%_s=kPnD^zVL6V81MJG3sw zYb2|8a&SIHV3O~mIA2IFUHTSGU+lz56>6Bo^kr3^R83h7>FqSr(hf>HY8AUys|jsL zQK6-L7(b-e%T-y6IQT-O4O-IHmDg`e8Q57UFG(g2`2PUW8u5)F-)Qs@VQxXB9AjZ> zpWY~=JTipu>e=|ITJFb{eE9~WGUByfWrSj{(~@Rh(lA;SESpEu!=7|{K+Z^hzGh|) zxL>W{2P)4nS;mB_h_$>C^7JfrNz|H^&qgMz$xch_2=crG4-uIK zm-qLZCE*0 z$BW*L)eEQV(dRjgsHhk6f7@uE<*o91bXO{bAWP*iVUw4J?3W?{msCsrKCd7 zavo>AM>L+axE~E+{Q~j`cZ`a3(HtUmAOB#JyyX)%nj0P+K8DsE&s&i`h(jbj@!{Yv${;v*^C;eB4 z;8-?~=Pw=1;d3X+1*$juoVQsFnvtsPwgyDfd!>ppz%#a(9!a^ZwR(?n#>1qe>3p)K zlb9MMDYC+w!#BBmWUWOUd>qwns~(&Q+<%@SXXv2ZrQpv-o9%5fxRM!eWXz4nNLXst zD{K-Nx6~izGQ%t7sz%Q3r21F-rU@(Jeb6;eElaMh*p*+} zn?eUvWf%_8H7)k2h4DxVC6UW1F{myrPQ9+`X~i*o8O9TAE4F*0ayz`&&3NaW9@dN%kJ---syTW4f&=Rs?XyJD{aY+nzCHl9B9sROm5=K6M zvHXgI^10^8&Qrsj2;ZnqzXI=YfUOOvB79sPiZe&f=!qj-*45Hy^HBy9blIYYY(nSL5FsgJ% z0O30y^zYJ@n=YIU{v#!LtN8XV`$^SztulWg0sUF5`7B>nfR`AiYPAo*=FNOj)`}!! zJ{d7Yowl{X!k9r~ihajU7Pk)(o_i_s6r?vA3p60h7#`4?J<{jK=ZC0*`~xcb#ve^r z2cf+3?ZpbjW_BbPG1FUVqZ3E^>UYD~4}OYFFq8aYX<jq8`6x@8kxeOqgnm6?oY^Y8on(;R%96=IBS%6)49(-04q zw#wlA&a6P!J;&r~i%ndF)s$lp9UO9U758IoRmXk=?B>DtZooh2Kh`&Gp#m{;AKMG& zu`%_}GYi+=E6vIe;VmOxyOIdg$Qk+HBrR5=g!^I%fk5Wd&ZWQHv=8urvH13 z^qxh^d%!a1tqz=z?u|pf;RbId(z6^{e*jBg9-MF0Z|j^fpr7f>2y5Y`-O@3o#=mx` zyiU0Yiz5^8nz=`6w`DnBm@4vxwt)%}@jGYLYtoe1E$btFE)o!CEs|vFxXHkMrvzP2 zR$-x+6E`|;YFb^nfh$NJR7JynlYgqQJ670^nSc9BToHhYyUm+;tOSxIMLoTQF-*=8g}IW)-deU0s=^1P)=9H*rxFM@e+7r zvavfe*hWI-gd~^M_qmT2Th)JiW8N-JGfxV#NI9E(AkP!hV-1|tabjD+CF$svv6AG% z+_FOX=8K|n&LjVLCZ&yQ0jK7hWIpn8Bni_#7$E@7+YLi{Ei;HDCieY+Q9#c(7Bib}o zh*jSV>QEa-Xe?#oekMYgTs;bsl{S7QIl@RW6!FKp;mx0VY_Ejwkhae?wCU&4rR zo2kLRa*ofxl!%?1Ej0var4ys51a&6R$75(^fUY!|^1ic=l2wTDEj_D%ai(9%NoqtS zMD9d}AsjUvD#NIE?`{Dsxk=G?<)P)NrrDM6JchuZk)2c3t?KFo;z~wmoSY!Lx4)i7 z&u1S=D1`$NhsuqHh@X5u``cteN6A0iT7LvKx10QfyoDIAan&;*V`c)Z3b`O$eN;}R zu%^e#Q9l*+|Ad{?+ZQL##BKV2rJo{Gd9j0ZSIVq!YW0znx9JUWE)1K$1ibA<(8ZRR ztEjHNbNqOx4+r3fe0Wh6jeIsu5OSnN;zWNllS=7x4keCbpoVecQInI%#jueQI0|;h zap{ZHwXkLRq)iy6_SFciD!Z5+dq}bu=^_W<|14FPQBq@8%e;t2e06VRImCh;8KpK? zb+gs8so%PYwHV*qUi^x*54(>9?aYQVh~tQFQl8Yn+H|O;$(4h#&zQWdy%9qkl^`Tt zF7EY`kVZ$(b}7icpmDuLUTZ?EaOD}qwz1}_`TcY{b@>x?CFAMXw3yEA*oPmQ@RuZ% z*2hFJhEX{CP_pkUEL`N51ByMGXb~zd(hMyHIn7dGc$MQ|3a#a<&0T8ow;*RJyx}VN z<^-5ah0FUY)rx${U|!N62YJ{s_g9t?-%2@xJ=!rAcEht?1_G^c>u&UQwB7vKPzZ!$X~0;$_yMC>Ew!$XSw$}~E2 zWTUgaRH%x5etL~z$GTJL>$+qj!_^rJ30G$<5}wH`sZg9DDAbV9erF*hCTq6BtnXJ> z#5j<5Z9K5U7Fs#IMkaDX9KxZJ#{0z3%njOM1rm7uZJE04wmQ@a_AG>Y^g}Z7KP2cl z&7HAU{ckMsQmy}3+tRFKzP7w>+%HsN7>R^|P&KWpaTo4P%u}D?BgLeJnYt#(XHfDS zBHs-=w}bJm@sl)Z2jXpX>Sf87+hT5xlF{6q>I)1{cw3^Y=Ui9^_qKxl7mZr%ni#?Q z#pVM3o6ME+xU77R-)f9YH}WR)h`ntwM=MUK6a8|3VJHR7@@qafLWF7CnXdh3vQaN1 zJr|&}0%tOxnY*O!-=Ph=o0iOmaf14C&#`5egr6!y^g#?`@oQ0W==XS8YSkW zKn*u+$J}hygpm|GP4Fvp-ocHDS*zgzl~B(O2lhR<4fRQbgM~w%m;}Y-q;{h6Rym3L z*mLrn=W%E~4FCjNs_arqCQjk}b5W}lJJ>30k4e|;t@_*4*t*ph`g!&A>*!OAQn--$wx=Kkr%mWblzSs)jUcQO)YYqT#pvD%FGg+||>=Z?>0KMVLyH1+$I9)!wQ{D@Nw9$U_AphiF5H5PtCcj4N6Q!3r z;J3EW*VU!lVqx`*_IJhOgX_ongu%xzeGqkM(C0i+{{3Y1MSvq}+%6YIKU?Ae@Dj~@1Hf!qut`W?J|3bCfpUU;?nFs7)IFWReUXEopW{&iD z+Ini4heP>5^z=#I%gDqXvb1C3+C9e)maCQy3@K@T14QlDhML;2pdo3#83LBMp)40B%qxFKUit=ErY6@JU|GyfgoLy3>(HLmpO z>N}yX4;S&#On)%f-85U_{gB_eB|#{VnOODDv9<_Ihi3F4MtylOLet93QDs~=+t!19 z8sH`EQ0-oE9N#V8*G_ILMSL(=XthIts>fIzMYIpi#27MrY6*@*L`Y{9Wg{qqIR7%` ze*8bZk3%s14W;VQu_)#Q(TEQEFFXR-(?TV9`#+@Sdub0DekhnYW&K6{Y{VVVE(8;<-g@3 z>rr>4-T1SZq#LbKjpsMIA^YH8)n7;D! z#*a(ETp){>?!XFDmXB3Bd#3)4`(luL5VEVJnTbnz8H*>1jmqW1ECPl9x)3ZB$PbBk@$!+xp zLfFoPo93>QIm7B44V8tbVtJI zdf5H0Z#1c%4UU?#iyDGfO6gn z{vH~e_~FEDFLAC#rV~$FYKol_k-`*6u;1QIPA*Vzq2zX#bTIU4A(KwBQ>7zI3Ep6C z95S&|j;#R@O$M~rpOryRYVrt41{G&O0=bvVM(+9efn)2n~HTl9kn;Q@T2 zC!zn!PlbJG8Vv~(SE;jQZ^oHwVlEdYjV1&sPA~Ntt*pEZokoArzaZicYFTBPzDpt; z33bEOKb=wJ^p(rt$P|S5zdBpAyrd5i8!PrO*D(S{7+ayCnD2wSjh9U@&69#0w|eyJ zF;|qq^cjhD374kt8%arR$;E@RO>2HER?bUL-4wHynFos7*pc-tIB<-X@bXZp+Tz4` z7l6lGoStRF>OI2|*K@p=AcsU7_XA}#nlpyDL&&?!^2z?Kkt@M5#3tNu+*vL5y|v%5 zl9q<&zXL?PqGu6(f02et+b7(NM4x~5e)}DU9aQ&#NQM05fnpWU+Yr6gq@2e6AHMtP z?V};#NyVbwU~bG5`{#=&v{OvhLGuACkxXHgdLz)W8e2`T`MQ@d7#P6pPnOVG}<0f-wa3jbFX@;Lj9nJRJ zN3-3oDT`vUN?D#UTc6r4#YwU7L|v+Ra*YhW0>ZNAwD`yxPxxT}B3-GJ1S4{LB&8Yt ztM;@tlF1V80Un6Ah)Ol;f$v)7V@n6N#awFP*D$HQFcVN-;+SC{4!KJm=-mSSamHI+ zUt^yb{&C7Pb>ANkD!2$sq6WSK8=EiB9Jc~rd+LQ`{)}N@zLdmNx^UVPnS+G37Ho+m zEmF&UhkCs>ffl6Hjz8ylBt@I2`+oSNTr1~?M_1LF1&qOw2qVW>(ZQe%wV&2O`>T|dRT%EFW-^{m| zrHgCcU}#F-i-v!2F)=~g`5V^Nw2pf!RJ<$UUVnJ`Yi{;RxuBLAi3TwF5@w@r_MZQB zJfH4tP*{JU#ie19bH3elyhl`VW_;ahJ|_t_Jsry+dK!Dm z5dzTC>7yo(=hHA1;=z%;<>?2HfP*0-S>tuz*-w+)+Ztj7 z#qWJ0Bpwj>z;xO5?J8%rE|;GS>w`jDjpSZOcLb4Emc7#MVDJOh<=>tIM~D$)NT|#`Dwn7)475w2~=L z$38HB><3b+ci}rm)y=*gZ7ngOV=T0Eu5{QO>j{D-u)_PuB=1@#rMFlmhL*oU-Mr=- zYrfWLI>NBcXG}8kUCb(vg&RinWfH?tB8z`YaDKr$*~w2BHK{LK9z^fXoH`SVL|4kS z0QYG?@gc2w>Y?{^!h0tm)NpaD<-=J0oT_&{O*f+8@*I6|%RcQ%-*)u)foQ09B zWLpwKHx3c@_}%Z1&?mP`(W1S0p}c{Q>D+t>+1W=~5^cy9uQ}?%ZLrj(5m(G~tHu^qM^|TURD*8p@Jwn<;IJ2A;f1 z9QmQD-_&>GOktMU58Sla=n3_67lJgbr>oL;{{$PmffF@PuF8rn=c4k6;oINolH+wD zsH;@}mymzh-Z$MIT#bDZHi~2H@RQ6O9 zAF6vOPd8{^EKne%<|U4MGPT5mXd+YzgTkzXmuKCgT?+4fjp8=|1DyCM5SlV)qq+3j z-79iIKryuGA#l;^!TFkjWaaeRq^Y&074`JiQrP-KV>Qogd0QUkBI{{(kkG_7eJ7i! zs9{dnG7ugy2EPvK{_)~=X8Z^;UHo+elMA3}}Q@S5Mwk9?y{_u8H#l3<$?PykgMhG_Fy z7t`SNDXwKzQ#qy?&fn%oLCS-w{bqZrfiM`7nKmb0H+ z7VSf8GKLTX1EbO~j|y@Nvry~Z@|QE)C|LuX1TL?ohP&CfoU@I$X=|xSElb=UH$xCa zEdzpZZknr4iEtW)!;HhGUXYlc(Qq@BAd~qCq?X#-HJrxV-ub}8>EVqF#bYrKmX*B_ ziDvlg_inSCEnVW?F+z3up%h@ZxyBPL!xT$HhkVvB6zaJn(&19~Z&NJQaeZUv6o4|e zF<&4Z+ss7`Co5xOxCGGzyYd*l4T$<(cILw@*2*n!`9^5vhJS@|#+kLb(qlO{($M&e zyu?V0w|$7^fX9Xzfv|6y`@pn|NymaZB8srXl#fZ!Lmtgv%AIKda8hjqw8s$6l}drb zd6tdMQMEbVh>9EQ)nEu&X4SK8VDC5NcP{lOY}*eV5+(~ul6h6KwzJ8qY|7EC2?ckj zZntCDiCBcRy~nPS5~)imuD;9o=ZGfuY$(4MsBXke4q3Qu1))&-f`Bd(3%#bvGZ?o7 z&2UtIH+2vtTb4QiUrg>_3d{o8?@G__F2E%gtM~+B-UuP8t>3$a$e}B4#izA>-g+V# z!|sYnvAvxEEd@}Gksjynqq+Y;%7ItepXPImB1!|zzjrF8ROG;@AQ! zA<-A5WvKMtI5y=GhI8E2g*N?H%K!9~FJUrU?9m7Rf*rmdV2dF~?)eCt*=$1d;h?=I z!}k$2d5I7DNIPU>2=x-Z6q`7Bp1zolTK`u0KeH~8f(Xv+d=dG_Z_ejG)c>?$N6pGV zKi#sU0GCvkKUqr3&&w~7@m^PCm>=S6f7+Tr@!PPQTOC}pFjHe$hfH2+n(EP#YRqt~ zeON@oY)ZLauT)@hWAy7f8!5sa~^RAI!GHAsJYL)ucGkzUej3W1M$<4r}@#-H__rlwma8CETY}S)^<; zPi$52F7bY%I@s%sn@J}RFe07?$1>M3w`2A9%AA&5=wgZL_AbO`+)`ZDd-$>HCuO|p z7Mp|UU!UcV)#L=DPUqF0{z!S8E)kLF>r<)qw&|8-e{lijbUjHS9%{}e4lUY071jTg zdXWwhCH~(Y$teAj>axxqn_Zf|iPazI3<5D+d%^8P#$I1Ax=5Aq@wAQt4ztlIHB0yG zRUW@K?&x4fOW8<@yYqYLA~%gAFf>uX!{A>~U(xzoEnWMuEK5t4-%ap8`{ML7%3ehu z?Qkme=q0RK`3w8g3iq9Y{vr)Lo=5i!SuM6hWtn|!#P7eanTrj!R&7J)t7RQHyzjWe z%@Xg!<;YS@hJ}e<;eyNeeG&dF?%p^ooM-+1jqcR@SZSqa2P)mi4Oo!?bp%8@XZjy~ zU8@bT5tnp+x(Bb`r&5ePmuy^Wqr5p=)~wD$Bp81?_}&wvi;zIj)nrSl{nSr!FWJLW zp4pvPN-D3H#SpSKevxxpy3M4;_jl0h&VwQUr#llwmq%%T-bsB^fU$b=^L(!kc5Cy| zFw1It#xqW(w*t=LQgvq!^GymvX}Fxwx3~j#)Rk*>YXRny8$EXtEK5OBZT`ufns_Uj z%{(2S&baNck|Ar1imELi*3D(wqxoon>@;h7tlO!SrRQ3M!v)e;DhDS%NkZoZ=ogXy zwC+43+$yXZ=`~8{q~9l;r^i-WY#03X#H2!{oRrUcb?*du3(em1p&I}86ci1Ae}S+6 z<)Z9YYUwMwvY04Iz}!y$z%Br|$|m}0(7Dnz1vWpHSk)TED^j`1@dL*5`hw9snr5#$ z6UkeDsCmL~bVo!ZNy8T^`ChRyFNfbHKkE02VJ{*@t)9Odeb!A!1VBXG?6GOQpW|@# zu_Mvu{(kaH>Ez|N+JRb(BOUwMX0u#(PB&DdbsC?MpKP5PM;h|z(=1tXoXE5+O3J^y zZCQL)=F@y<-P5x|<8eQpp057JRro6J{Mo7>p&G{JbMDd+CS(}Uy(;baZ&iBY0T*!hvGLi|O<WGz7n#0(=Sl}JF+X~Izru+&(}o2K7YSBx z8Zn~1#q&t{;Oi?}i23yBp;+v%Kkj^IpKwt;O3cqxI+lZub*kI&jV$M&0Qob<+Zs%n zP@Jylel00_qgAfdXdXqxl<7=mW?dz$th0V-_zP@w(EUY-e zP?(f+@G|k`EQ#MxYa>Nn)+T9TQgq{j#*^TWA?tq$_TCDMcg&X%>EfND$Lu1DH;(4{ z?d`C5DE5cQ3W+gZ>qu8NZwhYk8g*pKhUph&%4wRE6*)ciHojFlvu_D&6f|8R~I^Q|ldaP{7_OQiZ+LKy_s3ip_e1-+y&~p?D0*8K{yWhU|dfFM6 ze4z`|_nf|)b$T)$R61PvEsJ?|wai94q;V^vtGoOUo;La$f03hx5~U{%_=Mt^wn#Vd ziYmvNnqym|65En^w|AQS=mfrmWD1CapG2Jj5#niCqg2oRcvdLL{%;2D)4GoI7>az~ znYhwzsFm^oOZ+ogrh z>NJXxQS}boq^Ds9L1N#8(T;OOVk_Hu*%i(YPf3L1h707_#zp^Tr_B7{tqQ_ubGKBU ze(napJW}6Lq=F|CIpZwTOc7kYZC-&{)jN~$T(2fGRi4bx$GR!MO!zm`7R)ZTTmiF( zQFs+=Xh=1g|KWt6Touv$k+2*>I0e)5 zJUs4cP-)_w5PxbdE#3P_KVZ@lxoC@X*QmedVgJyO6>}B5lsp(GE!Yu16SdOzLM3rS z{*(EdX=hj~G+753%Dm0ho&NhUA&RWGm_IX6`)v%XF0J|FJQ#-15R4))%KpIkjcNIp++Tm)WzIa8 znjrdNUsB;_U{Z5et}Yu}xHS#GzGa*`dQdHn)u3Ig2P3_C^xqmgwD=1cM*+iRd0HLM~sRkJP`$&5M=pI}$WR7r*`k9=O}#`Sv-|nfe%&vrkTX0^{AyJZK`pLoG^^})43H=MMu9tm?<_Q&-z5-{hj&%4io}_K_ zv)>1Iq#NL>BlYKagvb&;GpGt|&8=+bMI0QM?F~)0JG-a7p zzIa9dor$3sqj>ssUUjD|6u9p?TX1x1TCo0P2r-zA>(V`!T<4aob*_B{9{$N*O|Fb*q8MLoxB9DowF$CM&IuAdZKg~}7 z{eC>1>ki6tqWJ4WTQOw@#Ta;+aWl9VH%R8#|8N2QMq-j}=%v-QN#KFRIFg@z$-$lBJ9k2%10aXlLz6BM zT0R?j(gdIHfT^jxm(hv2N0dhrX+dUTbkHw~sBN@6WxvJz8hv|R{JFf>|92o<84)uw zpPlbH*0vCd-Qh>8=WZ0#zM1tBMlyaur8{|sT{)!y(l?Fj_cwD3SrV(_H%4VP;crf3 z*c-Bvz_!zwmH98U6aDQ__P6RQGluWnyH;ANKRfk-ti@AG1=5Xn9w43qPUOhfg{Pg( zr$~kUEXZSKO*05;9Mxo7+%Jnusz@DMl7D55konXpus&ln;f&My;iVm5ZEW?Ey>mJL zS_=UAU8wY6!pXPmJmAaGH_T~O`S)S@0^-1^7AutD?H;{vZs!g!tdufwWzr)Mn$JHq+Wjf7xgKK?-b6n?hxRW4iAxSoFXsT=hQvlY9R= zZX?JfvYQpN*ZrpThi~G;qDuq6i2GRrigoHGXpW#pAZ7%3Pm4PR`L4Qa1a$g7{O7I8 z(njT9_U7tZaRTla4R0!%?ZrS9(WC$E3BlV-3YGn)PV|iFn9{#R!VQe{CU__G zL6o8DJ)FJQ$4y>chX}lDyrbe!JSsICT}@*6EgeV@HpLFI9}^C^^>3jm*rj@{tKP@I z!<=hP@K~Pt@F@<+4iS|8F^mgc1dbbUGvd~w&t~2|(Yzj?4jxsI)bzW|?zpM(2?mwH ztKA*SAjhz%qY5Mjd&Lsd7eTYa&n5c%fXfta3(L0ZIl67&mv-+|57P^U41Xs&VS&Cbtk!#9KNc90th)X9}eH(nGH-X!-o!CYI=wBmT z#HBB7Ut}Oz{+`lUlY*6XsHHcfcnj@KAAdSBoLA5*3LWefV?uqq?D}OA-S9k59*EF& zmoyfmc{+R zgBRJ87IvdGRks5TpE?EDR(oc4QXL@NVrzavLbCRBf-RAuH3^H(-MvUtiGBDTq(TU( zuA`=12bd)G_xv72AN7m&buZ*&$2L~G>}^`*$gFR>Wn@DwOEH4>1n?@^$VJG(Ao}r} zaTw3AqCxk!Z&Q(nai|_7BB#luHs9;+s7><`RgzLzrqCYac`Bcal)yGCu~z331n2u| zM_}D9%rNxC`u;oV(l`>le4xHD#E(S&YDm^&(Ldt(%AeoibTp{d*F5@lx&caGE`uTv zb=~?SIG4T1L0@{yr-)5K6bYy40 zZrt`GJ+ZKUIWiOC02@f3McdStqBy1kZ1viFV?aBD6AFv3N*{Qr3I!f_>PTB?Ok0&I zV=FGQI0yygp{nH{c}Z>~_lEoDAY+29&;i7=r~OJZ?F@&_oXw1lX#v_KYvK6sNKsF2jJZkjRjpd515HFh@l|o?svqf+Dn&6D^ zI4rchyF(VN13U_BPYl$8`wy{j%o)7H3dio;P`$^a^X^WSmZR>*CZ-^x@ie#9 zg%dot62${3F9=;TBvgQZ%l&ZjNuw*cbz?4iYzw$M-!-30%U0b)e>EIk6wro*x1xMF zDHxco?xe@RLctik@oOI>kl5*_u?-9>g$=Uo-^~NJ{cfIaj2Gcv?|FAJKG=}2UHr~WT38EdL4PuUaB3hP=p<6 zLm$&7S|0a!?tKe|DmhY>=JE)F@xp`bd;Uc@efj>S~$&P0SNi50o~ zT!x3l6^{Dc$jAS$yxJLreMG>-HnD5aK=y;>@ELe@HoOqAFRrE3RVn%+*k`8={G^t` z<~DcwzBirr4C5`A-UEG_O$xVXUu_Iyrn`d|oieCuqAP>1ZY#w}SozdyX8qN#D2Rll z)0agI7`bFCy_k^M*8bW+vnNF-@`hrz53lN-n2X3jtJ`KWnozgiu?RKOJM3a)Hs(7O z*fBpa&1m0mF_X%U@(HBp?|=VMPnsZ5sc2kfsCGeO8vUOoC?-FM2^wR8$ou#!m5mFH z&To%ked|+olD8hJLH{bVyA}-JDnDJJy)U}wnfq)c4S5>+hyX%)H=9_oS%_+)q7fJ- z76h5jMWx8sg{=MI<)i5jC?CXjXk}$bx84&=-EVCTT<43FyJ%(MKH9yYV=?iV6MV#C zfK_E+jG)(ibFA#l606$a4E<*{UHp>YOXIQxw#QOJT|)V_A@7YwPDX`R^2P z&E7xkPO+-4|F6G21P6uv5ryAn(udy1L@}YaBQGxQ`WJu4Cf;HoGrE4l)=%qA7x8H^ zE#AWRpK2TMQ|pv+D18v(39HjlFLcfS^U=<8WH|XI@ow&Kk_OM`etAJ$Z}NKM-^0QC z344=c+An15;+Y$bwmD1v)fe!=@Uyh~ZKxxjt)KhOD>HwTzG2W%O}^ioi`%cfQ}pfG zY$NM2UUao>6!`$4>qnm%NE?fC`@$}cAti5CL3>vy7k8p>CnHbydt5N=fVBIlT<^J+ z{B{LC*5eN60WA8O*jE3t%w+5FT}>;jj|jVPs0&foW+%r|!mgMWy~lC8V^6FM-fD)g@O~I0LKO=K7NDeSIZ#g z2D!hp{}1y_0c)Gr^L57qrB+(GO1X;GiF4Yk(8G4JCygdb_nZU^U zExgdq^jd*Q>onBt_d>QQA?Fhi;{_`1p#8Fx5Sm<%dQBU&38yc*s<|!gmS--pdT3hm zMAopnAgQfiW#0+pJ|kY z3BD07*~`%lU5gcmN;_$^duDcH-Y_$Z!Z|J{6Nx2lK!`x#52>H}r9%_)5v&RX9_B^CpkGP72y1 z-iC2fI3w>gr_^^(Pbmahq|HmG)~4)Cjdoutl6ripmd0xk5!iNtAfc=TN`DMuv{xc>cK z9YgZDq)86>acPAlqAVe_ZBy+;zXZp7Znqp8ONkz*v39ZFj)*Qwn@k(thg{pT1th~= z4EOU9_WqAX_<3jyfg<<|`1kst{R2>-Dy50vhrk{%R(YVl(ElR%sE6m%ud(ibZa+q- zi)h9p1~=j`v3#CfhHtPEl1J1JX%jc!Z*vX3%|Wq0hKiWLTSe0PnMid}|ys6dsX zdWQrF@iA7oUMYEti`FB7p4(&DhUb=tHKZZu>-z*%p<6Dz-A$H9#B8T#242$0bHZ=v zbSGP$t`k-gEaS~O_IMbp7qVs0TMQpNc~kkvu$mnfY;Mcv0;Ub;s@y+%e9poMPQv8g?gXQIOco!WRQ->ilB+}i2W;hi3?nZq8W0*TV`fQ+#-+e z=8ed~37Lr#)h;W<{nCFO_@sabx_0#$^8LUZl63RWmh`_e0L{OBYtuRhzjTe2z01>d zvLkYVD$FLMpS5;<0_H?|sF2e{j7f|@2=+%$vuy{1zhH#?BcfWcBs*hqYW{4eh~z7n z*NiJ?*D1Ce)KzA+9~gFX=$~X-j+1(a%2Ipn^BYQ47@1aImV(SMesAw!ucj3WKP|m< zF?miRc<4@K4<&jSX0tZcdB8iG99rC={hd&BF$Gr8gap%Sr%6Lcp zFLsXP>H6ZNlzQDQ`rAVE618_UoS&x=ROxW$EyJ#`JH5*7kWGnSx9K8Cjk-kM@}iFn`Izcrw96F$vV!$p36qqb?JK~Sm>h8>XvT!9L) ztwN_8CYs((<~gs>GT-9;LZ%8Z-9B|AAxX!z-&viH6BAZ`*I^&`tr*m+)#$v3`UqN$hr2IPa+SqR>94ZHZFZg7ZC;ZYYMs#1e*T z{CC}rw^Ovo2IIB#+AxL6Ma|Y9j8I;zXImjzYn!5Ry^_QC+MmrE2|6w>TRUSJhx4+Q z!xe^rI=TB)DI0&BC_}CF#&tMDk-|KCrJJ`z+5$F%&P^CavuS>Koo$jPk z*%JZr)pv&S>+)Ne;SAuPmwOl0FTtM(!dC^I#b|+3izgSSrv>h2s|}OP`VSzd7^W%` zL*X6~pue+ve}S_pA*l>MY;Io;KemtSa5JHnykH;3oF@*1KU0?o?Alf`PFD3OyGMuK z!xfgsk_45yp{g&2>I=D2Ho76BpjOc6)4RH+dVAbnXD!Ld8)-T@+A7(CBMEKo13h$h z*NSqs2z=ms;6P65y^x{6XtLWpIAa7i*tBA|pMB{4*9 znL8qa%UPka`>@lZR z*-L~F0f>UkE3-Axt!1J6wrz1G3_%KpqL>xrLFWm`ZXmJL&8%&~>jb~l4kWo1&X69g z3-J(&jwCDGN-rBwOC>H5b>>L0=ICl`DY+o7C)(x53e53cdR zs2mih1~C6Zo%XC~-}dxQ%37G5%yJ$4Dq;{`T)!~sBo{V9TV!ZSQJdhjnJ?rX-*4##Pztit}jzz?}-Nfm5zEBOII)Ij)-Ug80uIQacgtI zy22HM3;>8#vTjB7HcCtkCKLmJ=mfMEkLhHkyx~39UkTEj*YGQKc;!;s(RqcyV zfQ#17^iN;bYC5h_%X~7QJr~F{7@n-LQc&T6bD|n0i^HDQd?q?%XCsVrolK=W$I%At z^cZy;$cyQGjP~65qoWbu4m(tFYrl1G}09 zG)PQ*x74lW=_I7Vr1JCvg^L(*vRWq-h!ikR751aI9mP*2S#rNnObmDd@Av!P3}8xx zAX*9IG2H`%)cs*=tSmKXt5NER!eKHP4u`*=8&FzWfSkaAK3II2xTNhcw=1fvJ%{D< zp2UQ$l962YY`5C{`qMkoj(ZdHc_?85twJ?7J~Jl>k8t`epjA>6Do7{q(Zde8yQ5uf z@~!&ZMYxUKV_n`5^yNLLZ<5|q6E1i`B}U}jAD+|s9-Q8f9t@zVAWt%Kq_0W()B>)76 z^}Ft*%X{LA;( zQTy4|WfABjAgEj!I}ivQt+D%?O2U;6)l02xSNML4@Oqnp{1)XBIhGRAO$t$|FXp)>AM@^T+eT6Z=o3Vcb1~7|xo}f< zG{>C+LP8yCrOV}VUzg>Al^SX{d&jIVLxs5j=~tea29lY(Oy$hhUG-#hH=)dEsi=A| zF{S@#aru70iyTRtv_AQ6rG>N`m|dm8#zBs>Q*>j|cfsV>Kg)2jd_n(1{swaXWFQQG z|B;tv@1IWL#xF^P8@ne&%bmj_WXdn)BFqTQA+GLWAN+E0J_Us5JMAjf0?kyZR!KNe zAP8r&+$e$&F(m5f@Xy;&qjil}wnHWxz zQxb#zvO=69L?-RLdoA2*_k$*L_Ice9d;wwcVFRqbi*$lf&;in|cF9=I{<(thb5H{s zgsH>OJbvfSwUmt`)and6PldH6y&CCx^^t?vtn-RSpD8sRr||%0dtY&QH!y&|N&luw zHX^HCH1wg`t67H@Qi-n0mHENtHFfMr8cEi2Ktcbyex4y(J@?VHMaXIpL)O&Ap)sKF z>sWJXQlv?qz0!HYzzSw$M$RZhf=iGi%+NrPiX7RFv)^kpe~2Slhd+%IaO2MnU5Hh} zfH$}zPPNZ0wV}RX(pn}xUq6-=GCXHmI~7-B@Yg-1gf^QG}W@MmrSw2UU_=2o;+nKcjyt^XRW_>EZJw6Q6-a7fBd$=a- z6%duT3fX*x^n$i{JB`+TJ}XlMwAATxdUz{e|7{4785iG2lSk2M+zRA1)v0>FoK$U)zsBNxSlqb+8lYazc#G->rZBS*0qQU9+jS6wj@=^!#8zLBKZtuuGdE1mUp<0%wGY;={tdf+&lXSYED$fGOPc*Icwr--C z#I@;niwPW2S3@bt`5_VIRv4ZaH9X_HpO3D5!;gW_9E#KdI}hg#ZU=oJGrXQ5aF=?t z(@COCxuX9;QNB1_Y{SzHl#!d!X@MicQ|=%Qpjm;H%5g<#c%_(C;%X21odR#h&Ut~b zroWaxBU?tH87OduwN@qii9RK*Zihg&xAEAW-0)M`i@GxH&A6^0^VswuQxkn&Gx&~V z>?6%6?N;@-ju}^Gt;s1gvN!}*^}#x+z@Hdh4Sz~GVO{XyF1~l(_#cY}9Fr%3pq^9|c2BEoC(P$StNxw?{@VN6`Q#nt^=_Q*_SoSY$BNN?`+ zt&1PT^|Ax_O}d#7+@jOfOX7~vCQoBV+sg#w4Nr4Yk%I3(cVw|3uFGf6W=zVaQc9q% zf)$T-?Cz}|zv!NKJe|3dR2Su#VI>=2Af#+YM$`wrp2$(ridfO;u@5p$+4-L{IVQ`3 zrW72~bH5V08djd^#qXVPMJ?vlnmSW=-MZk50nga`lSl*iS6w@c)V0~#OE_1CeDCQ5 z43IuK+)D!r=NW@s3heVO8-`zN>TKrP=bD?DAvO1G(_i1Y>{F?BvygHgja0Z}vw(Oa ztnHyH*$v!;JhcpYyX~sYA1ULSH3KX*R+kpzGGT&~{01Ow=rQtz%9IK$ILJ*-vUb+u zb87=JoP$vPJ-#f7N6nqpqBk}EJ5Iu^u6RbxG`kqD=iQq18E$~a{j|9efL~U&K4K-l z3k=BF2|)O1!_A}HOg>G$-WOc1oamv3DviKEB3r;$F{=xPgsezr3Zi`iud#|uLG41) zMAKP9Dq`&zEb)0_Ia&Q`)w$05hFr7~(z7gTy3bExa`|kRt~Hw$7xt42FJz$}L*Pzj z4N_I9NnfcOSoV;DXS5NgaWr}yFwobA?)gXd&9eK1hF+d`1cbj=+4(EzYspOR0N?55 zg!5usoDyF6X2`R(<6iGj9{3!+$K+W9EZ>UZzM3Dfa$Bg^kL2GrF#p9gm_0?7`zT`jAOS?E0-f8+YQci$t9wJrv3aU6L{_E{NpHr9>0xrMv;HIA zH{+CP?Vu^+pSyg{oaBC5YHJ*o8MZ{yIkyM=n*N||;R4~*wVAGR?>r}ChGN>y)g6tH z&_+-UhE}s!HUI{E^*!eX0E(aFnMrBAJN?so_GxY)P~Yr=Eu&;r9L>o`iqJCfVORt9 zd(<+NNIP;uo_RR^1vx2bmm*^|5cED+;-cv|Zzd14QV`pCoI1Fssk!XOgKfuSyw~dW zmJ%KC!|aiP|A$;d0T4&r+(|E!h}_?P(rY}9JmoO!^&e%=->2DVT;u@ERtDFLUsyD3 zn5e;yHctY+6e9;ssIcMo6Is&*$aI7pQ?5`m-99sGr?ySyHw%?M z?e73+kiPgzxl%sBa`<@EabKRzhJ#i`4Kuz()MtBWu0D`i%4E=j_z1jQxf6wxlyi3m z7db8nGx^nGxNea+MRS$66z_}joD4Z!m;$AahoNp6l=suZ9cVeI_v5(GG!|421H0l^ z3Z8wGN3|?Vbm4tqn=pngQ2_XWf=Dl8^O+%0{NVl{vfSon)x@>U;-XLSBzR=CA&Gb* zH)PG>R9B>6Iz~z}`U2%dQ7P7S4S>F^H{#51p5+FsaC5FuP?dFfj*1P%1RU?4I$e56 zrM!nC@v3pJZ`CZyb|4ifMESx4M9rkNTpe91RIv+B-J`BdW#K9*FwGPO-+d;~pWqKYsDnuICpY$)+P8 zgB_gBQOTOCRIm8BiG;g_$T z;)rP7ZmyvODB6o6=Rk5R-Jt(GDY8x8hB+2fc(6IU?Iwk=1rV4*w^4Kev!(k3VRtpe z!)_q!yoafih80}>u~RSfhlp)3bgL(6S?tM&WmM4P$X?}x>R_K{HfmkW82j_D+WiKY zb}9=(-(AFl$?+6Go*_W>1ZoNJr_I}Fm!9Qb)ip2ZJLjz`#<-;Z&bMS$-K{-G0eaIW zRG>&-%#l=Se}_gd_P0e|s7|feKHk4Q;wFs~EH-WiAHtfv8i<|KmL;g>RmOH3Ee!(f`zAmHnyYcF~ zsTIYEnAXu?-N(C_hOWv_Kf>W0m6}m*lyzS0Q%qQRd1X19lnhN)Tj=^{Ns*@nEZ9um zjn;8ckIRzUXX_TJlF0azx9QKG&iL}GD!1S4HzX}u^vm|exyCo>-m{mTYl~TE{D;cj zEE1fb`!1J$?$zgb^gTa`OUdMK0E?+dxPdqSz%K!xV!Ux?T=N;&(y_VuP$w0SSii0g zFUNqkB8?nYmspDMmP=4PsVQkCW5?X^dh4$U;$3Bgzr~->MNT@jmQvVXPM;x)(bR!9 z=ilCKM49G!S){&lDdRp26?kFL-?L8O-HC#Zu}EW> ziCMD2w<{{5TI1yJMEA-=9ShmL0$N}YHyW}pjvHvXW!|DSLq|0<>$4AL`3jzpyw;2A z37C*S-`gz-c?n#T`_df!Hn$>6F1PJICiSlT<+!)$9jz?OZ$)3%x3hby=`S&_XtXtd z410$VKj*fSv4MLg7v@@2XwtHzIS!pSO7YixiG8TQc0(?{&6ZO|!e58(tq%8ieZ-=o zrueh;<%;s;oOMf4QFlzR_*{ClS2D^MfdjKn{c91)uI-17H9f1EKMS3jjl4S$du*sQ zml|-f!*ctkLFfRo@UWI)z+EkHnSaG|#_nsS^{i>ULGONlvEBL|@d;>p?I!sT5SRmY zqlDr)tpJI;lKf)z6uNOwbr&*s!4>6-pd)gyF4@rkT2L3IJ8fwwalzb)iT#Bm)|cj& zRej59{X`CF-SB;9s*~D?BLmg_a~;pf!pSx|Bykm6_&+Dk@gw4n>jHndG&7*|fPo;x z7*Ya4NDx-v|Sn8+) zxQ8p(vUyS*woRI=^BlICU)K3%uov7_o%Cn_IkP4R`T9<#_NwO5=%dB*d0xkze!;Tn z%XG#p5KZgm*eeG~?Gl1G1=3PM!x-);X8?!EX%cvUwMkaZb^u-<+>KolsDcgp1xq@3 zpheNxkuxCcDpwjNa3BmyUyH>24am>9%yuJjQMJCb*i8lMrbuoMa_-e@Ssa>n$%TUg zN74A`Bh(_Cx@24Y2>Oa?t4Jl?!geck$ot2otvmS_8!zhThp?pMbo@N|sA#p1i#O$< zS#d#ljLOcc(V`+rqFc1f!73V|Z$I93dV87OKh1T)P%iZazTOwvF{~CT^A0mHr2Z=O z&6Xv)LsLRP;WKhJZe#e@Vb3uMccOk}N}mgG+z*7dQ25!CXS7_cNnWMBfS=LdZoFu> z(0*7G+TVJgn`;GosX0s`ag4@sRyYXPl>Ud# z))X$Aybs*$TQsrCGwVzp`)4QJJ%|a?4Jz+5x5C&{4LmYibvtyb_{YtwtS)?5Nf~C4i2=U=T)ntuD9bLW}{IJa=sOHoNjAy z-Wy#>O;`4L2uMtIa(^_zgySdII0>K5^sIqa^byR&&S>|Jbk(OeSh2iKjU z+_|b(_+CC(lan(0#P$+Ip%d1y^Sn`3YU_5a#DDqO5+MYC^I*AESB+aNG3yHtL%%n_#SazFx2`dc>NB(0Rx4I&-qb9>2 z)5>eQ3(@-do`({t)!GKUn4x^Y zLdB75D(VXFaEBO0MRnmxPWV5=E%;ph`Mr6?1*PuuW8LWUfZQ;==n5KKuu8;OuerYe z1-Ux(z{vGJ7&nT%zWfCZd;)bhV2-99^6alsM!}3vXa58;_*ZaJPLJlG^gMHCu*T^y zj&5q-;&R8sjCAORc(lHLe%`Q5(Ln7AKNG1{YDxk5&iS;N;my#o6ec%%&9TbzkbCvSF88^O&CrOj~bf z_9`}qQ@kF#`O>q?UVpPs-U&aMG^bXjuj z$fqbt`Z3ni%ll_AXc*3IHDxXe%PCnc0-#4o6sHPYbHsOrJLeDOpKgY+n!CH^ju)c4J!7-ZX27^Tnne(BoG{?gN;}5>Ne~sD|)AFp~i%k z-(A#F`uP4C%3DYqGvHnsI;UcW##s~t<5T;}d|qvBf}9Nd&Pl>1qJT!9!P1T;vgLz! zhiRC}%5FFJ5Zc4B5Xqc5euWmcEySI2b*+&Sv9Tw0;IvMd5v}t&h1Ydg%bO1*$c2@Fx@S(fy7W7;70{g5+V@ojUNR%yQv<(i_+w)a}$6Qa)#i2jPQc%cG`%*qUD_> zG+xbKNui;|=A@)Isi3J8i#9qcLjKykhw}=9Gg8=c(^1AasEiVT|+Sdp%y`<5?V|^!X?=qD@ffMImwM39L z*}1J@Ej2_S%3JEW(35{>ryH@%Pz_eiQq&2l@0n6{UpJBlYsUAS)m1|3gTk~C@p_xA zxi;QTo{5TA_wpWbArpr!KQO&aA;t^I)zMRRtlAyXlr1g;i!dz$yp7PztVhj%`xM62 zU9>V&-_u$W5{|n-Ay2*<`(ev% z-5zsBP&;!%-s~2YUT@ByQNIM}G=MxiUD24oTG5~|+wfxBEtIQ#=gy)pJK)ognSG{^ex>>C zxNRAsY~V8tQu(L(pQ@NY$%w~Nz^}mi&m`WX!9oSw5FEa+m18fSkto^rBG1MZNQTQ@ zw>I-*QFbJmHqs`%TU}Ad3X$nyK1&mWa&WN3j(wa`TC;RG}~9M16n-Rdku5! z%qmAVPS;BE!0d!_=%#Gf$61L>qG%os#zuob1^VajdnOA$e>zIWk&bcuHIF z{m8RNWx@i5x}Go8esM>FLh4LGRf;6!;Y<7W`MN$nrAWNdHx79FxkvLk#blRzh(>95A;1^&DT6S=ZzvEe{%V0$R0r( z!%KoS<;U0*|9uY)E@Bv#Ef?OBPiJ+9ub@n5U;gYB!=*G^P z(te{mj+qRX5@IF0l(X7Dkh9eW;tDaI2wc@%R^%rz$^J=pc-Ud&MTZTn=$2G@r>|l? z2J^1druid~Yv8036T(eIfsZ3TV+Cy;)CAAZ|rowX1R! zJ6CWWrmT0nrrUZJ$kNQpg&Ff}^eSxh9(*J(L%( zSEg*Bl*W>g$H;gvc<9J(Pm^IOcQG5)>XlKcb?ao9ac*_F(>gjYWL5QvaC^em=h>o* z>4VaYVDXXTr&!D=Mc9P+371pl3JqxtIC6VRTU8Rh3z~@v^r>kX18oeq=$5pO-W$ht zov-$+xeMeP_qaTpfqe@wwW&9>&(VWVq)$HNK9`++Q8f+FAUM7ugxonme>Ph&sz*FV0gn(3ekDq83a&ihs^`o35_&Poo7{hC`dRBAVKt zwBo2(LrVvHV8`mR=Lqpv$n+-#DS9#ETq}*fWR3$e7cW>1k_@d)Gc^!YNKsykk-u`p z7!Q|O6gyD&;kbya7j!FobiYUoy{*&AZ#-cp{HGQ`pu_i|?L#4t&=s0tWl<7X{cZn6 z(%U5BE^rGtoSpnFOm(rRdrce&Hq1z{_@Ky_dYDn04x5)rgydNR|7|YaCN@0koXgzD zN#Or7Mv1>p;kvkN%+Y9*$r@v!?jAp1IFJx=4KBUTp0(ii&1vO+!&s&wDVqn>^d>X? zb@3)^U4cm~kGx2AX)T{Ub0%?KWxo1`xG>dRgB+&z#@pbD`W`Nyq!wMq%Hm%dCM(^f zpl)1;JuA(lWok^fl+{9RMZkRrx$T~rkx`pI%voRj^Hbt~4@VvGG>U(o5Ui|-~+b5uUHIekV$NL57Q-qr|qFNki@_-sm5DG6*{? zMi4Ed(=f=bMnM7lL3&o`v?84PKyMa4C@1yjQ5mMbWeP#&A<+e#e?1bf^Jr_O=U%!M zYrYF4;u)nN%hr5pzm->WFw?-Da+cgwlCPu}e;t_DRP^ z3=&$vK+)KaG}KcN18bMNZr;#VUCq-I7Z+HKuk?208!VT?805WM16QC$xpMWH{>l8@ z2ZJx>sNCqOq7@Wk;NL^W;E_w-)&3rC3yeO?`T|h56YoFqd_9+y$Amm&VO&Hjmq}?h z3{H9t9J>0?ip25FIiUg?FfGcQD_Hs74z!TkDOmY{wA)$fkI8KX_W0KPM4MVjHaYW0 z=U7p!P@jagcDS-uHW7EhYZRtk$O@j`?kunYtMZC@1*^;)`1Q|#9G4P;XkY%Q>`6X8UH^xm8XP0QOHT-@g zK21Qx!POMk>*{4}-rJWfDJZmzg!w@_DfP}Iki|}cAz8a z4HX^WI&G$Q-EXde!;!r;sO9tG>UTaFbSqO)!lpWKvdvQss`2j(G>=E5Xfc#-k5Gg~ zzQZ>6kSN7&i|gP{4Es{PAW4vRWsqTUP%g}BMjsg)17m5VJ@qyF9A|2{A;za2!^Hgg zvb*7Zy4{f`H8dG6(xMN%kV`l?;C&tcp}A(|lA~>g${t894?7t78Lljl9MHrb^(-8S zFL(15p<+ovHGlZ11l^^s)hU*3+JOP}qOhtWeEsj!{bstoJY;15AL=&z2>jXnTCi$a zCJ=O+_6Letl8y$}1XMIPi*~=IaCC*pNw*P3Ddxb=MQjsAOQy^gEYFQMfZ<za2qz(s7<+^F$~ba*YLTj&Fphqs{bb-Vo90Y=dGtMDCbQ{)eBkyt zUS}wE+G-cwhv(($9;&YKTsOj06waQH7xv-xH)8~@(j!91G!UJ%)`zFQ$R+_CX*X7b zrU2ls$akt0Cg$hdJMHu0yW9b8l*8RZ_YLE4a}Eg^C>)>{J#UNjNb91LP>YV=W-Dg> z8C)-oP@CjQ@3)=dYv|Rab^q(g_=`3D9=q>tjhidsw$QBGWQEi4@?%(`v8s=Xx;Gwc zjNcTV)awoWBI-4l8(r~67Zt3R^?>b%l{Lgp=!TT@qF^4ok?PQgH5;*`%Dv>=^Dv{^ z`4cK8bf#cA&d9+Nzv>UW+~}Q-wct6yj26@?Wm7E1IfMJV*A)eiz`DADx_F0ZXK=cm0cK>=diA1K|WhW?&=)h4?!()tTlG8Y`j@m{F(zO0O z{v{xa)k6y4FmkjnFsJ%k4b(pn!(y*BG(Q^53AlrQwE6)fQGF9gy~sODy(Nn4 z^`(-%pGz7!2jgpbC4d0)EC=!WJA4I%3g%sW1Su7qIj>B8Xsi2VEm8WChR5eBnmvZ~ z9~y^3VK=)rJAnVd%=EVZFterG!{pmcubk@AvAvlV)8Y-`i$I&tI>tqgW`@35l*k%1-|JBMsO$qH%UVttRn8;zP?D4 zNc_KlL361e&eqS%-4Y!8%kdveSH07z1I5^IDtg=1@Pv&V#k#vgKkDkgz-g(4{HEYT zBXaPy3|Ahz^|r! zC|7|S=*!qyWuOFt2U^ywLxg`12YYWTAoG?{yryHYKeZfMMk%uB`6NV~B4%Zw^8p9t zTl+faX|sk>s?t?h%a%M?tJJ)3f%WK6<(P8$TqOL;2{&KUt1t1tl=Qw{mU+6gx&V&B z*-6##z#P9ezcGRy)-*)8-f;#OvscPd{0YttD-grO8bK$ULBK#HCe#(9{H+wWjJU#{ z3h|-WoeGaH@9?7L68j%RzS4u}NbkPRY$4Uq885Z-un*%uO)Bc zn!C#at8Ajm&b)PpS2Dsu2)_Xo^Q+G3V89zwBh;O5rNqr{X7~KI9_T5o=9qw|uzI~% z8MIE+#4%a7VH$;1D=CLa;GgPY?jfOT)fJN5RlpxP)UYp+JDpO9Ux{sL!{RtzS!2nq zUy~g@x`_7oX>m(?Uh8NLQ%r)Xd{)mI;Hx*(Y!&K$IPHLdO)%R$*ahkeE0o3SyKAav zc&@-s3MksI$cgs^yg&Clw(x3IfOO;CM>< zlv&lvh2P9`3fG^J+KOWNEFOBPOmMVy6jKGdQJ>zFWWPdtw#4dR83folqRj)v5;kYY z$vS!-=GRaDVee`t}$^yf4kvX#Wm3B5i#33}m=_;^KG^1pJx@A8l zf6>zNEeJ$BqtW{0gGZ2X=;<63zq^CC33rrQ`fQ%&$ZQjO(M&v~Y{3HkYi;Uij5WxQ z#F+NY`t-7e`Jiwd8VoWKQIRV(J+R6mXoVhaCW+Nh0I9EmA%{6D|NC^NPTx*{al=+rgVYw3b8kYt6$8tsx#P<5tRH|t`T8_^H5EiB(ODV?z%{>yr@caJ~1ZHR1m+%bEQN zkbvp%(S7Pa$X3$2$O8wX*$ZuNoTFdsR5 zF(a4#!pdhPEPmq1*8KD$fJYiz7vopp{guf^1%@sv(5rvfcKnW>*rpBxH)z>yWSnw=eUxqvjdU}Nj0hwVbZJ1`AtG^{v8{Ww8kSg;kUrj7} zeM8-XZkun0C!OXW-vFRS1LKt}!m=h#^v*^|&)tji-28Lu>Ah(o_C%pfhqS}^M(F0I zH$f+K+~Pt^fhAv5bOb4SOFZDekDhYH6OX24E$_U=Wri_H`oaYlz-_ae8vE0wuAEHm zory)E))E#TK7g7oR9Jv~>!W*&rTn2z4`~;p%8lxYyzVTLA?G;E868)M_Tf|AjpL9v zN3$P7j~IyUR6H~e%EW~B`*U{L*oS84s;^##-0*2i6>MagL|3(_fHxzF8Dbol`bhD| z!r$hyzx!VdCVCC2>Gw{DO~L>r*XvaTsKP+E6LJN3lbOz-d*V{)HH*{#A3y8jss?z@ zC;0yV+YckJgVtUXfg9A%-nTBJeMZt?eYt7kd{}?=2KPJ}bKh4$Ihp)%AVWIzlBPrU z6#7pD-2r2+Q_%}}AtmyR=uhMNF^HL)%Hhn#yo)%B1m(iCTikEwh-~fxty>_QJs=5$ z`sqGw9IY^}7urPSHrM&cdrBA|yJLj}3X6BjeS=u)2 zOp=Y*^%qacMQw0}@;w65)0dQz>7TMTKoQ z2`t^WzCPRO@agEeMiw&GlUh%?9u4{yUa1yaG2LS`N_;CuGODuRh+8?;Zo~tIXBu5& z1-b8@x`p=oiG0YKFsvtrK*WoL@($Jmvj?zVnVfwK5y9Vg(R7i@@S5K}bfnNX46ZJk z)i7)MzNcV{rhw-9Yk>ZWIz!a0W2DGvj|6c8;W^g_>-uR3YqmbU1a1xzeKE)@5~4$3 zg!R2>E@&5z!rzdl55N;WV04qy`u%XvvX$#b1&zWcFrY_?%7{as=*l0P3gSmmzGGcD zk%25wQ4gVz5P=Zi!7I)*B^Ps<2$YunIcgURYPcEELFe@Cr3F0Y9C>sE4>5!w1>wcE zvJ6A(@C8H)Gw>xavmdZHL|_V3JSjtMnxJ2u#v;X^#zu&g7X2tr1*61l9~N2T1~JI! z#tYEkwjLH#f*1}pQqVyOgNXjkpDoy=^#@Ltj~I_8`>%9K7rK+Qzsu!#`Djlo5)>jZ zF*L~ax(F{*QEp8Lud||-1g|bVEy~z23pLauPnv6!8(KXKFKh8t^GWQ{1nM2V`b$X* z^7UuWpa^&`5*r_JN>hm4_FjDW{XLD{Cb)EaZi2&u(a>m2AQ046LU20ruY=; zOXJgtFZOROci5#={CMW8&u73By#6Gz3TfiH-S&gbP->N5Oa>Hqv=aa)30VQgYpf9b z>KQmIsf{+Yrg|!H7b&?8Eu^yh%FrhB{Yru1b0c+0n}ZJGKKs+%-ghY0ZqcygyudK@ zTGm~*lFC0Gb6f~9cMxL1GxM>th2B{2m3FkLMtvS>+S0**@hdc`3ioEap@P8R40FJH zx!s*P8JMkIqX}>nkA^jN>yf^zAvT7tTf2*r`!vwaJJ4WtHD9`3m$8k){WgW}n?pN} zV`#JF+UCLT?J_ANV-w2U7#N1n$F=Qe3tV~Y4_OVDWaYv+*=)>pt9T464P_r`wQ9VN z0nJvh6+O|oY{XgSS~TsxK3SOQqMM%q3{&kC4*nJSEs`{@w{;w^=ZF0^oRHKca7`LY zwF~ylleM8?=ePx3LJtJ;3hI2mb0BM0Yt4+k%CXzF>!kfv57rpU`g#3o>~_--`vO=g zOl*HB5 z!>;hY+}Z9FDwgN5)&qGJcIsRTWhgiYjA~8IQtPiFfEZL_c9F@}-jAsGC zoH;$yO|=Y5dQA%|yE$?OPuqcymfb2i7|`_H9uE#u+Y~#iXo>GqEZKw;jU5rd$FsIT z_gdrnCo8E9xj}8N!%rrUAYlM;aeeifRr5YK|DBq6<V}oe^q`hUzG_2KN zFQ$>QhaHSaRI7pYVy0QJR&$*o?ulPMAobU0hPs!AF0G)S=hXv?;T1GmuAhV~64_5C zmWhjz*=>rM001U5zNPtTV@Oq|!KLDlc%l^X+4gqmL z8~MbH_<=BXnQG9;zrH%0mqPbGyk8f;ojJ7l={GEO{o=|RD&g89`kn04H;QV=z2`S}W{Lt3{6Z~|&5Lpt27T-jR_1Ab;BbRl% zqv2i|^!|qS#!Y&&1iIECn)t5FNltCFMKPAlWp614rrUJ&MtE*uK$FSBi+&;jUbOWG zojCI3O`LO|d_0%jFf)}Zx`eW_<`x)7c&C~OI`08imU4I~yHDrLc5X{Udwh6P;n>}$ zU@LP0EU2exB}m|ZYw;rcKpM3L@N>t0_p^#>6&Bd|kgGT6(*Obc53Zu+ps{3f;l6ts zgxcpm$aYw$N(W}%26`4#$dbw~ynTVk*8=0u;7W=Zb4VwbRTznCqI_w~vhu3UcZ&bykd&q#EcCk|r_X_R`B9CR~ zhAhTHAVs&PAe>~pb^P!@kqHj%*$y(xx+bM1lYl=G=*%KaZ-jtx_DPqnF;tlC;_^ zaG3i%=3-coS23;quK;tGTwbU9r_0pMTL%ReBM>+|ST>?3j(>n0fnx&;)|}Z)R78bL zB4am^75@9~_4>^DjObm>l_&>)N z>xM1~-Zji)j{Q*u6Hgox1t`lce9+fp)6|;5Uk6n>7gM9_O-eH^6o}3Gu6phi+B6fgj%^xbCc6s~aj1aX`yh847*_3HcjxAC z)&=iqB^`E5K?p*E!bjYDWXz+pNaTtTXYG7c>15zg*$mm;U2*$ zt#;u?TDxS(#45_NK7{&f+4}@xC-EI_TMdL>TU7gDNyqse$V?DlFTdZxz5ULqJ;bga zI^l-S+W_abLaXI;ca{4=xj__R?nj5gSsL;KNGO~l_r5X>+EHq(43O*QZQU0Fhw4Hn z5ii)$oL7^eUfoanxCIv_gE#?z*inJC>4SLn3<0dPra)GS*3_Tg*SegmRlackuy!O$ zypoNso{tS#Xi?Rz3!iL6l@sir-O1M7e5-MgBHdn(CYtko_31le&uR_q38BJxZ$$mv zv}`Xd;|$)W0sr)0u*f4iR$u??z}stupyAo_`ajq!?B6zmJy|&~oMezw_|R1i!Enn4 zqdA@W-|%yMtUR*q11^1ymOk0&*RTAA0og%otTK~Df?hCuv!e*$$h=420a0IEQyTVo1^nGz6z3z=hN|09KA<_=1jZue*S5;+1tmAY2sI zo&(h|e97^}2BYNIWaVJT$&JuKF3L<^8GQBm{LlrUE?HTnaI!ci19}+PW+wK)*rh?9^&>=&=^u+9NRxH=zkX}@B1`)DpRZ2;?90!7{j)!=Tsm<3*@J6m zzqtMQCnNi>{`}9?kvZqDZtx5l_dFf=S7+{9SAYK5=Z~*%*?MOCKaKz8XJ5X3@b;#r zfBdoLpLY#r|Ni*80D6vmq(H4kMgGA@_T*FC-}L|rFwaG|ef0BcOy}(w#q%EPU*GGF zqnG?9vevdHPS$b7-u3l{Z^?xkR(opIx##U?(}fg@`zb#umYYG%)ZUc#Z?xwkJpjQU zvvp)oNk94Y+2TszD)}HCRpZD&mL3V}MAFa!8x{^sGN<2Na`Ec)-Zk$L?I zUu{aQ_Gh#~z$B9u9DX5^7AQZAPCjgV_H8E#<;lL%v^Eh%lKs%rso9I}Ze$t-ueWV9 z-{_eY-8-1jPaP56?nmWsL|o4&I+dB67Rw_{YHqfZ&-C*)=>~QMV%{U}sf}ZQbLB%d zd)0F9;%K{vEIHzPK0bU+0ZXWcDRAIJrE*fkeEZ$mYc{eQJV&*@kF6FbeRD;mp568A zM}lOwNDEW#ctZHhk|8r5{BIHO?sC8WxI<89TRZu0la{ZEsTHW)2)odbE5!Y~t267P z2fD8YN|1c`j#iqS3nO6Y&wRNqIj?sU+^b)u6L z%U{Kz>}2MrU6gyr18UQtm8ZO$DBoNxx+UC^z*t!Pu)of2tNYB}acq2m-KE|Z zqvNlCL+;+SaBTUN5pSBkUA=gR*L`v69#^~Z;7avS&u?;0U{+^iw8}drhST+Tan#kd z_scx$fq~BV2`>(vta~Do+IY2w^euhKwDCh!Yx}9|Ne4?_^*=yV(VqK0T*0GX^ZEvo zBitFWKE=-GPc`SbC5EG=t9v)brk0Jbc5MDXBQ7tTAL(kqDnCAFDfx$IoT)TYxqT^f zb*f>CxU%+5P9?eS`7VZMkAxNYxL%cYS2Wvv#?w0bMYY#p9Qe>RrcMsz_fd8lveij+ zVPc@EJDoK5!1qN5Df+laolMMstvi30ySj4xnqui@zkKZj)B7=PhuLQ{)Ijm?dCKP{ zr>@PK*hzB#-q@nr z>HemlvhbVW7abDzt8i(^3%15LUPR$BFon=4jWm!`LpFij3lWoWf?_u*>T23#rR46& z^H-dmk~3Dc`&JyDx`>Zxq`upe)xd3MH~(K&`TEzpNy`KK{`JditO>3>GQaPcP7E#7sznj!i{sP>!q z&g0`#-@VF=CmS19ho2c*ZdWwdkVMC3b97zONL}*mf|?NH z32yu%2)o=B*E{zh9RG~&g?&$1)z;M|8lGJ#QKoN@#?jKh#za&ftG<%7`*v!H)mHbR zGI1blTYMbsEHeBNWdK!s7BcJkx05P%VrC8ID`p{nFGi4%@Ehpi*N!*ioMs&s_QNH3F*>5(44QcYp=2+(Q zOljd6|Lc8|qK4g;8&dC%>^}U;$QJwadsaeZF%aFsUK` zHtFwbMBb4sGe)-(J7@QXsAq%{atv(j>W$TrX zUuK;Z8h`5ZN+)C%)n;|s`0r1%TT#F727ck2fVP~J2slrr0@Ib##+!AGWcKr}1#%n1 zHg|EcP?OX4;cSixT)UR(`If6VsAfFYh_q4i%6nJH$zkk%#9 z#P$twBeH+CT+1wf{A#yI(%(05?fFeU6V=#auSrrX?C4b@>R{hwrlPEVzhg{V zyvtcUs(bQE@fZ3|ci*CgqF~gKg|9rdrrW>l9+^cCoNM@K_wy$y_vmMvIQPE1tF1#% zE(&UUyPNDA6ZxN`KeznPr@_w8GI_GS3qpJ+;h-muF*!cW{C|_xg=f{ZJzV$OlIj9= zboJy?^KF9vPj1`7F~+MU{K)pQh+1cMYVm@f?_GcH{hF%-jH5}N{|9$({@3)m?T?;r z_b%PXDz$7UhHxxZc2%I1VhCo~-CAgil5J6D5(|Y`P{Lq@B#_ivMPx`3C5%ZcMP?$# z2tkr)86s06l0hI4fj}f-$_Sb7r)Qu0z4x4RU-xx>xv%@W_YX+2@;vKV&$HJ1z22+T zYFP%3K7-Od4tdVx8T3OObL5WEp5Ak1B&cY=_~6pT^V+tmR`utm`8TPjN4rO#G;-wm zn=@eBodbz$Ka6beU8;QbBg}d0uJUgu@v8pO@rTMe&`x|SJvhjS1R3I4z;wY$rg7Ve znj@AE5%^_4M5awK^b1OuBtF<>lp@LZ2=^GRfu`juqTa2_NiJepUHH^w2h_1P5YSiw z$6ImX-E1Jn3S({;kYdOgTdk#NP-oYbMjpcpC5Ti0F$}5vb?x5L?Hah~_O>qbPkkdg z#vwzqOIH_2Tj<+4I^)fgdisLI1wHxD6s`Vhgib$BmDX!t^e85UJ@{2@-7A%MsdFyJ zt_Mr(%?0H)rsqCA{&q^#S^u_eW&;TB2=k{!D(;G(YJO(laO!>6wp*9d>RHquJVO zq;^SRJ86FFd#M^pPFkfCf+i7`t7Xcspvo|mc?21cz-Ki{b-b8z28LYPI zM`7lY(Fh@VglC?=^#7NoMN=GiBEqY315rQUq-7 zJ~k1?v1c6-64u|o)dJ4hX%I)zI<;+Xh5#fyFgw$dJi9RDe?Q9DKx13=t8+t_R#%&6 z<9!XW+ou1DrjbSxjbA1(XsC>Ce|4`;5C_JZ&ytp4Aot#Z?22Chk)B?CI0t81Qnl3- zxkb%wC?4>=vr~`S1_+S&pm_zm1=S`Q8z>QXX`eQqqY+FncbdCVyLE_b{itu)3u7=h zHuiq`G5p|tyM6+R-Yki^dqil`zgawootjORWRfwzE{I>g+k={k$tn%TnjdXR2vE*I_MQi^U}=}C zeZ7!^>W`#XfP1Ho7!u85ci+HF;=Uu~dT>fJgKIv>ZQ~)5qw_^B6WR4p!$zEK!X@2& zNHU@J>(Vx5CrOC2I@(YTl&IH>)I9#VI?iiVO&P)0(9dz$k6W@23jeGuxvTti^E^?z z&J)W){j;fKf9Mj+rMqPKBhE)*a}D7>We36eP57e$k~XyYTe2EBFSdaRmyW!9VGiJQ z)7f$V?Zhm{;V&d;S1>cZ#;)*-1{c0lt$k=h9&Kp^g&P@g1^a!W={D7_b&(=z?kWQ` zG9fFCY}0$Uc>6wqi|!--{kZU86HN2G4^1hz{YV+=VKRO`_I+)b%U1hfhT)5Z#jc=@ zx)YZcCz)D>OY4o;#gS%Q_fbvEV>>&w_Dc`E`iC!QrN-~@!_A#pE_^@Bhkzv1kgWx; z{{pRV&ZcuW#D@?Nx0&hVwy&Q&F|>^Jt{JYpovCV@&5Wf6l(`|zXP=XdPC4}Im2IIO z#ER;e$GJ13i;dpV5+V`yups_pSo0!k=HXvGOKFp#P|k#qka{GX1}}U9Xo++MIcVkP z;GY0t3f;=+e2W?jBjPKh4=iUD>drF4;6?GDtvIj211FtI zgN;W6nHM!AFqKX_AG5w{cn->XrvJ5qh#R?=7eq+$)ab(z>gM(!AZb}6tt;j8R${nH z{WtEWPRI->YVF_|Ru*GWeQObA41S2}ZaIENonZMIVXI1NP9EzpQV?Ql&7C(Mz{p#s zYbvdgGu80aPpDoY@z)#gv!dkHSTBA9CaZl{D+8bP>UgLmPPWH+2RLO_#tv9i8^x{4 zYw!5xioa)F*1pfYaVRS5p|6|^C{HN{kFvHRIh?i{x7GTBGrg+Y&IP@xqW8tEE`Z$S zDZfnI(h%}=JN8qoDK2hl4hqRG@?%^V#}b-bnbFwq*#2s(PKb8$S@6!>jg;Y^3!%DE z6LNnFEI&%Ts6v(=%7!HNpUX{+1zzE%hve-@o!e zoO1AO?(q@!%f6{kJWc<_xU`bIdh0o8rt&}z%KUAejMd_cBy07%!GJhh`fQOg&6Moe zL!%8f*ln|w*9%~iPim#I=Or;w@tN0`eLD$;y!Qx4&ux>u910tCt&SfW>dDJ6YF`0? zfNq(w!lz|6O>Wu+W${l*3F?9tw zmY=%fEchBcvZs1<#$~Y))9&rPX%31~y;2t*+Ei71ZpwIwSsS?B+6X&>$TX%d7P@WP zP5xtwL5EbnpufPx|~olu&_!?5)v!U)pc6EB$8cq8zy zk7nY`lA8!;lMgh_EL}kEv;=pt{gwAp(%VQ&ATp5Ejg2=n>f*do$d*T`KJOwpPgiSL zvc}LgwTWRf048(!-_vzBqdbWzqMFz=iQ*v=xk=b(@Qha|&_=R+=Y8s3iQa?deU25FcltlbTUcs*GJ zqx5IL{kv=2j^i9TM6kW9gjttlCfhSNR1F7cNsKPcG3`n>#snjMhH?akPk-OF^q6N4F$7LA_^m;9kt$EMiq@#gv%hcdLYbCAOd;yQ z-(AGZ7fqj%$GgLcxZRt82QL;)qk+=ZesSTnXZ$H&e+mPaR1wcIV#V#^SJi*oDX+v0 z9i*PROhH~U)~EP(G%EQrpiCBM*iFUUiPE*S;>CrV<`M8PI94bvsA?O@7Pu~+p@xm+ zFG}M%XFSTLTIig!7;<+0ic&2l+QjYVkNR4$rUkJYJJZAsQ7&r^3p8h1b35I{porw#bK&+asi_Unx+q_V8tVnz0?Y5exHkvR0bc)2;WGQ{ z#H>QY*83xzSW8jzOl(Pej6$@)MCFeS7|sG;Q&3uMzBLjs3>Yi!RrM2X!2iznGF{(` z3Ib-(!0)ct1`gMEfCD$RUFkEy@%Y8N_kn4;O{K52RokVu@bqsp0b&VoT?WN&K45si!h5nQF%6*r2krxFp4`x9WYCy@qq z;7PE?44E6Xj{I@{obD%tn!DwGK#DG@t&o^*w}KM#Z3DNRo!9$EpJm}uPh-qPD6B4z z_;WIEQ%4Et45F;SLi^*}vnvDHs-b+C{sZNlx*>$dW-!^mCnE!eN3%0A*&y{@sfvL~ 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⋙YY?IaMxIgYuZX|9* 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 Date: Mon, 4 Nov 2024 15:48:55 +0800 Subject: [PATCH 054/221] Ignore test_bgp_allow_list and test_bgp_bbr for Cisco 8122 compute AI deployment (#15336) * First commit * Revise string --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 166659033d0..e312663373d 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -117,19 +117,19 @@ bfd/test_bfd_traffic.py: ####################################### bgp/test_bgp_allow_list.py: skip: - reason: "Only supported on t1 topo. But Cisco 8111 T1(compute ai) platform is not supported." + reason: "Only supported on t1 topo. But Cisco 8111 or 8122 T1(compute ai) platform is not supported." conditions_logical_operator: or conditions: - "'t1' not in topo_type" - - "platform in ['x86_64-8111_32eh_o-r0']" + - "platform in ['x86_64-8111_32eh_o-r0', 'x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" bgp/test_bgp_bbr.py: skip: - reason: "Only supported on t1 topo. But Cisco 8111 T1(compute ai) platform is not supported." + reason: "Only supported on t1 topo. But Cisco 8111 or 8122 T1(compute ai) platform is not supported." conditions_logical_operator: or conditions: - "'t1' not in topo_type" - - "platform in ['x86_64-8111_32eh_o-r0']" + - "platform in ['x86_64-8111_32eh_o-r0', 'x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" bgp/test_bgp_gr_helper.py: skip: From 0641d910e8e458ded5d0985fca4e1b94240966d5 Mon Sep 17 00:00:00 2001 From: Charudatta Chitale Date: Sun, 3 Nov 2024 23:49:24 -0800 Subject: [PATCH 055/221] adding 8122 platforms to watchdog.yml file (#15250) --- tests/platform_tests/api/watchdog.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/platform_tests/api/watchdog.yml b/tests/platform_tests/api/watchdog.yml index 37bc18b78d2..ad472bfed65 100644 --- a/tests/platform_tests/api/watchdog.yml +++ b/tests/platform_tests/api/watchdog.yml @@ -162,3 +162,15 @@ x86_64-8111_32eh_o-r0: valid_timeout: 10 greater_timeout: 6553 too_big_timeout: 6554 + +x86_64-8122_64ehf_o-r0: + default: + valid_timeout: 10 + greater_timeout: 6553 + too_big_timeout: 6554 + +x86_64-8122_64eh_o-r0: + default: + valid_timeout: 10 + greater_timeout: 6553 + too_big_timeout: 6554 From dd64a624c2f4d2c0a2a03e664bb937ea811fb54c Mon Sep 17 00:00:00 2001 From: Charudatta Chitale Date: Sun, 3 Nov 2024 23:54:40 -0800 Subject: [PATCH 056/221] skip vxlan_decap testcase on cisco 8122 platform (#15219) --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index e312663373d..34c09025b31 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -2086,6 +2086,12 @@ vxlan/test_vxlan_crm.py::Test_VxLAN_Crm::test_crm_512_nexthop_groups[v6_in_v6]: - "(is_multi_asic == True) or (platform not in ['x86_64-8102_64h_o-r0', 'x86_64-8101_32fh_o-r0', 'x86_64-mlnx_msn4600c-r0', 'x86_64-mlnx_msn2700-r0', 'x86_64-mlnx_msn2700a1-r0', 'x86_64-kvm_x86_64-r0', 'x86_64-mlnx_msn4700-r0', 'x86_64-nvidia_sn4280-r0'])" - "asic_gen == 'spc1'" +vxlan/test_vxlan_decap.py: + skip: + reason: "vxlan support not available for cisco-8122 platforms" + conditions: + - "platform in ['x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" + vxlan/test_vxlan_ecmp.py: skip: reason: "VxLAN ECMP test is not yet supported on multi-ASIC platform. Also this test can only run on some platforms." From 9c124855d7d70a121deda59978e710cd06cf2ff2 Mon Sep 17 00:00:00 2001 From: Dawei Huang Date: Mon, 4 Nov 2024 18:25:03 -0600 Subject: [PATCH 057/221] Create a test case for testing L2 configuration. (#14714) Reference: https://github.com/sonic-net/SONiC/wiki/L2-Switch-mode ### Description of PR Create a test case for configuring switch to L2 mode. Summary: Add a test case for writing L2 configuration into config DB. This is precursor to a testcase requested in issue 8777 https://github.com/sonic-net/sonic-mgmt/issues/8777 ### Approach Add a test case #### What is the motivation for this PR? Address https://github.com/sonic-net/sonic-mgmt/issues/8777 #### How did you do it? #### How did you verify/test it? Ran on virtual switch. --- tests/l2/test_l2_configure.py | 161 ++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 tests/l2/test_l2_configure.py diff --git a/tests/l2/test_l2_configure.py b/tests/l2/test_l2_configure.py new file mode 100644 index 00000000000..bdb392b9e7f --- /dev/null +++ b/tests/l2/test_l2_configure.py @@ -0,0 +1,161 @@ +""" +Tests related to L2 configuration +""" + +import logging +import pytest + +from tests.common import config_reload +from tests.common.platform.processes_utils import wait_critical_processes +from tests.common.helpers.assertions import pytest_assert + +CONFIG_DB = "/etc/sonic/config_db.json" +CONFIG_DB_BAK = "/etc/sonic/config_db.json.bak" +DUT_IMG_PATH = "/tmp/dut-sonic-img.bin" +LOCALHOST_IMG_PATH = "/tmp/localhost-sonic-img.bin" + +logger = logging.getLogger(__name__) + +pytestmark = [ + pytest.mark.topology("t0"), + pytest.mark.sanity_check(skip_sanity=True), + pytest.mark.disable_loganalyzer, + pytest.mark.skip_check_dut_health, +] + + +@pytest.fixture(autouse=True) +def setup_env(duthosts, rand_one_dut_hostname): + """ + Setup/teardown fixture for each loopback interface test. + rollback to check if it goes back to starting config + + Args: + duthosts: list of DUTs. + rand_selected_dut: The fixture returns a randomly selected DuT. + """ + duthost = duthosts[rand_one_dut_hostname] + duthost.shell("sudo cp {} {}".format(CONFIG_DB, CONFIG_DB_BAK)) + + yield + + duthost.shell("sudo cp {} {}".format(CONFIG_DB_BAK, CONFIG_DB)) + duthost.shell("sudo rm -f {}".format(CONFIG_DB_BAK)) + config_reload(duthost) + wait_critical_processes(duthost) + + +def is_table_empty(duthost, table): + """ + @summary: Verify a table is empty. + + Args: + duthost: DUT host object. + table: Table name to verify. + """ + # grep returns 1 when there is no match, use || true to override that. + count = int( + duthost.shell( + 'sonic-db-cli CONFIG_DB KEYS "{}|*" | grep -c {} || true'.format( + table, table + ) + )["stdout"] + ) + return count == 0 + + +def get_db_version(duthost): + """ + @summary: Get the current database version. + + Args: + duthost: DUT host object. + """ + try: + return duthost.shell('sonic-db-cli CONFIG_DB HGET "VERSIONS|DATABASE" VERSION')[ + "stdout" + ] + except Exception as e: + logger.error("Failed to get database version: {}".format(e)) + return "" + + +def test_no_hardcoded_minigraph(duthosts, rand_one_dut_hostname, tbinfo): + """ + @summary: A testcase asserts no hardcoded minigraph config is imported to config_db during L2 configuration. + + Args: + duthosts: list of DUTs. + rand_one_dut_hostname: The fixture returns a randomly selected DuT. + tbinfo: The testbed information. Needed for configuring management interface. + + """ + # Setup. + duthost = duthosts[rand_one_dut_hostname] + if is_table_empty(duthost, "TELEMETRY") or is_table_empty(duthost, "RESTAPI"): + pytest.skip("TELEMETRY or RESTAPI table is empty. Please load minigraph first.") + + hwsku = duthost.facts["hwsku"] + mgmt_fact = duthost.get_extended_minigraph_facts(tbinfo)["minigraph_mgmt_interface"] + + # Step 2: Configure DUT into L2 mode. + # Save original config + duthost.shell("sudo cp {} {}".format(CONFIG_DB, CONFIG_DB_BAK)) + # Perform L2 configuration + L2_INIT_CFG_FILE = "/tmp/init_l2_cfg.json" + MGMT_CFG_FILE = "/tmp/mgmt_cfg.json" + L2_CFG_FILE = "/tmp/l2_cfg.json" + gen_l2_cfg = "sudo sonic-cfggen --preset l2 -p -H -k {} > {}".format( + hwsku, L2_INIT_CFG_FILE + ) + duthost.shell(gen_l2_cfg) + gen_mgmt_cfg = """ + echo ' + {{ + "MGMT_INTERFACE": {{ + "eth0|{}/{}": {{ + "gwaddr": "{}" + }} + }}, + "DEVICE_METADATA": {{ + "localhost": {{ + "hostname": "{}" + }} + }}, + "MGMT_PORT": {{ + "eth0": {{ + "admin_status": "up", + "alias": "eth0" + }} + }} + }}' > {} + """.format( + mgmt_fact["addr"], + mgmt_fact["prefixlen"], + mgmt_fact["gwaddr"], + duthost.hostname, + MGMT_CFG_FILE, + ) + duthost.shell(gen_mgmt_cfg) + duthost.shell( + "jq -s '.[0] * .[1]' {} {} > {}".format( + L2_INIT_CFG_FILE, MGMT_CFG_FILE, L2_CFG_FILE + ) + ) + duthost.shell("sudo cp {} {}".format(L2_CFG_FILE, CONFIG_DB)) + db_version_before = get_db_version(duthost) + logger.info( + "Database version before L2 configuration reload: {}".format(db_version_before) + ) + config_reload(duthost) + wait_critical_processes(duthost) + db_version_after = get_db_version(duthost) + logger.info( + "Database version after L2 configuration reload: {}".format(db_version_after) + ) + + # Verify no minigraph config is present. + for table in ["TELEMETRY", "RESTAPI"]: + pytest_assert( + is_table_empty(duthost, table), "{} table is not empty!".format(table) + ) From 1d2e5a5d8bf8c86e83a3f0685becd0e5a787a33f Mon Sep 17 00:00:00 2001 From: sreejithsreekumaran <60534136+sreejithsreekumaran@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:09:43 +0530 Subject: [PATCH 058/221] sonic-mgmt/IXIA test to verify the PFC frame sent by DUT has a valid src_mac address (#14825) * Added Ixia snappi test case to verify the src_mac on the DUT sent PFC frame is the src mac of the DUT port itself. * Pick gateway mac which is the router mac and the expected mac on the PFC frame emitted from DUT --- tests/common/snappi_tests/read_pcap.py | 58 +++++ .../pfc/files/cisco_pfc_packet.py | 32 +++ .../files/valid_src_mac_pfc_frame_helper.py | 207 ++++++++++++++++++ .../pfc/test_valid_src_mac_pfc_frame.py | 98 +++++++++ 4 files changed, 395 insertions(+) create mode 100644 tests/snappi_tests/pfc/files/cisco_pfc_packet.py create mode 100644 tests/snappi_tests/pfc/files/valid_src_mac_pfc_frame_helper.py create mode 100644 tests/snappi_tests/pfc/test_valid_src_mac_pfc_frame.py diff --git a/tests/common/snappi_tests/read_pcap.py b/tests/common/snappi_tests/read_pcap.py index 1cd49f62131..f0a522b9576 100644 --- a/tests/common/snappi_tests/read_pcap.py +++ b/tests/common/snappi_tests/read_pcap.py @@ -3,6 +3,7 @@ from dpkt.utils import mac_to_str from tests.common.snappi_tests.pfc_packet import PFCPacket +from tests.snappi_tests.pfc.files.cisco_pfc_packet import CiscoPFCPacket logger = logging.getLogger(__name__) @@ -62,6 +63,63 @@ def validate_pfc_frame(pfc_pcap_file, SAMPLE_SIZE=15000, UTIL_THRESHOLD=0.8): return True, None +def validate_pfc_frame_cisco(pfc_pcap_file, SAMPLE_SIZE=15000, UTIL_THRESHOLD=0.8, peer_mac_addr=None): + """ + Validate PFC frame by checking the CBFC opcode, class enable vector and class pause times. + + Args: + pfc_cap: PFC pcap file + SAMPLE_SIZE: number of packets to sample + UTIL_THRESHOLD: threshold for PFC utilization to check if enough PFC frames were sent + + Returns: + True if valid PFC frame, False otherwise + """ + f = open(pfc_pcap_file, "rb") + pcap = dpkt.pcapng.Reader(f) + seen_non_zero_cev = False # Flag for checking if any PFC frame has non-zero class enable vector + + curPktCount = 0 + curPFCXoffPktCount = 0 + for _, buf in pcap: + if curPFCXoffPktCount >= SAMPLE_SIZE: + break + eth = dpkt.ethernet.Ethernet(buf) + if eth.type == PFC_MAC_CONTROL_CODE: + dest_mac = mac_to_str(eth.dst) + if dest_mac.lower() != PFC_DEST_MAC: + return False, "Destination MAC address is not 01:80:c2:00:00:01" + if peer_mac_addr: + src_mac = mac_to_str(eth.src) + if src_mac.lower() != peer_mac_addr: + return False, "Source MAC address is not the peer's mac address" + pfc_packet = CiscoPFCPacket(pfc_frame_bytes=bytes(eth.data)) + if not pfc_packet.is_valid(): + logger.info("PFC frame {} is not valid. Please check the capture file.".format(curPktCount)) + return False, "PFC frame is not valid" + cev = [int(i) for i in pfc_packet.class_enable_vec] + seen_non_zero_cev = True if sum(cev) > 0 else seen_non_zero_cev + if seen_non_zero_cev: + curPFCXoffPktCount += 1 + curPktCount += 1 + + if not seen_non_zero_cev: + logger.info("No PFC frames with non-zero class enable vector found in the capture file.") + return False, "No PFC frames with non-zero class enable vector found" + + f.close() + pfc_util = curPktCount / SAMPLE_SIZE + + if curPktCount == 0: + logger.info("No PFC frames found in the capture file.") + return False, "No PFC frames found in the capture file" + elif pfc_util < UTIL_THRESHOLD: + logger.info("PFC utilization is too low. Please check the capture file.") + return False, "PFC utilization is too low" + + return True, None + + def get_ipv4_pkts(pcap_file_name, protocol_num=61): """ Get IPv4 packets from the pcap/pcapng file diff --git a/tests/snappi_tests/pfc/files/cisco_pfc_packet.py b/tests/snappi_tests/pfc/files/cisco_pfc_packet.py new file mode 100644 index 00000000000..298e12b12d5 --- /dev/null +++ b/tests/snappi_tests/pfc/files/cisco_pfc_packet.py @@ -0,0 +1,32 @@ +""" +The CiscoPFCPacket module handles Cisco specific PFC frame checks +""" +from tests.common.snappi_tests.pfc_packet import PFCPacket, PRIO_DEFAULT_LEN + + +class CiscoPFCPacket(PFCPacket): + def __init__(self, pfc_frame_bytes=None, cbfc_opcode=None, class_enable_vec=None, class_pause_times=None): + """ + Initialize the PFCPacket base class + + """ + super().__init__(pfc_frame_bytes, cbfc_opcode, class_enable_vec, class_pause_times) + + def _check_class_pause_times(self): + """ + Check if class pause times are valid. Both conditions must be met: + 1) class pause times are between 0x0 and 0xFFFF + 2) class pause times are 0 if the corresponding bit in the class enable vector is 0, and vice versa + + Args: + + Returns: + True if valid class pause times, False otherwise + """ + for i in range(len(self.class_pause_times)): + if self.class_pause_times[i] < 0x0 or self.class_pause_times[i] > 0xFFFF: + return False + elif self.class_pause_times[i] == 0x0 and self.class_enable_vec[PRIO_DEFAULT_LEN - i - 1] == "1": + return False + + return True diff --git a/tests/snappi_tests/pfc/files/valid_src_mac_pfc_frame_helper.py b/tests/snappi_tests/pfc/files/valid_src_mac_pfc_frame_helper.py new file mode 100644 index 00000000000..bda9d53ec45 --- /dev/null +++ b/tests/snappi_tests/pfc/files/valid_src_mac_pfc_frame_helper.py @@ -0,0 +1,207 @@ +import logging +import time + +from tests.common.helpers.assertions import pytest_assert +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts # noqa F401 +from tests.common.snappi_tests.snappi_helpers import get_dut_port_id +from tests.common.snappi_tests.common_helpers import pfc_class_enable_vector,\ + get_lossless_buffer_size, get_pg_dropped_packets,\ + stop_pfcwd, disable_packet_aging, sec_to_nanosec,\ + get_pfc_frame_count, packet_capture, config_capture_pkt,\ + traffic_flow_mode, calc_pfc_pause_flow_rate # noqa F401 +from tests.common.snappi_tests.port import select_ports, select_tx_port # noqa F401 +from tests.common.snappi_tests.snappi_helpers import wait_for_arp # noqa F401 +from tests.common.snappi_tests.traffic_generation import setup_base_traffic_config, generate_test_flows, \ + generate_pause_flows, run_traffic, verify_basic_test_flow +from tests.common.snappi_tests.snappi_test_params import SnappiTestParams +from tests.common.snappi_tests.read_pcap import validate_pfc_frame_cisco + +logger = logging.getLogger(__name__) + +dut_port_config = [] +PAUSE_FLOW_NAME = 'Pause Storm' +TEST_FLOW_NAME = 'Test Flow' +TEST_FLOW_AGGR_RATE_PERCENT = 45 +data_flow_pkt_size = 1024 +DATA_FLOW_DURATION_SEC = 5 +data_flow_delay_sec = 1 +TOLERANCE_THRESHOLD = 0.05 +ANSIBLE_POLL_DELAY_SEC = 4 + + +def run_pfc_valid_src_mac_test( + api, + testbed_config, + port_config_list, + conn_data, + fanout_data, + duthost, + dut_port, + global_pause, + pause_prio_list, + test_prio_list, + prio_dscp_map, + test_traffic_pause, + snappi_extra_params=None): + """ + Run a PFC test + Args: + api (obj): snappi session + testbed_config (obj): testbed L1/L2/L3 configuration + port_config_list (list): list of port configuration + conn_data (dict): the dictionary returned by conn_graph_fact. + fanout_data (dict): the dictionary returned by fanout_graph_fact. + duthost (Ansible host instance): device under test + dut_port (str): DUT port to test + global_pause (bool): if pause frame is IEEE 802.3X pause + pause_prio_list (list): priorities to pause for pause frames + test_prio_list (list): priorities of test flows + prio_dscp_map (dict): Priority vs. DSCP map (key = priority). + test_traffic_pause (bool): if test flows are expected to be paused + snappi_extra_params (SnappiTestParams obj): additional parameters for Snappi traffic + + Returns: + N/A + """ + + pytest_assert(testbed_config is not None, 'Fail to get L2/3 testbed config') + + if snappi_extra_params is None: + snappi_extra_params = SnappiTestParams() + + stop_pfcwd(duthost) + disable_packet_aging(duthost) + global DATA_FLOW_DURATION_SEC + global data_flow_delay_sec + + # Get the ID of the port to test + port_id = get_dut_port_id(dut_hostname=duthost.hostname, + dut_port=dut_port, + conn_data=conn_data, + fanout_data=fanout_data) + + pytest_assert(port_id is not None, + 'Fail to get ID for port {}'.format(dut_port)) + + # Rate percent must be an integer + test_flow_rate_percent = int(TEST_FLOW_AGGR_RATE_PERCENT / len(test_prio_list)) + + # Generate base traffic config + snappi_extra_params.base_flow_config = setup_base_traffic_config(testbed_config=testbed_config, + port_config_list=port_config_list, + port_id=port_id) + + speed_str = testbed_config.layer1[0].speed + speed_gbps = int(speed_str.split('_')[1]) + + if snappi_extra_params.poll_device_runtime: + # If the switch needs to be polled as traffic is running for stats, + # then the test runtime needs to be increased for the polling delay + DATA_FLOW_DURATION_SEC += ANSIBLE_POLL_DELAY_SEC + data_flow_delay_sec = ANSIBLE_POLL_DELAY_SEC + + if snappi_extra_params.packet_capture_type != packet_capture.NO_CAPTURE: + # Setup capture config + if snappi_extra_params.is_snappi_ingress_port_cap: + # packet capture is required on the ingress snappi port + snappi_extra_params.packet_capture_ports = [snappi_extra_params.base_flow_config["rx_port_name"]] + else: + # packet capture will be on the egress snappi port + snappi_extra_params.packet_capture_ports = [snappi_extra_params.base_flow_config["tx_port_name"]] + + snappi_extra_params.packet_capture_file = snappi_extra_params.packet_capture_type.value + + config_capture_pkt(testbed_config=testbed_config, + port_names=snappi_extra_params.packet_capture_ports, + capture_type=snappi_extra_params.packet_capture_type, + capture_name=snappi_extra_params.packet_capture_file) + logger.info("Packet capture file: {}.pcapng".format(snappi_extra_params.packet_capture_file)) + + # Set default traffic flow configs if not set + if snappi_extra_params.traffic_flow_config.data_flow_config is None: + snappi_extra_params.traffic_flow_config.data_flow_config = { + "flow_name": TEST_FLOW_NAME, + "flow_dur_sec": DATA_FLOW_DURATION_SEC, + "flow_rate_percent": test_flow_rate_percent, + "flow_rate_pps": None, + "flow_rate_bps": None, + "flow_pkt_size": data_flow_pkt_size, + "flow_pkt_count": None, + "flow_delay_sec": data_flow_delay_sec, + "flow_traffic_type": traffic_flow_mode.FIXED_DURATION + } + + if snappi_extra_params.traffic_flow_config.pause_flow_config is None: + snappi_extra_params.traffic_flow_config.pause_flow_config = { + "flow_name": PAUSE_FLOW_NAME, + "flow_dur_sec": None, + "flow_rate_percent": None, + "flow_rate_pps": calc_pfc_pause_flow_rate(speed_gbps), + "flow_rate_bps": None, + "flow_pkt_size": 64, + "flow_pkt_count": None, + "flow_delay_sec": 0, + "flow_traffic_type": traffic_flow_mode.CONTINUOUS + } + + if snappi_extra_params.packet_capture_type == packet_capture.PFC_CAPTURE: + # PFC pause frame capture is requested + validate_pfc_frame = True + else: + # PFC pause frame capture is not requested + validate_pfc_frame = False + + # Generate test flow config + generate_test_flows(testbed_config=testbed_config, + test_flow_prio_list=test_prio_list, + prio_dscp_map=prio_dscp_map, + snappi_extra_params=snappi_extra_params) + + # Generate pause storm config + generate_pause_flows(testbed_config=testbed_config, + pause_prio_list=pause_prio_list, + global_pause=global_pause, + snappi_extra_params=snappi_extra_params) + + flows = testbed_config.flows + + all_flow_names = [flow.name for flow in flows] + data_flow_names = [flow.name for flow in flows if PAUSE_FLOW_NAME not in flow.name] + + # Clear PFC, queue and interface counters before traffic run + duthost.command(" sonic-clear pfccounters") + duthost.command("sonic-clear queuecounters") + duthost.command("sonic-clear counters") + time.sleep(1) + + """ Run traffic """ + tgen_flow_stats, _, _ = run_traffic( + duthost=duthost, + api=api, + config=testbed_config, + data_flow_names=data_flow_names, + all_flow_names=all_flow_names, + exp_dur_sec=DATA_FLOW_DURATION_SEC + + data_flow_delay_sec, + snappi_extra_params=snappi_extra_params) + + # Reset pfc delay parameter + pfc = testbed_config.layer1[0].flow_control.ieee_802_1qbb + pfc.pfc_delay = 0 + + # Verify PFC pause frames + if validate_pfc_frame: + peer_mac_addr = snappi_extra_params.base_flow_config["rx_port_config"].gateway_mac + is_valid_pfc_frame, error_msg = validate_pfc_frame_cisco( + snappi_extra_params.packet_capture_file + ".pcapng", + peer_mac_addr=peer_mac_addr) + pytest_assert(is_valid_pfc_frame, error_msg) + return + + # Verify basic test flows metrics from ixia + verify_basic_test_flow(flow_metrics=tgen_flow_stats, + speed_gbps=speed_gbps, + tolerance=TOLERANCE_THRESHOLD, + test_flow_pause=test_traffic_pause, + snappi_extra_params=snappi_extra_params) diff --git a/tests/snappi_tests/pfc/test_valid_src_mac_pfc_frame.py b/tests/snappi_tests/pfc/test_valid_src_mac_pfc_frame.py new file mode 100644 index 00000000000..fddc0408ee5 --- /dev/null +++ b/tests/snappi_tests/pfc/test_valid_src_mac_pfc_frame.py @@ -0,0 +1,98 @@ +import logging +import pytest + + +from tests.snappi_tests.pfc.files.valid_src_mac_pfc_frame_helper import run_pfc_valid_src_mac_test +from tests.common.helpers.assertions import pytest_require +from tests.common.fixtures.conn_graph_facts import conn_graph_facts,\ + fanout_graph_facts # noqa F401 +from tests.common.snappi_tests.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port,\ + snappi_api, snappi_testbed_config, is_snappi_multidut # noqa F401 +from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, all_prio_list, lossless_prio_list,\ + lossy_prio_list # noqa F401 +from tests.common.snappi_tests.snappi_test_params import SnappiTestParams +from tests.common.snappi_tests.common_helpers import packet_capture +from tests.common.cisco_data import is_cisco_device + +logger = logging.getLogger(__name__) + +pytestmark = [pytest.mark.topology('tgen')] + + +def test_valid_pfc_frame_src_mac( + snappi_api, # noqa F811 + snappi_testbed_config, # noqa F811 + conn_graph_facts, # noqa F811 + fanout_graph_facts, # noqa F811 + duthosts, + rand_one_dut_hostname, + rand_one_dut_portname_oper_up, + lossless_prio_list, # noqa F811 + prio_dscp_map): # noqa F811 + """ + Test if PFC Pause frame generated by device under test (DUT) is having a valid src mac + + Topology: + snappi (1) -> DUT -> snappi (2) + + Test steps: + 1) Create congestion on ingress port of ixia (snappi 2). This is done by letting 1 send data traffic to 2, and 2 + sending PFC pause frames to DUT. + 2) tgen 2 sends PFC pause frames to DUT. + 3) DUT responds to PFC frames by also sending back PFC pause frames back to tgen 1. + 4) Using packet capture on tgen 1 port, verify PFC pause frames meet IEEE 802.1Qbb code point standards. + a) There is a pause quanta specified in the frame (value between 0x0 and 0xFFFF). + b) There is a valid class enable vector set on the frame - an 8-bit mask that specifies + which 802.1p priority levels should be paused. + c) The destination MAC address on the frame is "01:80:c2:00:00:01" + d) The source MAC address on the frame is of the DUT port + + Args: + snappi_api (pytest fixture): SNAPPI session + snappi_testbed_config (pytest fixture): testbed configuration information + conn_graph_facts (pytest fixture): connection graph + fanout_graph_facts (pytest fixture): fanout graph + duthosts (pytest fixture): list of DUTs + rand_one_dut_hostname (str): hostname of DUT + rand_one_dut_portname_oper_up (str): port to test, e.g., 's6100-1|Ethernet0' + lossless_prio_list (pytest fixture): list of all the lossless priorities + prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). + + Returns: + N/A + """ + + dut_hostname, dut_port = rand_one_dut_portname_oper_up.split('|') + pytest_require(rand_one_dut_hostname == dut_hostname, + "Port is not mapped to the expected DUT") + + testbed_config, port_config_list = snappi_testbed_config + duthost = duthosts[rand_one_dut_hostname] + + if not is_cisco_device(duthost): + pytest.skip("Test is supported on Cisco device only") + + if is_snappi_multidut(duthosts): + pytest.skip("Test is not supported on multi-dut") + + pause_prio_list = lossless_prio_list + test_prio_list = lossless_prio_list + + snappi_extra_params = SnappiTestParams() + snappi_extra_params.packet_capture_type = packet_capture.PFC_CAPTURE + snappi_extra_params.is_snappi_ingress_port_cap = False + + run_pfc_valid_src_mac_test( + api=snappi_api, + testbed_config=testbed_config, + port_config_list=port_config_list, + conn_data=conn_graph_facts, + fanout_data=fanout_graph_facts, + duthost=duthost, + dut_port=dut_port, + global_pause=False, + pause_prio_list=pause_prio_list, + test_prio_list=test_prio_list, + prio_dscp_map=prio_dscp_map, + test_traffic_pause=True, + snappi_extra_params=snappi_extra_params) From 96167cccbad2c677db530e04f3befe2d41af5660 Mon Sep 17 00:00:00 2001 From: sreejithsreekumaran <60534136+sreejithsreekumaran@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:10:21 +0530 Subject: [PATCH 059/221] Fixed the failure of test_valid_pfc_frame_with_snappi.py in Cisco DUT (#15002) * Fixed the testcase as Cisco DUT generates XON frames. This causes the PFC capture sampling to not detect a XOFF frame being capture. Further the buffer size for capture could be small or big depending on the IXIA model capabaility Hence using continous XOFF injection to avoid overwriting the buffer with XON frames post a XON-XOFF-XON transition * Made !is_cisco do regular else cisco specific --- tests/snappi_tests/pfc/files/helper.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/snappi_tests/pfc/files/helper.py b/tests/snappi_tests/pfc/files/helper.py index 154e5fd17bf..89216bf0b96 100644 --- a/tests/snappi_tests/pfc/files/helper.py +++ b/tests/snappi_tests/pfc/files/helper.py @@ -18,7 +18,8 @@ verify_in_flight_buffer_pkts, verify_unset_cev_pause_frame_count, verify_tx_frame_count_dut, \ verify_rx_frame_count_dut from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.common.snappi_tests.read_pcap import validate_pfc_frame +from tests.common.cisco_data import is_cisco_device +from tests.common.snappi_tests.read_pcap import validate_pfc_frame, validate_pfc_frame_cisco logger = logging.getLogger(__name__) @@ -191,7 +192,7 @@ def run_pfc_test(api, # PFC pause frame capture is not requested valid_pfc_frame_test = False - if valid_pfc_frame_test: + if valid_pfc_frame_test and not is_cisco_device(duthost): snappi_extra_params.traffic_flow_config.pause_flow_config["flow_dur_sec"] = DATA_FLOW_DURATION_SEC + \ data_flow_delay_sec + SNAPPI_POLL_DELAY_SEC + PAUSE_FLOW_DUR_BASE_SEC snappi_extra_params.traffic_flow_config.pause_flow_config["flow_traffic_type"] = \ @@ -245,7 +246,11 @@ def run_pfc_test(api, # Verify PFC pause frames if valid_pfc_frame_test: - is_valid_pfc_frame, error_msg = validate_pfc_frame(snappi_extra_params.packet_capture_file + ".pcapng") + if not is_cisco_device(duthost): + is_valid_pfc_frame, error_msg = validate_pfc_frame(snappi_extra_params.packet_capture_file + ".pcapng") + else: + is_valid_pfc_frame, error_msg = validate_pfc_frame_cisco( + snappi_extra_params.packet_capture_file + ".pcapng") pytest_assert(is_valid_pfc_frame, error_msg) return From ac8695759c6ab649b8285798dcdc00dd42dbf8e2 Mon Sep 17 00:00:00 2001 From: rbpittman Date: Tue, 5 Nov 2024 01:41:18 -0500 Subject: [PATCH 060/221] Cisco-8122 Q watermark test update (#15328) * Revise qsharedwatermark test for gr2 to no longer refill the queue as with other asics. Add lower margin on final check on the q shared watermark test case. * Remove extra dut_asic setting. --- .../conditional_mark/tests_mark_conditions.yaml | 2 +- tests/qos/test_qos_sai.py | 3 ++- tests/saitests/py3/sai_qos_tests.py | 17 +++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 34c09025b31..c56f6addd7f 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1516,7 +1516,7 @@ qos/test_qos_sai.py::TestQosSai::testQosSaiLossyQueueVoqMultiSrc: reason: "Lossy Queue Voq multiple source test is not supported / M0/MX topo does not support qos" conditions_logical_operator: or conditions: - - "asic_type not in ['cisco-8000']" + - "asic_type not in ['cisco-8000'] or platform in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" qos/test_qos_sai.py::TestQosSai::testQosSaiPGDrop: diff --git a/tests/qos/test_qos_sai.py b/tests/qos/test_qos_sai.py index 06152d3300b..270799e8f02 100644 --- a/tests/qos/test_qos_sai.py +++ b/tests/qos/test_qos_sai.py @@ -1839,7 +1839,8 @@ def testQosSaiQSharedWatermark( "pkts_num_fill_min": qosConfig[queueProfile]["pkts_num_fill_min"], "pkts_num_trig_drp": triggerDrop, "cell_size": qosConfig[queueProfile]["cell_size"], - "hwsku": dutTestParams['hwsku'] + "hwsku": dutTestParams['hwsku'], + "dut_asic": dutConfig["dutAsic"] }) if "platform_asic" in dutTestParams["basicParams"]: diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index 86369ffff56..dd5b159f684 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -5003,6 +5003,7 @@ def runTest(self): cell_size = int(self.test_params['cell_size']) hwsku = self.test_params['hwsku'] platform_asic = self.test_params['platform_asic'] + dut_asic = self.test_params['dut_asic'] if 'packet_size' in list(self.test_params.keys()): packet_length = int(self.test_params['packet_size']) @@ -5056,6 +5057,9 @@ def runTest(self): recv_counters_base, _ = sai_thrift_read_port_counters(self.src_client, asic_type, port_list['src'][src_port_id]) xmit_counters_base, _ = sai_thrift_read_port_counters(self.dst_client, asic_type, port_list['dst'][dst_port_id]) self.sai_thrift_port_tx_disable(self.dst_client, asic_type, [dst_port_id]) + if 'cisco-8000' in asic_type: + fill_leakout_plus_one(self, src_port_id, dst_port_id, pkt, queue, asic_type) + pg_cntrs_base = sai_thrift_read_pg_counters(self.src_client, port_list['src'][src_port_id]) dst_pg_cntrs_base = sai_thrift_read_pg_counters(self.dst_client, port_list['dst'][dst_port_id]) q_wm_res_base, pg_shared_wm_res_base, pg_headroom_wm_res_base = sai_thrift_read_port_watermarks( @@ -5133,6 +5137,7 @@ def runTest(self): else: pkts_num = 1 + margin fragment = 0 + refill_queue = 'cisco-8000' in asic_type and dut_asic != 'gr2' while (expected_wm < total_shared - fragment): expected_wm += pkts_num * cell_occupancy if (expected_wm > total_shared): @@ -5142,9 +5147,9 @@ def runTest(self): expected_wm -= diff * cell_occupancy fragment = total_shared - expected_wm - if 'cisco-8000' in asic_type: + if refill_queue: self.sai_thrift_port_tx_disable(self.dst_client, asic_type, [dst_port_id]) - assert (fill_leakout_plus_one(self, src_port_id, dst_port_id, pkt, queue, asic_type)) + fill_leakout_plus_one(self, src_port_id, dst_port_id, pkt, queue, asic_type) pkts_total += pkts_num pkts_num = pkts_total - 1 @@ -5153,7 +5158,7 @@ def runTest(self): send_packet(self, src_port_id, pkt, pkts_num) - if 'cisco-8000' in asic_type: + if refill_queue: self.sai_thrift_port_tx_enable( self.dst_client, asic_type, [dst_port_id]) @@ -5205,7 +5210,7 @@ def runTest(self): pkts_num = pkts_inc - if 'cisco-8000' in asic_type: + if refill_queue: self.sai_thrift_port_tx_disable(self.dst_client, asic_type, [dst_port_id]) fill_leakout_plus_one( self, src_port_id, dst_port_id, pkt, queue, asic_type) @@ -5215,7 +5220,7 @@ def runTest(self): # overflow the shared pool send_packet(self, src_port_id, pkt, pkts_num) - if 'cisco-8000' in asic_type: + if refill_queue: self.sai_thrift_port_tx_enable(self.dst_client, asic_type, [dst_port_id]) time.sleep(8) @@ -5243,7 +5248,7 @@ def runTest(self): logging.info("On J2C+ don't support SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES " + "stat - so ignoring this step for now") else: - assert (expected_wm * cell_size <= q_wm_res[queue]) + assert ((expected_wm - margin) * cell_size <= q_wm_res[queue]) assert (q_wm_res[queue] <= (expected_wm + margin) * cell_size) finally: From 6c722e2122d435eaa439ce92d3b56b905783bffa Mon Sep 17 00:00:00 2001 From: rbpittman Date: Tue, 5 Nov 2024 01:41:55 -0500 Subject: [PATCH 061/221] Ansible error formatting (#15208) * Revise ansible error formatting. * Revise to assume stdout_lines and stderr_lines are present. pre-commit. * Revert "Revise to assume stdout_lines and stderr_lines are present." This reverts commit 5f002ae9f92f266778f425bb1a80fb5a3904a924. * Revise to assume stdout_lines and stderr_lines are present. * Remove excess newlines. --- tests/common/errors.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/tests/common/errors.py b/tests/common/errors.py index 7f7d3f7cb98..d162ac26d5c 100644 --- a/tests/common/errors.py +++ b/tests/common/errors.py @@ -2,19 +2,31 @@ Customize exceptions """ from ansible.errors import AnsibleError -from ansible.plugins.loader import callback_loader class UnsupportedAnsibleModule(Exception): pass -def dump_ansible_results(results, stdout_callback='json'): - try: - cb = callback_loader.get(stdout_callback) - return cb._dump_results(results) if cb else results - except Exception: - return str(results) +def dump_ansible_results(results): + """Dump ansible results in a clean format. + Prints simple attributes printed first, followed by the stdout and stderr.""" + simple_attrs = "" + stdout = "stdout =\n" + stderr = "stderr =\n" + for key in results: + if key in ['stdout', 'stderr']: + # Use stdout_lines and stderr_lines instead + continue + if '_lines' in key: + text = "\n".join(results[key]) + if key == 'stdout_lines': + stdout += text + else: + stderr += text + else: + simple_attrs += "{} = {}\n".format(key, results[key]) + return "{}{}{}".format(simple_attrs, stdout, stderr) class RunAnsibleModuleFail(AnsibleError): From 039bab7a5af8c36f9af7371b49d86e48751f4541 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:37:21 +0800 Subject: [PATCH 062/221] Add dummy ptf.testutils library to skip traffic test in KVM (#15322) What is the motivation for this PR? Currently we are using marker "skip_traffic_test" to decide whether to run traffic test or not. Then the marker would pass to a fixture called by each data plane testcase. This approach is only applied in master branch, which cause a lot of code change in test scripts, and difficult to do cherry pick. How did you do it? Based on the marker "skip_traffic_test", use a testcase level pytest hook to get the marker, if it exists, then setattr to a function always return for all testutils function startwith "send" or "verify", and setattr back when test finished. How did you verify/test it? Verified in KVM test Any platform specific information? Supported testbed topology if it's a new test case? --- tests/common/dualtor/tunnel_traffic_utils.py | 7 ++++- .../plugins/ptfadapter/dummy_testutils.py | 28 +++++++++++++++++++ tests/conftest.py | 16 +++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/common/plugins/ptfadapter/dummy_testutils.py diff --git a/tests/common/dualtor/tunnel_traffic_utils.py b/tests/common/dualtor/tunnel_traffic_utils.py index 7e59f3c2d8e..14b4f7786e4 100644 --- a/tests/common/dualtor/tunnel_traffic_utils.py +++ b/tests/common/dualtor/tunnel_traffic_utils.py @@ -297,11 +297,16 @@ def __exit__(self, *exc_info): logging.info("Skip tunnel traffic verify due to traffic test was skipped.") return try: - port_index, rec_pkt = testutils.verify_packet_any_port( + result = testutils.verify_packet_any_port( ptfadapter, self.exp_pkt, ports=self.listen_ports ) + if isinstance(result, tuple): + port_index, rec_pkt = result + elif isinstance(result, bool): + logging.info("Using dummy testutils to skip traffic test.") + return except AssertionError as detail: logging.debug("Error occurred in polling for tunnel traffic", exc_info=True) if "Did not receive expected packet on any of ports" in str(detail): diff --git a/tests/common/plugins/ptfadapter/dummy_testutils.py b/tests/common/plugins/ptfadapter/dummy_testutils.py new file mode 100644 index 00000000000..f88b087556b --- /dev/null +++ b/tests/common/plugins/ptfadapter/dummy_testutils.py @@ -0,0 +1,28 @@ +import ptf.testutils as testutils +import inspect +import logging + +logger = logging.getLogger(__name__) + + +def wrapped(*args, **kwargs): + return True + + +class DummyTestUtils: + def __init__(self, *args, **kwargs): + func_dict = {} + for name, func in inspect.getmembers(testutils, inspect.isfunction): + if name.startswith("verify"): + func_dict[name] = func + self.func_dict = func_dict + + def __enter__(self, *args, **kwargs): + """ enter in 'with' block """ + for name, func in self.func_dict.items(): + setattr(testutils, name, wrapped) + + def __exit__(self, *args, **kwargs): + """ exit from 'with' block """ + for name, func in self.func_dict.items(): + setattr(testutils, name, self.func_dict[name]) diff --git a/tests/conftest.py b/tests/conftest.py index 8e9e7ce2674..b9ba2c76de9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -66,6 +66,7 @@ from tests.common.helpers.assertions import pytest_assert as pt_assert from tests.common.helpers.inventory_utils import trim_inventory from tests.common.utilities import InterruptableThread +from tests.common.plugins.ptfadapter.dummy_testutils import DummyTestUtils try: from tests.macsec import MacsecPluginT2, MacsecPluginT0 @@ -991,6 +992,21 @@ def pytest_runtest_makereport(item, call): setattr(item, "rep_" + rep.when, rep) +# This function is a pytest hook implementation that is called in runtest call stage. +# We are using this hook to set ptf.testutils to DummyTestUtils if the test is marked with "skip_traffic_test", +# DummyTestUtils would always return True for all verify function in ptf.testutils. +@pytest.hookimpl(tryfirst=True, hookwrapper=True) +def pytest_runtest_call(item): + if "skip_traffic_test" in item.keywords: + logger.info("Got skip_traffic_test marker, will skip traffic test") + with DummyTestUtils(): + logger.info("Set ptf.testutils to DummyTestUtils to skip traffic test") + yield + logger.info("Reset ptf.testutils") + else: + yield + + def collect_techsupport_on_dut(request, a_dut): # request.node is an "item" because we use the default # "function" scope From c96e78659324af2bf41aa68625f32801c279819b Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:52:53 +0800 Subject: [PATCH 063/221] Add mgmt branch parameter in pytest-collect-only.yml (#15348) What is the motivation for this PR? Currently pytest-collect-only.yml check only support running on self branch, but in some scenarios we need to use it in target branch. How did you do it? Add a new parameter mgmt_branch in pytest-collect-only.yml to support running on target branch How did you verify/test it? --- .azure-pipelines/pytest-collect-only.yml | 5 +++++ azure-pipelines.yml | 2 ++ 2 files changed, 7 insertions(+) diff --git a/.azure-pipelines/pytest-collect-only.yml b/.azure-pipelines/pytest-collect-only.yml index 6d1d2bca9e0..afbfef7cd7a 100644 --- a/.azure-pipelines/pytest-collect-only.yml +++ b/.azure-pipelines/pytest-collect-only.yml @@ -34,6 +34,11 @@ steps: - script: | set -x + if [ -n "${{ parameters.MGMT_BRANCH }}" ]; then + git branch -D ${{ parameters.MGMT_BRANCH }} || true + git checkout -b ${{ parameters.MGMT_BRANCH }} origin/${{ parameters.MGMT_BRANCH }} + fi + sudo docker exec -t -w /var/src/sonic-mgmt/tests sonic-mgmt-collect \ python3 -m pytest --inventory ../ansible/veos_vtb --host-pattern all \ --testbed_file vtestbed.yaml --testbed vms-kvm-t0 \ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5ffbf11de09..c06c4b0bfca 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -40,6 +40,8 @@ stages: pool: sonic-common steps: - template: .azure-pipelines/pytest-collect-only.yml + parameters: + MGMT_BRANCH: "" - stage: Test dependsOn: Pre_test From b55378f2722ab2610689ba5b7c7299ec00238adb Mon Sep 17 00:00:00 2001 From: Changrong Wu Date: Tue, 5 Nov 2024 15:37:27 -0800 Subject: [PATCH 064/221] Add new test cases to verify route consistency before and after critical processes crash (#15151) Summary: Fixes # (issue) #14983 Approach What is the motivation for this PR? To address the test gap raised by the issue. How did you do it? I added 3 cases each of which tests the route consistency of the DUT before and after a type of critical processes crash. Now the test cover the following critical processes: bgpd in bgp container syncd in syncd container orchagent in swss container How did you verify/test it? I verified it on t0, t1 and t2 testbeds in MSFT internal lab devices. --- tests/common/utilities.py | 28 ++++ .../test_critical_process_monitoring.py | 30 +---- tests/route/test_route_consistency.py | 123 +++++++++++++++++- 3 files changed, 146 insertions(+), 35 deletions(-) diff --git a/tests/common/utilities.py b/tests/common/utilities.py index 760e885deb7..8c8e2d70410 100644 --- a/tests/common/utilities.py +++ b/tests/common/utilities.py @@ -1358,3 +1358,31 @@ def run_show_features(duthosts, enum_dut_hostname): .format(cmd_key), module_ignore_errors=False)['stdout'] pytest_assert(redis_value.lower() == cmd_value.lower(), "'{}' is '{}' which does not match with config_db".format(cmd_key, cmd_value)) + + +def kill_process_by_pid(duthost, container_name, program_name, program_pid): + """Kills a process in the specified container by its pid. + + Args: + duthost: Hostname of DUT. + container_name: A string shows container name. + program_name: A string shows process name. + program_pid: An integer represents the PID of a process. + + Returns: + None. + """ + if "20191130" in duthost.os_version: + kill_cmd_result = duthost.shell("docker exec {} supervisorctl stop {}".format(container_name, program_name)) + else: + # If we used the command `supervisorctl stop ' to stop process, + # Supervisord will treat the exit code of process as expected and it will not generate + # alerting message. + kill_cmd_result = duthost.shell("docker exec {} kill -SIGKILL {}".format(container_name, program_pid)) + + # Get the exit code of 'kill' or 'supervisorctl stop' command + exit_code = kill_cmd_result["rc"] + pytest_assert(exit_code == 0, "Failed to stop program '{}' before test".format(program_name)) + + logger.info("Program '{}' in container '{}' was stopped successfully" + .format(program_name, container_name)) diff --git a/tests/process_monitoring/test_critical_process_monitoring.py b/tests/process_monitoring/test_critical_process_monitoring.py index 6626c7f5260..b99fcf190f8 100755 --- a/tests/process_monitoring/test_critical_process_monitoring.py +++ b/tests/process_monitoring/test_critical_process_monitoring.py @@ -18,7 +18,7 @@ from tests.common.helpers.dut_utils import get_group_program_info from tests.common.helpers.dut_utils import is_container_running from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer -from tests.common.utilities import wait_until +from tests.common.utilities import wait_until, kill_process_by_pid logger = logging.getLogger(__name__) @@ -371,34 +371,6 @@ def get_containers_namespace_ids(duthost, skip_containers): return containers_in_namespaces -def kill_process_by_pid(duthost, container_name, program_name, program_pid): - """Kills a process in the specified container by its pid. - - Args: - duthost: Hostname of DUT. - container_name: A string shows container name. - program_name: A string shows process name. - program_pid: An integer represents the PID of a process. - - Returns: - None. - """ - if "20191130" in duthost.os_version: - kill_cmd_result = duthost.shell("docker exec {} supervisorctl stop {}".format(container_name, program_name)) - else: - # If we used the command `supervisorctl stop ' to stop process, - # Supervisord will treat the exit code of process as expected and it will not generate - # alerting message. - kill_cmd_result = duthost.shell("docker exec {} kill -SIGKILL {}".format(container_name, program_pid)) - - # Get the exit code of 'kill' or 'supervisorctl stop' command - exit_code = kill_cmd_result["rc"] - pytest_assert(exit_code == 0, "Failed to stop program '{}' before test".format(program_name)) - - logger.info("Program '{}' in container '{}' was stopped successfully" - .format(program_name, container_name)) - - def check_and_kill_process(duthost, container_name, program_name, program_status, program_pid): """Checks the running status of a critical process. If it is running, kill it. Otherwise, fail this test. diff --git a/tests/route/test_route_consistency.py b/tests/route/test_route_consistency.py index f36cfdf0935..f106951688d 100644 --- a/tests/route/test_route_consistency.py +++ b/tests/route/test_route_consistency.py @@ -1,8 +1,14 @@ import pytest import logging +import threading +import queue import re import time import math +from tests.common.helpers.assertions import pytest_assert +from tests.common.helpers.dut_utils import get_program_info +from tests.common.config_reload import config_reload +from tests.common.utilities import kill_process_by_pid, wait_until pytestmark = [ pytest.mark.topology('any') @@ -11,6 +17,38 @@ logger = logging.getLogger(__name__) +def check_and_kill_process(duthost, container_name, program_name): + """Checks the running status of a critical process. If it is running, kill it. Otherwise, + fail this test. + + Args: + duthost: Hostname of DUT. + container_name: A string shows container name. + program_name: A string shows process name. + + Returns: + None. + """ + program_status, program_pid = get_program_info(duthost, container_name, program_name) + if program_status == "RUNNING": + kill_process_by_pid(duthost, container_name, program_name, program_pid) + elif program_status in ["EXITED", "STOPPED", "STARTING"]: + pytest.fail("Program '{}' in container '{}' is in the '{}' state, expected 'RUNNING'" + .format(program_name, container_name, program_status)) + else: + pytest.fail("Failed to find program '{}' in container '{}'" + .format(program_name, container_name)) + + +def is_all_neighbor_session_established(duthost): + # handle both multi-asic and single-asic + bgp_facts = duthost.bgp_facts(num_npus=duthost.sonichost.num_asics())["ansible_facts"] + for neighbor in bgp_facts["bgp_neighbors"]: + if bgp_facts["bgp_neighbors"][neighbor]["state"] != "established": + return False + return True + + class TestRouteConsistency(): """ TestRouteConsistency class for testing route consistency across all the Frontend DUTs in the testbed It verifies route consistency by taking a snapshot of route table from ASIC_DB from all the DUTs before the test @@ -28,16 +66,34 @@ def extract_dest_ips(self, route_entries): def get_route_prefix_snapshot_from_asicdb(self, duthosts): prefix_snapshot = {} max_prefix_cnt = 0 + + def retrieve_route_snapshot(asic, prefix_snapshot, dut_instance_name, signal_queue): + prefix_snapshot[dut_instance_name] = \ + set(self.extract_dest_ips(asic.run_sonic_db_cli_cmd('ASIC_DB KEYS *ROUTE_ENTRY*')['stdout_lines'])) + logger.debug("snapshot of route table from {}: {}".format(dut_instance_name, + len(prefix_snapshot[dut_instance_name]))) + signal_queue.put(1) + + thread_count = 0 + signal_queue = queue.Queue() for idx, dut in enumerate(duthosts.frontend_nodes): for asic in dut.asics: dut_instance_name = dut.hostname + '-' + str(asic.asic_index) if dut.facts['switch_type'] == "voq" and idx == 0: dut_instance_name = dut_instance_name + "UpstreamLc" - prefix_snapshot[dut_instance_name] = \ - set(self.extract_dest_ips(asic.run_sonic_db_cli_cmd('ASIC_DB KEYS *ROUTE_ENTRY*')['stdout_lines'])) - logger.debug("snapshot of route table from {}: {}".format(dut_instance_name, - len(prefix_snapshot[dut_instance_name]))) - max_prefix_cnt = max(max_prefix_cnt, len(prefix_snapshot[dut_instance_name])) + threading.Thread(target=retrieve_route_snapshot, args=(asic, prefix_snapshot, + dut_instance_name, signal_queue)).start() + thread_count += 1 + + ts1 = time.time() + while signal_queue.qsize() < thread_count: + ts2 = time.time() + if (ts2 - ts1) > 60: + raise TimeoutError("Get route prefix snapshot from asicdb Timeout!") + continue + + for dut_instance_name in prefix_snapshot.keys(): + max_prefix_cnt = max(max_prefix_cnt, len(prefix_snapshot[dut_instance_name])) return prefix_snapshot, max_prefix_cnt @pytest.fixture(scope="class", autouse=True) @@ -49,7 +105,7 @@ def setup(self, duthosts): withdraw and advertise the routes by peers. """ self.__class__.sleep_interval = math.ceil(max_prefix_cnt/3000) + 120 - logger.debug("max_no_of_prefix: {} sleep_interval: {}".format(max_prefix_cnt, self.sleep_interval)) + logger.info("max_no_of_prefix: {} sleep_interval: {}".format(max_prefix_cnt, self.sleep_interval)) def test_route_withdraw_advertise(self, duthosts, tbinfo, localhost): @@ -137,3 +193,58 @@ def test_bgp_shut_noshut(self, duthosts, enum_rand_one_per_hwsku_frontend_hostna # startup bgp back in case of any exception duthost.shell("sudo config bgp startup all") time.sleep(self.sleep_interval) + + @pytest.mark.disable_loganalyzer + @pytest.mark.parametrize("container_name, program_name", [ + ("bgp", "bgpd"), + ("syncd", "syncd"), + ("swss", "orchagent") + ]) + def test_critical_process_crash_and_recover(self, duthosts, container_name, program_name): + duthost = None + for idx, dut in enumerate(duthosts.frontend_nodes): + if dut.facts['switch_type'] == "voq" and idx == 0: + # pick a UpstreamLC to get higher route churn in VoQ chassis + duthost = dut + if duthost is None: + duthost = duthosts[0] + logger.info("test_{}_crash_and_recover: DUT{}".format(program_name, duthost.hostname)) + + namespace_ids, succeeded = duthost.get_namespace_ids(container_name) + pytest_assert(succeeded, "Failed to get namespace ids of container '{}'".format(container_name)) + logger.info("namespace_ids: {}".format(namespace_ids)) + + try: + logger.info("kill {}(s) for {}".format(program_name, duthost.hostname)) + for id in namespace_ids: + if id is None: + id = "" + check_and_kill_process(duthost, container_name + str(id), program_name) + time.sleep(30) + + post_withdraw_route_snapshot, _ = self.get_route_prefix_snapshot_from_asicdb(duthosts) + num_routes_withdrawn = 0 + for dut_instance_name in self.pre_test_route_snapshot.keys(): + if num_routes_withdrawn == 0: + num_routes_withdrawn = len(self.pre_test_route_snapshot[dut_instance_name] - + post_withdraw_route_snapshot[dut_instance_name]) + logger.info("num_routes_withdrawn: {}".format(num_routes_withdrawn)) + else: + assert num_routes_withdrawn == len(self.pre_test_route_snapshot[dut_instance_name] - + post_withdraw_route_snapshot[dut_instance_name]) + + logger.info("Recover containers on {}".format(duthost.hostname)) + config_reload(duthost) + wait_until(300, 10, 0, is_all_neighbor_session_established, duthost) + time.sleep(self.sleep_interval) + + # take the snapshot of route table from all the DUTs + post_test_route_snapshot, _ = self.get_route_prefix_snapshot_from_asicdb(duthosts) + for dut_instance_name in self.pre_test_route_snapshot.keys(): + assert self.pre_test_route_snapshot[dut_instance_name] == post_test_route_snapshot[dut_instance_name] + logger.info("Route table is consistent across all the DUTs") + except Exception: + # startup bgpd back in case of any exception + logger.info("Encountered error. Perform a config reload to recover!") + config_reload(duthost) + time.sleep(self.sleep_interval) From dd6bafb0b7ef653f8873c43beec15641adeea874 Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:18:55 -0800 Subject: [PATCH 065/221] Fix conflicted skiping condition for test_pfc_asym (#15327) --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index c56f6addd7f..aeb3773a23a 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1259,12 +1259,6 @@ pfc_asym/test_pfc_asym.py: conditions: - "asic_type not in ['barefoot']" -pfc_asym/test_pfc_asym.py::test_pfc_asym_off_rx_pause_frames: - skip: - reason: "skipped for Barefoot platform" - conditions: - - "asic_type in ['barefoot']" - ####################################### ##### pfcwd ##### ####################################### From 61b3ba589958d804d9fac1797bf6b49907ac4346 Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:26:05 +0800 Subject: [PATCH 066/221] Add static route check for test_nhop_group test (#14475) Add the static route validation in cases of weak switch Change-Id: I83f2a9a2318adbf901b94f82dcc39b9362d43f78 --- tests/ipfwd/test_nhop_group.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/ipfwd/test_nhop_group.py b/tests/ipfwd/test_nhop_group.py index d9f5e683a4f..31711c18098 100644 --- a/tests/ipfwd/test_nhop_group.py +++ b/tests/ipfwd/test_nhop_group.py @@ -324,6 +324,17 @@ def build_pkt(dest_mac, ip_addr, ttl, flow_count): return pkt, exp_packet +def validate_asic_route(duthost, route, exist=True): + logger.info(f"Checking ip route: {route}") + asic_info = duthost.shell(f'redis-cli -n 1 keys "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:*{route}*"', + module_ignore_errors=True)["stdout"] + if route in asic_info: + logger.info(f"Matched ASIC route: {asic_info}") + return exist is True + else: + return exist is False + + def test_nhop_group_member_count(duthost, tbinfo, loganalyzer): """ Test next hop group resource count. Steps: @@ -534,8 +545,9 @@ def built_and_send_tcp_ip_packet(): nhop.add_ip_route(ip_prefix, ips) nhop.program_routes() - # wait for routes to be synced and programmed - time.sleep(15) + + pytest_assert(wait_until(60, 5, 0, validate_asic_route, duthost, ip_prefix), + f"Static route: {ip_prefix} is failed to be programmed!") ptfadapter.dataplane.flush() @@ -565,6 +577,8 @@ def built_and_send_tcp_ip_packet(): asic.start_service("bgp") time.sleep(15) nhop.delete_routes() + pytest_assert(wait_until(60, 5, 0, validate_asic_route, duthost, ip_prefix, False), + f"Static route: {ip_prefix} is failed to be removed!") arplist.clean_up() th_asic_flow_map = {0: 'c0:ff:ee:00:00:12', 1: 'c0:ff:ee:00:00:10', From 8fdd1a498c974d34c639c5697bf185d999a8994f Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:54:14 +0800 Subject: [PATCH 067/221] [CI] Enhance elastictest template and test_plan.py, fix az token issue (#15342) What is the motivation for this PR? [CI] Enhance elastictest template and test_plan.py, fix az token issue How did you do it? Use bash script instead azcli task to fix s360 task. Enhance azlogin and get token logic to fix token expiration issue. Derectly specify MGMT_BRANCH to "master" to avoid download test_plan.py from master branch. Other Code readability optimization. How did you verify/test it? Can be vefied in this PR. Need pass. Signed-off-by: Chun'ang Li --- .../run-test-elastictest-template.yml | 343 ++++++++---------- .azure-pipelines/test_plan.py | 334 ++++++++--------- azure-pipelines.yml | 20 +- 3 files changed, 331 insertions(+), 366 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 595a6cb3136..882ab9ce6b9 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -1,3 +1,10 @@ +# Description: +# - This template manages the entire life cycle of the Elastictest test plan in test pipelines. +# +# Important!!!: +# - This template is referenced in multiple pipelines. +# - Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. + parameters: - name: TOPOLOGY type: string @@ -184,206 +191,176 @@ steps: fi displayName: "Install azure-cli" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - - pip install PyYAML - - rm -f new_test_plan_id.txt - - python ./.azure-pipelines/test_plan.py create \ - -t ${{ parameters.TOPOLOGY }} \ - -o new_test_plan_id.txt \ - --min-worker ${{ parameters.MIN_WORKER }} \ - --max-worker ${{ parameters.MAX_WORKER }} \ - --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ - --test-set ${{ parameters.TEST_SET }} \ - --kvm-build-id $(KVM_BUILD_ID) \ - --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ - --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ - --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ - --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ - --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ - --image_url ${{ parameters.IMAGE_URL }} \ - --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ - --hwsku ${{ parameters.HWSKU }} \ - --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ - --platform ${{ parameters.PLATFORM }} \ - --testbed-name "${{ parameters.TESTBED_NAME }}" \ - --scripts "${{ parameters.SCRIPTS }}" \ - --features "${{ parameters.FEATURES }}" \ - --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ - --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ - --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ - --affinity='${{ parameters.AFFINITY }}' \ - --build-reason ${{ parameters.BUILD_REASON }} \ - --repo-name ${{ parameters.REPO_NAME }} \ - --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ - --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ - --retry-times ${{ parameters.RETRY_TIMES }} \ - --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ - --requester "${{ parameters.REQUESTER }}" \ - --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ - --test-plan-num ${{ parameters.TEST_PLAN_NUM }} - - TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo "Created test plan $TEST_PLAN_ID" - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - done - TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") - TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} - echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" + - script: | + set -e + + pip install PyYAML + + rm -f new_test_plan_id.txt + + python ./.azure-pipelines/test_plan.py create \ + -t ${{ parameters.TOPOLOGY }} \ + -o new_test_plan_id.txt \ + --min-worker ${{ parameters.MIN_WORKER }} \ + --max-worker ${{ parameters.MAX_WORKER }} \ + --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ + --test-set ${{ parameters.TEST_SET }} \ + --kvm-build-id $(KVM_BUILD_ID) \ + --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ + --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ + --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ + --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ + --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ + --image_url ${{ parameters.IMAGE_URL }} \ + --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ + --hwsku ${{ parameters.HWSKU }} \ + --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ + --platform ${{ parameters.PLATFORM }} \ + --testbed-name "${{ parameters.TESTBED_NAME }}" \ + --scripts "${{ parameters.SCRIPTS }}" \ + --features "${{ parameters.FEATURES }}" \ + --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ + --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ + --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ + --affinity='${{ parameters.AFFINITY }}' \ + --build-reason ${{ parameters.BUILD_REASON }} \ + --repo-name ${{ parameters.REPO_NAME }} \ + --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ + --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --retry-times ${{ parameters.RETRY_TIMES }} \ + --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ + --requester "${{ parameters.REQUESTER }}" \ + --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ + --test-plan-num ${{ parameters.TEST_PLAN_NUM }} + + TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo "Created test plan $TEST_PLAN_ID" + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + done + TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") + TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} + echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" displayName: "Trigger test" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Lock testbed" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" - echo "[test_plan.py] poll LOCK_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Lock testbed" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" + echo "[test_plan.py] poll LOCK_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Lock testbed" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Prepare testbed" - echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" - echo "[test_plan.py] poll PREPARE_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Prepare testbed" + echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" + echo "[test_plan.py] poll PREPARE_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Prepare testbed" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Run test" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" - echo "[test_plan.py] poll EXECUTING status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Run test" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" + echo "[test_plan.py] poll EXECUTING status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Run test" timeoutInMinutes: ${{ parameters.MAX_RUN_TEST_MINUTES }} - ${{ if eq(parameters.DUMP_KVM_IF_FAIL, 'True') }}: - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - echo "KVM dump" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" - echo "##[group][test_plan.py] poll KVMDUMP status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP - done + - script: | + set -e + echo "KVM dump" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" + echo "##[group][test_plan.py] poll KVMDUMP status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP + done condition: succeededOrFailed() displayName: "KVM dump" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID - done + - script: | + set -e + echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID + done condition: always() displayName: "Finalize running test plan" diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index f4b07bb2d18..1cc48fdbd31 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -1,3 +1,12 @@ +""" +Description: +- This script provides access to Elastictest test plan API, including creating, canceling, and polling status. + +Important!!!: +- This script is downloaded in multiple pipelines. +- Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. +""" + from __future__ import print_function, division import argparse @@ -8,7 +17,7 @@ import subprocess import copy import time -from datetime import datetime, timedelta +from datetime import datetime, timezone import requests import yaml @@ -22,8 +31,7 @@ INTERNAL_SONIC_MGMT_REPO = "https://dev.azure.com/mssonic/internal/_git/sonic-mgmt-int" PR_TEST_SCRIPTS_FILE = "pr_test_scripts.yaml" SPECIFIC_PARAM_KEYWORD = "specific_param" -TOLERATE_HTTP_EXCEPTION_TIMES = 20 -TOKEN_EXPIRE_HOURS = 1 +MAX_POLL_RETRY_TIMES = 10 MAX_GET_TOKEN_RETRY_TIMES = 3 TEST_PLAN_STATUS_UNSUCCESSFUL_FINISHED = ["FAILED", "CANCELLED"] TEST_PLAN_STEP_STATUS_UNFINISHED = ["EXECUTING", None] @@ -83,13 +91,15 @@ def __init__(self, status): def get_status(self): return self.status.value - def print_logs(self, test_plan_id, resp_data, start_time): + def print_logs(self, test_plan_id, resp_data, expected_status, start_time): status = resp_data.get("status", None) current_status = test_plan_status_factory(status).get_status() if current_status == self.get_status(): - print("Test plan id: {}, status: {}, elapsed: {:.0f} seconds" - .format(test_plan_id, resp_data.get("status", None), time.time() - start_time)) + print( + f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " + f"expected_status: {expected_status}, elapsed: {time.time() - start_time:.0f} seconds" + ) class InitStatus(AbstractStatus): @@ -111,10 +121,12 @@ class ExecutingStatus(AbstractStatus): def __init__(self): super(ExecutingStatus, self).__init__(TestPlanStatus.EXECUTING) - def print_logs(self, test_plan_id, resp_data, start_time): - print("Test plan id: {}, status: {}, progress: {:.2f}%, elapsed: {:.0f} seconds" - .format(test_plan_id, resp_data.get("status", None), - resp_data.get("progress", 0) * 100, time.time() - start_time)) + def print_logs(self, test_plan_id, resp_data, expected_status, start_time): + print( + f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " + f"expected_status: {expected_status}, progress: {resp_data.get('progress', 0) * 100:.2f}%, " + f"elapsed: {time.time() - start_time:.0f} seconds" + ) class KvmDumpStatus(AbstractStatus): @@ -150,74 +162,81 @@ def parse_list_from_str(s): if single_str.strip()] +def run_cmd(cmd): + process = subprocess.Popen( + cmd.split(), + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + return_code = process.returncode + + if return_code != 0: + raise Exception(f'Command {cmd} execution failed, rc={return_code}, error={stderr}') + return stdout, stderr, return_code + + class TestPlanManager(object): - def __init__(self, scheduler_url, community_url, frontend_url, client_id=None): + def __init__(self, scheduler_url, frontend_url, client_id, managed_identity_id): self.scheduler_url = scheduler_url - self.community_url = community_url self.frontend_url = frontend_url self.client_id = client_id - self.with_auth = False - self._token = None - self._token_expires_on = None - if self.client_id: - self.with_auth = True - self.get_token() - - def cmd(self, cmds): - process = subprocess.Popen( - cmds, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - stdout, stderr = process.communicate() - return_code = process.returncode - - return stdout, stderr, return_code - - def az_run(self, cmd): - stdout, stderr, retcode = self.cmd(cmd.split()) - if retcode != 0: - raise Exception(f'Command {cmd} execution failed, rc={retcode}, error={stderr}') - return stdout, stderr, retcode + self.managed_identity_id = managed_identity_id def get_token(self): - token_is_valid = \ - self._token_expires_on is not None and \ - (self._token_expires_on - datetime.now()) > timedelta(hours=TOKEN_EXPIRE_HOURS) + # 1. Run az login with re-try + az_login_cmd = f"az login --identity --username {self.managed_identity_id}" + az_login_attempts = 0 + while az_login_attempts < MAX_GET_TOKEN_RETRY_TIMES: + try: + stdout, _, _ = run_cmd(az_login_cmd) + print(f"Az login successfully. Login time: {datetime.now(timezone.utc)}") + break + except Exception as exception: + az_login_attempts += 1 + print( + f"Failed to az login with exception: {repr(exception)}. " + f"Retry {MAX_GET_TOKEN_RETRY_TIMES - az_login_attempts} times to login." + ) - if self._token is not None and token_is_valid: - return self._token + # If az login failed, return with exception + if az_login_attempts >= MAX_GET_TOKEN_RETRY_TIMES: + raise Exception(f"Failed to az login after {MAX_GET_TOKEN_RETRY_TIMES} attempts.") - cmd = 'az account get-access-token --resource {}'.format(self.client_id) - attempt = 0 - while attempt < MAX_GET_TOKEN_RETRY_TIMES: + # 2. Get access token with re-try + get_token_cmd = f"az account get-access-token --resource {self.client_id}" + get_token_attempts = 0 + while get_token_attempts < MAX_GET_TOKEN_RETRY_TIMES: try: - stdout, _, _ = self.az_run(cmd) + stdout, _, _ = run_cmd(get_token_cmd) token = json.loads(stdout.decode("utf-8")) - self._token = token.get("accessToken", None) - if not self._token: - raise Exception("Parse token from stdout failed") + access_token = token.get("accessToken", None) + if not access_token: + raise Exception("Parse token from stdout failed, accessToken is None.") # Parse token expires time from string token_expires_on = token.get("expiresOn", "") - self._token_expires_on = datetime.strptime(token_expires_on, "%Y-%m-%d %H:%M:%S.%f") - print("Get token successfully.") - return self._token + if token_expires_on: + print(f"Get token successfully. Token will expire on {token_expires_on}.") + + return access_token except Exception as exception: - attempt += 1 - print("Failed to get token with exception: {}".format(repr(exception))) + get_token_attempts += 1 + print(f"Failed to get token with exception: {repr(exception)}.") - raise Exception("Failed to get token after {} attempts".format(MAX_GET_TOKEN_RETRY_TIMES)) + # If az get token failed, return with exception + if get_token_attempts >= MAX_GET_TOKEN_RETRY_TIMES: + raise Exception(f"Failed to get token after {MAX_GET_TOKEN_RETRY_TIMES} attempts") def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params="", kvm_build_id="", min_worker=None, max_worker=None, pr_id="unknown", output=None, common_extra_params="", **kwargs): - tp_url = "{}/test_plan".format(self.scheduler_url) + tp_url = f"{self.scheduler_url}/test_plan" testbed_name = parse_list_from_str(kwargs.get("testbed_name", None)) image_url = kwargs.get("image_url", None) hwsku = kwargs.get("hwsku", None) @@ -229,8 +248,10 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) - print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, - repo_name, pr_id, build_id)) + print( + f"Creating test plan, topology: {topology}, name: {test_plan_name}, " + f"build info:{repo_name} {pr_id} {build_id}" + ) print("Test scripts to be covered in this test plan:") print(json.dumps(scripts, indent=4)) @@ -320,10 +341,9 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "extra_params": {}, "priority": 10 } - print('Creating test plan with payload:\n{}'.format(json.dumps(payload, indent=4))) + print(f"Creating test plan with payload:\n{json.dumps(payload, indent=4)}") headers = { - "Authorization": "Bearer {}".format(self.get_token()), - "scheduler-site": "PRTest", + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } raw_resp = {} @@ -331,17 +351,16 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params raw_resp = requests.post(tp_url, headers=headers, data=json.dumps(payload), timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" - .format(tp_url, str(raw_resp), str(exception))) + raise Exception(f"HTTP execute failure, url: {tp_url}, raw_resp: {raw_resp}, exception: {str(exception)}") if not resp["data"]: - raise Exception("Pre deploy action failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Create test plan failed with error: {resp['errmsg']}") if not resp["success"]: - raise Exception("Create test plan failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Create test plan failed with error: {resp['errmsg']}") - print("Result of creating test plan: {}".format(str(resp["data"]))) + print(f"Result of creating test plan: {str(resp['data'])}") if output: - print("Store new test plan id to file {}".format(output)) + print(f"Store new test plan id to file {output}") with open(output, "a") as f: f.write(str(resp["data"]) + "\n") @@ -349,15 +368,14 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params def cancel(self, test_plan_id): - tp_url = "{}/test_plan/{}".format(self.scheduler_url, test_plan_id) - cancel_url = "{}/cancel".format(tp_url) + tp_url = f"{self.scheduler_url}/test_plan/{test_plan_id}" + cancel_url = f"{tp_url}/cancel" - print("Cancelling test plan at {}".format(cancel_url)) + print(f"Cancelling test plan at {cancel_url}") payload = json.dumps({}) headers = { - "Authorization": "Bearer {}".format(self.get_token()), - "scheduler-site": "PRTest", + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } @@ -366,73 +384,57 @@ def cancel(self, test_plan_id): raw_resp = requests.post(cancel_url, headers=headers, data=payload, timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" - .format(cancel_url, str(raw_resp), str(exception))) + raise Exception(f"HTTP execute failure, url: {cancel_url}, raw_resp: {str(raw_resp)}, " + f"exception: {str(exception)}") if not resp["success"]: - raise Exception("Cancel test plan failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Cancel test plan failed with error: {resp['errmsg']}") - print("Result of cancelling test plan at {}:".format(tp_url)) + print(f"Result of cancelling test plan at {tp_url}:") print(str(resp["data"])) def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expected_result=None): - print("Polling progress and status of test plan at {}/scheduler/testplan/{}" - .format(self.frontend_url, test_plan_id)) - print("Polling interval: {} seconds".format(interval)) + print(f"Polling progress and status of test plan at {self.frontend_url}/scheduler/testplan/{test_plan_id}") + print(f"Polling interval: {interval} seconds") - poll_url = "{}/test_plan/{}/get_test_plan_status".format(self.scheduler_url, test_plan_id) - poll_url_no_auth = "{}/get_test_plan_status/{}".format(self.community_url, test_plan_id) + poll_url = f"{self.scheduler_url}/test_plan/{test_plan_id}/get_test_plan_status" + # In current polling task, initialize headers one time to avoid frequent token accessing + # For some tasks running over 24h, then token may expire, need a fresh headers = { + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } start_time = time.time() - http_exception_times = 0 - http_exception_times_no_auth = 0 - failed_poll_auth_url = False + poll_retry_times = 0 while timeout < 0 or (time.time() - start_time) < timeout: resp = None - # To make the transition smoother, first try to access the original API - if not failed_poll_auth_url: - try: - if self.with_auth: - headers["Authorization"] = "Bearer {}".format(self.get_token()) - resp = requests.get(poll_url, headers=headers, timeout=10).json() - except Exception as exception: - print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url, resp, - str(exception))) - http_exception_times = http_exception_times + 1 - if http_exception_times >= TOLERATE_HTTP_EXCEPTION_TIMES: - failed_poll_auth_url = True - else: - time.sleep(interval) - continue - - # If failed on poll auth url(most likely token has expired), try with no-auth url - else: - print("Polling test plan status failed with auth url, try with no-auth url.") - try: - resp = requests.get(poll_url_no_auth, headers={"Content-Type": "application/json"}, - timeout=10).json() - except Exception as e: - print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, - repr(e))) - http_exception_times_no_auth = http_exception_times_no_auth + 1 - if http_exception_times_no_auth >= TOLERATE_HTTP_EXCEPTION_TIMES: - raise Exception( - "HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, - repr(e))) - else: - time.sleep(interval) - continue + try: + resp = requests.get(poll_url, headers=headers, timeout=10).json() - if not resp: - raise Exception("Poll test plan status failed with request error, no response!") + if not resp: + raise Exception("Poll test plan status failed with request error, no response!") - if not resp["success"]: - raise Exception("Query test plan at {} failed with error: {}".format(poll_url, resp["errmsg"])) + if not resp["success"]: + raise Exception(f"Get test plan status failed with error: {resp['errmsg']}") + + resp_data = resp.get("data", None) + if not resp_data: + raise Exception("No valid data in response.") + + except Exception as exception: + print(f"Failed to get valid response, url: {poll_url}, raw_resp: {resp}, exception: {str(exception)}") - resp_data = resp.get("data", None) - if not resp_data: - raise Exception("No valid data in response: {}".format(str(resp))) + # Refresh headers token to address token expiration issue + headers = { + "Authorization": f"Bearer {self.get_token()}", + "Content-Type": "application/json" + } + + poll_retry_times = poll_retry_times + 1 + if poll_retry_times >= MAX_POLL_RETRY_TIMES: + raise Exception("Poll test plan status failed, exceeded the maximum number of retries.") + else: + time.sleep(interval) + continue current_tp_status = resp_data.get("status", None) current_tp_result = resp_data.get("result", None) @@ -441,11 +443,10 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte current_status = test_plan_status_factory(current_tp_status) expected_status = test_plan_status_factory(expected_state) - print("current test plan status: {}, expected status: {}".format(current_tp_status, expected_state)) + current_status.print_logs(test_plan_id, resp_data, expected_state, start_time) - if expected_status.get_status() == current_status.get_status(): - current_status.print_logs(test_plan_id, resp_data, start_time) - elif expected_status.get_status() < current_status.get_status(): + # If test plan has finished current step, its now status will behind the expected status + if expected_status.get_status() < current_status.get_status(): steps = None step_status = None runtime = resp_data.get("runtime", None) @@ -460,7 +461,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print test summary test_summary = resp_data.get("runtime", {}).get("test_summary", None) if test_summary: - print("Test summary:\n{}".format(json.dumps(test_summary, indent=4))) + print(f"Test summary:\n{json.dumps(test_summary, indent=4)}") """ In below scenarios, need to return false to pipeline. @@ -477,38 +478,34 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print error type and message err_code = resp_data.get("runtime", {}).get("err_code", None) if err_code: - print("Error type: {}".format(err_code)) + print(f"Error type: {err_code}") err_msg = resp_data.get("runtime", {}).get("message", None) if err_msg: - print("Error message: {}".format(err_msg)) + print(f"Error message: {err_msg}") - raise Exception("Test plan id: {}, status: {}, result: {}, Elapsed {:.0f} seconds. " - "Check {}/scheduler/testplan/{} for test plan status" - .format(test_plan_id, step_status, current_tp_result, time.time() - start_time, - self.frontend_url, - test_plan_id)) + raise Exception( + f"Test plan id: {test_plan_id}, status: {step_status}, " + f"result: {current_tp_result}, Elapsed {time.time() - start_time:.0f} seconds. " + f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" + ) if expected_result: if current_tp_result != expected_result: - raise Exception("Test plan id: {}, status: {}, result: {} not match expected result: {}, " - "Elapsed {:.0f} seconds. " - "Check {}/scheduler/testplan/{} for test plan status" - .format(test_plan_id, step_status, current_tp_result, - expected_result, time.time() - start_time, - self.frontend_url, - test_plan_id)) - - print("Current step status is {}".format(step_status)) + raise Exception( + f"Test plan id: {test_plan_id}, status: {step_status}, " + f"result: {current_tp_result} not match expected result: {expected_result}, " + f"Elapsed {time.time() - start_time:.0f} seconds. " + f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" + ) + + print(f"Current step status is {step_status}.") return - else: - print("Current test plan state is {}, waiting for the expected state {}".format(current_tp_status, - expected_state)) time.sleep(interval) else: raise PollTimeoutException( - "Max polling time reached, test plan at {} is not successfully finished or cancelled".format(poll_url) + f"Max polling time reached, test plan at {poll_url} is not successfully finished or cancelled" ) @@ -930,30 +927,28 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # https://github.com/microsoft/azure-pipelines-tasks/issues/10331 args.test_plan_id = args.test_plan_id.replace("'", "") - print("Test plan utils parameters: {}".format(args)) - auth_env = ["CLIENT_ID"] - required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL"] + print(f"Test plan utils parameters: {args}") - if args.action in ["create", "cancel"]: - required_env.extend(auth_env) + required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL", "CLIENT_ID", "SONIC_AUTOMATION_UMI"] env = { - "elastictest_scheduler_backend_url": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), - "elastictest_community_url": os.environ.get("ELASTICTEST_COMMUNITY_URL"), - "client_id": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), - "frontend_url": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), + "ELASTICTEST_SCHEDULER_BACKEND_URL": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), + "CLIENT_ID": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), + "FRONTEND_URL": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), + "SONIC_AUTOMATION_UMI": os.environ.get("SONIC_AUTOMATION_UMI"), } env_missing = [k.upper() for k, v in env.items() if k.upper() in required_env and not v] if env_missing: - print("Missing required environment variables: {}".format(env_missing)) + print(f"Missing required environment variables: {env_missing}.") sys.exit(1) try: tp = TestPlanManager( - env["elastictest_scheduler_backend_url"], - env["elastictest_community_url"], - env["frontend_url"], - env["client_id"]) + env["ELASTICTEST_SCHEDULER_BACKEND_URL"], + env["FRONTEND_URL"], + env["CLIENT_ID"], + env["SONIC_AUTOMATION_UMI"] + ) if args.action == "create": pr_id = os.environ.get("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") or os.environ.get( @@ -964,14 +959,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte job_name = os.environ.get("SYSTEM_JOBDISPLAYNAME") repo_name = args.repo_name if args.repo_name else os.environ.get("BUILD_REPOSITORY_NAME") - test_plan_prefix = "{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}" \ - .format( - repo=repo, - reason=reason, - pr_id=pr_id, - build_id=build_id, - job_name=job_name - ).replace(' ', '_') + test_plan_prefix = f"{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}".replace(' ', '_') scripts = args.scripts specific_param = json.loads(args.specific_param) @@ -989,7 +977,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte for num in range(args.test_plan_num): test_plan_name = copy.copy(test_plan_prefix) if args.test_plan_num > 1: - test_plan_name = "{}_{}".format(test_plan_name, num + 1) + test_plan_name = f"{test_plan_name}_{num + 1}" tp.create( args.topology, @@ -1033,8 +1021,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte tp.cancel(args.test_plan_id) sys.exit(0) except PollTimeoutException as e: - print("Polling test plan failed with exception: {}".format(repr(e))) + print(f"Polling test plan failed with exception: {repr(e)}") sys.exit(2) except Exception as e: - print("Operation failed with exception: {}".format(repr(e))) + print(f"Operation failed with exception: {repr(e)}") sys.exit(3) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c06c4b0bfca..cebd7d40d8a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -71,7 +71,7 @@ stages: MIN_WORKER: $(T0_INSTANCE_NUM) MAX_WORKER: $(T0_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: t0_2vlans_elastictest displayName: "kvmtest-t0-2vlans by Elastictest" @@ -87,7 +87,7 @@ stages: MAX_WORKER: $(T0_2VLANS_INSTANCE_NUM) DEPLOY_MG_EXTRA_PARAMS: "-e vlan_config=two_vlan_a" KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: t1_lag_elastictest displayName: "kvmtest-t1-lag by Elastictest" @@ -101,7 +101,7 @@ stages: MIN_WORKER: $(T1_LAG_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: dualtor_elastictest displayName: "kvmtest-dualtor-t0 by Elastictest" @@ -116,7 +116,7 @@ stages: MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) COMMON_EXTRA_PARAMS: "--disable_loganalyzer " KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: multi_asic_elastictest displayName: "kvmtest-multi-asic-t1-lag by Elastictest" @@ -132,7 +132,7 @@ stages: MAX_WORKER: $(MULTI_ASIC_INSTANCE_NUM) NUM_ASIC: 4 KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: sonic_t0_elastictest displayName: "kvmtest-t0-sonic by Elastictest" @@ -149,7 +149,7 @@ stages: COMMON_EXTRA_PARAMS: "--neighbor_type=sonic " VM_TYPE: vsonic KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: dpu_elastictest displayName: "kvmtest-dpu by Elastictest" @@ -163,7 +163,7 @@ stages: MIN_WORKER: $(T0_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: onboarding_elastictest_t0 displayName: "onboarding t0 testcases by Elastictest - optional" @@ -179,7 +179,7 @@ stages: MIN_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" TEST_SET: onboarding_t0 - job: onboarding_elastictest_t1 @@ -196,7 +196,7 @@ stages: MIN_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" TEST_SET: onboarding_t1 # - job: onboarding_elastictest_dualtor @@ -213,7 +213,7 @@ stages: # MIN_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # KVM_IMAGE_BRANCH: $(BUILD_BRANCH) -# MGMT_BRANCH: $(BUILD_BRANCH) +# MGMT_BRANCH: "master" # TEST_SET: onboarding_dualtor # - job: wan_elastictest From f91b5395ed5de6bc6e1600cfedf68254eb6a801e Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:57:03 +0800 Subject: [PATCH 068/221] Add snappi tests to PR test skip yml (#15365) What is the motivation for this PR? Elastictest performs well in distribute running PR test in multiple KVMs, which support us to add more test scripts to PR checker. Meanwhile, we are using .azure-pipelines/testscripts_analyse/ to static test scripts have been added or not, if a test script need to skip in KVM test, need to add it to .azure-pipelines/pr_test_skip_scripts.yaml and we would mark it as checked/covered. Based on that, snappi test could not run on KVM platform, so need to add these tests to .azure-pipelines/pr_test_skip_scripts.yaml How did you do it? Add snappi test scripts to .azure-pipelines/pr_test_skip_scripts.yaml How did you verify/test it? Co-authored-by: xwjiang2021 <96218837+xwjiang2021@users.noreply.github.com> --- .azure-pipelines/pr_test_skip_scripts.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.azure-pipelines/pr_test_skip_scripts.yaml b/.azure-pipelines/pr_test_skip_scripts.yaml index e3aaa8fb502..f233f470736 100644 --- a/.azure-pipelines/pr_test_skip_scripts.yaml +++ b/.azure-pipelines/pr_test_skip_scripts.yaml @@ -216,6 +216,7 @@ tgen: - snappi_tests/bgp/test_bgp_rib_in_convergence.py - snappi_tests/bgp/test_bgp_scalability.py - snappi_tests/ecn/test_dequeue_ecn_with_snappi.py + - snappi_tests/ecn/test_ecn_marking_cisco8000.py - snappi_tests/ecn/test_red_accuracy_with_snappi.py - snappi_tests/multidut/bgp/test_bgp_outbound_downlink_port_flap.py - snappi_tests/multidut/bgp/test_bgp_outbound_downlink_process_crash.py @@ -239,6 +240,7 @@ tgen: - snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py - snappi_tests/multidut/pfcwd/test_multidut_pfcwd_burst_storm_with_snappi.py - snappi_tests/multidut/pfcwd/test_multidut_pfcwd_m2o_with_snappi.py + - snappi_tests/multidut/pfcwd/test_multidut_pfcwd_runtime_traffic_with_snappi.py - snappi_tests/lacp/test_add_remove_link_from_dut.py - snappi_tests/lacp/test_add_remove_link_physically.py - snappi_tests/lacp/test_lacp_timers_effect.py @@ -255,6 +257,7 @@ tgen: - snappi_tests/pfcwd/test_pfcwd_m2o_with_snappi.py - snappi_tests/pfcwd/test_pfcwd_runtime_traffic_with_snappi.py - snappi_tests/qos/test_ipip_packet_reorder_with_snappi.py + - snappi_tests/test_multidut_snappi.py snappi: # Snappi test only support on physical snappi testbed From ee38900fcb8b5ef9c400154622e58c250656acfc Mon Sep 17 00:00:00 2001 From: Zhaohui Sun <94606222+ZhaohuiS@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:08:44 +0800 Subject: [PATCH 069/221] Fix mismatch between show lldp table and the content of lldp entry table (#15337) * Fix mismatch between show lldp table and the content of lldp entry table Signed-off-by: Zhaohui Sun * Get lldp content after reboot Signed-off-by: Zhaohui Sun --------- Signed-off-by: Zhaohui Sun --- tests/lldp/test_lldp_syncd.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/lldp/test_lldp_syncd.py b/tests/lldp/test_lldp_syncd.py index 7cce1ec3b14..361188f0dc1 100644 --- a/tests/lldp/test_lldp_syncd.py +++ b/tests/lldp/test_lldp_syncd.py @@ -46,6 +46,7 @@ def get_lldp_entry_keys(dbs): for db in dbs: items = db.get_keys("LLDP_ENTRY_TABLE*") lldp_entries.extend([key.split(":")[1] for key in items]) + logger.debug("lldp entry keys: {}".format(lldp_entries)) return lldp_entries @@ -54,6 +55,7 @@ def get_lldp_entry_content(dbs, interface): lldp_content = {} for db in dbs: lldp_content.update(db.hget_all("LLDP_ENTRY_TABLE:{}".format(interface))) + logger.debug("lldp entry content: {}".format(lldp_content)) return lldp_content @@ -288,7 +290,7 @@ def test_lldp_entry_table_after_lldp_restart( for asic in duthost.asics: duthost.shell("sudo systemctl restart {}".format(asic.get_service_name('lldp'))) result = wait_until( - 60, 2, 5, verify_lldp_table, duthost + 60, 2, 20, verify_lldp_table, duthost ) # Adjust based on LLDP service restart time pytest_assert(result, "no output for show lldp table after restarting lldp") for asic in duthost.asics: @@ -320,10 +322,6 @@ def test_lldp_entry_table_after_reboot( localhost, duthosts, enum_rand_one_per_hwsku_frontend_hostname, db_instance ): duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] - lldp_entry_keys = get_lldp_entry_keys(db_instance) - show_lldp_table_int_list = get_show_lldp_table_output(duthost) - lldpctl_output = get_lldpctl_output(duthost) - # reboot logging.info("Run cold reboot on DUT") reboot( @@ -335,6 +333,9 @@ def test_lldp_entry_table_after_reboot( safe_reboot=True, check_intf_up_ports=True ) + lldp_entry_keys = get_lldp_entry_keys(db_instance) + lldpctl_output = get_lldpctl_output(duthost) + show_lldp_table_int_list = get_show_lldp_table_output(duthost) lldpctl_interfaces = lldpctl_output["lldp"]["interface"] assert_lldp_interfaces( lldp_entry_keys, show_lldp_table_int_list, lldpctl_interfaces From 0b7f233ab511bb4fd06d59ae51ab64dc597a1e27 Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:27:50 +0800 Subject: [PATCH 070/221] =?UTF-8?q?Revert=20"[CI]=20Enhance=20elastictest?= =?UTF-8?q?=20template=20and=20test=5Fplan.py,=20fix=20az=20token=20issu?= =?UTF-8?q?=E2=80=A6"=20(#15376)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8fdd1a498c974d34c639c5697bf185d999a8994f. --- .../run-test-elastictest-template.yml | 343 ++++++++++-------- .azure-pipelines/test_plan.py | 334 +++++++++-------- azure-pipelines.yml | 20 +- 3 files changed, 366 insertions(+), 331 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 882ab9ce6b9..595a6cb3136 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -1,10 +1,3 @@ -# Description: -# - This template manages the entire life cycle of the Elastictest test plan in test pipelines. -# -# Important!!!: -# - This template is referenced in multiple pipelines. -# - Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. - parameters: - name: TOPOLOGY type: string @@ -191,176 +184,206 @@ steps: fi displayName: "Install azure-cli" - - script: | - set -e - - pip install PyYAML - - rm -f new_test_plan_id.txt - - python ./.azure-pipelines/test_plan.py create \ - -t ${{ parameters.TOPOLOGY }} \ - -o new_test_plan_id.txt \ - --min-worker ${{ parameters.MIN_WORKER }} \ - --max-worker ${{ parameters.MAX_WORKER }} \ - --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ - --test-set ${{ parameters.TEST_SET }} \ - --kvm-build-id $(KVM_BUILD_ID) \ - --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ - --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ - --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ - --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ - --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ - --image_url ${{ parameters.IMAGE_URL }} \ - --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ - --hwsku ${{ parameters.HWSKU }} \ - --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ - --platform ${{ parameters.PLATFORM }} \ - --testbed-name "${{ parameters.TESTBED_NAME }}" \ - --scripts "${{ parameters.SCRIPTS }}" \ - --features "${{ parameters.FEATURES }}" \ - --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ - --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ - --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ - --affinity='${{ parameters.AFFINITY }}' \ - --build-reason ${{ parameters.BUILD_REASON }} \ - --repo-name ${{ parameters.REPO_NAME }} \ - --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ - --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ - --retry-times ${{ parameters.RETRY_TIMES }} \ - --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ - --requester "${{ parameters.REQUESTER }}" \ - --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ - --test-plan-num ${{ parameters.TEST_PLAN_NUM }} - - TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo "Created test plan $TEST_PLAN_ID" - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - done - TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") - TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} - echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + + pip install PyYAML + + rm -f new_test_plan_id.txt + + python ./.azure-pipelines/test_plan.py create \ + -t ${{ parameters.TOPOLOGY }} \ + -o new_test_plan_id.txt \ + --min-worker ${{ parameters.MIN_WORKER }} \ + --max-worker ${{ parameters.MAX_WORKER }} \ + --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ + --test-set ${{ parameters.TEST_SET }} \ + --kvm-build-id $(KVM_BUILD_ID) \ + --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ + --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ + --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ + --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ + --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ + --image_url ${{ parameters.IMAGE_URL }} \ + --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ + --hwsku ${{ parameters.HWSKU }} \ + --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ + --platform ${{ parameters.PLATFORM }} \ + --testbed-name "${{ parameters.TESTBED_NAME }}" \ + --scripts "${{ parameters.SCRIPTS }}" \ + --features "${{ parameters.FEATURES }}" \ + --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ + --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ + --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ + --affinity='${{ parameters.AFFINITY }}' \ + --build-reason ${{ parameters.BUILD_REASON }} \ + --repo-name ${{ parameters.REPO_NAME }} \ + --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ + --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --retry-times ${{ parameters.RETRY_TIMES }} \ + --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ + --requester "${{ parameters.REQUESTER }}" \ + --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ + --test-plan-num ${{ parameters.TEST_PLAN_NUM }} + + TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo "Created test plan $TEST_PLAN_ID" + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + done + TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") + TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} + echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" displayName: "Trigger test" - - script: | - set -o - echo "Lock testbed" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" - echo "[test_plan.py] poll LOCK_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Lock testbed" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" + echo "[test_plan.py] poll LOCK_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Lock testbed" - - script: | - set -o - echo "Prepare testbed" - echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" - echo "[test_plan.py] poll PREPARE_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Prepare testbed" + echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" + echo "[test_plan.py] poll PREPARE_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Prepare testbed" - - script: | - set -o - echo "Run test" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" - echo "[test_plan.py] poll EXECUTING status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Run test" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" + echo "[test_plan.py] poll EXECUTING status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Run test" timeoutInMinutes: ${{ parameters.MAX_RUN_TEST_MINUTES }} - ${{ if eq(parameters.DUMP_KVM_IF_FAIL, 'True') }}: - - script: | - set -e - echo "KVM dump" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" - echo "##[group][test_plan.py] poll KVMDUMP status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP - done + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + echo "KVM dump" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" + echo "##[group][test_plan.py] poll KVMDUMP status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP + done condition: succeededOrFailed() displayName: "KVM dump" - - script: | - set -e - echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID - done + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID + done condition: always() displayName: "Finalize running test plan" diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index 1cc48fdbd31..f4b07bb2d18 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -1,12 +1,3 @@ -""" -Description: -- This script provides access to Elastictest test plan API, including creating, canceling, and polling status. - -Important!!!: -- This script is downloaded in multiple pipelines. -- Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. -""" - from __future__ import print_function, division import argparse @@ -17,7 +8,7 @@ import subprocess import copy import time -from datetime import datetime, timezone +from datetime import datetime, timedelta import requests import yaml @@ -31,7 +22,8 @@ INTERNAL_SONIC_MGMT_REPO = "https://dev.azure.com/mssonic/internal/_git/sonic-mgmt-int" PR_TEST_SCRIPTS_FILE = "pr_test_scripts.yaml" SPECIFIC_PARAM_KEYWORD = "specific_param" -MAX_POLL_RETRY_TIMES = 10 +TOLERATE_HTTP_EXCEPTION_TIMES = 20 +TOKEN_EXPIRE_HOURS = 1 MAX_GET_TOKEN_RETRY_TIMES = 3 TEST_PLAN_STATUS_UNSUCCESSFUL_FINISHED = ["FAILED", "CANCELLED"] TEST_PLAN_STEP_STATUS_UNFINISHED = ["EXECUTING", None] @@ -91,15 +83,13 @@ def __init__(self, status): def get_status(self): return self.status.value - def print_logs(self, test_plan_id, resp_data, expected_status, start_time): + def print_logs(self, test_plan_id, resp_data, start_time): status = resp_data.get("status", None) current_status = test_plan_status_factory(status).get_status() if current_status == self.get_status(): - print( - f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " - f"expected_status: {expected_status}, elapsed: {time.time() - start_time:.0f} seconds" - ) + print("Test plan id: {}, status: {}, elapsed: {:.0f} seconds" + .format(test_plan_id, resp_data.get("status", None), time.time() - start_time)) class InitStatus(AbstractStatus): @@ -121,12 +111,10 @@ class ExecutingStatus(AbstractStatus): def __init__(self): super(ExecutingStatus, self).__init__(TestPlanStatus.EXECUTING) - def print_logs(self, test_plan_id, resp_data, expected_status, start_time): - print( - f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " - f"expected_status: {expected_status}, progress: {resp_data.get('progress', 0) * 100:.2f}%, " - f"elapsed: {time.time() - start_time:.0f} seconds" - ) + def print_logs(self, test_plan_id, resp_data, start_time): + print("Test plan id: {}, status: {}, progress: {:.2f}%, elapsed: {:.0f} seconds" + .format(test_plan_id, resp_data.get("status", None), + resp_data.get("progress", 0) * 100, time.time() - start_time)) class KvmDumpStatus(AbstractStatus): @@ -162,81 +150,74 @@ def parse_list_from_str(s): if single_str.strip()] -def run_cmd(cmd): - process = subprocess.Popen( - cmd.split(), - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - stdout, stderr = process.communicate() - return_code = process.returncode - - if return_code != 0: - raise Exception(f'Command {cmd} execution failed, rc={return_code}, error={stderr}') - return stdout, stderr, return_code - - class TestPlanManager(object): - def __init__(self, scheduler_url, frontend_url, client_id, managed_identity_id): + def __init__(self, scheduler_url, community_url, frontend_url, client_id=None): self.scheduler_url = scheduler_url + self.community_url = community_url self.frontend_url = frontend_url self.client_id = client_id - self.managed_identity_id = managed_identity_id + self.with_auth = False + self._token = None + self._token_expires_on = None + if self.client_id: + self.with_auth = True + self.get_token() + + def cmd(self, cmds): + process = subprocess.Popen( + cmds, + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + return_code = process.returncode + + return stdout, stderr, return_code + + def az_run(self, cmd): + stdout, stderr, retcode = self.cmd(cmd.split()) + if retcode != 0: + raise Exception(f'Command {cmd} execution failed, rc={retcode}, error={stderr}') + return stdout, stderr, retcode def get_token(self): - # 1. Run az login with re-try - az_login_cmd = f"az login --identity --username {self.managed_identity_id}" - az_login_attempts = 0 - while az_login_attempts < MAX_GET_TOKEN_RETRY_TIMES: - try: - stdout, _, _ = run_cmd(az_login_cmd) - print(f"Az login successfully. Login time: {datetime.now(timezone.utc)}") - break - except Exception as exception: - az_login_attempts += 1 - print( - f"Failed to az login with exception: {repr(exception)}. " - f"Retry {MAX_GET_TOKEN_RETRY_TIMES - az_login_attempts} times to login." - ) + token_is_valid = \ + self._token_expires_on is not None and \ + (self._token_expires_on - datetime.now()) > timedelta(hours=TOKEN_EXPIRE_HOURS) - # If az login failed, return with exception - if az_login_attempts >= MAX_GET_TOKEN_RETRY_TIMES: - raise Exception(f"Failed to az login after {MAX_GET_TOKEN_RETRY_TIMES} attempts.") + if self._token is not None and token_is_valid: + return self._token - # 2. Get access token with re-try - get_token_cmd = f"az account get-access-token --resource {self.client_id}" - get_token_attempts = 0 - while get_token_attempts < MAX_GET_TOKEN_RETRY_TIMES: + cmd = 'az account get-access-token --resource {}'.format(self.client_id) + attempt = 0 + while attempt < MAX_GET_TOKEN_RETRY_TIMES: try: - stdout, _, _ = run_cmd(get_token_cmd) + stdout, _, _ = self.az_run(cmd) token = json.loads(stdout.decode("utf-8")) - access_token = token.get("accessToken", None) - if not access_token: - raise Exception("Parse token from stdout failed, accessToken is None.") + self._token = token.get("accessToken", None) + if not self._token: + raise Exception("Parse token from stdout failed") # Parse token expires time from string token_expires_on = token.get("expiresOn", "") - if token_expires_on: - print(f"Get token successfully. Token will expire on {token_expires_on}.") - - return access_token + self._token_expires_on = datetime.strptime(token_expires_on, "%Y-%m-%d %H:%M:%S.%f") + print("Get token successfully.") + return self._token except Exception as exception: - get_token_attempts += 1 - print(f"Failed to get token with exception: {repr(exception)}.") + attempt += 1 + print("Failed to get token with exception: {}".format(repr(exception))) - # If az get token failed, return with exception - if get_token_attempts >= MAX_GET_TOKEN_RETRY_TIMES: - raise Exception(f"Failed to get token after {MAX_GET_TOKEN_RETRY_TIMES} attempts") + raise Exception("Failed to get token after {} attempts".format(MAX_GET_TOKEN_RETRY_TIMES)) def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params="", kvm_build_id="", min_worker=None, max_worker=None, pr_id="unknown", output=None, common_extra_params="", **kwargs): - tp_url = f"{self.scheduler_url}/test_plan" + tp_url = "{}/test_plan".format(self.scheduler_url) testbed_name = parse_list_from_str(kwargs.get("testbed_name", None)) image_url = kwargs.get("image_url", None) hwsku = kwargs.get("hwsku", None) @@ -248,10 +229,8 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) - print( - f"Creating test plan, topology: {topology}, name: {test_plan_name}, " - f"build info:{repo_name} {pr_id} {build_id}" - ) + print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, + repo_name, pr_id, build_id)) print("Test scripts to be covered in this test plan:") print(json.dumps(scripts, indent=4)) @@ -341,9 +320,10 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "extra_params": {}, "priority": 10 } - print(f"Creating test plan with payload:\n{json.dumps(payload, indent=4)}") + print('Creating test plan with payload:\n{}'.format(json.dumps(payload, indent=4))) headers = { - "Authorization": f"Bearer {self.get_token()}", + "Authorization": "Bearer {}".format(self.get_token()), + "scheduler-site": "PRTest", "Content-Type": "application/json" } raw_resp = {} @@ -351,16 +331,17 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params raw_resp = requests.post(tp_url, headers=headers, data=json.dumps(payload), timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception(f"HTTP execute failure, url: {tp_url}, raw_resp: {raw_resp}, exception: {str(exception)}") + raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" + .format(tp_url, str(raw_resp), str(exception))) if not resp["data"]: - raise Exception(f"Create test plan failed with error: {resp['errmsg']}") + raise Exception("Pre deploy action failed with error: {}".format(resp["errmsg"])) if not resp["success"]: - raise Exception(f"Create test plan failed with error: {resp['errmsg']}") + raise Exception("Create test plan failed with error: {}".format(resp["errmsg"])) - print(f"Result of creating test plan: {str(resp['data'])}") + print("Result of creating test plan: {}".format(str(resp["data"]))) if output: - print(f"Store new test plan id to file {output}") + print("Store new test plan id to file {}".format(output)) with open(output, "a") as f: f.write(str(resp["data"]) + "\n") @@ -368,14 +349,15 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params def cancel(self, test_plan_id): - tp_url = f"{self.scheduler_url}/test_plan/{test_plan_id}" - cancel_url = f"{tp_url}/cancel" + tp_url = "{}/test_plan/{}".format(self.scheduler_url, test_plan_id) + cancel_url = "{}/cancel".format(tp_url) - print(f"Cancelling test plan at {cancel_url}") + print("Cancelling test plan at {}".format(cancel_url)) payload = json.dumps({}) headers = { - "Authorization": f"Bearer {self.get_token()}", + "Authorization": "Bearer {}".format(self.get_token()), + "scheduler-site": "PRTest", "Content-Type": "application/json" } @@ -384,57 +366,73 @@ def cancel(self, test_plan_id): raw_resp = requests.post(cancel_url, headers=headers, data=payload, timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception(f"HTTP execute failure, url: {cancel_url}, raw_resp: {str(raw_resp)}, " - f"exception: {str(exception)}") + raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" + .format(cancel_url, str(raw_resp), str(exception))) if not resp["success"]: - raise Exception(f"Cancel test plan failed with error: {resp['errmsg']}") + raise Exception("Cancel test plan failed with error: {}".format(resp["errmsg"])) - print(f"Result of cancelling test plan at {tp_url}:") + print("Result of cancelling test plan at {}:".format(tp_url)) print(str(resp["data"])) def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expected_result=None): - print(f"Polling progress and status of test plan at {self.frontend_url}/scheduler/testplan/{test_plan_id}") - print(f"Polling interval: {interval} seconds") + print("Polling progress and status of test plan at {}/scheduler/testplan/{}" + .format(self.frontend_url, test_plan_id)) + print("Polling interval: {} seconds".format(interval)) - poll_url = f"{self.scheduler_url}/test_plan/{test_plan_id}/get_test_plan_status" - # In current polling task, initialize headers one time to avoid frequent token accessing - # For some tasks running over 24h, then token may expire, need a fresh + poll_url = "{}/test_plan/{}/get_test_plan_status".format(self.scheduler_url, test_plan_id) + poll_url_no_auth = "{}/get_test_plan_status/{}".format(self.community_url, test_plan_id) headers = { - "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } start_time = time.time() - poll_retry_times = 0 + http_exception_times = 0 + http_exception_times_no_auth = 0 + failed_poll_auth_url = False while timeout < 0 or (time.time() - start_time) < timeout: resp = None - try: - resp = requests.get(poll_url, headers=headers, timeout=10).json() - - if not resp: - raise Exception("Poll test plan status failed with request error, no response!") - - if not resp["success"]: - raise Exception(f"Get test plan status failed with error: {resp['errmsg']}") + # To make the transition smoother, first try to access the original API + if not failed_poll_auth_url: + try: + if self.with_auth: + headers["Authorization"] = "Bearer {}".format(self.get_token()) + resp = requests.get(poll_url, headers=headers, timeout=10).json() + except Exception as exception: + print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url, resp, + str(exception))) + http_exception_times = http_exception_times + 1 + if http_exception_times >= TOLERATE_HTTP_EXCEPTION_TIMES: + failed_poll_auth_url = True + else: + time.sleep(interval) + continue + + # If failed on poll auth url(most likely token has expired), try with no-auth url + else: + print("Polling test plan status failed with auth url, try with no-auth url.") + try: + resp = requests.get(poll_url_no_auth, headers={"Content-Type": "application/json"}, + timeout=10).json() + except Exception as e: + print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, + repr(e))) + http_exception_times_no_auth = http_exception_times_no_auth + 1 + if http_exception_times_no_auth >= TOLERATE_HTTP_EXCEPTION_TIMES: + raise Exception( + "HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, + repr(e))) + else: + time.sleep(interval) + continue - resp_data = resp.get("data", None) - if not resp_data: - raise Exception("No valid data in response.") + if not resp: + raise Exception("Poll test plan status failed with request error, no response!") - except Exception as exception: - print(f"Failed to get valid response, url: {poll_url}, raw_resp: {resp}, exception: {str(exception)}") + if not resp["success"]: + raise Exception("Query test plan at {} failed with error: {}".format(poll_url, resp["errmsg"])) - # Refresh headers token to address token expiration issue - headers = { - "Authorization": f"Bearer {self.get_token()}", - "Content-Type": "application/json" - } - - poll_retry_times = poll_retry_times + 1 - if poll_retry_times >= MAX_POLL_RETRY_TIMES: - raise Exception("Poll test plan status failed, exceeded the maximum number of retries.") - else: - time.sleep(interval) - continue + resp_data = resp.get("data", None) + if not resp_data: + raise Exception("No valid data in response: {}".format(str(resp))) current_tp_status = resp_data.get("status", None) current_tp_result = resp_data.get("result", None) @@ -443,10 +441,11 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte current_status = test_plan_status_factory(current_tp_status) expected_status = test_plan_status_factory(expected_state) - current_status.print_logs(test_plan_id, resp_data, expected_state, start_time) + print("current test plan status: {}, expected status: {}".format(current_tp_status, expected_state)) - # If test plan has finished current step, its now status will behind the expected status - if expected_status.get_status() < current_status.get_status(): + if expected_status.get_status() == current_status.get_status(): + current_status.print_logs(test_plan_id, resp_data, start_time) + elif expected_status.get_status() < current_status.get_status(): steps = None step_status = None runtime = resp_data.get("runtime", None) @@ -461,7 +460,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print test summary test_summary = resp_data.get("runtime", {}).get("test_summary", None) if test_summary: - print(f"Test summary:\n{json.dumps(test_summary, indent=4)}") + print("Test summary:\n{}".format(json.dumps(test_summary, indent=4))) """ In below scenarios, need to return false to pipeline. @@ -478,34 +477,38 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print error type and message err_code = resp_data.get("runtime", {}).get("err_code", None) if err_code: - print(f"Error type: {err_code}") + print("Error type: {}".format(err_code)) err_msg = resp_data.get("runtime", {}).get("message", None) if err_msg: - print(f"Error message: {err_msg}") + print("Error message: {}".format(err_msg)) - raise Exception( - f"Test plan id: {test_plan_id}, status: {step_status}, " - f"result: {current_tp_result}, Elapsed {time.time() - start_time:.0f} seconds. " - f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" - ) + raise Exception("Test plan id: {}, status: {}, result: {}, Elapsed {:.0f} seconds. " + "Check {}/scheduler/testplan/{} for test plan status" + .format(test_plan_id, step_status, current_tp_result, time.time() - start_time, + self.frontend_url, + test_plan_id)) if expected_result: if current_tp_result != expected_result: - raise Exception( - f"Test plan id: {test_plan_id}, status: {step_status}, " - f"result: {current_tp_result} not match expected result: {expected_result}, " - f"Elapsed {time.time() - start_time:.0f} seconds. " - f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" - ) - - print(f"Current step status is {step_status}.") + raise Exception("Test plan id: {}, status: {}, result: {} not match expected result: {}, " + "Elapsed {:.0f} seconds. " + "Check {}/scheduler/testplan/{} for test plan status" + .format(test_plan_id, step_status, current_tp_result, + expected_result, time.time() - start_time, + self.frontend_url, + test_plan_id)) + + print("Current step status is {}".format(step_status)) return + else: + print("Current test plan state is {}, waiting for the expected state {}".format(current_tp_status, + expected_state)) time.sleep(interval) else: raise PollTimeoutException( - f"Max polling time reached, test plan at {poll_url} is not successfully finished or cancelled" + "Max polling time reached, test plan at {} is not successfully finished or cancelled".format(poll_url) ) @@ -927,28 +930,30 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # https://github.com/microsoft/azure-pipelines-tasks/issues/10331 args.test_plan_id = args.test_plan_id.replace("'", "") - print(f"Test plan utils parameters: {args}") + print("Test plan utils parameters: {}".format(args)) + auth_env = ["CLIENT_ID"] + required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL"] - required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL", "CLIENT_ID", "SONIC_AUTOMATION_UMI"] + if args.action in ["create", "cancel"]: + required_env.extend(auth_env) env = { - "ELASTICTEST_SCHEDULER_BACKEND_URL": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), - "CLIENT_ID": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), - "FRONTEND_URL": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), - "SONIC_AUTOMATION_UMI": os.environ.get("SONIC_AUTOMATION_UMI"), + "elastictest_scheduler_backend_url": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), + "elastictest_community_url": os.environ.get("ELASTICTEST_COMMUNITY_URL"), + "client_id": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), + "frontend_url": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), } env_missing = [k.upper() for k, v in env.items() if k.upper() in required_env and not v] if env_missing: - print(f"Missing required environment variables: {env_missing}.") + print("Missing required environment variables: {}".format(env_missing)) sys.exit(1) try: tp = TestPlanManager( - env["ELASTICTEST_SCHEDULER_BACKEND_URL"], - env["FRONTEND_URL"], - env["CLIENT_ID"], - env["SONIC_AUTOMATION_UMI"] - ) + env["elastictest_scheduler_backend_url"], + env["elastictest_community_url"], + env["frontend_url"], + env["client_id"]) if args.action == "create": pr_id = os.environ.get("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") or os.environ.get( @@ -959,7 +964,14 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte job_name = os.environ.get("SYSTEM_JOBDISPLAYNAME") repo_name = args.repo_name if args.repo_name else os.environ.get("BUILD_REPOSITORY_NAME") - test_plan_prefix = f"{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}".replace(' ', '_') + test_plan_prefix = "{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}" \ + .format( + repo=repo, + reason=reason, + pr_id=pr_id, + build_id=build_id, + job_name=job_name + ).replace(' ', '_') scripts = args.scripts specific_param = json.loads(args.specific_param) @@ -977,7 +989,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte for num in range(args.test_plan_num): test_plan_name = copy.copy(test_plan_prefix) if args.test_plan_num > 1: - test_plan_name = f"{test_plan_name}_{num + 1}" + test_plan_name = "{}_{}".format(test_plan_name, num + 1) tp.create( args.topology, @@ -1021,8 +1033,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte tp.cancel(args.test_plan_id) sys.exit(0) except PollTimeoutException as e: - print(f"Polling test plan failed with exception: {repr(e)}") + print("Polling test plan failed with exception: {}".format(repr(e))) sys.exit(2) except Exception as e: - print(f"Operation failed with exception: {repr(e)}") + print("Operation failed with exception: {}".format(repr(e))) sys.exit(3) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index cebd7d40d8a..c06c4b0bfca 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -71,7 +71,7 @@ stages: MIN_WORKER: $(T0_INSTANCE_NUM) MAX_WORKER: $(T0_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: t0_2vlans_elastictest displayName: "kvmtest-t0-2vlans by Elastictest" @@ -87,7 +87,7 @@ stages: MAX_WORKER: $(T0_2VLANS_INSTANCE_NUM) DEPLOY_MG_EXTRA_PARAMS: "-e vlan_config=two_vlan_a" KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: t1_lag_elastictest displayName: "kvmtest-t1-lag by Elastictest" @@ -101,7 +101,7 @@ stages: MIN_WORKER: $(T1_LAG_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: dualtor_elastictest displayName: "kvmtest-dualtor-t0 by Elastictest" @@ -116,7 +116,7 @@ stages: MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) COMMON_EXTRA_PARAMS: "--disable_loganalyzer " KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: multi_asic_elastictest displayName: "kvmtest-multi-asic-t1-lag by Elastictest" @@ -132,7 +132,7 @@ stages: MAX_WORKER: $(MULTI_ASIC_INSTANCE_NUM) NUM_ASIC: 4 KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: sonic_t0_elastictest displayName: "kvmtest-t0-sonic by Elastictest" @@ -149,7 +149,7 @@ stages: COMMON_EXTRA_PARAMS: "--neighbor_type=sonic " VM_TYPE: vsonic KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: dpu_elastictest displayName: "kvmtest-dpu by Elastictest" @@ -163,7 +163,7 @@ stages: MIN_WORKER: $(T0_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: onboarding_elastictest_t0 displayName: "onboarding t0 testcases by Elastictest - optional" @@ -179,7 +179,7 @@ stages: MIN_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) TEST_SET: onboarding_t0 - job: onboarding_elastictest_t1 @@ -196,7 +196,7 @@ stages: MIN_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) TEST_SET: onboarding_t1 # - job: onboarding_elastictest_dualtor @@ -213,7 +213,7 @@ stages: # MIN_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # KVM_IMAGE_BRANCH: $(BUILD_BRANCH) -# MGMT_BRANCH: "master" +# MGMT_BRANCH: $(BUILD_BRANCH) # TEST_SET: onboarding_dualtor # - job: wan_elastictest From 0d7e6caa68f98852a44717448c217755897edabd Mon Sep 17 00:00:00 2001 From: Alpesh Patel Date: Wed, 6 Nov 2024 00:38:19 -0500 Subject: [PATCH 071/221] Skip check for Rx PFC count if multiple lossy TC bits are set (#15052) * Skip check for Rx PFC count if multiple lossy TC bits are set Signed-off-by: Alpesh S Patel * Skip check for Rx PFC count if multiple lossy TC bits are set Signed-off-by: Alpesh S Patel * Skip check for Rx PFC count if multiple lossy TC bits are set Signed-off-by: Alpesh S Patel * Skip check for Rx PFC count if multiple lossy TC bits are set Signed-off-by: Alpesh S Patel * Skip check for Rx PFC count if multiple lossy TC bits are set Signed-off-by: Alpesh S Patel --------- Signed-off-by: Alpesh S Patel --- tests/common/snappi_tests/traffic_generation.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/common/snappi_tests/traffic_generation.py b/tests/common/snappi_tests/traffic_generation.py index 2d3a1755c42..5acf21c90fd 100644 --- a/tests/common/snappi_tests/traffic_generation.py +++ b/tests/common/snappi_tests/traffic_generation.py @@ -12,6 +12,7 @@ from tests.common.snappi_tests.port import select_ports, select_tx_port from tests.common.snappi_tests.snappi_helpers import wait_for_arp, fetch_snappi_flow_metrics from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.cisco_data import is_cisco_device logger = logging.getLogger(__name__) @@ -619,9 +620,14 @@ def verify_pause_frame_count_dut(rx_dut, pytest_assert(pfc_pause_rx_frames == 0, "PFC pause frames with no bit set in the class enable vector should be dropped") else: - pytest_assert(pfc_pause_rx_frames > 0, - "PFC pause frames should be received and counted in RX PFC counters for priority {}" - .format(prio)) + if len(prios) > 1 and is_cisco_device(tx_dut) and not test_traffic_pause: + pytest_assert(pfc_pause_rx_frames == 0, + "PFC pause frames should not be counted in RX PFC counters for priority {}" + .format(prios)) + else: + pytest_assert(pfc_pause_rx_frames > 0, + "PFC pause frames should be received and counted in RX PFC counters for priority {}" + .format(prio)) for peer_port, prios in dut_port_config[0].items(): # PFC pause frames sent by DUT's ingress port to TGEN for prio in prios: From 5527113e6a770db720771f37c9ecabf9f5a6917c Mon Sep 17 00:00:00 2001 From: Perumal Venkatesh Date: Wed, 6 Nov 2024 01:03:46 -0800 Subject: [PATCH 072/221] Add check to see if bgp sessions are up before proceeding with the tests (#15312) Description of PR Test currently doesn't check if the bgp sessions are all up before proceeding with the tests. Adding a check to make sure they are and then proceed with the tests. With this change we are seeing all the tests pass for chassis Approach What is the motivation for this PR? Test currently doesn't check if the bgp sessions are all up before proceeding with the tests. Adding a check to make sure they are and then proceed with the tests. With this change we are seeing all the tests pass for chassis How did you do it? How did you verify/test it? Any platform specific information? Validated on Cisco chassis ============================= test session starts ============================== platform linux -- Python 3.8.10, pytest-7.4.0, pluggy-1.5.0 ansible: 2.13.13 rootdir: /data/tests configfile: pytest.ini plugins: metadata-3.1.1, forked-1.6.0, html-4.1.1, repeat-0.9.3, xdist-1.28.0, allure-pytest-2.8.22, ansible-4.0.0 collected 4 items bgp/test_seq_idf_isolation.py::test_idf_isolated_no_export PASSED [ 25%] bgp/test_seq_idf_isolation.py::test_idf_isolated_withdraw_all PASSED [ 50%] bgp/test_seq_idf_isolation.py::test_idf_isolation_no_export_with_config_reload PASSED [ 75%] bgp/test_seq_idf_isolation.py::test_idf_isolation_withdraw_all_with_config_reload PASSED [100%] co-authorized by: jianquanye@microsoft.com --- tests/bgp/test_seq_idf_isolation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/bgp/test_seq_idf_isolation.py b/tests/bgp/test_seq_idf_isolation.py index bdaf5dac62f..9d236b0ecb2 100644 --- a/tests/bgp/test_seq_idf_isolation.py +++ b/tests/bgp/test_seq_idf_isolation.py @@ -210,7 +210,7 @@ def test_idf_isolation_no_export_with_config_reload(rand_one_downlink_duthost, # Issue command to isolate with no export community on DUT duthost.shell("sudo idf_isolation isolated_no_export") duthost.shell('sudo config save -y') - config_reload(duthost, safe_reload=True, check_intf_up_ports=True) + config_reload(duthost, safe_reload=True, check_intf_up_ports=True, wait_for_bgp=True) # Verify DUT is in isolated-no-export state. pytest_assert(IDF_ISOLATED_NO_EXPORT == get_idf_isolation_state(duthost), @@ -235,7 +235,7 @@ def test_idf_isolation_no_export_with_config_reload(rand_one_downlink_duthost, """ duthost.shell("sudo idf_isolation unisolated") duthost.shell('sudo config save -y') - config_reload(duthost, safe_reload=True, check_intf_up_ports=True) + config_reload(duthost, safe_reload=True, check_intf_up_ports=True, wait_for_bgp=True) pytest_assert(IDF_UNISOLATED == get_idf_isolation_state(duthost), "DUT is not isolated_no_export state") @@ -276,7 +276,7 @@ def test_idf_isolation_withdraw_all_with_config_reload(duthosts, rand_one_downli # Issue command to isolate with no export community on DUT duthost.shell("sudo idf_isolation isolated_withdraw_all") duthost.shell('sudo config save -y') - config_reload(duthost, safe_reload=True, check_intf_up_ports=True) + config_reload(duthost, safe_reload=True, check_intf_up_ports=True, wait_for_bgp=True) # Verify DUT is in isolated-withdraw-all state. pytest_assert(IDF_ISOLATED_WITHDRAW_ALL == get_idf_isolation_state(duthost), From e45414e8d07827a27bf4173744b6ca73d6257d55 Mon Sep 17 00:00:00 2001 From: Yaqiang Zhu Date: Wed, 6 Nov 2024 18:32:28 +0800 Subject: [PATCH 073/221] [m0][mx] Skip check pfcwd during config reload for m0/mx (#15364) What is the motivation for this PR? pfcwd is not enabled in m0/mx, hence skip check it when config reload How did you do it? Skip check pfcwd when config reload on m0/mx How did you verify/test it? Run tests --- tests/common/config_reload.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/common/config_reload.py b/tests/common/config_reload.py index ae43156288f..0b0fe7c2768 100644 --- a/tests/common/config_reload.py +++ b/tests/common/config_reload.py @@ -108,7 +108,8 @@ def config_reload_minigraph_with_rendered_golden_config_override( def pfcwd_feature_enabled(duthost): device_metadata = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts']['DEVICE_METADATA'] pfc_status = device_metadata['localhost']["default_pfcwd_status"] - return pfc_status == 'enable' + switch_role = device_metadata['localhost'].get('type', '') + return pfc_status == 'enable' and switch_role not in ['MgmtToRRouter', 'BmcMgmtToRRouter'] @ignore_loganalyzer From e2f3201cc3ec3066d45ca0a11e9327a477f79168 Mon Sep 17 00:00:00 2001 From: Yaqiang Zhu Date: Wed, 6 Nov 2024 18:32:59 +0800 Subject: [PATCH 074/221] [m0][mx] Skip queue related tests for m0/mx (#15363) What is the motivation for this PR? Queue related tests are not expected to run in M0/MX topos How did you do it? Skip those cases in M0/MX How did you verify/test it? Run tests --- .../conditional_mark/tests_mark_conditions.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index aeb3773a23a..d3ab72aad49 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1740,10 +1740,11 @@ snmp/test_snmp_queue.py: snmp/test_snmp_queue_counters.py: skip: - reason: "Have an known issue on kvm testbed" + conditions_logical_operator: OR + reason: "Have an known issue on kvm testbed / Unsupported in MGFX topos" conditions: - - asic_type in ['vs'] - - https://github.com/sonic-net/sonic-mgmt/issues/14007 + - "asic_type in ['vs'] and https://github.com/sonic-net/sonic-mgmt/issues/14007" + - "topo_type in ['m0', 'mx']" ####################################### ##### span ##### @@ -1888,9 +1889,11 @@ telemetry/test_telemetry.py: telemetry/test_telemetry.py::test_telemetry_queue_buffer_cnt: skip: - reason: "Testcase ignored due to switch type is voq" + conditions_logical_operator: or + reason: "Testcase ignored due to switch type is voq / Unsupported in MGFX topos" conditions: - "(switch_type=='voq')" + - "topo_type in ['m0', 'mx']" ####################################### ##### pktgen ##### From 8311c4720292ba183288bbbabef451969bcd0b52 Mon Sep 17 00:00:00 2001 From: Yaqiang Zhu Date: Wed, 6 Nov 2024 18:33:34 +0800 Subject: [PATCH 075/221] [drop_packets] Skip drop_packets on MGFX (#15341) What is the motivation for this PR? drop_packtes tests were skipped for MGFX by folder previously. Now it is broken by this change #14395 Hence update condition mark How did you do it? Update condition mark How did you verify/test it? Run tests --- .../tests_mark_conditions_drop_packets.yaml | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions_drop_packets.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions_drop_packets.yaml index b1bd6251861..222014ab10b 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions_drop_packets.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions_drop_packets.yaml @@ -5,11 +5,12 @@ #Hence, it is not dropped by default in Cisco-8000. For dropping link local address, it should be done through security/DATA ACL drop_packets/test_configurable_drop_counters.py::test_dip_link_local: skip: - reason: "Cisco 8000 platform and some mlx platforms does not drop DIP link local packets" + reason: "MGFX topos doesn't support drop packets / Cisco 8000 platform and some mlx platforms does not drop DIP link local packets" conditions_logical_operator: or conditions: - "'Mellanox' in hwsku" - asic_type=='cisco-8000' + - "topo_type in ['m0', 'mx']" drop_packets/test_configurable_drop_counters.py::test_neighbor_link_down: skip: @@ -19,31 +20,38 @@ drop_packets/test_configurable_drop_counters.py::test_neighbor_link_down: drop_packets/test_configurable_drop_counters.py::test_sip_link_local: skip: - reason: "Cisco 8000 platform and some MLX platforms does not drop SIP link local packets" + reason: "MGFX topos doesn't support drop packets / Cisco 8000 platform and some MLX platforms does not drop SIP link local packets" conditions_logical_operator: or conditions: - asic_type=="cisco-8000" - "'Mellanox' in hwsku" + - "topo_type in ['m0', 'mx']" ####################################### ##### test_drop_counters.py ##### ####################################### drop_packets/test_drop_counters.py::test_absent_ip_header: skip: - reason: "Test case not supported on Broadcom DNX platform" + reason: "Test case not supported on Broadcom DNX platform and MGFX topos" + conditions_logical_operator: or conditions: - "asic_subtype in ['broadcom-dnx']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_acl_egress_drop: skip: - reason: "Not supported on Broadcom platforms" + reason: "Not supported on Broadcom platforms and MGFX topos" + conditions_logical_operator: or conditions: - "asic_type in ['broadcom']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_dst_ip_absent: skip: - reason: "Test case not supported on Broadcom DNX platform and Cisco 8000 platform" + reason: "Test case not supported on Broadcom DNX platform and Cisco 8000 platform and MGFX topos" + conditions_logical_operator: or conditions: - "asic_subtype in ['broadcom-dnx'] or asic_type in ['cisco-8000']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_dst_ip_absent[vlan_members]: skip: @@ -55,9 +63,11 @@ drop_packets/test_drop_counters.py::test_dst_ip_absent[vlan_members]: drop_packets/test_drop_counters.py::test_dst_ip_is_loopback_addr: skip: - reason: "Cisco 8000 platform does not drop DIP loopback packets. Test also not supported on Broadcom DNX" + reason: "Cisco 8000 platform does not drop DIP loopback packets. Test also not supported on Broadcom DNX and MGFX topos" + conditions_logical_operator: or conditions: - "(asic_type=='cisco-8000') or (asic_subtype in ['broadcom-dnx'])" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_dst_ip_is_loopback_addr[vlan_members]: skip: @@ -69,23 +79,28 @@ drop_packets/test_drop_counters.py::test_dst_ip_is_loopback_addr[vlan_members]: drop_packets/test_drop_counters.py::test_dst_ip_link_local: skip: - reason: "Cisco 8000 broadcom DNX platforms and some MLX platforms do not drop DIP linklocal packets" + reason: "MGFX topos doesn't support drop packets / Cisco 8000 broadcom DNX platforms and some MLX platforms do not drop DIP linklocal packets" conditions_logical_operator: or conditions: - "(asic_type=='cisco-8000') or (asic_subtype in ['broadcom-dnx'])" - "'Mellanox' in hwsku" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_equal_smac_dmac_drop: skip: - reason: "Drop not enabled on chassis since internal traffic uses same smac & dmac" + conditions_logical_operator: or + reason: "MGFX topos doesn't support drop packets / Drop not enabled on chassis since internal traffic uses same smac & dmac" conditions: - "asic_subtype in ['broadcom-dnx']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_ip_is_zero_addr: skip: - reason: "Cisco 8000 platform does not drop packets with 0.0.0.0 source or destination IP address" + conditions_logical_operator: or + reason: "MGFX topos doesn't support drop packets / Cisco 8000 platform does not drop packets with 0.0.0.0 source or destination IP address" conditions: - "asic_type=='cisco-8000'" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_ip_is_zero_addr[vlan_members-ipv4-dst]: skip: @@ -128,9 +143,11 @@ drop_packets/test_drop_counters.py::test_ip_is_zero_addr[vlan_members-ipv6-src]: drop_packets/test_drop_counters.py::test_ip_pkt_with_expired_ttl: skip: - reason: "Not supported on Mellanox devices" + reason: "Not supported on Mellanox devices and MGFX topos" + conditions_logical_operator: or conditions: - "asic_type in ['mellanox']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_loopback_filter: # Test case is skipped, because SONiC does not have a control to adjust loop-back filter settings. @@ -143,9 +160,11 @@ drop_packets/test_drop_counters.py::test_loopback_filter: drop_packets/test_drop_counters.py::test_no_egress_drop_on_down_link: skip: - reason: "VS platform do not support fanout configuration" + reason: "MGFX topos doesn't support drop packets / VS platform do not support fanout configuration" + conditions_logical_operator: or conditions: - "asic_type in ['vs']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_not_expected_vlan_tag_drop[vlan_members]: skip: @@ -163,15 +182,19 @@ drop_packets/test_drop_counters.py::test_not_expected_vlan_tag_drop[vlan_members drop_packets/test_drop_counters.py::test_src_ip_is_class_e: skip: - reason: "Cisco 8000 platform does not drop packets with source IP address in class E" + reason: "MGFX topos doesn't support drop packets / Cisco 8000 platform does not drop packets with source IP address in class E" + conditions_logical_operator: or conditions: - "asic_type=='cisco-8000'" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_src_ip_is_loopback_addr: skip: - reason: "Test currently not supported on broadcom DNX platform" + conditions_logical_operator: or + reason: "MGFX topos doesn't support drop packets / Test currently not supported on broadcom DNX platform" conditions: - "asic_subtype in ['broadcom-dnx']" + - "topo_type in ['m0', 'mx']" drop_packets/test_drop_counters.py::test_src_ip_is_loopback_addr[vlan_members]: skip: @@ -199,8 +222,9 @@ drop_packets/test_drop_counters.py::test_src_ip_is_multicast_addr[vlan_members-i drop_packets/test_drop_counters.py::test_src_ip_link_local: skip: - reason: "Cisco 8000 broadcom DNX platforms and some MLX platforms do not drop SIP linklocal packets" + reason: "MGFX topos doesn't support drop packets / Cisco 8000 broadcom DNX platforms and some MLX platforms do not drop SIP linklocal packets" conditions_logical_operator: or conditions: - "(asic_type=='cisco-8000') or (asic_subtype in ['broadcom-dnx'])" - "'Mellanox' in hwsku" + - "topo_type in ['m0', 'mx']" From f3cf75c46e8104b7fd14ca4e53b891665b33e698 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:34:06 +0800 Subject: [PATCH 076/221] Add some dataplane test to onboarding PR checker list (#15372) What is the motivation for this PR? Elastictest performs well in distribute running PR test in multiple KVMs, which support us to add more test scripts to PR checker. But some traffic test using ptfadapter can't be tested on KVM platform, we need to skip traffic test if needed How did you do it? Add some t0/t1 dataplane test to onboarding test job How did you verify/test it? Co-authored-by: xwjiang2021 <96218837+xwjiang2021@users.noreply.github.com> --- .azure-pipelines/pr_test_scripts.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.azure-pipelines/pr_test_scripts.yaml b/.azure-pipelines/pr_test_scripts.yaml index b00c9c51f9f..3d48dfbef25 100644 --- a/.azure-pipelines/pr_test_scripts.yaml +++ b/.azure-pipelines/pr_test_scripts.yaml @@ -461,10 +461,16 @@ onboarding_t0: - lldp/test_lldp_syncd.py # Flaky, we will triage and fix it later, move to onboarding to unblock pr check - dhcp_relay/test_dhcp_relay_stress.py + - arp/test_arp_update.py + - decap/test_subnet_decap.py + - fdb/test_fdb_mac_learning.py + - ip/test_mgmt_ipv6_only.py onboarding_t1: - lldp/test_lldp_syncd.py + - mpls/test_mpls.py + - vxlan/test_vxlan_route_advertisement.py specific_param: From 2aa8281705d18f2a3e13df97c1343f5c59aa3a10 Mon Sep 17 00:00:00 2001 From: Wenda Chu <32250288+w1nda@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:44:52 +0800 Subject: [PATCH 077/221] [wol_test] Add udp related tests into wol test plan (#15321) We extended wol tool to support sending magic pattern in udp paylod, and we need to add related tests into test plan. Related PRs: sonic-net/SONiC#1827, sonic-net/sonic-buildimage#20523 What is the motivation for this PR? We extended wol tool to support sending magic pattern in udp paylod, and we need to add related tests into test plan. How did you do it? Add udp related tests and give some demo commands. --- docs/testplan/WoL-test-plan.md | 38 +++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/docs/testplan/WoL-test-plan.md b/docs/testplan/WoL-test-plan.md index 5e48160dd48..b2fc70b8244 100644 --- a/docs/testplan/WoL-test-plan.md +++ b/docs/testplan/WoL-test-plan.md @@ -32,13 +32,19 @@ The test will issue `wol` commands with various parameter combinations on DUT, t #### Test case #1 - Verrify send a wol packet to a specific interface 1. Start `tcpdump` process in PTF to capture WoL packet on spacific interface. Save the captured packets to `.pcap` file. -1. Issue command on DUT host: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55`) +1. Issue command on DUT host: + 1. Send magic pattern in ethernet payload: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55`) + 1. Send magic pattern in udp payload with ipv4 address: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -u --ip-address 255.255.255.255`) + 1. Send magic pattern in udp payload with ipv6 address and a specific udp_port: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -u --ip-address 2404:f801:10::ffff::ffff:ffff --udp-port 1234`) 1. Stop `tcpdump` process in PTF. 1. Check if only one wol packet exists in `.pcap` file and the content is expected. #### Test case #2 - Verify send a wol packekt to each member of a vlan 1. Start multiple `tcpdump` processes in PTF to capture WoL packet on each interfaces. Save the captured packets to different `.pcap` files. -1. Issue command on DUT host: `wol `. (e.g., `wol Vlan1000 00:11:22:33:44:55`) +1. Issue command on DUT host: + 1. Send magic pattern in ethernet payload: `wol `. (e.g., `wol Vlan1000 00:11:22:33:44:55`) + 1. Send magic pattern in udp payload with ipv4 address: `wol ` (e.g., `wol Vlan1000 00:11:22:33:44:55 -u --ip-address 255.255.255.255`) + 1. Send magic pattern in udp payload with ipv6 address and a specific udp_port: `wol ` (e.g., `wol Vlan1000 00:11:22:33:44:55 -u --ip-address 2404:f801:10::ffff::ffff:ffff --udp-port 1234`) 1. Stop all `tcpdump` processes in PTF. 1. *For each interface in vlan*, check if one wol packet exists in corresponding `.pcap` file and the content is expected. 1. *For each interface not in vlan*, check no wol packet exists in corresponding `.pcap` file. @@ -51,21 +57,43 @@ The test will issue `wol` commands with various parameter combinations on DUT, t #### Test case #4 - Verify send a wol packet with password 1. Start `tcpdump` process in PTF to capture WoL packet on spacific interface. Save the captured packets to `.pcap` file. -1. Issue command on DUT host: `wol -p ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -p 192.168.1.1`) +1. Issue command on DUT host: + 1. Send magic pattern in ethernet payload: `wol -p ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -p 192.168.1.1`) + 1. Send magic pattern in udp payload with ipv4 address: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -u --ip-address 255.255.255.255` -p 11:22:33:44:55:66`) + 1. Send magic pattern in udp payload with ipv6 address and a specific udp_port: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -u --ip-address 2404:f801:10::ffff::ffff:ffff --udp-port 1234 -p 192.168.123.123`) 1. Stop `tcpdump` process in PTF. 1. Check if only one wol packet exists in `.pcap` file and the content is expected. Especially, verify the password in wol packet is same as command. #### Test case #5 - Verify send multiple wol packets with specific interval to a specific interface 1. Start `tcpdump` process in PTF to capture WoL packet on spacific interface. Save the captured packets to `.pcap` file. -1. Issue command on DUT host: `wol -c -i ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -c 3 -i 2000`) +1. Issue command on DUT host: + 1. Send magic pattern in ethernet payload: `wol -c -i ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -c 3 -i 2000`) + 1. Send magic pattern in udp payload with ipv4 address: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -u --ip-address 255.255.255.255 -c 4 -i 1000`) + 1. Send magic pattern in udp payload with ipv6 address and a specific udp_port: `wol ` (e.g., `wol Ethernet10 00:11:22:33:44:55 -u --ip-address 2404:f801:10::ffff::ffff:ffff --udp-port1234 -c 5 -i 1500`) 1. Stop `tcpdump` process in PTF. 1. Check if exact `` wol packets exist in `.pcap` file and the content is expected. Moreover, check the time interval between each wol packet in `.pcap` file is ALMOST SAME[^1] as input ``. #### Test case #6 - Verify send multiple wol packets with specific interval to each membor of a vlan 1. Start multiple `tcpdump` processes in PTF to capture WoL packet on each interfaces. Save the captured packets to different `.pcap` files. -1. Issue command on DUT host: `wol -c -i ` (e.g., `wol Vlan1000 00:11:22:33:44:55 -c 3 -i 2000`) +1. Issue command on DUT host: + 1. `wol -c -i ` (e.g., `wol Vlan1000 00:11:22:33:44:55 -c 3 -i 2000`) + 1. Send magic pattern in udp payload with ipv4 address: `wol ` (e.g., `wol Vlan1000 00:11:22:33:44:55 -u --ip-address 255.255.255.255 -c 4 -i 1000`) + 1. Send magic pattern in udp payload with ipv6 address and a specific udp_port: `wol ` (e.g., `wol Vlan1000 00:11:22:33:44:55 -u --ip-address 2404:f801:10::ffff::ffff:ffff --udp-port 1234 -c 5 -i 1500`) 1. Stop `tcpdump` process in PTF. 1. *For each interface in vlan*, check if exact `` wol packets exist in `.pcap` file and the content is expected. Moreover, check the time interval between each wol packet in `.pcap` file is ALMOST SAME[^1] as input ``. 1. *For each interface not in vlan*, check no wol packet exists in corresponding `.pcap` file. +#### Test case #7 - Verify constrain of parameters +1. Make sure count and interval both exist or not. +1. Make sure udp flag is required when using ip address or udp port. +1. Make sure udp flag is conflict with mac broadcast flag. + +#### Test case #8 - Verify parameters can be set correctly by CLI +1. Make sure interface that receving packet and command line parameter interface are same. +1. Make sure target_mac in payload and command line parameter target_mac are same. +1. Make sure ip address in header and command line parameter ip_address are same. (Test both ipv4 and ipv6 address with broadcase address or unicast address on VLAN interface or port interface, so there should be 8 combinations, maybe we can leverage pytest parametrize mark to realize that.) +1. Make sure when command line parameter ip_address is empty, ip address in header is default value: 255.255.255.255. +1. Make sure udp port in header and command line parameter udp port are same. +1. Make sure when command line parameter udp_port is empty, udp port in header is default value: 9. + [^1]: ALMOST SAME means we should tolerate small errors caused by electrical characteristics. From 5d15b8fc9c4d0f6a00cf98b1d45d6ba7d42fd6db Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:15:57 -0800 Subject: [PATCH 078/221] Stabilize pfcwd warm-reboot test on Mellanox platform (#15314) --- tests/pfcwd/conftest.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/pfcwd/conftest.py b/tests/pfcwd/conftest.py index fc6e3086119..2c5592bbcde 100644 --- a/tests/pfcwd/conftest.py +++ b/tests/pfcwd/conftest.py @@ -35,7 +35,7 @@ def pytest_addoption(parser): @pytest.fixture(scope="module") -def two_queues(request): +def two_queues(request, duthosts, enum_rand_one_per_hwsku_frontend_hostname, fanouthosts): """ Enable/Disable sending traffic to queues [4, 3] By default send to queue 4 @@ -48,6 +48,14 @@ def two_queues(request): Returns: two_queues: False/True """ + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + dut_asic_type = duthost.facts["asic_type"].lower() + # On Mellanox devices, if the leaf-fanout is running EOS, then only one queue is supported + if dut_asic_type == "mellanox": + for fanouthost in list(fanouthosts.values()): + fanout_os = fanouthost.get_fanout_os() + if fanout_os == 'eos': + return False return request.config.getoption('--two-queues') From e3e732a404b422a7a22e9261f244150b9d3fc0d9 Mon Sep 17 00:00:00 2001 From: nissampa <99767762+nissampa@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:45:30 -0800 Subject: [PATCH 079/221] Dpu test plan phase 2 (#14773) * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md * Update Smartswitch-test-plan.md --- docs/testplan/Smartswitch-test-plan.md | 776 +++++++++++++++++++++++-- 1 file changed, 739 insertions(+), 37 deletions(-) diff --git a/docs/testplan/Smartswitch-test-plan.md b/docs/testplan/Smartswitch-test-plan.md index 3083f9f8a77..3e6d55028d6 100644 --- a/docs/testplan/Smartswitch-test-plan.md +++ b/docs/testplan/Smartswitch-test-plan.md @@ -2,6 +2,8 @@ - [Introduction](#introduction) - [Scope](#scope) +- [Testbed and Version](#testbed-and-version) +- [Topology](#topology) - [Definitions and Abbreviations](#definitions-and-abbreviations) - [Objectives of CLI Test Cases](#objectives-of-cli-test-cases) - [CLI Test Cases](#cli-test-cases) @@ -9,14 +11,23 @@ - [1.2 Check platform voltage](#12-check-platform-voltage) - [1.3 Check platform temperature](#13-check-platform-temperature) - [1.4 Check DPU console](#14-check-DPU-console) - - [1.5 Check midplane ip address between NPU and DPU](#15-check-midplane-ip-address-between-npu-and-dpu) + - [1.5 Check midplane ip address between Switch and DPU](#15-check-midplane-ip-address-between-switch-and-dpu) - [1.6 Check DPU shutdown and power up individually](#16-check-DPU-shutdown-and-power-up-individually) - - [1.7 Check removal of pcie link between NPU and DPU](#17-check-removal-of-pcie-link-between-npu-and-dpu) - - [1.8 Check the NTP date and timezone between DPU and NPU](#18-check-the-ntp-date-and-timezone-between-dpu-and-npu) + - [1.7 Check pcie link status between Switch and DPU](#17-check-pcie-link-status-between-switch-and-dpu) + - [1.8 Check the NTP date and timezone between DPU and Switch](#18-check-the-ntp-date-and-timezone-between-dpu-and-switch) - [1.9 Check the State of DPUs](#19-check-the-state-of-dpus) - [1.10 Check the Health of DPUs](#110-check-the-health-of-dpus) - [1.11 Check reboot cause history](#111-check-reboot-cause-history) - - [1.12 Check the DPU state after OS reboot](#112-check-the-dpu-state-after-os-reboot) + - [1.12 Check the DPU state after Switch reboot](#112-check-the-dpu-state-after-switch-reboot) + - [1.13 Check memory on DPU](#113-check-memory-on-dpu) + - [1.14 Check DPU status and pcie Link after memory exhaustion on Switch](#114-check-dpu-status-and-pcie-link-after-memory-exhaustion-on-switch) + - [1.15 Check DPU status and pcie Link after memory exhaustion on DPU](#115-check-dpu-status-and-pcie-link-after-memory-exhaustion-on-dpu) + - [1.16 Check DPU status and pcie Link after restart pmon on Switch](#116-check-dpu-status-and-pcie-link-after-restart-pmon-on-switch) + - [1.17 Check DPU status and pcie Link after reload of configuration on Switch](#117-check-dpu-status-and-pcie-link-after-reload-of-configuration-on-switch) + - [1.18 Check DPU status and pcie Link after kernel panic on Switch](#118-check-dpu-status-and-pcie-link-after-kernel-panic-on-switch) + - [1.19 Check DPU status and pcie Link after kernel panic on DPU](#119-check-dpu-status-and-pcie-link-after-kernel-panic-on-dpu) + - [1.20 Check DPU status and pcie Link after switch power cycle](#120-check-dpu-status-and-pcie-link-after-switch-power-cycle) + - [1.21 Check DPU status and pcie Link after SW trip by temperature trigger](#121-check-dpu-status-and-pcie-link-after-sw-trip-by-temperature-trigger) - [Objectives of API Test Cases](#objectives-of-api-test-cases) - [API Test Cases](#api-test-cases) - [1.1 Check SmartSwitch specific ChassisClass APIs](#11-check-smartswitch-specific-chassisclass-apis) @@ -36,6 +47,19 @@ Purpose of the test is to verify smartswich platform related functionalities/fea For every test cases, all DPUs need to be powered on unless specified in any of the case. General convention of DPU0, DPU1, DPU2 and DPUX has been followed to represent DPU modules and the number of DPU modules can vary. +## Testbed and Version + +The test runs on the os versions 202411 and above. +Add a check to confirm that the test environment uses version 202411 or later; if the version is earlier, skip the test. +After the above check, it needs to check DPUs in the testbed are in dark mode or not. +If it is in dark mode, then power up all the DPUs. +Dark mode is one in which all the DPUs admin_status are down. + +## Topology + +New topology called smartswitch-t1 has been added for running smartswitch cases. +T1 cases also runs on the new topology. + ## Definitions and Abbreviations | **Term** | **Meaning** | @@ -54,14 +78,23 @@ General convention of DPU0, DPU1, DPU2 and DPUX has been followed to represent D | 1.2 | Check platform voltage | To verify the Voltage sensor values and and functionality of alarm by changing the threshold values | | | 1.3 | Check platform temperature | To Verify the Temperature sensor values and functionality of alarm by changing the threshold values | | | 1.4 | Check DPU console | To Verify console access for all DPUs | | -| 1.5 | Check midplane ip address between NPU and DPU | To Verify PCIe interface created between NPU and DPU according to bus number | | +| 1.5 | Check midplane ip address between Switch and DPU | To Verify PCIe interface created between Switch and DPU according to bus number | | | 1.6 | Check DPU shutdown and power up individually | To Verify DPU shutdown and DPUs power up | | -| 1.7 | Check removal of pcie link between NPU and DPU | To Verify the PCie hot plug functinality | | -| 1.8 | Check the NTP date and timezone between DPU and NPU | To Verify NPU and DPU are in sync with respect to timezone and logs timestamp | | +| 1.7 | Check pcie link status between Switch and DPU | To Verify the PCie hot plug functinality | | +| 1.8 | Check the NTP date and timezone between DPU and Switch | To Verify Switch and DPU are in sync with respect to timezone and logs timestamp | | | 1.9 | Check the State of DPUs | To Verify DPU state details during online and offline | | | 1.10 | Check the Health of DPUs | To Verify overall health (LED, process, docker, services and hw) of DPU | Phase:2 | | 1.11 | Check reboot cause history | To Verify reboot cause history cli | | | 1.12 | Check the DPU state after OS reboot | To Verify DPU state on host reboot | | +| 1.13 | Check memory on DPU | To verify Memory and its threshold on all the DPUs | +| 1.14 | Check DPU status and pcie Link after memory exhaustion on Switch | To verify dpu status and connectivity after memory exhaustion on Switch | +| 1.15 | Check DPU status and pcie Link after memory exhaustion on DPU | To verify dpu status and connectivity after memory exhaustion on DPU | +| 1.16 | Check DPU status and pcie Link after restart pmon on Switch | To verify dpu status and connectivity after restart of pmon on NPU | +| 1.17 | Check DPU status and pcie Link after reload of configuration on Switch | To verify dpu status and connectivity after reload of configuration on Switch | +| 1.18 | Check DPU status and pcie Link after kernel panic on Switch| To verify dpu status and connectivity after Kernel Panic on Switch | +| 1.19 | Check DPU status and pcie Link after kernel panic on DPU | To verify dpu status and connectivity after Kernel Panic on DPU | +| 1.20 | Check DPU status and pcie Link after switch power cycle | To verify dpu status and connectivity after switch power cycle | +| 1.21 | Check DPU status and pcie Link after SW trip by temperature trigger | To verify dpu status and connectivity after SW trip by temperature trigger | ## CLI Test Cases @@ -69,7 +102,7 @@ General convention of DPU0, DPU1, DPU2 and DPUX has been followed to represent D ### 1.1 Check DPU Status #### Steps - * Use command `show chassis modules status` to get DPU status + * Use command on Switch: `show chassis modules status` to get DPU status * Get the number of DPU modules from ansible inventory file for the testbed. #### Verify in @@ -93,7 +126,7 @@ root@sonic:/home/cisco# show chassis modules status ### 1.2 Check platform voltage #### Steps - * Use command `show platform voltage` to get platform voltage + * Use command on Switch: `show platform voltage` to get platform voltage #### Verify in * Switch @@ -197,7 +230,7 @@ root@sonic:/home/cisco# ### 1.3 Check platform temperature #### Steps - * Use command `show platform temperature` to get platform temperature + * Use command on Switch: `show platform temperature` to get platform temperature #### Verify in * Switch @@ -318,7 +351,7 @@ root@sonic:/home/cisco# * cntrl+a and then cntrl+x to come out of the DPU console. -### 1.5 Check midplane ip address between NPU and DPU +### 1.5 Check midplane ip address between Switch and DPU #### Steps * Get the number of DPU modules from from ansible inventory file for the testbed. @@ -347,10 +380,10 @@ root@sonic:/home/cisco# #### Steps * Get the number of DPU modules from Ansible inventory file for the testbed. - * Use command `config chassis modules shutdown ` to shut down individual DPU - * Use command `show chassis modules status` to show DPU status - * Use command `config chassis modules startup ` to power up individual DPU - * Use command `show chassis modules status` to show DPU status + * Use command on Switch: `config chassis modules shutdown ` to shut down individual DPU + * Use command on Switch: `show chassis modules status` to show DPU status + * Use command on Switch: `config chassis modules startup ` to power up individual DPU + * Use command on Switch: `show chassis modules status` to show DPU status #### Verify in * Switch @@ -384,14 +417,14 @@ root@sonic:/home/cisco# show chassis modules status * Verify DPU is shown in show chassis modules status after DPU powered on -### 1.7 Check removal of pcie link between NPU and DPU +### 1.7 Check pcie link status between Switch and DPU #### Steps - * Use `show platform pcieinfo -c` to run the pcie info test to check everything is passing - * Use command `config chassis modules shutdown DPU` to bring down the dpu (This will bring down the pcie link between npu and dpu) - * Use `show platform pcieinfo -c` to run the pcie info test to check pcie link has been removed - * Use command `config chassis modules startup DPU` to bring up the dpu (This will rescan pcie links) - * Use `show platform pcieinfo -c` to run the pcie info test to check everything is passing + * Use command on Switch: `show platform pcieinfo -c` to run the pcie info test to check everything is passing + * Use command on Switch: `config chassis modules shutdown DPU` to bring down the dpu (This will bring down the pcie link between npu and dpu) + * Use command on Switch: `show platform pcieinfo -c` to run the pcie info test to check pcie link has been removed + * Use command on Switch: `config chassis modules startup DPU` to bring up the dpu (This will rescan pcie links) + * Use command on Switch: `show platform pcieinfo -c` to run the pcie info test to check everything is passing * This test is to check the PCie hot plug functinality since there is no OIR possible #### Verify in @@ -404,9 +437,9 @@ On Switch: Showing example of one DPU pcie link root@sonic:/home/cisco# show platform pcieinfo -c -root@sonic:/home/cisco# echo 1 > /sys/bus/pci/devices/0000:1a:00.0/remove +root@sonic:/home/cisco# config chassis modules shutdown DPU root@sonic:/home/cisco# -root@sonic:/home/cisco# echo 1 > /sys/bus/pci/rescan +root@sonic:/home/cisco# config chassis modules startup DPU root@sonic:/home/cisco# root@sonic:/home/cisco# show platform pcieinfo -c @@ -416,12 +449,12 @@ root@sonic:/home/cisco# show platform pcieinfo -c * Verify pcieinfo test pass for all after bringing back up the link -### 1.8 Check the NTP date and timezone between DPU and NPU +### 1.8 Check the NTP date and timezone between DPU and Switch #### Steps - * Use command `date` to get date and time zone on Switch - * Use command `ssh admin@169.254.x.x` to enter into required dpu. - * Use command `date` to get date and time zone on DPU + * Use command on Switch: `date` to get date and time zone on Switch + * Use command on Switch: `ssh admin@169.254.x.x` to enter into required dpu. + * Use command on DPU: `date` to get date and time zone on DPU #### Verify in * Switch and DPU @@ -452,7 +485,7 @@ root@sonic:/home/cisco# ### 1.9 Check the State of DPUs #### Steps - * Use command `show system-health DPU all` to get DPU health status. + * Use command on Switch:`show system-health DPU all` to get DPU health status. #### Verify in * Switch and DPU @@ -507,7 +540,7 @@ DPU0 1 Partial Online dpu_midplane_link_state up * This Test case is to be covered in Phase 2 #### Steps - * Use command `show system-health detail ` to check the health of the DPU. + * Use command on Switch: `show system-health detail ` to check the health of the DPU. #### Verify in * Switch @@ -546,13 +579,13 @@ rsyslog OK Process ### 1.11 Check reboot cause history #### Steps - * The "show reboot-cause" CLI on the switch shows the most recent rebooted device, time and the cause. - * The "show reboot-cause history" CLI on the switch shows the history of the Switch and all DPUs - * The "show reboot-cause history module-name" CLI on the switch shows the history of the specified module - * Use `config chassis modules shutdown ` - * Use `config chassis modules startup ` + * Use command on Switch: "show reboot-cause" CLI to show the most recent rebooted device, time and the cause. + * Use command on Switch: "show reboot-cause history" CLI to show the history of the Switch and all DPUs + * Use command on Switch: "show reboot-cause history module-name" CLI to show the history of the specified module + * Use command on Switch: `config chassis modules shutdown ` + * Use command on Switch: `config chassis modules startup ` * Wait for 5 minutes for Pmon to update the DPU states - * Use `show reboot-cause ` to check the latest reboot is displayed + * Use command on Switch: `show reboot-cause ` to check the latest reboot is displayed #### Verify in * Switch @@ -600,7 +633,7 @@ DPU3 2023_10_02_17_23_46 Host Reset DPU Sun 02 Oct 2 #### Steps -Existing Test case for NPU: +Existing Test case for Switch: * Reboot using a particular command (sonic reboot, watchdog reboot, etc) * All the timeout and poll timings are read from platform.json * Wait for ssh to drop @@ -617,7 +650,7 @@ Reboot Test Case for DPU: * Save the configurations of all DPU state before reboot * Power on all the DPUs that were powered on before reboot using `config chassis modules startup ` * Wait for DPUs to be up - * Use command `show chassis modules status` to get DPU status + * Use command on Switch: `show chassis modules status` to get DPU status * Get the number of DPU modules from ansible inventory file for the testbed. #### Verify in @@ -645,6 +678,675 @@ root@sonic:/home/cisco# show chassis modules status * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. +### 1.13 Check Memory on DPU + +### Steps + + * Infrastructure support will be provided to choose from following clis or in combinations based on the vendor. + * Use command on DPU: `show system-memory` to get memory usage on each of those DPUs + * Use command on Switch: `show system-health dpu ` to check memory check service status + * Use command on DPU: `pdsctl show system --events` to check memory related events triggered. + (This is vendor specific event monitoring cli) + +#### Verify in + * DPU + +#### Sample Output +``` +On DPU: + +root@sonic:/home/admin# show system-memory + total used free shared buff/cache available +Mem: 6266 4198 1509 28 765 2067 +Swap: 0 0 0 +root@sonic:/home/admin# +root@sonic:/home/admin# + +On Switch: + +root@MtFuji:/home/cisco# show system-health dpu DPU0 +is_smartswitch returning True +Name ID Oper-Status State-Detail State-Value Time Reason +------ ---- ------------- ----------------------- ------------- ----------------- -------------------------------------------------------------------------------------------------------------------------- +DPU0 0 Online dpu_midplane_link_state UP 20241003 17:57:22 INTERNAL-MGMT : admin state - UP, oper_state - UP, status - OK, HOST-MGMT : admin state - UP, oper_state - UP, status - OK + dpu_control_plane_state UP 20241003 17:57:22 All containers are up and running, host-ethlink-status: Uplink1/1 is UP + dpu_data_plane_state UP 20241001 19:54:30 DPU container named polaris is running, pdsagent running : OK, pciemgrd running : OK +root@MtFuji:/home/cisco# + +On DPU: +# Note: This command is run on cisco specific testbed. +# HwSKU: Cisco-8102-28FH-DPU-O-T1 + +root@sonic:/home/admin# pdsctl show system --events +---------------------------------------------------------------------------------------------------- +Event Severity Timestamp +---------------------------------------------------------------------------------------------------- +DSE_SERVICE_STARTED DEBUG 2024-09-20 21:48:11.515551 +0000 UTC +DSE_SERVICE_STARTED DEBUG 2024-09-20 21:48:11.668685 +0000 UTC +DSE_SERVICE_STARTED DEBUG 2024-09-20 21:48:12.379261 +0000 UTC +DSE_SERVICE_STARTED DEBUG 2024-09-20 21:48:19.379819 +0000 UTC +root@sonic:/home/admin# + +``` + +#### Pass/Fail Criteria + + * Verify that used memory should not cross the specified threshold value (90) of total memory. + * Threshold can be set different based on platform. + * Verify that dpu_control_plane_state is up under system-health dpu cli. + * Verify no memory related events (MEM_FAILURE_EVENT) under pdsctl show system --events cli. This is vendor specific event montioring cli. + * Increase the memory to go beyond threshold (head -c /dev/zero | tail &) and verify it in pdsctl show system --events cli. + + +### 1.14 Check DPU status and pcie Link after memory exhaustion on Switch + +#### Steps + + * Use command on Switch: `sudo swapoff -a`. Swapping is turned off so the OOM is triggered in a shorter time. + * Use command on Switch: 'nohup bash -c "sleep 5 && tail /dev/zero" &' to run out of memory completely. + * It runs on the background and `nohup` is also necessary to protect the background process. + * Added `sleep 5` to ensure ansible receive the result first. + * Check the status and power on DPUs after switch goes for reboot and comes back + * Use command on Switch: `show chassis modules status` to check status of the DPUs. + * Append to the existing test case: https://github.com/sonic-net/sonic-mgmt/blob/master/tests/platform_tests/test_memory_exhaustion.py + + #### Verify in + + * Switch + +#### Sample Output + +``` +root@sonic:/home/cisco# sudo swapoff -a +root@sonic:/home/cisco# +root@sonic:/home/cisco# nohup bash -c "sleep 5 && tail /dev/zero" & +root@sonic:/home/cisco# nohup: ignoring input and appending output to 'nohup.out' +root@sonic:/home/cisco# +. +(Going for reboot) +. +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Offline down 154226463179152 + DPU2 Data Processing Unit N/A Offline down 154226463179168 + DPUX Data Processing Unit N/A Offline down 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# config chassis startup DPU1 +root@sonic:/home/cisco# config chassis startup DPU2 +root@sonic:/home/cisco# config chassis startup DPUX +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# +``` + +#### Pass/Fail Criteria + + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + + +### 1.15 Check DPU status and pcie Link after memory exhaustion on DPU + +#### Steps + +* Use command on DPU: `sudo swapoff -a`. Swapping is turned off so the OOM is triggered in a shorter time. +* Use command on DPU: 'nohup bash -c "sleep 5 && tail /dev/zero" &' to to run out of memory completely. +* It runs on the background and `nohup` is also necessary to protect the background process. +* Added `sleep 5` to ensure ansible receive the result first. +* Powercycling of DPU is to ensure that pcie link came up properly after the memory exhaustion test. +* Use command on Switch: `config chassis module shutdown ` to power off the DPUs. +* Wait for 3 mins. +* Use command on Switch: `config chassis module startup ` to power on the DPUs. + + #### Verify in + + * DPU and Switch + +#### Sample Output + +DPU: + +``` +root@sonic:/home/admin# sudo swapoff -a +root@sonic:/home/adminsco# +root@sonic:/home/admin# nohup bash -c "sleep 5 && tail /dev/zero" & +root@sonic:/home/admin# nohup: ignoring input and appending output to 'nohup.out' +root@sonic:/home/admin# +. +(Going for reboot) +. +``` + +Switch: + +``` +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Offline down 154226463179152 + DPU2 Data Processing Unit N/A Offline down 154226463179168 + DPUX Data Processing Unit N/A Offline down 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# config chassis startup DPU1 +root@sonic:/home/cisco# config chassis startup DPU2 +root@sonic:/home/cisco# config chassis startup DPUX +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# +``` + +#### Pass/Fail Criteria + + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + + +### 1.16 Check DPU status and pcie Link after restart pmon on Switch + +#### Steps + * Use command on Switch: `docker ps` to check the status of all the dockers. + * Use command on Switch: `systemctl restart pmon` + * Wait for 3 mins + * Use command on Switch: `docker ps` to check the status of all the dockers. + * Use command on Switch: `show chassis modules status` to check status of the DPUs. + +#### Verify in + * Switch + +#### Sample Output + +``` +root@MtFuji:/home/cisco# docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +a49fcf07beb8 docker-snmp:latest "/usr/local/bin/supe…" 3 days ago Up 3 days snmp +57ecc675292d docker-platform-monitor:latest "/usr/bin/docker_ini…" 3 days ago Up 3 days pmon +f1306072ba01 docker-sonic-mgmt-framework:latest "/usr/local/bin/supe…" 3 days ago Up 3 days mgmt-framework +571cc36585ae docker-lldp:latest "/usr/bin/docker-lld…" 3 days ago Up 3 days lldp +db4b1444e8a0 docker-sonic-gnmi:latest "/usr/local/bin/supe…" 3 days ago Up 3 days gnmi +a90702b9c541 d0a0fb621c53 "/usr/bin/docker_ini…" 3 days ago Up 3 days dhcp_server +4d2d79b77c66 2c214d2315a2 "/usr/bin/docker_ini…" 3 days ago Up 3 days dhcp_relay +90246d1e26d2 docker-fpm-frr:latest "/usr/bin/docker_ini…" 3 days ago Up 3 days bgp +42cf834770a8 docker-orchagent:latest "/usr/bin/docker-ini…" 3 days ago Up 3 days swss +7eb9da209385 docker-router-advertiser:latest "/usr/bin/docker-ini…" 3 days ago Up 3 days radv +66c4c8779e60 docker-syncd-cisco:latest "/usr/local/bin/supe…" 3 days ago Up 3 days syncd +5d542c98fb00 docker-teamd:latest "/usr/local/bin/supe…" 3 days ago Up 3 days teamd +a5225d08bcf4 docker-eventd:latest "/usr/local/bin/supe…" 3 days ago Up 3 days eventd +bd7555425d6d docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu5 +42fd04767a03 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu4 +a1633fc4a6ff docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu3 +32b4e9506827 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu0 +bb73239399e4 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu6 +e5281aba74de docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu7 +96032ebcb451 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu1 +45418ff0d88f docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu2 +39ddbddd3fb3 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days database +f1cac669cd08 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days database-chassis +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# systemctl restart pmon +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +a49fcf07beb8 docker-snmp:latest "/usr/local/bin/supe…" 3 days ago Up 3 days snmp +57ecc675292d docker-platform-monitor:latest "/usr/bin/docker_ini…" 3 days ago Up 4 seconds pmon +f1306072ba01 docker-sonic-mgmt-framework:latest "/usr/local/bin/supe…" 3 days ago Up 3 days mgmt-framework +571cc36585ae docker-lldp:latest "/usr/bin/docker-lld…" 3 days ago Up 3 days lldp +db4b1444e8a0 docker-sonic-gnmi:latest "/usr/local/bin/supe…" 3 days ago Up 3 days gnmi +a90702b9c541 d0a0fb621c53 "/usr/bin/docker_ini…" 3 days ago Up 3 days dhcp_server +4d2d79b77c66 2c214d2315a2 "/usr/bin/docker_ini…" 3 days ago Up 3 days dhcp_relay +90246d1e26d2 docker-fpm-frr:latest "/usr/bin/docker_ini…" 3 days ago Up 3 days bgp +42cf834770a8 docker-orchagent:latest "/usr/bin/docker-ini…" 3 days ago Up 3 days swss +7eb9da209385 docker-router-advertiser:latest "/usr/bin/docker-ini…" 3 days ago Up 3 days radv +66c4c8779e60 docker-syncd-cisco:latest "/usr/local/bin/supe…" 3 days ago Up 3 days syncd +5d542c98fb00 docker-teamd:latest "/usr/local/bin/supe…" 3 days ago Up 3 days teamd +a5225d08bcf4 docker-eventd:latest "/usr/local/bin/supe…" 3 days ago Up 3 days eventd +bd7555425d6d docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu5 +42fd04767a03 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu4 +a1633fc4a6ff docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu3 +32b4e9506827 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu0 +bb73239399e4 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu6 +e5281aba74de docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu7 +96032ebcb451 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu1 +45418ff0d88f docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days databasedpu2 +39ddbddd3fb3 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days database +f1cac669cd08 docker-database:latest "/usr/local/bin/dock…" 3 days ago Up 3 days database-chassis +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# +root@MtFuji:/home/cisco# systemctl status pmon +● pmon.service - Platform monitor container + Loaded: loaded (/lib/systemd/system/pmon.service; static) + Drop-In: /etc/systemd/system/pmon.service.d + └─auto_restart.conf + Active: active (running) since Sat 2024-10-05 00:22:29 UTC; 24s ago + Process: 3584922 ExecStartPre=/usr/bin/pmon.sh start (code=exited, status=0> + Main PID: 3584995 (pmon.sh) + Tasks: 2 (limit: 153342) + Memory: 27.6M + CGroup: /system.slice/pmon.service + ├─3584995 /bin/bash /usr/bin/pmon.sh wait + └─3585000 python3 /usr/local/bin/container wait pmon + +Oct 05 00:22:28 MtFuji container[3584943]: container_start: pmon: set_owner:loc> +Oct 05 00:22:29 MtFuji container[3584943]: docker cmd: start for pmon +Oct 05 00:22:29 MtFuji container[3584943]: container_start: END +Oct 05 00:22:29 MtFuji systemd[1]: Started pmon.service - Platform monitor cont> +Oct 05 00:22:29 MtFuji container[3585000]: container_wait: BEGIN +Oct 05 00:22:29 MtFuji container[3585000]: read_data: config:True feature:pmon > +Oct 05 00:22:29 MtFuji container[3585000]: read_data: config:False feature:pmon> +Oct 05 00:22:29 MtFuji container[3585000]: docker get image version for pmon +Oct 05 00:22:29 MtFuji container[3585000]: container_wait: pmon: set_owner:loca> +Oct 05 00:22:29 MtFuji container[3585000]: container_wait: END -- transitioning> + +root@MtFuji:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# + +``` +#### Pass/Fail Criteria + * Verify pmon and all the associated critical process is up are up. + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + + +### 1.17 Check DPU status and pcie Link after reload of configuration on Switch + +#### Steps +* Use command on Switch: `config reload -y` to reload the configurations in the switch. +* Wait for 3 mins. +* Use command on Switch: `show chassis modules status` to check status of the DPUs. +* Use command on Switch: `config chassis module startup ` to power on the DPUs. +* Use command on Switch: `show chassis modules status` to check status of the DPUs. + +#### Verify in + * Switch + +#### Sample Output + +``` +root@sonic:/home/cisco# config reload -y +Acquired lock on /etc/sonic/reload.lock +Disabling container monitoring ... +Stopping SONiC target ... +Running command: /usr/local/bin/sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db +Running command: /usr/local/bin/db_migrator.py -o migrate +Running command: /usr/local/bin/sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t /usr/share/sonic/templates/sonic-environment.j2,/etc/sonic/sonic-environment +Restarting SONiC target ... +Enabling container monitoring ... +Reloading Monit configuration ... +Reinitializing monit daemon +Released lock on /etc/sonic/reload.lock +root@MtFuji:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Offline down 154226463179152 + DPU2 Data Processing Unit N/A Offline down 154226463179168 + DPUX Data Processing Unit N/A Offline down 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# config chassis startup DPU1 +root@sonic:/home/cisco# config chassis startup DPU2 +root@sonic:/home/cisco# config chassis startup DPUX +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# + +``` + +#### Pass/Fail Criteria + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + + +### 1.18 Check DPU status and pcie Link after kernel panic on Switch + +#### Steps +* Use command on Switch: `nohup bash -c "sleep 5 && echo c > /proc/sysrq-trigger" &` +* Use command on Switch: `show chassis modules status` to check status of the DPUs. +* Use command on Switch: `config chassis module startup ` to power on the DPUs. +* Use command on Switch: `show chassis modules status` to check status of the DPUs. +* Append to the existing test case: https://github.com/sonic-net/sonic-mgmt/blob/master/tests/platform_tests/test_kdump.py + +#### Verify in + * Switch + +#### Sample Output + +``` +root@sonic:/home/cisco# nohup bash -c "sleep 5 && echo c > /proc/sysrq-trigger" & +. +(Going for reboot) +. +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Offline down 154226463179152 + DPU2 Data Processing Unit N/A Offline down 154226463179168 + DPUX Data Processing Unit N/A Offline down 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# config chassis startup DPU1 +root@sonic:/home/cisco# config chassis startup DPU2 +root@sonic:/home/cisco# config chassis startup DPUX +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# show reboot-cause + +``` + +#### Pass/Fail Criteria + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + * Verify `show reboot-cause ` to check the reboot is caused by kernel panic. + + +### 1.19 Check DPU status and pcie Link after kernel panic on DPU + +#### Steps +* Use command on DPU: `nohup bash -c "sleep 5 && echo c > /proc/sysrq-trigger" &`. +* Powercycling of DPU is to ensure that pcie link came up properly after the memory exhaustion test. +* Use command on Switch: `config chassis module shutdown ` to power off the DPUs. +* Wait for 3 mins. +* Use command on Switch: `config chassis module startup ` to power on the DPUs. + +#### Verify in + * DPU and Switch + +#### Sample Output + +DPU: + +``` +root@sonic:/home/admin# nohup bash -c "sleep 5 && echo c > /proc/sysrq-trigger" & +. +(Going for reboot) +. +``` + +Switch: + +``` +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Offline down 154226463179152 + DPU2 Data Processing Unit N/A Offline down 154226463179168 + DPUX Data Processing Unit N/A Offline down 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# config chassis startup DPU1 +root@sonic:/home/cisco# config chassis startup DPU2 +root@sonic:/home/cisco# config chassis startup DPUX +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# +root@sonic:/home/cisco# show reboot-cause + +``` + +#### Pass/Fail Criteria + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + * Verify `show reboot-cause ` to check the reboot is caused by kernel panic. + + +### 1.20 Check DPU status and pcie Link after switch power cycle + +#### Steps + * Power cycle the testbed using PDU controller. + * Use command on Switch: `config chassis module startup ` to power on the DPUs. + * Use command on Switch: `show chassis modules status` to check status of the DPUs. + * Append to the existing test case: https://github.com/sonic-net/sonic-mgmt/blob/master/tests/platform_tests/test_power_off_reboot.py + +#### Verify in + * Switch + +#### Sample Output + +After power cycle of the testbed, + +``` +root@sonic:/home/cisco# +root@sonic:/home/cisco# +. +(Going for power off reboot using pdu controller) +. +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Offline down 154226463179152 + DPU2 Data Processing Unit N/A Offline down 154226463179168 + DPUX Data Processing Unit N/A Offline down 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# config chassis startup DPU1 +root@sonic:/home/cisco# config chassis startup DPU2 +root@sonic:/home/cisco# config chassis startup DPUX +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis modules startup +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# +``` + +#### Pass/Fail Criteria + * Verify number of DPUs from inventory file for the testbed and number of DPUs shown in the cli output. + * Verify Ping works to all the mid plane ip listed in the ansible inventory file for the testbed. + + +### 1.21 Check DPU status and pcie Link after SW trip by temperature trigger + +#### Steps + + * Infrastructure will be provided to run the scripts that triggers the temperature trip based on vendor. + * The following is the example sequence to trigger temperature trip on the DPU + - Note: If Cisco setup, the following steps work. + - In DPU, Execute: `docker exec -it polaris /bin/bash` + - Create /tmp/temp_sim.json file with dictionary { "hbmtemp": 65, "dietemp": 85} + - Increase dietemp to 125 to trigger the trip. + +#### Verify in + * DPU + +#### Sample Output + +DPU: + +``` +# Note: This command is run on cisco specific testbed. +# HwSKU: Cisco-8102-28FH-DPU-O-T1 + +root@sonic:/home/admin# +root@sonic:/home/admin# docker exec -it polaris /bin/bash +bash-4.4# +bash-4.4# cat /tmp/temp_sim.json +{ "hbmtemp": 65, +"dietemp": 85 } +bash-4.4# +bash-4.4# +bash-4.4# +bash-4.4# cat /tmp/temp_sim.json +{ "hbmtemp": 65, +"dietemp": 125 } +bash-4.4# exit +exit +root@sonic:/home/admin# e** RESETTING: SW TRIP dietemBoot0 v19, Id 0x82 +Boot fwid 0 @ 0x74200000... OK + +. +(Going for reboot) +. + +``` +Switch: + +``` +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Offline down 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# config chassis shutdown DPU0 +root@sonic:/home/cisco# config chassis startup DPU0 +root@sonic:/home/cisco# +root@sonic:/home/cisco# +root@sonic:/home/cisco# show chassis modules status + Name Description Physical-Slot Oper-Status Admin-Status Serial +------ -------------------- --------------- ------------- -------------- --------------- + DPU0 Data Processing Unit N/A Online up 154226463179136 + DPU1 Data Processing Unit N/A Online up 154226463179152 + DPU2 Data Processing Unit N/A Online up 154226463179168 + DPUX Data Processing Unit N/A Online up 154226463179184 + +root@sonic:/home/cisco# ping 169.254.200.1 +PING 169.254.200.1 (169.254.200.1) 56(84) bytes of data. +64 bytes from 169.254.200.1: icmp_seq=1 ttl=64 time=0.160 ms +^C +--- 169.254.28.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.160/0.160/0.160/0.000 ms +root@sonic:/home/cisco# +root@sonic:/home/cisco# show reboot-cause history dpu0 + + +``` + +#### Pass/Fail Criteria + * Verify Ping works to DPU mid plane ip listed in the ansible inventory file for the testbed. + * Verify the command on Swithc: show reboot cause history to check the cause as cattrip. + + ## Objectives of API Test Cases | | **Test Case** | **Intention** | **Comments** | From 315c7e2e25f8e3a45b5185554f2f25b9acdc8fec Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Thu, 7 Nov 2024 05:31:14 +0800 Subject: [PATCH 080/221] Update qos pcbb parameter for SN4600C on dualtor aa topology (#15303) Update qos pcbb parameter for SN4600C on dualtor aa topology Change-Id: Ie99762681cad38e02059cb064a28fdd86288e672 --- tests/qos/files/qos_params.spc3.yaml | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/qos/files/qos_params.spc3.yaml b/tests/qos/files/qos_params.spc3.yaml index b132af4c1ae..e4b91b88e8f 100644 --- a/tests/qos/files/qos_params.spc3.yaml +++ b/tests/qos/files/qos_params.spc3.yaml @@ -99,6 +99,39 @@ qos_params: pkts_num_trig_pfc: 176064 pkts_num_trig_ingr_drp: 177916 pkts_num_margin: 4 + topo-dualtor-aa: + 100000_40m: + pkts_num_leak_out: 0 + pcbb_xoff_1: + dscp: 3 + ecn: 1 + pg: 3 + pkts_num_trig_pfc: 176064 + pkts_num_trig_ingr_drp: 177916 + pkts_num_margin: 4 + pcbb_xoff_2: + dscp: 4 + ecn: 1 + pg: 4 + pkts_num_trig_pfc: 176064 + pkts_num_trig_ingr_drp: 177916 + pkts_num_margin: 4 + pcbb_xoff_3: + outer_dscp: 2 + dscp: 3 + ecn: 1 + pg: 2 + pkts_num_trig_pfc: 176064 + pkts_num_trig_ingr_drp: 177916 + pkts_num_margin: 4 + pcbb_xoff_4: + outer_dscp: 6 + dscp: 4 + ecn: 1 + pg: 6 + pkts_num_trig_pfc: 176064 + pkts_num_trig_ingr_drp: 177916 + pkts_num_margin: 4 topo-dualtor-aa-64-breakout: 200000_40m: pkts_num_leak_out: 0 From d3f233a9cc86a59f0a7dee281d60dc360480a0ed Mon Sep 17 00:00:00 2001 From: weguo-NV <154216071+weiguo-nvidia@users.noreply.github.com> Date: Thu, 7 Nov 2024 05:43:38 +0800 Subject: [PATCH 081/221] Fix test_check_show_lpmode case (#15062) --- .../platform_tests/sfp/test_show_intf_xcvr.py | 14 +++++++++++++- tests/platform_tests/sfp/util.py | 19 +++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/tests/platform_tests/sfp/test_show_intf_xcvr.py b/tests/platform_tests/sfp/test_show_intf_xcvr.py index 928720e0a34..962e58dd762 100644 --- a/tests/platform_tests/sfp/test_show_intf_xcvr.py +++ b/tests/platform_tests/sfp/test_show_intf_xcvr.py @@ -83,7 +83,19 @@ def test_check_show_lpmode(duthosts, enum_rand_one_per_hwsku_frontend_hostname, return assert sfp_lpmode['rc'] == 0, "Run command '{}' failed".format(cmd_sfp_presence) + sfp_lpmode_data = sfp_lpmode["stdout_lines"] + + # Check if the header is present + header = sfp_lpmode_data[0] + logging.info(f"The header is: {header}") + if header.replace(" ", "") != "Port Low-power Mode".replace(" ", ""): + logging.error("Invalid output format: Header missing") + return False + + # Check interface lpmode + sfp_lpmode_info = parse_output(sfp_lpmode_data[2:]) + logging.info(f"The interface sfp lpmode info is: {sfp_lpmode_info}") for intf in dev_conn: if intf not in xcvr_skip_list[duthost.hostname]: assert validate_transceiver_lpmode( - sfp_lpmode['stdout']), "Interface mode incorrect in 'show interface transceiver lpmode'" + sfp_lpmode_info, intf), "Interface mode incorrect in 'show interface transceiver lpmode'" diff --git a/tests/platform_tests/sfp/util.py b/tests/platform_tests/sfp/util.py index 50065ceb421..c793291b432 100644 --- a/tests/platform_tests/sfp/util.py +++ b/tests/platform_tests/sfp/util.py @@ -47,15 +47,14 @@ def get_dev_conn(duthost, conn_graph_facts, asic_index): return portmap, dev_conn -def validate_transceiver_lpmode(output): - lines = output.strip().split('\n') - # Check if the header is present - if lines[0].replace(" ", "") != "Port Low-power Mode".replace(" ", ""): - logging.error("Invalid output format: Header missing") +def validate_transceiver_lpmode(sfp_lpmode, port): + lpmode = sfp_lpmode.get(port) + if lpmode is None: + logging.error(f"Interface {port} does not present in the show command") return False - for line in lines[2:]: - port, lpmode = line.strip().split() - if lpmode not in ["Off", "On"]: - logging.error("Invalid low-power mode {} for port {}".format(lpmode, port)) - return False + + if lpmode not in ["Off", "On"]: + logging.error("Invalid low-power mode {} for port {}".format(lpmode, port)) + return False + return True From 827177af2f774be0c0a0f324f6299fe1bdabdabb Mon Sep 17 00:00:00 2001 From: Jibin Bao Date: Thu, 7 Nov 2024 05:44:24 +0800 Subject: [PATCH 082/221] fix testQosSaiDscpToPgMapping issue (#15378) The issue is introduced by the PR:https://github.com/sonic-net/sonic-mgmt/pull/9859. This PR should be dedicated for broadcom-dnx, it should not change the logic for the remaining platform, so restore the original logic for non-broadcom-dnx. --- tests/saitests/py3/sai_qos_tests.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index dd5b159f684..eb3373596b4 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -1193,11 +1193,11 @@ def runTest(self): print(list(map(operator.sub, pg_cntrs, pg_cntrs_base)), file=sys.stderr) for i in range(0, PG_NUM): - # DNX/Chassis: - # pg = 0 => Some extra packets with unmarked TC - # pg = 4 => Extra packets for LACP/BGP packets - # pg = 7 => packets from cpu to front panel ports - if platform_asic and platform_asic in ["broadcom-dnx", "cisco-8000"]: + if platform_asic and platform_asic == "broadcom-dnx": + # DNX/Chassis: + # pg = 0 => Some extra packets with unmarked TC + # pg = 4 => Extra packets for LACP/BGP packets + # pg = 7 => packets from cpu to front panel ports if i == pg: if i == 3: assert (pg_cntrs[pg] == pg_cntrs_base[pg] + len(dscps)) @@ -1210,9 +1210,19 @@ def runTest(self): assert (pg_cntrs[i] == pg_cntrs_base[i]) else: if i == pg: - assert (pg_cntrs[pg] == pg_cntrs_base[pg] + len(dscps)) + if i == 0 or i == 4: + assert (pg_cntrs[pg] >= + pg_cntrs_base[pg] + len(dscps)) + else: + assert (pg_cntrs[pg] == + pg_cntrs_base[pg] + len(dscps)) else: - assert (pg_cntrs[i] == pg_cntrs_base[i]) + # LACP packets are mapped to queue0 and tcp syn packets for BGP to queue4 + # So for those queues the count could be more + if i == 0 or i == 4: + assert (pg_cntrs[i] >= pg_cntrs_base[i]) + else: + assert (pg_cntrs[i] == pg_cntrs_base[i]) # confirm that dscp pkts are received total_recv_cnt = 0 dscp_recv_cnt = 0 From 7d6094d05289da91b0eacee6d93663aef4e668c3 Mon Sep 17 00:00:00 2001 From: Jianquan Ye Date: Thu, 7 Nov 2024 08:56:57 +1000 Subject: [PATCH 083/221] [CI/CD] prolong pytest collect only time out setting (#15386) Description of PR Summary: Fixes the timeout issue on pytest collect only Approach What is the motivation for this PR? Fixes the timeout issue on pytest collect only co-authorized by: jianquanye@microsoft.com --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c06c4b0bfca..1256f817404 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,7 +35,7 @@ stages: - job: validate_test_cases displayName: "Validate Test Cases" - timeoutInMinutes: 20 + timeoutInMinutes: 30 continueOnError: false pool: sonic-common steps: From 9c40bc43d7513264bc9a00de399d2d98d6584560 Mon Sep 17 00:00:00 2001 From: Jianquan Ye Date: Thu, 7 Nov 2024 09:05:10 +1000 Subject: [PATCH 084/221] Fix the wrong reboot wait/timeout setting on test_link_down (#15377) Description of PR Summary: Fixes # (issue) Fix the wait ssh timeout. set_max_to_reboot is expected to set max wait time due to different duthost, But previously it auto uses the fixture duthost, which always return the first dut in duthosts, For example, if duthosts= [lc1,lc2,rp] the duthost=lc. But for test case test_link_down_on_sup_reboot, we should get the configuration for rp. Hence update the logic, explicitly pass the target duthost to the function. Approach What is the motivation for this PR? Fix the failure for chassis on test_link_down How did you do it? explicitly pass the target duthost to the set_max_to_reboot . How did you verify/test it? run it locally with physical testbes co-authorized by: jianquanye@microsoft.com --- tests/platform_tests/test_link_down.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/platform_tests/test_link_down.py b/tests/platform_tests/test_link_down.py index 75426c219ef..7cad169c6a2 100644 --- a/tests/platform_tests/test_link_down.py +++ b/tests/platform_tests/test_link_down.py @@ -26,7 +26,6 @@ MAX_TIME_TO_REBOOT = 120 -@pytest.fixture(scope='function') def set_max_to_reboot(duthost): """ For chassis testbeds, we need to specify plt_reboot_ctrl in inventory file, @@ -148,12 +147,13 @@ def check_interfaces_and_services_all_LCs(duthosts, conn_graph_facts, xcvr_skip_ def test_link_down_on_sup_reboot(duthosts, localhost, enum_supervisor_dut_hostname, - conn_graph_facts, set_max_to_reboot, + conn_graph_facts, fanouthosts, xcvr_skip_list): if len(duthosts.nodes) == 1: pytest.skip("Skip single-host dut for this test") duthost = duthosts[enum_supervisor_dut_hostname] + set_max_to_reboot(duthost) # There are some errors due to reboot happened before this test file for some reason, # and SUP may not have enough time to recover all dockers and the wait for process wait for 300 secs in @@ -203,9 +203,10 @@ def test_link_down_on_sup_reboot(duthosts, localhost, enum_supervisor_dut_hostna def test_link_status_on_host_reboot(duthosts, localhost, enum_rand_one_per_hwsku_frontend_hostname, - conn_graph_facts, set_max_to_reboot, + conn_graph_facts, fanouthosts, xcvr_skip_list): duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + set_max_to_reboot(duthost) hostname = duthost.hostname # Before test, check all interfaces and services are up From ee3a928e59b095946d2e9c41b25d1a91769463f5 Mon Sep 17 00:00:00 2001 From: Jibin Bao Date: Thu, 7 Nov 2024 09:03:35 +0800 Subject: [PATCH 085/221] update for test_acl_tcp_rst due to design change (#13648) 1. For receiver and sender, tcp srt packet will have no payload. 2. Remove some fields ignore to check them, because they are expected same as the sent packet. Change-Id: Icf9b975c6563188202408d09612d79ea0bb1184f --- tests/dash/dash_acl.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/dash/dash_acl.py b/tests/dash/dash_acl.py index 1ce0abe5f7d..0248d4d6b91 100644 --- a/tests/dash/dash_acl.py +++ b/tests/dash/dash_acl.py @@ -1132,11 +1132,6 @@ def _check_tcp_rst_pkt_acl_permit(pkt): def _check_tcp_rst_pkt_acl_deny(pkt): def _set_do_not_care_fields(expected_rst_packt, bit_length_after_inner_tcp_falg): - expected_rst_packt.set_do_not_care(128, 16) # external packet total length - expected_rst_packt.set_do_not_care(304, 16) # udp length - expected_rst_packt.set_do_not_care(336, 16) # vxlan flags - expected_rst_packt.set_do_not_care(352, 16) # vxlan group policy id - expected_rst_packt.set_do_not_care(528, 16) # inner ip total length expected_rst_packt.set_do_not_care(592, 16) # checksum in inner packet # it includes the fields after inner tcp flag expected_rst_packt.set_do_not_care(784, bit_length_after_inner_tcp_falg) @@ -1146,11 +1141,12 @@ def _get_expected_rst_packet_to_receiver(): inner_extra_conf_to_receiver = copy.deepcopy(pkt.inner_extra_conf) inner_extra_conf_to_receiver["tcp_flags"] = "R" inner_extra_conf_to_receiver["ip_id"] = 0x0000 + inner_extra_conf_to_receiver["pktlen"] = 54 _, _, _, expected_rst_packet_to_receiver = packets.inbound_vnet_packets(pkt.dash_config_info, inner_extra_conf_to_receiver, inner_packet_type='tcp') logger.info("Set ignore fields for expected rst packet sent to receiver") - _set_do_not_care_fields(expected_rst_packet_to_receiver, 416) + _set_do_not_care_fields(expected_rst_packet_to_receiver, 48) return expected_rst_packet_to_receiver @@ -1185,7 +1181,7 @@ def _get_expected_rst_packet_to_sender(): # Verify packet(no syn) is dropped # verify packet RST packet is sent to two ends - len_expected_rst_packet_to_receiver = 150 + len_expected_rst_packet_to_receiver = 104 len_expected_rst_packet_to_sender = 104 packets.verify_tcp_packet_drop_rst_packet_sent( ptfadapter, From abb3df35e444a53054bddf5dc0fd14b447f4c2c1 Mon Sep 17 00:00:00 2001 From: Perumal Venkatesh Date: Wed, 6 Nov 2024 17:26:34 -0800 Subject: [PATCH 086/221] Increase startup_tsa_tsb time based on Cisco's observation. (#15367) Description of PR We are noticing that the time diff is ranging from 120-145 secs. Hence increasing it to 160secs to be on the safer side. After increasing the time we are seeing all testcases passing with all other changes that was added in PR #13290 In our case, since kdump is enabled, during abnormal reboot case, our reboot-cause is Kernel Panic. Made an appropriate change for Cisco chassis Approach What is the motivation for this PR? Check the functionality with a slight increase in time How did you do it? How did you verify/test it? Any platform specific information? Validated on Cisco 8808 chassis with T2 profile Supported testbed topology if it's a new test case? Documentation =========================== short test summary info ============================ PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_dut_cold_reboot[sfd-lt2-lc0] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_dut_abnormal_reboot[sfd-lt2-lc0] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_user_init_tsa[sfd-lt2-lc0] PASSED bgp/test_startup_tsa_tsb_service.py::test_user_init_tsa_while_service_run_on_dut[sfd-lt2-lc0] PASSED bgp/test_startup_tsa_tsb_service.py::test_user_init_tsb_while_service_run_on_dut[sfd-lt2-lc0] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_timer_efficiency[sfd-lt2-lc0] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_dut_cold_reboot[sfd-lt2-lc1] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_dut_abnormal_reboot[sfd-lt2-lc1] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_user_init_tsa[sfd-lt2-lc1] PASSED bgp/test_startup_tsa_tsb_service.py::test_user_init_tsa_while_service_run_on_dut[sfd-lt2-lc1] PASSED bgp/test_startup_tsa_tsb_service.py::test_user_init_tsb_while_service_run_on_dut[sfd-lt2-lc1] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_timer_efficiency[sfd-lt2-lc1] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_supervisor_cold_reboot[sfd-lt2-sup] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_supervisor_abnormal_reboot[sfd-lt2-sup] PASSED bgp/test_startup_tsa_tsb_service.py::test_user_init_tsb_on_sup_while_service_run_on_dut[sfd-lt2-sup] PASSED bgp/test_startup_tsa_tsb_service.py::test_tsa_tsb_service_with_tsa_on_sup[sfd-lt2-sup] ================= 16 passed, 1 warning in 31255.04s (8:40:55) ================== co-authorized by: jianquanye@microsoft.com --- tests/bgp/test_reliable_tsa.py | 8 ++-- tests/bgp/test_startup_tsa_tsb_service.py | 48 ++++++++++++++++------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/tests/bgp/test_reliable_tsa.py b/tests/bgp/test_reliable_tsa.py index e956d6ef26a..928e9590d97 100644 --- a/tests/bgp/test_reliable_tsa.py +++ b/tests/bgp/test_reliable_tsa.py @@ -850,7 +850,7 @@ def test_sup_tsa_act_with_sup_reboot(duthosts, localhost, enum_supervisor_dut_ho logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in the same maintenance state like before supervisor reboot @@ -1043,7 +1043,7 @@ def test_dut_tsa_act_with_reboot_when_sup_dut_on_tsb_init(duthosts, localhost, e logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify startup_tsa_tsb service is not started and in exited due to manual TSA pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'exited'), @@ -1355,7 +1355,7 @@ def test_sup_tsa_when_startup_tsa_tsb_service_running(duthosts, localhost, enum_ logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify startup_tsa_tsb service is started and running pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'running'), @@ -1464,7 +1464,7 @@ def test_sup_tsb_when_startup_tsa_tsb_service_running(duthosts, localhost, enum_ logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify startup_tsa_tsb service is started and running pytest_assert(wait_until(tsa_tsb_timer[linecard], 20, 0, get_tsa_tsb_service_status, linecard, 'running'), diff --git a/tests/bgp/test_startup_tsa_tsb_service.py b/tests/bgp/test_startup_tsa_tsb_service.py index 2b3e779b328..4170fdb766a 100644 --- a/tests/bgp/test_startup_tsa_tsb_service.py +++ b/tests/bgp/test_startup_tsa_tsb_service.py @@ -19,7 +19,7 @@ logger = logging.getLogger(__name__) - +KERNEL_PANIC_REBOOT_CAUSE = "Kernel Panic" COLD_REBOOT_CAUSE = 'cold' UNKNOWN_REBOOT_CAUSE = "Unknown" SUP_REBOOT_CAUSE = 'Reboot from Supervisor' @@ -209,7 +209,7 @@ def test_tsa_tsb_service_with_dut_cold_reboot(duthosts, localhost, enum_rand_one logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(duthost) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in maintenance state. @@ -325,7 +325,7 @@ def test_tsa_tsb_service_with_dut_abnormal_reboot(duthosts, localhost, enum_rand service_uptime = get_tsa_tsb_service_uptime(duthost) time_diff = (service_uptime - dut_uptime).total_seconds() logger.info("Time difference between dut up-time & tsa_tsb_service up-time is {}".format(int(time_diff))) - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Make sure BGP containers are running properly before verifying @@ -384,8 +384,17 @@ def test_tsa_tsb_service_with_dut_abnormal_reboot(duthosts, localhost, enum_rand # Make sure the dut's reboot cause is as expected logger.info("Check reboot cause of the dut") reboot_cause = get_reboot_cause(duthost) - pytest_assert(reboot_cause == UNKNOWN_REBOOT_CAUSE, - "Reboot cause {} did not match the trigger {}".format(reboot_cause, UNKNOWN_REBOOT_CAUSE)) + out = duthost.command('show kdump config') + if "Enabled" not in out["stdout"]: + pytest_assert( + reboot_cause == UNKNOWN_REBOOT_CAUSE, + "Reboot cause {} did not match the trigger {}".format(reboot_cause, UNKNOWN_REBOOT_CAUSE) + ) + else: + pytest_assert( + reboot_cause == KERNEL_PANIC_REBOOT_CAUSE, + "Reboot cause {} did not match the trigger {}".format(reboot_cause, KERNEL_PANIC_REBOOT_CAUSE) + ) @pytest.mark.disable_loganalyzer @@ -442,7 +451,7 @@ def test_tsa_tsb_service_with_supervisor_cold_reboot(duthosts, localhost, enum_s logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in maintenance state. @@ -592,7 +601,7 @@ def test_tsa_tsb_service_with_supervisor_abnormal_reboot(duthosts, localhost, en logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Make sure BGP containers are running properly before verifying @@ -669,8 +678,17 @@ def test_tsa_tsb_service_with_supervisor_abnormal_reboot(duthosts, localhost, en # Make sure the Supervisor's reboot cause is as expected logger.info("Check reboot cause of the supervisor") reboot_cause = get_reboot_cause(suphost) - pytest_assert(reboot_cause == UNKNOWN_REBOOT_CAUSE, - "Reboot cause {} did not match the trigger {}".format(reboot_cause, UNKNOWN_REBOOT_CAUSE)) + out = suphost.command('show kdump config') + if "Enabled" not in out["stdout"]: + pytest_assert( + reboot_cause == UNKNOWN_REBOOT_CAUSE, + "Reboot cause {} did not match the trigger {}".format(reboot_cause, UNKNOWN_REBOOT_CAUSE) + ) + else: + pytest_assert( + reboot_cause == KERNEL_PANIC_REBOOT_CAUSE, + "Reboot cause {} did not match the trigger {}".format(reboot_cause, KERNEL_PANIC_REBOOT_CAUSE) + ) @pytest.mark.disable_loganalyzer @@ -718,7 +736,7 @@ def test_tsa_tsb_service_with_user_init_tsa(duthosts, localhost, enum_rand_one_p logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(duthost) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Ensure startup_tsa_tsb service is in exited state after dut reboot @@ -825,7 +843,7 @@ def test_user_init_tsa_while_service_run_on_dut(duthosts, localhost, enum_rand_o logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(duthost) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in maintenance state. @@ -941,7 +959,7 @@ def test_user_init_tsb_while_service_run_on_dut(duthosts, localhost, enum_rand_o logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(duthost) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in maintenance state. @@ -1059,7 +1077,7 @@ def test_user_init_tsb_on_sup_while_service_run_on_dut(duthosts, localhost, logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in maintenance state. @@ -1184,7 +1202,7 @@ def test_tsa_tsb_timer_efficiency(duthosts, localhost, enum_rand_one_per_hwsku_f logging.info('DUT {} up since {}'.format(duthost.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(duthost) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") logging.info("Wait until all critical services are fully started") @@ -1309,7 +1327,7 @@ def test_tsa_tsb_service_with_tsa_on_sup(duthosts, localhost, logging.info('DUT {} up since {}'.format(linecard.hostname, dut_uptime)) service_uptime = get_tsa_tsb_service_uptime(linecard) time_diff = (service_uptime - dut_uptime).total_seconds() - pytest_assert(int(time_diff) < 120, + pytest_assert(int(time_diff) < 160, "startup_tsa_tsb service started much later than the expected time after dut reboot") # Verify DUT is in maintenance state. From 7ea5c82a899d4403adb78a9c599d47c944552d25 Mon Sep 17 00:00:00 2001 From: Sai Kiran <110003254+opcoder0@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:12:44 +1100 Subject: [PATCH 087/221] Re-configure ExaBGP http-api (for py3 only) (#15383) Re-configure ExaBGP's http-api (for Py3 only). With Python 3 only environment using ExaBGP 4 with Flask 3.x the werkzeug Requests max form memory is capped to 500k (https://werkzeug.palletsprojects.com/en/stable/request_data/#limiting-request-data). This breaks announce routes. This PR increases the limit. --- ansible/library/exabgp.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ansible/library/exabgp.py b/ansible/library/exabgp.py index 3a8b41de911..f46b262211d 100644 --- a/ansible/library/exabgp.py +++ b/ansible/library/exabgp.py @@ -78,6 +78,16 @@ def run_command(): return "OK\\n" if __name__ == '__main__': + # with werkzeug 3.x the default size of max_form_memory_size + # is 500K. Routes reach a bit beyond that and the client + # receives HTTP 413. + # Configure the max size to 4 MB to be safe. + if not six.PY2: + from werkzeug import Request + max_content_length = 4 * 1024 * 1024 + Request.max_content_length = max_content_length + Request.max_form_memory_size = max_content_length + Request.max_form_parts = max_content_length app.run(host='0.0.0.0', port=sys.argv[1]) ''' From 20a1958073430280d8f1988b03fbc2c368304214 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:31:19 +0800 Subject: [PATCH 088/221] Remove skip_traffic_test fixture in acl tests (#15366) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test in testcases How did you verify/test it? --- .../custom_acl_table/test_custom_acl_table.py | 30 ++--- .../acl/null_route/test_null_route_helper.py | 10 +- tests/acl/test_acl.py | 116 +++++++++--------- tests/acl/test_acl_outer_vlan.py | 66 +++++----- tests/acl/test_stress_acl.py | 24 ++-- 5 files changed, 118 insertions(+), 128 deletions(-) diff --git a/tests/acl/custom_acl_table/test_custom_acl_table.py b/tests/acl/custom_acl_table/test_custom_acl_table.py index 617e9cac66f..7e1cddc252b 100644 --- a/tests/acl/custom_acl_table/test_custom_acl_table.py +++ b/tests/acl/custom_acl_table/test_custom_acl_table.py @@ -11,7 +11,6 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa: F401 logger = logging.getLogger(__name__) @@ -251,7 +250,7 @@ def build_exp_pkt(input_pkt): def test_custom_acl(rand_selected_dut, rand_unselected_dut, tbinfo, ptfadapter, setup_acl_rules, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_counterpoll_interval, remove_dataacl_table, skip_traffic_test): # noqa F811 + setup_counterpoll_interval, remove_dataacl_table): # noqa F811 """ The test case is to verify the functionality of custom ACL table Test steps @@ -263,6 +262,7 @@ def test_custom_acl(rand_selected_dut, rand_unselected_dut, tbinfo, ptfadapter, 6. Verify the counter of expected rule increases as expected """ mg_facts = rand_selected_dut.get_extended_minigraph_facts(tbinfo) + asic_type = rand_selected_dut.facts['asic_type'] if "dualtor" in tbinfo["topo"]["name"]: mg_facts_unselected_dut = rand_unselected_dut.get_extended_minigraph_facts(tbinfo) vlan_name = list(mg_facts['minigraph_vlans'].keys())[0] @@ -288,15 +288,17 @@ def test_custom_acl(rand_selected_dut, rand_unselected_dut, tbinfo, ptfadapter, exp_pkt = build_exp_pkt(pkt) # Send and verify packet clear_acl_counter(rand_selected_dut) - if not skip_traffic_test: - if "dualtor-aa" in tbinfo["topo"]["name"]: - clear_acl_counter(rand_unselected_dut) - ptfadapter.dataplane.flush() - testutils.send(ptfadapter, pkt=pkt, port_id=src_port_indice) - testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=dst_port_indices, timeout=5) - acl_counter = read_acl_counter(rand_selected_dut, rule) - if "dualtor-aa" in tbinfo["topo"]["name"]: - acl_counter_unselected_dut = read_acl_counter(rand_unselected_dut, rule) - acl_counter += acl_counter_unselected_dut - # Verify acl counter - pytest_assert(acl_counter == 1, "ACL counter for {} didn't increase as expected".format(rule)) + if "dualtor-aa" in tbinfo["topo"]["name"]: + clear_acl_counter(rand_unselected_dut) + if asic_type == 'vs': + logger.info("Skip ACL verification on VS platform") + continue + ptfadapter.dataplane.flush() + testutils.send(ptfadapter, pkt=pkt, port_id=src_port_indice) + testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=dst_port_indices, timeout=5) + acl_counter = read_acl_counter(rand_selected_dut, rule) + if "dualtor-aa" in tbinfo["topo"]["name"]: + acl_counter_unselected_dut = read_acl_counter(rand_unselected_dut, rule) + acl_counter += acl_counter_unselected_dut + # Verify acl counter + pytest_assert(acl_counter == 1, "ACL counter for {} didn't increase as expected".format(rule)) diff --git a/tests/acl/null_route/test_null_route_helper.py b/tests/acl/null_route/test_null_route_helper.py index e2f5da0a557..fbea5d5f1d7 100644 --- a/tests/acl/null_route/test_null_route_helper.py +++ b/tests/acl/null_route/test_null_route_helper.py @@ -9,7 +9,7 @@ from ptf.mask import Mask import ptf.packet as scapy -from tests.common.fixtures.ptfhost_utils import remove_ip_addresses, skip_traffic_test # noqa F401 +from tests.common.fixtures.ptfhost_utils import remove_ip_addresses # noqa F401 import ptf.testutils as testutils from tests.common.helpers.assertions import pytest_require from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError @@ -229,12 +229,10 @@ def generate_packet(src_ip, dst_ip, dst_mac): return pkt, exp_pkt -def send_and_verify_packet(ptfadapter, pkt, exp_pkt, tx_port, rx_port, expected_action, skip_traffic_test): # noqa F811 +def send_and_verify_packet(ptfadapter, pkt, exp_pkt, tx_port, rx_port, expected_action): # noqa F811 """ Send packet with ptfadapter and verify if packet is forwarded or dropped as expected. """ - if skip_traffic_test: - return ptfadapter.dataplane.flush() testutils.send(ptfadapter, pkt=pkt, port_id=tx_port) if expected_action == FORWARD: @@ -244,7 +242,7 @@ def send_and_verify_packet(ptfadapter, pkt, exp_pkt, tx_port, rx_port, expected_ def test_null_route_helper(rand_selected_dut, tbinfo, ptfadapter, - apply_pre_defined_rules, setup_ptf, skip_traffic_test): # noqa F811 + apply_pre_defined_rules, setup_ptf): # noqa F811 """ Test case to verify script null_route_helper. Some packets are generated as defined in TEST_DATA and sent to DUT, @@ -280,4 +278,4 @@ def test_null_route_helper(rand_selected_dut, tbinfo, ptfadapter, time.sleep(1) send_and_verify_packet(ptfadapter, pkt, exp_pkt, random.choice(ptf_interfaces), - rx_port, expected_result, skip_traffic_test) + rx_port, expected_result) diff --git a/tests/acl/test_acl.py b/tests/acl/test_acl.py index e97d0fb176d..1831e1343f0 100644 --- a/tests/acl/test_acl.py +++ b/tests/acl/test_acl.py @@ -19,7 +19,6 @@ from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError from tests.common.config_reload import config_reload from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py, run_garp_service, change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.dualtor.dual_tor_mock import mock_server_base_ip_addr # noqa F401 from tests.common.helpers.constants import DEFAULT_NAMESPACE from tests.common.utilities import wait_until, get_upstream_neigh_type, get_downstream_neigh_type, check_msg_in_syslog @@ -634,7 +633,7 @@ def setup_rules(self, dut, acl_table, ip_version): """ pass - def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, conn_graph_facts): # noqa F811 + def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, conn_graph_facts): # noqa F811 """Perform actions after rules have been applied. Args: @@ -664,7 +663,7 @@ def teardown_rules(self, dut): @pytest.fixture(scope="class", autouse=True) def acl_rules(self, duthosts, localhost, setup, acl_table, populate_vlan_arp_entries, tbinfo, - ip_version, conn_graph_facts): # noqa F811 + ip_version, conn_graph_facts): # noqa F811 """Setup/teardown ACL rules for the current set of tests. Args: @@ -704,7 +703,7 @@ def tear_down_acl_rule_single_dut(self, duthost, loganalyzer): duthost, LOG_EXPECT_ACL_RULE_REMOVE_RE) def set_up_acl_rules_single_dut(self, acl_table, - conn_graph_facts, dut_to_analyzer_map, duthost, # noqa F811 + conn_graph_facts, dut_to_analyzer_map, duthost, # noqa F811 ip_version, localhost, populate_vlan_arp_entries, tbinfo): logger.info("{}: ACL rule application started".format(duthost.hostname)) @@ -967,57 +966,57 @@ def expected_mask_routed_packet(self, pkt, ip_version): return exp_pkt - def test_ingress_unmatched_blocked(self, setup, direction, ptfadapter, ip_version, stage, skip_traffic_test): # noqa F811 + def test_ingress_unmatched_blocked(self, setup, direction, ptfadapter, ip_version, stage): """Verify that unmatched packets are dropped for ingress.""" if stage == "egress": pytest.skip("Only run for ingress") pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) - def test_egress_unmatched_forwarded(self, setup, direction, ptfadapter, ip_version, stage, skip_traffic_test): # noqa F811 + def test_egress_unmatched_forwarded(self, setup, direction, ptfadapter, ip_version, stage): """Verify that default egress rule allow all traffics""" if stage == "ingress": pytest.skip("Only run for egress") pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) def test_source_ip_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward a packet on source IP.""" src_ip = "20.0.0.2" if ip_version == "ipv4" else "60c0:a800::6" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(1) def test_rules_priority_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we respect rule priorites in the forwarding case.""" src_ip = "20.0.0.7" if ip_version == "ipv4" else "60c0:a800::7" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(20) def test_rules_priority_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we respect rule priorites in the drop case.""" src_ip = "20.0.0.3" if ip_version == "ipv4" else "60c0:a800::4" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(7) def test_dest_ip_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, vlan_name, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version, vlan_name): """Verify that we can match and forward a packet on destination IP.""" dst_ip = DOWNSTREAM_IP_TO_ALLOW[ip_version] \ if direction == "uplink->downlink" else UPSTREAM_IP_TO_ALLOW[ip_version] pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, dst_ip=dst_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) # Because m0_l3_scenario use differnet IPs, so need to verify different acl rules. if direction == "uplink->downlink": if setup["topo"] == "m0_l3": @@ -1037,13 +1036,13 @@ def test_dest_ip_match_forwarded(self, setup, direction, ptfadapter, counters_sanity_check.append(rule_id) def test_dest_ip_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, vlan_name, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version, vlan_name): """Verify that we can match and drop a packet on destination IP.""" dst_ip = DOWNSTREAM_IP_TO_BLOCK[ip_version] \ if direction == "uplink->downlink" else UPSTREAM_IP_TO_BLOCK[ip_version] pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, dst_ip=dst_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) # Because m0_l3_scenario use differnet IPs, so need to verify different acl rules. if direction == "uplink->downlink": if setup["topo"] == "m0_l3": @@ -1063,156 +1062,156 @@ def test_dest_ip_match_dropped(self, setup, direction, ptfadapter, counters_sanity_check.append(rule_id) def test_source_ip_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop a packet on source IP.""" src_ip = "20.0.0.6" if ip_version == "ipv4" else "60c0:a800::3" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(14) def test_udp_source_ip_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward a UDP packet on source IP.""" src_ip = "20.0.0.4" if ip_version == "ipv4" else "60c0:a800::8" pkt = self.udp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(13) def test_udp_source_ip_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop a UDP packet on source IP.""" src_ip = "20.0.0.8" if ip_version == "ipv4" else "60c0:a800::2" pkt = self.udp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(26) def test_icmp_source_ip_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop an ICMP packet on source IP.""" src_ip = "20.0.0.8" if ip_version == "ipv4" else "60c0:a800::2" pkt = self.icmp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(25) def test_icmp_source_ip_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward an ICMP packet on source IP.""" src_ip = "20.0.0.4" if ip_version == "ipv4" else "60c0:a800::8" pkt = self.icmp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(12) def test_l4_dport_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward on L4 destination port.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, dport=0x1217) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(9) def test_l4_sport_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward on L4 source port.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, sport=0x120D) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(4) def test_l4_dport_range_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward on a range of L4 destination ports.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, dport=0x123B) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(11) def test_l4_sport_range_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward on a range of L4 source ports.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, sport=0x123A) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(10) def test_l4_dport_range_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on a range of L4 destination ports.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, dport=0x127B) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(22) def test_l4_sport_range_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on a range of L4 source ports.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, sport=0x1271) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(17) def test_ip_proto_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward on the IP protocol.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, proto=0x7E) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(5) def test_tcp_flags_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and forward on the TCP flags.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, flags=0x1B) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(6) def test_l4_dport_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on L4 destination port.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, dport=0x127B) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(22) def test_l4_sport_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on L4 source port.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, sport=0x1271) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(17) def test_ip_proto_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on the IP protocol.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, proto=0x7F) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(18) def test_tcp_flags_match_dropped(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on the TCP flags.""" pkt = self.tcp_packet(setup, direction, ptfadapter, ip_version, flags=0x24) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, True, ip_version) counters_sanity_check.append(19) def test_icmp_match_forwarded(self, setup, direction, ptfadapter, - counters_sanity_check, ip_version, skip_traffic_test): # noqa F811 + counters_sanity_check, ip_version): """Verify that we can match and drop on the TCP flags.""" src_ip = "20.0.0.10" if ip_version == "ipv4" else "60c0:a800::10" pkt = self.icmp_packet(setup, direction, ptfadapter, ip_version, src_ip=src_ip, icmp_type=3, icmp_code=1) - self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version, skip_traffic_test) + self._verify_acl_traffic(setup, direction, ptfadapter, pkt, False, ip_version) counters_sanity_check.append(29) - def _verify_acl_traffic(self, setup, direction, ptfadapter, pkt, dropped, ip_version, skip_traffic_test): # noqa F811 + def _verify_acl_traffic(self, setup, direction, ptfadapter, pkt, dropped, ip_version): exp_pkt = self.expected_mask_routed_packet(pkt, ip_version) if ip_version == "ipv4": @@ -1220,9 +1219,6 @@ def _verify_acl_traffic(self, setup, direction, ptfadapter, pkt, dropped, ip_ver else: downstream_dst_port = DOWNSTREAM_IP_PORT_MAP.get(pkt[packet.IPv6].dst) - if skip_traffic_test: - return - ptfadapter.dataplane.flush() testutils.send(ptfadapter, self.src_port, pkt) if direction == "uplink->downlink" and downstream_dst_port: @@ -1299,7 +1295,7 @@ class TestAclWithReboot(TestBasicAcl): upon startup. """ - def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, conn_graph_facts): # noqa F811 + def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, conn_graph_facts): # noqa F811 """Save configuration and reboot after rules are applied. Args: @@ -1344,7 +1340,7 @@ class TestAclWithPortToggle(TestBasicAcl): Verify that ACLs still function as expected after links flap. """ - def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, conn_graph_facts): # noqa F811 + def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, conn_graph_facts): # noqa F811 """Toggle ports after rules are applied. Args: diff --git a/tests/acl/test_acl_outer_vlan.py b/tests/acl/test_acl_outer_vlan.py index a9a237b8a08..0c1d0288401 100644 --- a/tests/acl/test_acl_outer_vlan.py +++ b/tests/acl/test_acl_outer_vlan.py @@ -14,7 +14,7 @@ from tests.common.utilities import wait_until from tests.common.config_reload import config_reload from tests.common.helpers.assertions import pytest_assert, pytest_require -from tests.common.fixtures.ptfhost_utils import change_mac_addresses, skip_traffic_test # noqa F401 +from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError from abc import abstractmethod from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor_m # noqa F401 @@ -515,7 +515,7 @@ def setup(self, rand_selected_dut, ptfhost, ip_version, vlan_setup_info): self.post_running_hook(rand_selected_dut, ptfhost, ip_version) def _do_verification(self, ptfadapter, duthost, tbinfo, vlan_setup_info, - ip_version, tagged_mode, action, skip_traffic_test): # noqa F811 + ip_version, tagged_mode, action): # noqa F811 vlan_setup, _, _, _ = vlan_setup_info test_setup_config = self.setup_cfg(duthost, tbinfo, vlan_setup, tagged_mode, ip_version) @@ -556,17 +556,21 @@ def _do_verification(self, ptfadapter, duthost, tbinfo, vlan_setup_info, testutils.send(ptfadapter, port, mac_pkt) table_name = ACL_TABLE_NAME_TEMPLATE.format(stage, ip_version) + asic_type = duthost.facts['asic_type'] + if asic_type == 'vs': + logger.info("Skip ACL verification on VS platform") + return try: self._setup_acl_rules(duthost, stage, ip_version, outer_vlan_id, action) - if not skip_traffic_test: - count_before = get_acl_counter(duthost, table_name, RULE_1, timeout=0) - send_and_verify_traffic(ptfadapter, pkt, exp_pkt, src_port, dst_port, pkt_action=action) - count_after = get_acl_counter(duthost, table_name, RULE_1) - - logger.info("Verify Acl counter incremented {} > {}".format(count_after, count_before)) - pytest_assert(count_after >= count_before + 1, - "Unexpected results, counter_after {} > counter_before {}" - .format(count_after, count_before)) + + count_before = get_acl_counter(duthost, table_name, RULE_1, timeout=0) + send_and_verify_traffic(ptfadapter, pkt, exp_pkt, src_port, dst_port, pkt_action=action) + count_after = get_acl_counter(duthost, table_name, RULE_1) + + logger.info("Verify Acl counter incremented {} > {}".format(count_after, count_before)) + pytest_assert(count_after >= count_before + 1, + "Unexpected results, counter_after {} > counter_before {}" + .format(count_after, count_before)) except Exception as e: raise (e) finally: @@ -574,83 +578,75 @@ def _do_verification(self, ptfadapter, duthost, tbinfo, vlan_setup_info, @pytest.mark.po2vlan def test_tagged_forwarded(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is forwarded by ACL rule on tagged interface """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_TAGGED, ACTION_FORWARD, skip_traffic_test) + ip_version, TYPE_TAGGED, ACTION_FORWARD) @pytest.mark.po2vlan def test_tagged_dropped(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is dropped by ACL rule on tagged interface """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_TAGGED, ACTION_DROP, skip_traffic_test) + ip_version, TYPE_TAGGED, ACTION_DROP) @pytest.mark.po2vlan def test_untagged_forwarded(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is forwarded by ACL rule on untagged interface """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_UNTAGGED, ACTION_FORWARD, skip_traffic_test) + ip_version, TYPE_UNTAGGED, ACTION_FORWARD) @pytest.mark.po2vlan def test_untagged_dropped(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is dropped by ACL rule on untagged interface """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_UNTAGGED, ACTION_DROP, skip_traffic_test) + ip_version, TYPE_UNTAGGED, ACTION_DROP) @pytest.mark.po2vlan def test_combined_tagged_forwarded(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is forwarded by ACL rule on tagged interface, and the interface belongs to two vlans """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_COMBINE_TAGGED, ACTION_FORWARD, skip_traffic_test) + ip_version, TYPE_COMBINE_TAGGED, ACTION_FORWARD) @pytest.mark.po2vlan def test_combined_tagged_dropped(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is dropped by ACL rule on tagged interface, and the interface belongs to two vlans """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_COMBINE_TAGGED, ACTION_DROP, skip_traffic_test) + ip_version, TYPE_COMBINE_TAGGED, ACTION_DROP) @pytest.mark.po2vlan def test_combined_untagged_forwarded(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is forwarded by ACL rule on untagged interface, and the interface belongs to two vlans """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_COMBINE_UNTAGGED, ACTION_FORWARD, skip_traffic_test) + ip_version, TYPE_COMBINE_UNTAGGED, ACTION_FORWARD) @pytest.mark.po2vlan def test_combined_untagged_dropped(self, ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 - skip_traffic_test): # noqa F811 + ip_version, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ Verify packet is dropped by ACL rule on untagged interface, and the interface belongs to two vlans """ self._do_verification(ptfadapter, rand_selected_dut, tbinfo, vlan_setup_info, - ip_version, TYPE_COMBINE_UNTAGGED, ACTION_DROP, skip_traffic_test) + ip_version, TYPE_COMBINE_UNTAGGED, ACTION_DROP) @pytest.fixture(scope='module', autouse=True) diff --git a/tests/acl/test_stress_acl.py b/tests/acl/test_stress_acl.py index bae67cdb873..47244a30bc4 100644 --- a/tests/acl/test_stress_acl.py +++ b/tests/acl/test_stress_acl.py @@ -7,7 +7,6 @@ from collections import defaultdict from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa F401 from tests.common.utilities import wait_until -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 pytestmark = [ pytest.mark.topology("t0", "t1", "m0", "mx"), @@ -119,7 +118,7 @@ def prepare_test_port(rand_selected_dut, tbinfo): def verify_acl_rules(rand_selected_dut, ptfadapter, ptf_src_port, ptf_dst_ports, - acl_rule_list, del_rule_id, verity_status, skip_traffic_test): # noqa F811 + acl_rule_list, del_rule_id, verity_status): for acl_id in acl_rule_list: ip_addr1 = acl_id % 256 @@ -146,13 +145,12 @@ def verify_acl_rules(rand_selected_dut, ptfadapter, ptf_src_port, ptf_dst_ports, exp_pkt.set_do_not_care_scapy(packet.Ether, 'src') exp_pkt.set_do_not_care_scapy(packet.IP, "chksum") - if not skip_traffic_test: - ptfadapter.dataplane.flush() - testutils.send(test=ptfadapter, port_id=ptf_src_port, pkt=pkt) - if verity_status == "forward" or acl_id == del_rule_id: - testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, ports=ptf_dst_ports) - elif verity_status == "drop" and acl_id != del_rule_id: - testutils.verify_no_packet_any(test=ptfadapter, pkt=exp_pkt, ports=ptf_dst_ports) + ptfadapter.dataplane.flush() + testutils.send(test=ptfadapter, port_id=ptf_src_port, pkt=pkt) + if verity_status == "forward" or acl_id == del_rule_id: + testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, ports=ptf_dst_ports) + elif verity_status == "drop" and acl_id != del_rule_id: + testutils.verify_no_packet_any(test=ptfadapter, pkt=exp_pkt, ports=ptf_dst_ports) def acl_rule_loaded(rand_selected_dut, acl_rule_list): @@ -168,7 +166,7 @@ def acl_rule_loaded(rand_selected_dut, acl_rule_list): def test_acl_add_del_stress(rand_selected_dut, tbinfo, ptfadapter, prepare_test_file, prepare_test_port, get_function_completeness_level, - toggle_all_simulator_ports_to_rand_selected_tor, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 ptf_src_port, ptf_dst_ports, dut_port = prepare_test_port @@ -186,7 +184,7 @@ def test_acl_add_del_stress(rand_selected_dut, tbinfo, ptfadapter, prepare_test_ rand_selected_dut.shell(cmd_create_table) acl_rule_list = list(range(1, ACL_RULE_NUMS + 1)) verify_acl_rules(rand_selected_dut, ptfadapter, ptf_src_port, ptf_dst_ports, - acl_rule_list, 0, "forward", skip_traffic_test) + acl_rule_list, 0, "forward") try: loops = 0 while loops <= loop_times: @@ -204,7 +202,7 @@ def test_acl_add_del_stress(rand_selected_dut, tbinfo, ptfadapter, prepare_test_ wait_until(wait_timeout, 2, 0, acl_rule_loaded, rand_selected_dut, acl_rule_list) verify_acl_rules(rand_selected_dut, ptfadapter, ptf_src_port, ptf_dst_ports, - acl_rule_list, 0, "drop", skip_traffic_test) + acl_rule_list, 0, "drop") del_rule_id = random.choice(acl_rule_list) rand_selected_dut.shell('sonic-db-cli CONFIG_DB del "ACL_RULE|STRESS_ACL| RULE_{}"'.format(del_rule_id)) @@ -212,7 +210,7 @@ def test_acl_add_del_stress(rand_selected_dut, tbinfo, ptfadapter, prepare_test_ wait_until(wait_timeout, 2, 0, acl_rule_loaded, rand_selected_dut, acl_rule_list) verify_acl_rules(rand_selected_dut, ptfadapter, ptf_src_port, ptf_dst_ports, - acl_rule_list, del_rule_id, "drop", skip_traffic_test) + acl_rule_list, del_rule_id, "drop") loops += 1 finally: From 43ae678c6aeaf6090a824829fc65d6b4ed1030c2 Mon Sep 17 00:00:00 2001 From: Chris <156943338+ccroy-arista@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:54:36 -0800 Subject: [PATCH 089/221] sonic-mgmt: fix info in testbed_vm_info.py err msg (#15249) In ansible/library/testbed_vm_info.py, there is a format string passed to a method without the actual formatting applied, i.e. the '{}'s are printed out rather than the desired information they're supposed to represent. This change passes the error message to the method with the correct formatting applied. --- ansible/library/testbed_vm_info.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ansible/library/testbed_vm_info.py b/ansible/library/testbed_vm_info.py index c5293be7bf1..19b1a485819 100644 --- a/ansible/library/testbed_vm_info.py +++ b/ansible/library/testbed_vm_info.py @@ -129,8 +129,7 @@ def main(): else: err_msg = "Cannot find the vm {} in VM inventory file {}, please make sure you have enough VMs" \ "for the topology you are using." - err_msg.format(vm_name, vm_facts.vm_file) - module.fail_json(msg=err_msg) + module.fail_json(msg=err_msg.format(vm_name, vm_facts.vm_file)) module.exit_json( ansible_facts={'neighbor_eosvm_mgmt': vm_mgmt_ip, 'topoall': vm_facts.topoall}) except (IOError, OSError): From 357c09a398226efe23ef021e55913fb39e8ebf3b Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:49:15 +0800 Subject: [PATCH 090/221] Set default kvm_support to False in ptf_runner (#15380) What is the motivation for this PR? In PR #12598, we set default kvm_support to True in ptf_runner params, but most of tests do not support traffic test in KVM, to minimize code change in testcases, it's better to set default kvm_support to False How did you do it? Set default kvm_support to False and set kvm_support to True in tests currently running ptf_runner How did you verify/test it? --- tests/arp/test_arpall.py | 15 ++++++++++----- tests/bgp/test_bgp_speaker.py | 3 ++- tests/dhcp_relay/test_dhcp_relay.py | 21 ++++++++++++++------- tests/dhcp_relay/test_dhcp_relay_stress.py | 9 ++++++--- tests/dhcp_relay/test_dhcpv6_relay.py | 3 ++- tests/fdb/test_fdb_flush.py | 1 + tests/fdb/test_fdb_mac_expire.py | 3 ++- tests/fdb/test_fdb_mac_learning.py | 1 + tests/ipfwd/test_mtu.py | 3 ++- tests/pc/test_lag_2.py | 3 ++- tests/pc/test_lag_member.py | 3 ++- tests/ptf_runner.py | 3 ++- tests/radv/test_radv_ipv6_ra.py | 12 ++++++++---- 13 files changed, 54 insertions(+), 26 deletions(-) diff --git a/tests/arp/test_arpall.py b/tests/arp/test_arpall.py index b885023b688..11637cacd26 100644 --- a/tests/arp/test_arpall.py +++ b/tests/arp/test_arpall.py @@ -26,7 +26,8 @@ def test_arp_unicast_reply(common_setup_teardown, intfs_for_test, enum_frontend_ clear_dut_arp_cache(duthost, asichost.cli_ns_option) params = { 'acs_mac': router_mac, - 'port': intf1_indice + 'port': intf1_indice, + 'kvm_support': True } log_file = "/tmp/arptest.VerifyUnicastARPReply.{0}.log".format(datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.VerifyUnicastARPReply", '/root/ptftests', @@ -45,7 +46,8 @@ def test_arp_expect_reply(common_setup_teardown, intfs_for_test, enum_frontend_a asichost = duthost.asic_instance(enum_frontend_asic_index) params = { 'acs_mac': router_mac, - 'port': intf1_indice + 'port': intf1_indice, + 'kvm_support': True } # Start PTF runner and send correct arp packets @@ -69,7 +71,8 @@ def test_arp_no_reply_other_intf(common_setup_teardown, intfs_for_test, enum_fro clear_dut_arp_cache(duthost, asichost.cli_ns_option) intf2_params = { 'acs_mac': router_mac, - 'port': intf2_indice + 'port': intf2_indice, + 'kvm_support': True } log_file = "/tmp/arptest.SrcOutRangeNoReply.{0}.log".format(datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) ptf_runner(ptfhost, 'ptftests', "arptest.SrcOutRangeNoReply", '/root/ptftests', @@ -87,7 +90,8 @@ def test_arp_no_reply_src_out_range(common_setup_teardown, intfs_for_test, enum_ asichost = duthost.asic_instance(enum_frontend_asic_index) params = { 'acs_mac': router_mac, - 'port': intf1_indice + 'port': intf1_indice, + 'kvm_support': True } # Check DUT won't reply ARP and install ARP entry when src address is not in interface subnet range @@ -108,7 +112,8 @@ def test_arp_garp_no_update(common_setup_teardown, intfs_for_test, enum_frontend asichost = duthost.asic_instance(enum_frontend_asic_index) params = { 'acs_mac': router_mac, - 'port': intf1_indice + 'port': intf1_indice, + 'kvm_support': True } # Test Gratuitous ARP behavior, no Gratuitous ARP installed when arp was not resolved before diff --git a/tests/bgp/test_bgp_speaker.py b/tests/bgp/test_bgp_speaker.py index 6082f19fc90..28c6e26b1db 100644 --- a/tests/bgp/test_bgp_speaker.py +++ b/tests/bgp/test_bgp_speaker.py @@ -334,7 +334,8 @@ def bgp_speaker_announce_routes_common(common_setup_teardown, tbinfo, duthost, "ipv6": ipv6, "testbed_mtu": mtu, "asic_type": asic_type, - "test_balancing": False}, + "test_balancing": False, + "kvm_support": True}, log_file="/tmp/bgp_speaker_test.FibTest.log", socket_recv_size=16384, is_python3=True) diff --git a/tests/dhcp_relay/test_dhcp_relay.py b/tests/dhcp_relay/test_dhcp_relay.py index 99e622dbe8c..f14db90766d 100644 --- a/tests/dhcp_relay/test_dhcp_relay.py +++ b/tests/dhcp_relay/test_dhcp_relay.py @@ -254,7 +254,8 @@ def test_dhcp_relay_default(ptfhost, dut_dhcp_relay_data, validate_dut_routes_ex "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.DHCPTest.log", is_python3=True) if not skip_dhcpmon: time.sleep(36) # dhcpmon debug counter prints every 18 seconds @@ -343,7 +344,8 @@ def test_dhcp_relay_with_source_port_ip_in_relay_enabled(ptfhost, dut_dhcp_relay "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), "testing_mode": testing_mode, - "enable_source_port_ip_in_relay": True}, + "enable_source_port_ip_in_relay": True, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.DHCPTest.log", is_python3=True) if not skip_dhcpmon: time.sleep(36) # dhcpmon debug counter prints every 18 seconds @@ -404,7 +406,8 @@ def test_dhcp_relay_after_link_flap(ptfhost, dut_dhcp_relay_data, validate_dut_r "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.DHCPTest.log", is_python3=True) @@ -460,7 +463,8 @@ def test_dhcp_relay_start_with_uplinks_down(ptfhost, dut_dhcp_relay_data, valida "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.DHCPTest.log", is_python3=True) @@ -495,7 +499,8 @@ def test_dhcp_relay_unicast_mac(ptfhost, dut_dhcp_relay_data, validate_dut_route "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.DHCPTest.log", is_python3=True) @@ -529,7 +534,8 @@ def test_dhcp_relay_random_sport(ptfhost, dut_dhcp_relay_data, validate_dut_rout "client_udp_src_port": RANDOM_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.DHCPTest.log", is_python3=True) @@ -597,7 +603,8 @@ def test_dhcp_relay_counter(ptfhost, dut_dhcp_relay_data, validate_dut_routes_ex "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dhcp_relay['switch_loopback_ip'], "uplink_mac": str(dhcp_relay['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test_counter.DHCPTest.log", is_python3=True) for type in dhcp_message_types: if type in ["Discover", "Request"]: diff --git a/tests/dhcp_relay/test_dhcp_relay_stress.py b/tests/dhcp_relay/test_dhcp_relay_stress.py index edfd94761ef..d7a69d16ffc 100644 --- a/tests/dhcp_relay/test_dhcp_relay_stress.py +++ b/tests/dhcp_relay/test_dhcp_relay_stress.py @@ -55,7 +55,8 @@ def test_dhcp_relay_restart_with_stress(ptfhost, dut_dhcp_relay_data, validate_d "uplink_mac": str(dut_dhcp_relay_data[0]['uplink_mac']), "testing_mode": testing_mode, "duration": duration, - "pps": pps}, + "pps": pps, + "kvm_support": True}, log_file="/tmp/dhcp_relay_stress_test.DHCPContinuousStressTest.log", is_python3=True, async_mode=True) @@ -95,7 +96,8 @@ def _check_socket_buffer(): "client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT, "switch_loopback_ip": dut_dhcp_relay_data[0]['switch_loopback_ip'], "uplink_mac": str(dut_dhcp_relay_data[0]['uplink_mac']), - "testing_mode": testing_mode}, + "testing_mode": testing_mode, + "kvm_support": True}, log_file="/tmp/dhcp_relay_test.stress.DHCPTest.log", is_python3=True) @@ -162,7 +164,8 @@ def test_dhcp_relay_stress(ptfhost, ptfadapter, dut_dhcp_relay_data, validate_du "uplink_mac": str(dhcp_relay['uplink_mac']), "packets_send_duration": packets_send_duration, "client_packets_per_sec": client_packets_per_sec, - "testing_mode": testing_mode + "testing_mode": testing_mode, + "kvm_support": True } count_file = '/tmp/dhcp_stress_test_{}.json'.format(dhcp_type) diff --git a/tests/dhcp_relay/test_dhcpv6_relay.py b/tests/dhcp_relay/test_dhcpv6_relay.py index e06a6d7057d..2446727f710 100644 --- a/tests/dhcp_relay/test_dhcpv6_relay.py +++ b/tests/dhcp_relay/test_dhcpv6_relay.py @@ -324,7 +324,8 @@ def test_dhcpv6_relay_counter(ptfhost, duthosts, rand_one_dut_hostname, dut_dhcp "dut_mac": str(dhcp_relay['uplink_mac']), "vlan_ip": str(dhcp_relay['downlink_vlan_iface']['addr']), "loopback_ipv6": str(dhcp_relay['loopback_ipv6']), - "is_dualtor": str(dhcp_relay['is_dualtor'])}, + "is_dualtor": str(dhcp_relay['is_dualtor']), + "kvm_support": True}, log_file="/tmp/dhcpv6_relay_test.DHCPCounterTest.log", is_python3=True) for type in message_types: diff --git a/tests/fdb/test_fdb_flush.py b/tests/fdb/test_fdb_flush.py index 5c7670bb355..82594dcf620 100644 --- a/tests/fdb/test_fdb_flush.py +++ b/tests/fdb/test_fdb_flush.py @@ -324,6 +324,7 @@ def dynamic_fdb_oper(self, duthost, tbinfo, ptfhost, create_or_clear): "router_mac": duthost.facts["router_mac"], "fdb_info": self.FDB_INFO_FILE, "dummy_mac_prefix": self.DUMMY_MAC_PREFIX, + "kvm_support": True } self.__runPtfTest(ptfhost, "fdb_flush_test.FdbFlushTest", testParams) elif 'clear' == create_or_clear: diff --git a/tests/fdb/test_fdb_mac_expire.py b/tests/fdb/test_fdb_mac_expire.py index 4f340f46c1f..e98e86c2d7a 100644 --- a/tests/fdb/test_fdb_mac_expire.py +++ b/tests/fdb/test_fdb_mac_expire.py @@ -222,7 +222,8 @@ def testFdbMacExpire(self, request, tbinfo, rand_selected_dut, ptfhost, refresh_ "fdb_info": self.FDB_INFO_FILE, "dummy_mac_prefix": self.DUMMY_MAC_PREFIX, "refresh_type": refresh_type, - "aging_time": fdbAgingTime + "aging_time": fdbAgingTime, + "kvm_support": True } self.__runPtfTest(ptfhost, "fdb_mac_expire_test.FdbMacExpireTest", testParams) diff --git a/tests/fdb/test_fdb_mac_learning.py b/tests/fdb/test_fdb_mac_learning.py index a8bf4243e8e..e8f192243b4 100644 --- a/tests/fdb/test_fdb_mac_learning.py +++ b/tests/fdb/test_fdb_mac_learning.py @@ -167,6 +167,7 @@ def dynamic_fdb_oper(self, duthost, tbinfo, ptfhost, dut_ptf_ports): "router_mac": duthost.facts["router_mac"], "dut_ptf_ports": dut_ptf_ports, "dummy_mac_prefix": self.DUMMY_MAC_PREFIX, + "kvm_support": True } self.__runPtfTest(ptfhost, "fdb_mac_learning_test.FdbMacLearningTest", testParams) diff --git a/tests/ipfwd/test_mtu.py b/tests/ipfwd/test_mtu.py index b80c2489379..b8351a3bd59 100644 --- a/tests/ipfwd/test_mtu.py +++ b/tests/ipfwd/test_mtu.py @@ -35,7 +35,8 @@ def test_mtu(tbinfo, ptfhost, mtu, gather_facts): "src_router_ipv6": gather_facts['src_router_ipv6'], "dst_host_ipv6": gather_facts['dst_host_ipv6'], "src_ptf_port_list": gather_facts['src_port_ids'], - "dst_ptf_port_list": gather_facts['dst_port_ids'] + "dst_ptf_port_list": gather_facts['dst_port_ids'], + "kvm_support": True }, log_file=log_file, socket_recv_size=16384, diff --git a/tests/pc/test_lag_2.py b/tests/pc/test_lag_2.py index cff700c924b..f50e1b1cd1a 100644 --- a/tests/pc/test_lag_2.py +++ b/tests/pc/test_lag_2.py @@ -100,7 +100,8 @@ def __verify_lag_lacp_timing(self, lacp_timer, exp_iface): 'timeout': 35, 'packet_timing': lacp_timer, 'ether_type': 0x8809, - 'interval_count': 3 + 'interval_count': 3, + 'kvm_support': True } ptf_runner(self.ptfhost, 'acstests', "lag_test.LacpTimingTest", '/root/ptftests', params=params, is_python3=True) diff --git a/tests/pc/test_lag_member.py b/tests/pc/test_lag_member.py index 7f53c358d9f..b39009adb2c 100644 --- a/tests/pc/test_lag_member.py +++ b/tests/pc/test_lag_member.py @@ -452,7 +452,8 @@ def run_lag_member_traffic_test(duthost, dut_vlan, ptf_ports, ptfhost): "dut_mac": duthost.facts["router_mac"], "dut_vlan": dut_vlan, "ptf_lag": ptf_lag, - ATTR_PORT_NOT_BEHIND_LAG: ptf_not_lag + ATTR_PORT_NOT_BEHIND_LAG: ptf_not_lag, + "kvm_support": True } ptf_runner(ptfhost, 'acstests', "lag_test.LagMemberTrafficTest", "/root/ptftests", params=params, is_python3=True) diff --git a/tests/ptf_runner.py b/tests/ptf_runner.py index 7fc6e5a2471..ab87aa8e4b3 100644 --- a/tests/ptf_runner.py +++ b/tests/ptf_runner.py @@ -105,7 +105,8 @@ def ptf_runner(host, testdir, testname, platform_dir=None, params={}, module_ignore_errors=False, is_python3=None, async_mode=False, pdb=False): dut_type = get_dut_type(host) - if dut_type == "kvm" and params.get("kvm_support", True) is False: + kvm_support = params.get("kvm_support", False) + if dut_type == "kvm" and kvm_support is False: logger.info("Skip test case {} for not support on KVM DUT".format(testname)) return True diff --git a/tests/radv/test_radv_ipv6_ra.py b/tests/radv/test_radv_ipv6_ra.py index 8f453bb68fe..aff361fa3aa 100644 --- a/tests/radv/test_radv_ipv6_ra.py +++ b/tests/radv/test_radv_ipv6_ra.py @@ -134,7 +134,8 @@ def test_radv_router_advertisement( "downlink_vlan_mac": vlan_intf['downlink_vlan_intf']['mac'], "downlink_vlan_ip6": vlan_intf['downlink_vlan_intf']['ip6'], "ptf_port_index": vlan_intf['ptf_port']['port_idx'], - "max_ra_interval": RADV_MAX_RA_INTERVAL_SECS}, + "max_ra_interval": RADV_MAX_RA_INTERVAL_SECS, + "kvm_support": True}, log_file="/tmp/radv_ipv6_ra_test.RadvUnSolicitedRATest.log", is_python3=True) @@ -161,7 +162,8 @@ def test_solicited_router_advertisement( "downlink_vlan_ip6": vlan_intf['downlink_vlan_intf']['ip6'], "ptf_port_index": vlan_intf['ptf_port']['port_idx'], "ptf_port_ip6": vlan_intf['ptf_port']['ip6'], - "max_ra_interval": RADV_MAX_RA_INTERVAL_SECS}, + "max_ra_interval": RADV_MAX_RA_INTERVAL_SECS, + "kvm_support": True}, log_file="/tmp/radv_ipv6_ra_test.RadvSolicitedRATest.log", is_python3=True) @@ -187,7 +189,8 @@ def test_unsolicited_router_advertisement_with_m_flag( "downlink_vlan_mac": vlan_intf['downlink_vlan_intf']['mac'], "downlink_vlan_ip6": vlan_intf['downlink_vlan_intf']['ip6'], "ptf_port_index": vlan_intf['ptf_port']['port_idx'], - "max_ra_interval": 180}, + "max_ra_interval": 180, + "kvm_support": True}, log_file="/tmp/router_adv_mflag_test.RadvUnSolicitedRATest.log", is_python3=True) @@ -214,5 +217,6 @@ def test_solicited_router_advertisement_with_m_flag( "downlink_vlan_ip6": vlan_intf['downlink_vlan_intf']['ip6'], "ptf_port_index": vlan_intf['ptf_port']['port_idx'], "ptf_port_ip6": vlan_intf['ptf_port']['ip6'], - "max_ra_interval": RADV_MAX_RA_INTERVAL_SECS}, + "max_ra_interval": RADV_MAX_RA_INTERVAL_SECS, + "kvm_support": True}, log_file="/tmp/router_adv_mflag_test.RadvSolicitedRATest.log", is_python3=True) From 3597c7cdd8044c097f113ca744a85fc6e336ac45 Mon Sep 17 00:00:00 2001 From: Rajendra Kumar Thirumurthi Date: Thu, 7 Nov 2024 01:12:05 -0800 Subject: [PATCH 091/221] ACL testcase fix for Cisco 8122 Platform (#15404) * ACL testcase fix for Cisco 8122 Platform * ACL testcase fix for Cisco 8122 Platform --- tests/acl/test_acl.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/acl/test_acl.py b/tests/acl/test_acl.py index 1831e1343f0..2908cfc2038 100644 --- a/tests/acl/test_acl.py +++ b/tests/acl/test_acl.py @@ -806,10 +806,8 @@ def counters_sanity_check(self, duthosts, acl_rules, acl_table): continue counters_after[PACKETS_COUNT] += acl_facts[duthost]['after'][rule][PACKETS_COUNT] counters_after[BYTES_COUNT] += acl_facts[duthost]['after'][rule][BYTES_COUNT] - if (duthost.facts["hwsku"] == "Cisco-8111-O64" or - duthost.facts["hwsku"] == "Cisco-8111-O32" or - duthost.facts["hwsku"] == "Cisco-8111-C32" or - duthost.facts["hwsku"] == "Cisco-8111-O62C2"): + if duthost.facts["platform"] in ["x86_64-8111_32eh_o-r0", + "x86_64-8122_64eh_o-r0", "x86_64-8122_64ehf_o-r0"]: skip_byte_accounting = True logger.info("Counters for ACL rule \"{}\" after traffic:\n{}" From 730b79b9b0adcb197eef471f30157e6a9704baff Mon Sep 17 00:00:00 2001 From: rbpittman Date: Thu, 7 Nov 2024 04:17:01 -0500 Subject: [PATCH 092/221] Revise after XON counter change. (#15400) --- tests/saitests/py3/sai_qos_tests.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index eb3373596b4..2d649a4221e 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -3504,16 +3504,7 @@ def get_pfc_tx_cnt(src_port_id, pg_cntr_idx): pfc_tx_cnt_base = get_pfc_tx_cnt(src_port_id, pg_cntr_idx) time.sleep(2) xoff_txd = get_pfc_tx_cnt(src_port_id, pg_cntr_idx) - pfc_tx_cnt_base - print("Verifying XOFF TX, count {}".format(xoff_txd), file=sys.stderr) - assert xoff_txd != 0, "Expected XOFF" - - # TODO: Revisit when TX counter in this case is correctly handled - send_packet(self, src_port_id, pkt, 1) - time.sleep(2) - pfc_tx_cnt_base = get_pfc_tx_cnt(src_port_id, pg_cntr_idx) - time.sleep(2) - xoff_txd = get_pfc_tx_cnt(src_port_id, pg_cntr_idx) - pfc_tx_cnt_base - print("Verifying XOFF TX stopped, count {}".format(xoff_txd), file=sys.stderr) + print("Verifying no XOFF TX, count {}".format(xoff_txd), file=sys.stderr) assert xoff_txd == 0, "Unexpected XOFF" finally: From fe375aa2aff288d7b3c579c6215aca4793ee2922 Mon Sep 17 00:00:00 2001 From: wenyiz2021 <91497961+wenyiz2021@users.noreply.github.com> Date: Thu, 7 Nov 2024 02:51:04 -0800 Subject: [PATCH 093/221] Update test_chassis_reboot.py (#15422) Description of PR Summary: Fixes # (issue) Fix the issue when running dut.command("reboot"), when some T2 platform running the command itself can exceed ansible timeout we defined in ansible.cfg that is 60sec. In this case, test will error out saying "Host unreachable", but it's actually due to ansible command timeout. Approach What is the motivation for this PR? Avoid testcase failure that is command runtime dependent How did you do it? Thread the reboot command, so even it timeout in a single thread, main thread is fine How did you verify/test it? Before: 03/11/2024 12:04:25 test_chassis_reboot.chassis_cold_reboot L0027 INFO | Run cold reboot on 03/11/2024 12:04:25 base._run L0071 DEBUG | /var/src/sonic-mgmt_8800-1_66b4a53de4614bccc2e74f8c/tests/common/devices/multi_asic.py::_run_on_asics#135: [8800-lc4] AnsibleModule::command, args=["reboot"], kwargs={} 03/11/2024 12:05:24 transport._log L1873 DEBUG | EOF in transport thread 03/11/2024 12:05:24 __init__.pytest_runtest_call L0040 ERROR | Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/_pytest/python.py", line 1788, in runtest self.ihook.pytest_pyfunc_call(pyfuncitem=self) File "/usr/local/lib/python3.8/dist-packages/pluggy/_hooks.py", line 513, in __call__ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) File "/usr/local/lib/python3.8/dist-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) File "/usr/local/lib/python3.8/dist-packages/pluggy/_callers.py", line 139, in _multicall raise exception.with_traceback(exception.__traceback__) File "/usr/local/lib/python3.8/dist-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(*args) File "/usr/local/lib/python3.8/dist-packages/_pytest/python.py", line 194, in pytest_pyfunc_call result = testfunction(**testargs) File "/var/src/sonic-mgmt_t2-8800-1_66b4a53de4614bccc2e74f8c/tests/platform_tests/test_chassis_reboot.py", line 70, in test_parallel_reboot chassis_cold_reboot(dut, localhost) File "/var/src/sonic-mgmt_t2-8800-1_66b4a53de4614bccc2e74f8c/tests/platform_tests/test_chassis_reboot.py", line 28, in chassis_cold_reboot dut.command("reboot") File "/var/src/sonic-mgmt-t2-8800-1_66b4a53de4614bccc2e74f8c/tests/common/devices/multi_asic.py", line 135, in _run_on_asics return getattr(self.sonichost, self.multi_asic_attr)(*module_args, **complex_args) File "/var/src/sonic-mgmt-t2-8800-1_66b4a53de4614bccc2e74f8c/tests/common/devices/base.py", line 105, in _run res = self.module(*module_args, **complex_args)[self.hostname] File "/usr/local/lib/python3.8/dist-packages/pytest_ansible/module_dispatcher/v213.py", line 232, in _run raise AnsibleConnectionFailure( pytest_ansible.errors.AnsibleConnectionFailure: Host unreachable in the inventory After: ----------------------------------------------------------------------------------------- live log sessionfinish -----------------------------------------------------------------------------------------05:47:44 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs =============================================================================== 1 passed, 1 warning in 2017.89s (0:33:37) ================================================================================DEBUG:tests.conftest:[log_custom_msg] item: DEBUG:tests.conftest:append custom_msg: {'dut_check_result': {'core_dump_check_pass': True, 'config_db_check_pass': False}} Any platform specific information? The issue is seen on Cisco T2 that takes more time to reboot. But is a general enhancement. co-authorized by: jianquanye@microsoft.com --- tests/platform_tests/test_chassis_reboot.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/platform_tests/test_chassis_reboot.py b/tests/platform_tests/test_chassis_reboot.py index 30d2bc5d255..9d872818529 100644 --- a/tests/platform_tests/test_chassis_reboot.py +++ b/tests/platform_tests/test_chassis_reboot.py @@ -5,6 +5,7 @@ import random import logging import time +import concurrent.futures from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until from tests.common.reboot import wait_for_startup,\ @@ -59,15 +60,16 @@ def test_parallel_reboot(duthosts, localhost, conn_graph_facts, xcvr_skip_list): core_dumps = {} # Perform reboot on multiple LCs within 30sec - for dut in duthosts: - if dut.is_supervisor_node(): - continue + executor = concurrent.futures.ThreadPoolExecutor(max_workers=8) + for dut in duthosts.frontend_nodes: # collect core dump before reboot core_dumps[dut.hostname] = get_core_dump(dut) # Perform cold reboot on all linecards, with an internal within 30sec to mimic a parallel reboot scenario - chassis_cold_reboot(dut, localhost) + # Change this to threaded reboot, to avoid ansible command timeout in 60sec, we have seen some T2 platform + # reboot exceed 60 sec, and causes test to error out + executor.submit(chassis_cold_reboot, dut, localhost) # Wait for 0 ~ 30sec rand_interval = random.randint(0, 30) @@ -88,9 +90,7 @@ def test_parallel_reboot(duthosts, localhost, conn_graph_facts, xcvr_skip_list): "Not all BGP sessions are established on DUT") # Check if new core dumps are generated - for dut in duthosts: - if dut.is_supervisor_node(): - continue + for dut in duthosts.frontend_nodes: post_core_dump = get_core_dump(dut) new_core_dumps = (set(post_core_dump) - set(core_dumps[dut.hostname])) From 829ca01441bcc3c44f4baf3dc3c8e48cc5d9a474 Mon Sep 17 00:00:00 2001 From: Perumal Venkatesh Date: Thu, 7 Nov 2024 03:37:39 -0800 Subject: [PATCH 094/221] Adding log analyzer ignore messages (#15420) Description of PR Adding log analyzer ignore messages based on Cisco Chassis. These messages are harmless messages. Adding it to loganalyzer ignore file WARNING kernel: [55926.179286] pcieport 0000:0a:00.0: device [10b5:8713] error status/mask=00002001/0000e000 ERR kernel: [39978.088854] cisco-fpga-p2pm-m-slot p2pm-m-slot.2: cisco_fpga_select_new_acpi_companion: searching for child status0 0x2420017a; fpga_id 0x42 ERR kernel: [ 8.160032] cisco-fpga-pci 0000:5f:00.0: cisco_fpga_select_new_acpi_companion: searching for child status0 0x26100179; fpga_id 0x61 create a loganalyzer ignore Approach What is the motivation for this PR? To ignore harmless log messages that can cause testcase errors. How did you do it? Adding the messages as part of log analyzer ignore file co-authorized by: jianquanye@microsoft.com --- .../files/tools/loganalyzer/loganalyzer_common_ignore.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ansible/roles/test/files/tools/loganalyzer/loganalyzer_common_ignore.txt b/ansible/roles/test/files/tools/loganalyzer/loganalyzer_common_ignore.txt index b30a4de578e..1dfafae8765 100644 --- a/ansible/roles/test/files/tools/loganalyzer/loganalyzer_common_ignore.txt +++ b/ansible/roles/test/files/tools/loganalyzer/loganalyzer_common_ignore.txt @@ -285,6 +285,10 @@ r, ".* INFO .*[duty_cycle_map]: illegal pwm value .*" r, ".* INFO .*command '/usr/sbin/smartctl' failed: [116] Stale file handle.*" r, ".* INFO healthd.*Key 'TEMPERATURE_INFO|ASIC' field 'high_threshold' unavailable in database 'STATE_DB'.*" r, ".* INFO healthd.*Key 'TEMPERATURE_INFO|ASIC' field 'temperature' unavailable in database 'STATE_DB'.*" +r, ".* ERR kernel:.*cisco-fpga-p2pm-m-slot p2pm-m-slot\.\d+: cisco_fpga_select_new_acpi_companion: searching for child status\d+ 0x[0-9a-f]+; fpga_id 0x[0-9a-f]+.*" +r, ".* ERR kernel:.*cisco-fpga-pci \d+:\d+:\d+\.\d+: cisco_fpga_select_new_acpi_companion: searching for child status\d+ 0x[0-9a-f]+; fpga_id 0x[0-9a-f]+.*" +r, ".* WARNING kernel:.*pcieport.*device.*error.*status/mask=.*" + # Ignore rsyslog librelp error if rsyslogd on host or container is down or going down r, ".* ERR .*#rsyslogd: librelp error 10008 forwarding to server .* - suspending.*" From e64bb719d18c02dd9b6d8722a46e651e1659ba26 Mon Sep 17 00:00:00 2001 From: Yatish Date: Thu, 7 Nov 2024 10:56:07 -0800 Subject: [PATCH 095/221] =?UTF-8?q?[Chassis]=20Added=20new=20testcase=20fo?= =?UTF-8?q?r=20checking=20console=20connections=20from=20supervisor=20t?= =?UTF-8?q?=E2=80=A6=20(#15198)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Approach What is the motivation for this PR? Testgap - #5084 How did you do it? How did you verify/test it? By running on Cisco and Arista T2 chassis Any platform specific information? Arista and Cisco --- tests/common/helpers/console_helper.py | 38 +++++++++ .../dut_console/test_console_chassis_conn.py | 82 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 tests/dut_console/test_console_chassis_conn.py diff --git a/tests/common/helpers/console_helper.py b/tests/common/helpers/console_helper.py index 58bf82326aa..37f4f95997e 100644 --- a/tests/common/helpers/console_helper.py +++ b/tests/common/helpers/console_helper.py @@ -1,5 +1,6 @@ import pytest import pexpect +import re def assert_expect_text(client, text, target_line, timeout_sec=0.1): @@ -22,3 +23,40 @@ def create_ssh_client(ip, user, pwd): def ensure_console_session_up(client, line): client.expect_exact('Successful connection to line [{}]'.format(line)) client.expect_exact('Press ^A ^X to disconnect') + + +def get_target_lines(duthost): + """ + retrieve the indices of online line cards. + Returns a list of indices of the line cards that are online. + """ + result = duthost.shell("show chassis module status", module_ignore_errors=True) + lines = result['stdout'].splitlines() + linecards = [] + + # Pattern to match lines that have a "LINE-CARD" entry and "Online" in the Oper-Status column + linecard_pattern = re.compile(r"^\s*(LINE-CARD\d+)\s+.*?\s+\d+\s+Online\s+up\s+\S+") + + for line in lines: + match = linecard_pattern.match(line) + if match: + linecard_name = match.group(1) + index = linecard_name.split("LINE-CARD")[1] + linecards.append(index) + + if not linecards: + pytest.fail("No line cards are online.") + + return linecards + + +def handle_pexpect_exceptions(target_line): + """Handle pexpect exceptions during console interactions.""" + try: + yield + except pexpect.exceptions.EOF: + pytest.fail(f"EOF reached during console interaction for line {target_line}.") + except pexpect.exceptions.TIMEOUT: + pytest.fail(f"Timeout reached during console interaction for line {target_line}.") + except Exception as e: + pytest.fail(f"Error occured during console interaction for line {target_line}: {e}") diff --git a/tests/dut_console/test_console_chassis_conn.py b/tests/dut_console/test_console_chassis_conn.py new file mode 100644 index 00000000000..49e05babb41 --- /dev/null +++ b/tests/dut_console/test_console_chassis_conn.py @@ -0,0 +1,82 @@ +import pexpect +import pytest +import time + +from tests.common.helpers.assertions import pytest_assert +from tests.common.helpers.console_helper import get_target_lines, handle_pexpect_exceptions + +pytestmark = [ + pytest.mark.topology("t2") # Test is only for T2 Chassis +] + + +def test_console_availability_serial_ports(duthost, duthosts, creds, enum_supervisor_dut_hostname): + + duthost = duthosts[enum_supervisor_dut_hostname] + dutip = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] + dutuser, dutpass = creds['sonicadmin_user'], creds['sonicadmin_password'] + + target_lines = get_target_lines(duthost) # List of Serial port numbers connected from supervisor to linecards + + for target_line in target_lines: + if 'arista' in duthost.facts['hwsku'].lower(): + console_command = f"sudo /usr/bin/picocom /dev/ttySCD{target_line}" + try: + client = pexpect.spawn('ssh {}@{} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + .format(dutuser, dutip)) + client.expect('[Pp]assword:') + client.sendline(dutpass) + client.sendline(console_command) + time.sleep(5) + client.sendline('\n') + client.expect(['login:'], timeout=20) + client.sendline(dutuser) + client.expect(['[Pp]assword:'], timeout=10) + client.sendline(dutpass) + + i = client.expect([r'.*Software\s+for\s+Open\s+Networking\s+in\s+the\s+Cloud.*', + 'Login incorrect'], timeout=100) + pytest_assert(i == 0, + f"Failed to connect to line card {target_line} " + "on Arista device. Please check credentials.") + + client.sendline('exit') + time.sleep(2) + client.sendcontrol('a') + time.sleep(2) + client.sendcontrol('x') + except Exception as e: + handle_pexpect_exceptions(target_line)(e) + + elif 'cisco' in duthost.facts['hwsku'].lower(): + console_command = f"sudo /opt/cisco/bin/rconsole.py -s {target_line}" + try: + client = pexpect.spawn('ssh {}@{} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + .format(dutuser, dutip)) + client.expect('[Pp]assword:') + client.sendline(dutpass) + time.sleep(10) + client.sendline(console_command) + time.sleep(10) + client.sendline(dutuser) + client.expect(['[Pp]assword:'], timeout=10) + time.sleep(10) + client.sendline(dutpass) + time.sleep(10) + + i = client.expect([r'.*Software\s+for\s+Open\s+Networking\s+in\s+the\s+Cloud.*', + 'Login incorrect'], timeout=100) + pytest_assert(i == 0, + f"Failed to connect to line card {target_line} on Cisco device.Please check credentials.") + + client.sendline('exit') + time.sleep(2) + client.sendcontrol('\\') + time.sleep(2) + client.sendline('quit') + + except Exception as e: + handle_pexpect_exceptions(target_line)(e) + + else: + pytest.skip("Skipping test because test is not supported on this hwsku.") From d5dfb8a7d1ae3decaf3da0a30c0cd6d76e9027c7 Mon Sep 17 00:00:00 2001 From: ansrajpu-git <113939367+ansrajpu-git@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:07:08 -0500 Subject: [PATCH 096/221] [Chassis][Voq][Qos]qos_yaml updated for 400G (#14802) Fixing intermittent failure in lossy queue by adjusting the pkts_num_trig_egr_drp for 'broadcom-dnx' t2 chassis. Updation on the original PR # #14585 Summary: Fixes # (issue) Type of change Bug fix Testbed and Framework(new/improvement) Test case(new/improvement) Back port request 202012 202205 202305 202311 202405 Approach What is the motivation for this PR? How did you do it? Since the pkts_num_leakout is more for 100G.Adjusting the count of pkt sent to trigger egress drop. How did you verify/test it? Executed the qos test and verify. --- tests/qos/files/qos_params.j2c.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/qos/files/qos_params.j2c.yaml b/tests/qos/files/qos_params.j2c.yaml index aa88cee420c..9b569efaca0 100644 --- a/tests/qos/files/qos_params.j2c.yaml +++ b/tests/qos/files/qos_params.j2c.yaml @@ -481,7 +481,7 @@ qos_params: dscp: 8 ecn: 1 pg: 0 - pkts_num_trig_egr_drp: 2179900 + pkts_num_trig_egr_drp: 2179770 pkts_num_margin: 100 wm_pg_shared_lossless: dscp: 3 @@ -497,7 +497,7 @@ qos_params: ecn: 1 pg: 0 pkts_num_fill_min: 0 - pkts_num_trig_egr_drp: 2179900 + pkts_num_trig_egr_drp: 2179770 packet_size: 64 cell_size: 4096 pkts_num_margin: 40 @@ -523,7 +523,7 @@ qos_params: ecn: 1 queue: 0 pkts_num_fill_min: 0 - pkts_num_trig_egr_drp: 2179900 + pkts_num_trig_egr_drp: 2179770 cell_size: 4096 wm_buf_pool_lossy: dscp: 8 From db8b51765bb33363d455e9cd0aa4835871112de4 Mon Sep 17 00:00:00 2001 From: smagarwal-arista <160662020+smagarwal-arista@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:18:04 -0500 Subject: [PATCH 097/221] Retry test_psu.py::TestPsuApi::test_power if power not within tolerance (#14788) * Retry test_power calculated power above 10% If the test fails on `abs(power - (voltage*current)) < power*0.1` then retry the test. Test is repeated for a maximum of three times until it passes, else it is failed. This change is introduced to account for the stringent tolerance level of 10% and the errors that might be caused due to time differences reading each of the parameters. * Retry test_power.py::TestPsuApi::test_power if power above tolerance If the test fails on `abs(power - (voltage*current)) < power*0.1` then retry the test. The test is repeated for a maximum of three times until it passes. This change is introduced to account for the stringent tolerance level of 10% and the errors that might be caused due to time differences in reading each of the parameters. * Add check to detect occurrence of a failure before power calculation * Resolve pre-commit check issue * Refactor test_power function to improve readability * Use wait_until function for retry --- .../api/platform_api_test_base.py | 3 + tests/platform_tests/api/test_psu.py | 99 ++++++++++--------- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/tests/platform_tests/api/platform_api_test_base.py b/tests/platform_tests/api/platform_api_test_base.py index 0550242eaa6..cb183d1adc6 100644 --- a/tests/platform_tests/api/platform_api_test_base.py +++ b/tests/platform_tests/api/platform_api_test_base.py @@ -30,3 +30,6 @@ def assert_expectations(self): # TODO: When we move to Python 3.3+, we can use self.failed_expectations.clear() instead del self.failed_expectations[:] pytest_assert(False, err_msg) + + def get_len_failed_expectations(self): + return len(self.failed_expectations) diff --git a/tests/platform_tests/api/test_psu.py b/tests/platform_tests/api/test_psu.py index 877187b40d5..b9ad83b1ea2 100644 --- a/tests/platform_tests/api/test_psu.py +++ b/tests/platform_tests/api/test_psu.py @@ -6,7 +6,7 @@ from tests.common.utilities import skip_release from tests.platform_tests.cli.util import get_skip_mod_list from .platform_api_test_base import PlatformApiTestBase -from tests.common.utilities import skip_release_for_platform +from tests.common.utilities import skip_release_for_platform, wait_until ################################################### @@ -89,6 +89,16 @@ def skip_absent_psu(self, psu_num, platform_api_conn): return True return False + def get_psu_parameter(self, psu_info, psu_parameter, get_data, message): + data = None + is_supported = self.get_psu_facts(psu_info["duthost"], psu_info["psu_id"], True, psu_parameter) + if is_supported: + data = get_data(psu_info["api"], psu_info["psu_id"]) + if self.expect(data is not None, "Failed to retrieve {} of PSU {}".format(message, psu_info["psu_id"])): + self.expect(isinstance(data, float), "PSU {} {} appears incorrect".format(psu_info["psu_id"], message)) + + return data + # # Functions to test methods inherited from DeviceBase class # @@ -204,68 +214,61 @@ def test_power(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, plat ''' PSU power test ''' duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["arista"]) + voltage = current = power = None + psu_info = { + "duthost": duthost, + "api": platform_api_conn, + "psu_id": None + } + + def check_psu_power(failure_count): + nonlocal voltage + nonlocal current + nonlocal power + voltage = self.get_psu_parameter(psu_info, "voltage", psu.get_voltage, "voltage") + current = self.get_psu_parameter(psu_info, "current", psu.get_current, "current") + power = self.get_psu_parameter(psu_info, "power", psu.get_power, "power") + + failure_occured = self.get_len_failed_expectations() > failure_count + if current and voltage and power: + is_within_tolerance = abs(power - (voltage*current)) < power*0.1 + if not failure_occured and not is_within_tolerance: + return False + + self.expect(is_within_tolerance, "PSU {} reading does not make sense \ + (power:{}, voltage:{}, current:{})".format(psu_id, power, voltage, current)) + + return True for psu_id in range(self.num_psus): + failure_count = self.get_len_failed_expectations() + psu_info['psu_id'] = psu_id name = psu.get_name(platform_api_conn, psu_id) if name in self.psu_skip_list: logger.info("skipping check for {}".format(name)) else: - voltage = None - voltage_supported = self.get_psu_facts(duthost, psu_id, True, "voltage") - if voltage_supported: - voltage = psu.get_voltage(platform_api_conn, psu_id) - if self.expect(voltage is not None, "Failed to retrieve voltage of PSU {}".format(psu_id)): - self.expect(isinstance(voltage, float), "PSU {} voltage appears incorrect".format(psu_id)) - current = None - current_supported = self.get_psu_facts(duthost, psu_id, True, "current") - if current_supported: - current = psu.get_current(platform_api_conn, psu_id) - if self.expect(current is not None, "Failed to retrieve current of PSU {}".format(psu_id)): - self.expect(isinstance(current, float), "PSU {} current appears incorrect".format(psu_id)) - power = None - power_supported = self.get_psu_facts(duthost, psu_id, True, "power") - if power_supported: - power = psu.get_power(platform_api_conn, psu_id) - if self.expect(power is not None, "Failed to retrieve power of PSU {}".format(psu_id)): - self.expect(isinstance(power, float), "PSU {} power appears incorrect".format(psu_id)) - max_supp_power = None - max_power_supported = self.get_psu_facts(duthost, psu_id, True, "max_power") - if max_power_supported: - max_supp_power = psu.get_maximum_supplied_power(platform_api_conn, psu_id) - if self.expect(max_supp_power is not None, - "Failed to retrieve maximum supplied power power of PSU {}".format(psu_id)): - self.expect(isinstance(max_supp_power, float), - "PSU {} maximum supplied power appears incorrect".format(psu_id)) - - if current is not None and voltage is not None and power is not None: - self.expect(abs(power - (voltage*current)) < power*0.1, "PSU {} reading does not make sense \ - (power:{}, voltage:{}, current:{})".format(psu_id, power, voltage, current)) + check_result = wait_until(30, 10, 0, check_psu_power, failure_count) + self.expect(check_result, "PSU {} reading does not make sense \ + (power:{}, voltage:{}, current:{})".format(psu_id, power, voltage, current)) + + self.get_psu_parameter(psu_info, "max_power", psu.get_maximum_supplied_power, + "maximum supplied power") powergood_status = psu.get_powergood_status(platform_api_conn, psu_id) if self.expect(powergood_status is not None, "Failed to retrieve operational status of PSU {}".format(psu_id)): self.expect(powergood_status is True, "PSU {} is not operational".format(psu_id)) - high_threshold = None - voltage_high_threshold_supported = self.get_psu_facts(duthost, psu_id, True, "voltage_high_threshold") - if voltage_high_threshold_supported: - high_threshold = psu.get_voltage_high_threshold(platform_api_conn, psu_id) - if self.expect(high_threshold is not None, - "Failed to retrieve the high voltage threshold of PSU {}".format(psu_id)): - self.expect(isinstance(high_threshold, float), - "PSU {} voltage high threshold appears incorrect".format(psu_id)) - low_threshold = None - voltage_low_threshold_supported = self.get_psu_facts(duthost, psu_id, True, "voltage_low_threshold") - if voltage_low_threshold_supported: - low_threshold = psu.get_voltage_low_threshold(platform_api_conn, psu_id) - if self.expect(low_threshold is not None, - "Failed to retrieve the low voltage threshold of PSU {}".format(psu_id)): - self.expect(isinstance(low_threshold, float), - "PSU {} voltage low threshold appears incorrect".format(psu_id)) - if high_threshold is not None and low_threshold is not None: + high_threshold = self.get_psu_parameter(psu_info, "voltage_high_threshold", + psu.get_voltage_high_threshold, "high voltage threshold") + low_threshold = self.get_psu_parameter(psu_info, "voltage_low_threshold", + psu.get_voltage_low_threshold, "low voltage threshold") + + if high_threshold and low_threshold: self.expect(voltage < high_threshold and voltage > low_threshold, "Voltage {} of PSU {} is not in between {} and {}" .format(voltage, psu_id, low_threshold, high_threshold)) + self.assert_expectations() def test_temperature(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): From 6a3d8e57eaf3bd6d5a08d016fb1c52b5c0e8a9ed Mon Sep 17 00:00:00 2001 From: wumiao_nokia Date: Thu, 7 Nov 2024 18:12:45 -0500 Subject: [PATCH 098/221] Multi-asic Support for Telemetry Test (#14982) Description of PR Add multi-asic support for telemetry test. This does not include multi-asic support for events (bgp, swss etc) as there are issues with multi-asic support on server side. A different PR #13826 will handle telemetry event multi-asic support on mgmt. Approach What is the motivation for this PR? Multi-asic support for telemetry test How did you do it? How did you verify/test it? Whole telemetry OC testd pass with the changes (exclude events test). co-authorized by: jianquanye@microsoft.com --- .azure-pipelines/pr_test_scripts.yaml | 2 ++ tests/common/devices/multi_asic.py | 16 +++++++--- tests/common/devices/sonic.py | 11 +++++-- .../tests_mark_conditions.yaml | 3 +- tests/telemetry/telemetry_utils.py | 10 +++++-- tests/telemetry/test_telemetry.py | 29 +++++++++++++------ 6 files changed, 51 insertions(+), 20 deletions(-) diff --git a/.azure-pipelines/pr_test_scripts.yaml b/.azure-pipelines/pr_test_scripts.yaml index 3d48dfbef25..af74bf44aa0 100644 --- a/.azure-pipelines/pr_test_scripts.yaml +++ b/.azure-pipelines/pr_test_scripts.yaml @@ -447,6 +447,8 @@ multi-asic-t1-lag: - process_monitoring/test_critical_process_monitoring.py - container_checker/test_container_checker.py - http/test_http_copy.py + - telemetry/test_telemetry_cert_rotation.py + - telemetry/test_telemetry.py dpu: - dash/test_dash_vnet.py diff --git a/tests/common/devices/multi_asic.py b/tests/common/devices/multi_asic.py index df1eaf1b7b7..6f541c201af 100644 --- a/tests/common/devices/multi_asic.py +++ b/tests/common/devices/multi_asic.py @@ -286,6 +286,12 @@ def get_linux_ip_cmd_for_namespace(self, cmd, namespace): ns_cmd = cmd.replace('ip', 'ip -n {}'.format(namespace)) return ns_cmd + def get_cli_cmd_for_namespace(self, cmd, namespace): + if not namespace: + return cmd + ns_cmd = cmd.replace('sonic-db-cli', 'sonic-db-cli -n {}'.format(namespace)) + return ns_cmd + @property def ttl_decr_value(self): """ @@ -520,9 +526,10 @@ def modify_syslog_rate_limit(self, feature, rl_option='disable'): cmds.append(cmd_reload.format(docker)) self.sonichost.shell_cmds(cmds=cmds) - def get_bgp_neighbors(self): + def get_bgp_neighbors(self, namespace=None): """ - Get a diction of BGP neighbor states + Get a diction of BGP neighbor states. If namespace is not None + will get a dictionary of BGP neighbor states for that namespace Args: None @@ -531,8 +538,9 @@ def get_bgp_neighbors(self): """ bgp_neigh = {} for asic in self.asics: - bgp_info = asic.bgp_facts() - bgp_neigh.update(bgp_info["ansible_facts"]["bgp_neighbors"]) + if namespace is None or asic.namespace == namespace: + bgp_info = asic.bgp_facts() + bgp_neigh.update(bgp_info["ansible_facts"]["bgp_neighbors"]) return bgp_neigh diff --git a/tests/common/devices/sonic.py b/tests/common/devices/sonic.py index 892535c94fb..83a6d52ed31 100644 --- a/tests/common/devices/sonic.py +++ b/tests/common/devices/sonic.py @@ -1378,17 +1378,22 @@ def get_intf_link_local_ipv6_addr(self, intf): addr = self.shell(cmd)["stdout"] return addr - def get_bgp_neighbor_info(self, neighbor_ip): + def get_bgp_neighbor_info(self, neighbor_ip, asic_id=None): """ @summary: return bgp neighbor info @param neighbor_ip: bgp neighbor IP """ nbip = ipaddress.ip_address(neighbor_ip) + vtysh = "vtysh" + if asic_id is not None: + vtysh = "vtysh -n {}".format(asic_id) + if nbip.version == 4: - out = self.command("vtysh -c \"show ip bgp neighbor {} json\"".format(neighbor_ip)) + out = self.command("{} -c \"show ip bgp neighbor {} json\"".format(vtysh, neighbor_ip)) else: - out = self.command("vtysh -c \"show bgp ipv6 neighbor {} json\"".format(neighbor_ip)) + out = self.command("{} -c \"show bgp ipv6 neighbor {} json\"".format(vtysh, neighbor_ip)) + nbinfo = json.loads(re.sub(r"\\\"", '"', re.sub(r"\\n", "", out['stdout']))) logging.info("bgp neighbor {} info {}".format(neighbor_ip, nbinfo)) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index d3ab72aad49..d91c871a263 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1890,10 +1890,11 @@ telemetry/test_telemetry.py: telemetry/test_telemetry.py::test_telemetry_queue_buffer_cnt: skip: conditions_logical_operator: or - reason: "Testcase ignored due to switch type is voq / Unsupported in MGFX topos" + reason: "Testcase ignored due to switch type is voq / Unsupported in MGFX topos / multi-asic issue 15393" conditions: - "(switch_type=='voq')" - "topo_type in ['m0', 'mx']" + - "(is_multi_asic==True) and https://github.com/sonic-net/sonic-mgmt/issues/15393" ####################################### ##### pktgen ##### diff --git a/tests/telemetry/telemetry_utils.py b/tests/telemetry/telemetry_utils.py index ef4cac780e6..1b6de9e9ed5 100644 --- a/tests/telemetry/telemetry_utils.py +++ b/tests/telemetry/telemetry_utils.py @@ -106,7 +106,7 @@ def trigger_logger(duthost, log, process, container="", priority="local0.notice" def generate_client_cli(duthost, gnxi_path, method=METHOD_GET, xpath="COUNTERS/Ethernet0", target="COUNTERS_DB", subscribe_mode=SUBSCRIBE_MODE_STREAM, submode=SUBMODE_SAMPLE, - intervalms=0, update_count=3, create_connections=1, filter_event_regex="", + intervalms=0, update_count=3, create_connections=1, filter_event_regex="", namespace=None, timeout=-1): """ Generate the py_gnmicli command line based on the given params. t --target: gNMI target; required @@ -121,11 +121,15 @@ def generate_client_cli(duthost, gnxi_path, method=METHOD_GET, xpath="COUNTERS/E update_count: Max number of streaming updates to receive. 0 means no limit. default 0 create_connections: Creates TCP connections with gNMI server; default 1; -1 for infinite connections filter_event_regex: Regex to filter event when querying events path + namespace: namespace for multi-asic timeout: Subscription duration in seconds; After X seconds, request terminates; default none """ env = GNMIEnvironment(duthost, GNMIEnvironment.TELEMETRY_MODE) - cmdFormat = 'python ' + gnxi_path + 'gnmi_cli_py/py_gnmicli.py -g -t {0} -p {1} -m {2} -x {3} -xt {4} -o {5}' - cmd = cmdFormat.format(duthost.mgmt_ip, env.gnmi_port, method, xpath, target, "ndastreamingservertest") + ns = "" + if namespace is not None: + ns = "/{}".format(namespace) + cmdFormat = 'python ' + gnxi_path + 'gnmi_cli_py/py_gnmicli.py -g -t {0} -p {1} -m {2} -x {3} -xt {4}{5} -o {6}' + cmd = cmdFormat.format(duthost.mgmt_ip, env.gnmi_port, method, xpath, target, ns, "ndastreamingservertest") if method == METHOD_SUBSCRIBE: cmd += " --subscribe_mode {0} --submode {1} --interval {2} --update_count {3} --create_connections {4}".format( diff --git a/tests/telemetry/test_telemetry.py b/tests/telemetry/test_telemetry.py index 3014c3aea98..c975f532fd4 100644 --- a/tests/telemetry/test_telemetry.py +++ b/tests/telemetry/test_telemetry.py @@ -281,24 +281,33 @@ def test_on_change_updates(duthosts, enum_rand_one_per_hwsku_hostname, ptfhost, logger.info("Testing on change update notifications") duthost = duthosts[enum_rand_one_per_hwsku_hostname] + if duthost.is_supervisor_node(): + pytest.skip( + "Skipping test as no Ethernet0 frontpanel port on supervisor") skip_201911_and_older(duthost) - cmd = generate_client_cli(duthost=duthost, gnxi_path=gnxi_path, method=METHOD_SUBSCRIBE, - submode=SUBMODE_ONCHANGE, update_count=2, xpath="NEIGH_STATE_TABLE", - target="STATE_DB") - bgp_nbrs = list(duthost.get_bgp_neighbors().keys()) + nslist = duthost.get_asic_namespace_list() + ns = random.choice(nslist) + bgp_nbrs = list(duthost.get_bgp_neighbors(ns).keys()) bgp_neighbor = random.choice(bgp_nbrs) - bgp_info = duthost.get_bgp_neighbor_info(bgp_neighbor) + asic_id = duthost.get_asic_id_from_namespace(ns) + bgp_info = duthost.get_bgp_neighbor_info(bgp_neighbor, asic_id) original_state = bgp_info["bgpState"] new_state = "Established" if original_state.lower() == "active" else "Active" + cmd = generate_client_cli(duthost=duthost, gnxi_path=gnxi_path, method=METHOD_SUBSCRIBE, + submode=SUBMODE_ONCHANGE, update_count=2, xpath="NEIGH_STATE_TABLE", + target="STATE_DB", namespace=ns) + def callback(result): logger.info("Assert that ptf client output is non empty and contains on change update") try: assert result != "", "Did not get output from PTF client" finally: - duthost.shell("sonic-db-cli STATE_DB HSET \"NEIGH_STATE_TABLE|{}\" \"state\" {}".format(bgp_neighbor, - original_state)) + ccmd = "sonic-db-cli STATE_DB HSET \"NEIGH_STATE_TABLE|{}\" \"state\" {}".format(bgp_neighbor, + original_state) + ccmd = duthost.get_cli_cmd_for_namespace(ccmd, ns) + duthost.shell(ccmd) ret = parse_gnmi_output(result, 1, bgp_neighbor) assert ret is True, "Did not find key in update" @@ -306,8 +315,10 @@ def callback(result): client_thread.start() wait_until(5, 1, 0, check_gnmi_cli_running, ptfhost) - duthost.shell("sonic-db-cli STATE_DB HSET \"NEIGH_STATE_TABLE|{}\" \"state\" {}".format(bgp_neighbor, - new_state)) + cmd = "sonic-db-cli STATE_DB HSET \"NEIGH_STATE_TABLE|{}\" \"state\" {}".format(bgp_neighbor, + new_state) + cmd = duthost.get_cli_cmd_for_namespace(cmd, ns) + duthost.shell(cmd) client_thread.join(60) # max timeout of 60s, expect update to come in <=30s From db7c2f21aeb103ef3ad725f530d9eccfd237f3cb Mon Sep 17 00:00:00 2001 From: liamkearney-msft Date: Fri, 8 Nov 2024 10:08:02 +1000 Subject: [PATCH 099/221] [dut_console/test_console_baud_rate]: cast expected baudrate to str (#15217) Description of PR Cast expected console baudrate to str so comparison works properly Summary: Fixes #14874 Signed-off-by: Liam Kearney --- tests/dut_console/test_console_baud_rate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/dut_console/test_console_baud_rate.py b/tests/dut_console/test_console_baud_rate.py index 6c974edfc95..a156c6f77d4 100644 --- a/tests/dut_console/test_console_baud_rate.py +++ b/tests/dut_console/test_console_baud_rate.py @@ -22,7 +22,7 @@ def is_sonic_console(conn_graph_facts, dut_hostname): def get_expected_baud_rate(duthost): - DEFAULT_BAUDRATE = "9600" + DEFAULT_BAUDRATE = 9600 hostvars = duthost.host.options['variable_manager']._hostvars[duthost.hostname] return hostvars.get('console_baudrate', DEFAULT_BAUDRATE) @@ -31,7 +31,7 @@ def test_console_baud_rate_config(duthost): expected_baud_rate = get_expected_baud_rate(duthost) res = duthost.shell("cat /proc/cmdline | grep -Eo 'console=ttyS[0-9]+,[0-9]+' | cut -d ',' -f2") pytest_require(res["stdout"] != "", "Cannot get baud rate") - if res["stdout"] != expected_baud_rate: + if res["stdout"] != str(expected_baud_rate): global pass_config_test pass_config_test = False pytest.fail("Device baud rate is {}, expected {}".format(res["stdout"], expected_baud_rate)) From e98017585d0ce1d82534de9fb294a2e9c2725173 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:24:01 +0800 Subject: [PATCH 100/221] Remove skip_traffic_test fixture in hash tests (#15436) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in hash tests How did you verify/test it? --- tests/hash/test_generic_hash.py | 295 +++++++++++++++----------------- 1 file changed, 140 insertions(+), 155 deletions(-) diff --git a/tests/hash/test_generic_hash.py b/tests/hash/test_generic_hash.py index 7e4db3fdadb..fd9c0191d0d 100644 --- a/tests/hash/test_generic_hash.py +++ b/tests/hash/test_generic_hash.py @@ -15,7 +15,6 @@ from tests.common.utilities import wait_until from tests.ptf_runner import ptf_runner from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer from tests.common.reboot import reboot from tests.common.config_reload import config_reload @@ -130,8 +129,8 @@ def test_hash_capability(duthost, global_hash_capabilities): # noqa:F811 'The lag hash capability is not as expected.') -def test_ecmp_hash(duthost, tbinfo, ptfhost, fine_params, mg_facts, global_hash_capabilities, # noqa:F811 - restore_vxlan_port, toggle_all_simulator_ports_to_upper_tor, skip_traffic_test): # noqa:F811 +def test_ecmp_hash(duthost, tbinfo, ptfhost, fine_params, mg_facts, global_hash_capabilities, # noqa:F811 + restore_vxlan_port, toggle_all_simulator_ports_to_upper_tor): # noqa:F811 """ Test case to validate the ecmp hash. The hash field to test is randomly chosen from the supported hash fields. Args: @@ -174,23 +173,22 @@ def test_ecmp_hash(duthost, tbinfo, ptfhost, fine_params, mg_facts, global_hash_ # Check the default route before the ptf test pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) def test_lag_hash(duthost, ptfhost, tbinfo, fine_params, mg_facts, restore_configuration, # noqa:F811 restore_vxlan_port, global_hash_capabilities, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test): # noqa:F811 + toggle_all_simulator_ports_to_upper_tor): # noqa:F811 """ Test case to validate the lag hash. The hash field to test is randomly chosen from the supported hash fields. When hash field is in [DST_MAC, ETHERTYPE, VLAN_ID], need to re-configure the dut for L2 traffic. @@ -247,18 +245,17 @@ def test_lag_hash(duthost, ptfhost, tbinfo, fine_params, mg_facts, restore_confi if not is_l2_test: pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) def config_all_hash_fields(duthost, global_hash_capabilities): # noqa:F811 @@ -273,7 +270,7 @@ def config_all_hash_algorithm(duthost, ecmp_algorithm, lag_algorithm): # noqa:F def test_ecmp_and_lag_hash(duthost, tbinfo, ptfhost, fine_params, mg_facts, global_hash_capabilities, # noqa:F811 restore_vxlan_port, get_supported_hash_algorithms, # noqa:F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test): # noqa:F811 + toggle_all_simulator_ports_to_upper_tor): # noqa:F811 """ Test case to validate the hash behavior when both ecmp and lag hash are configured with a same field. The hash field to test is randomly chosen from the supported hash fields. @@ -312,23 +309,22 @@ def test_ecmp_and_lag_hash(duthost, tbinfo, ptfhost, fine_params, mg_facts, glob # Check the default route before the ptf test pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) def test_nexthop_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restore_interfaces, # noqa:F811 restore_vxlan_port, global_hash_capabilities, get_supported_hash_algorithms, # noqa:F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test): # noqa:F811 + toggle_all_simulator_ports_to_upper_tor): # noqa:F811 """ Test case to validate the ecmp hash when there is nexthop flapping. The hash field to test is randomly chosen from the supported hash fields. @@ -368,18 +364,17 @@ def test_nexthop_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restore_i # Check the default route before the ptf test pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) with allure.step('Randomly shutdown 1 nexthop interface'): interface = random.choice(list(uplink_interfaces.keys())) remaining_uplink_interfaces = uplink_interfaces.copy() @@ -389,18 +384,17 @@ def test_nexthop_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restore_i mg_facts, downlink_interfaces=[], uplink_interfaces=remaining_uplink_interfaces) shutdown_interface(duthost, interface) with allure.step('Start the ptf test, send traffic and check the balancing'): - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) with allure.step('Startup the interface, and then flap it 3 more times'): startup_interface(duthost, interface) flap_interfaces(duthost, [interface], times=3) @@ -408,24 +402,22 @@ def test_nexthop_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restore_i 'The default route is not restored after the flapping.') ptf_params['expected_port_groups'] = origin_ptf_expected_port_groups with allure.step('Start the ptf test, send traffic and check the balancing'): - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) def test_lag_member_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restore_configuration, # noqa F811 restore_interfaces, global_hash_capabilities, restore_vxlan_port, # noqa F811 - get_supported_hash_algorithms, toggle_all_simulator_ports_to_upper_tor, # noqa F811 - skip_traffic_test): # noqa F811 + get_supported_hash_algorithms, toggle_all_simulator_ports_to_upper_tor): # noqa F811 """ Test case to validate the lag hash when there is lag member flapping. The hash field to test is randomly chosen from the supported hash fields. @@ -482,18 +474,17 @@ def test_lag_member_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restor if not is_l2_test: pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) with allure.step('Randomly select one member in each portchannel and flap them 3 times'): # Randomly choose the members to flap @@ -509,24 +500,22 @@ def test_lag_member_flap(duthost, tbinfo, ptfhost, fine_params, mg_facts, restor pytest_assert(wait_until(30, 5, 0, check_default_route, duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') with allure.step('Start the ptf test, send traffic and check the balancing'): - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) def test_lag_member_remove_add(duthost, tbinfo, ptfhost, fine_params, mg_facts, restore_configuration, # noqa F811 restore_interfaces, global_hash_capabilities, restore_vxlan_port, # noqa F811 - get_supported_hash_algorithms, toggle_all_simulator_ports_to_upper_tor, # noqa F811 - skip_traffic_test): # noqa F811 + get_supported_hash_algorithms, toggle_all_simulator_ports_to_upper_tor): # noqa F811 """ Test case to validate the lag hash when a lag member is removed from the lag and added back for a few times. @@ -584,18 +573,17 @@ def test_lag_member_remove_add(duthost, tbinfo, ptfhost, fine_params, mg_facts, if not is_l2_test: pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) with allure.step('Randomly select one member in each portchannel and remove it from the lag and add it back'): # Randomly choose the members to remove/add @@ -609,23 +597,22 @@ def test_lag_member_remove_add(duthost, tbinfo, ptfhost, fine_params, mg_facts, 'The default route is not available or some nexthops are missing.') with allure.step('Start the ptf test, send traffic and check the balancing'): - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) def test_reboot(duthost, tbinfo, ptfhost, localhost, fine_params, mg_facts, restore_vxlan_port, # noqa F811 global_hash_capabilities, reboot_type, get_supported_hash_algorithms, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_upper_tor): # noqa F811 """ Test case to validate the hash behavior after fast/warm/cold reboot. The hash field to test is randomly chosen from the supported hash fields. @@ -665,18 +652,17 @@ def test_reboot(duthost, tbinfo, ptfhost, localhost, fine_params, mg_facts, rest # Check the default route before the ptf test pytest_assert(check_default_route(duthost, uplink_interfaces.keys()), 'The default route is not available or some nexthops are missing.') - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) with allure.step(f'Randomly choose a reboot type: {reboot_type}, and reboot'): # Save config if reboot type is config reload or cold reboot @@ -698,18 +684,17 @@ def test_reboot(duthost, tbinfo, ptfhost, localhost, fine_params, mg_facts, rest pytest_assert(wait_until(60, 10, 0, check_default_route, duthost, uplink_interfaces.keys()), "The default route is not established after the cold reboot.") with allure.step('Start the ptf test, send traffic and check the balancing'): - if not skip_traffic_test: - ptf_runner( - ptfhost, - "ptftests", - "generic_hash_test.GenericHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=PTF_LOG_PATH, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True - ) + ptf_runner( + ptfhost, + "ptftests", + "generic_hash_test.GenericHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=PTF_LOG_PATH, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True + ) @pytest.mark.disable_loganalyzer From 4e2f38e331e6e3f4d9fd45d681d8058a049873dd Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:25:10 +0800 Subject: [PATCH 101/221] Remove skip_traffic_test fixture in gcu tests (#15435) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in gcu tests How did you verify/test it? --- .../test_dynamic_acl.py | 78 +++++++------------ 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/tests/generic_config_updater/test_dynamic_acl.py b/tests/generic_config_updater/test_dynamic_acl.py index f7c86f056b9..2b5a3b2ed1d 100644 --- a/tests/generic_config_updater/test_dynamic_acl.py +++ b/tests/generic_config_updater/test_dynamic_acl.py @@ -25,7 +25,6 @@ from ipaddress import ip_network, IPv6Network, IPv4Network from tests.common.fixtures.ptfhost_utils import remove_ip_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.gu_utils import expect_op_success, expect_op_failure from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import apply_formed_json_patch @@ -846,8 +845,7 @@ def dynamic_acl_create_dhcp_forward_rule(duthost, setup): expect_acl_rule_match(duthost, "DHCPV6_RULE", expected_v6_rule_content, setup) -def dynamic_acl_verify_packets(setup, ptfadapter, packets, packets_dropped, src_port=None, - skip_traffic_test=False): # noqa F811 +def dynamic_acl_verify_packets(setup, ptfadapter, packets, packets_dropped, src_port=None): """Verify that the given packets are either dropped/forwarded correctly Args: @@ -862,9 +860,6 @@ def dynamic_acl_verify_packets(setup, ptfadapter, packets, packets_dropped, src_ if src_port is None: src_port = setup["blocked_src_port_indice"] - if skip_traffic_test is True: - logger.info("Skipping traffic test") - return for rule, pkt in list(packets.items()): logger.info("Testing that {} packets are correctly {}".format(rule, action_type)) exp_pkt = build_exp_pkt(pkt) @@ -1069,8 +1064,7 @@ def test_gcu_acl_arp_rule_creation(rand_selected_dut, setup, dynamic_acl_create_table, prepare_ptf_intf_and_ip, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Test that we can create a blanket ARP/NDP packet forwarding rule with GCU, and that ARP/NDP packets are correctly forwarded while all others are dropped.""" @@ -1105,8 +1099,7 @@ def test_gcu_acl_arp_rule_creation(rand_selected_dut, ptfadapter, packets=generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), packets_dropped=True, - src_port=ptf_intf_index, - skip_traffic_test=skip_traffic_test) + src_port=ptf_intf_index) def test_gcu_acl_dhcp_rule_creation(rand_selected_dut, @@ -1115,8 +1108,7 @@ def test_gcu_acl_dhcp_rule_creation(rand_selected_dut, setup, dynamic_acl_create_table, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + setup_standby_ports_on_rand_unselected_tor): # noqa F811 """Verify that DHCP and DHCPv6 forwarding rules can be created, and that dhcp packets are properly forwarded whereas others are dropped""" @@ -1131,8 +1123,7 @@ def test_gcu_acl_dhcp_rule_creation(rand_selected_dut, dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), - packets_dropped=True, - skip_traffic_test=skip_traffic_test) + packets_dropped=True) def test_gcu_acl_drop_rule_creation(rand_selected_dut, @@ -1140,8 +1131,7 @@ def test_gcu_acl_drop_rule_creation(rand_selected_dut, ptfadapter, setup, dynamic_acl_create_table, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Test that we can create a drop rule via GCU, and that once this drop rule is in place packets that match the drop rule are dropped and packets that do not match the drop rule are forwarded""" @@ -1150,14 +1140,12 @@ def test_gcu_acl_drop_rule_creation(rand_selected_dut, dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), - packets_dropped=True, - skip_traffic_test=skip_traffic_test) + packets_dropped=True) dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), packets_dropped=False, - src_port=setup["unblocked_src_port_indice"], - skip_traffic_test=skip_traffic_test) + src_port=setup["unblocked_src_port_indice"]) def test_gcu_acl_drop_rule_removal(rand_selected_dut, @@ -1165,8 +1153,7 @@ def test_gcu_acl_drop_rule_removal(rand_selected_dut, ptfadapter, setup, dynamic_acl_create_table, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Test that once a drop rule is removed, packets that were previously being dropped are now forwarded""" dynamic_acl_create_three_drop_rules(rand_selected_dut, setup) @@ -1176,8 +1163,7 @@ def test_gcu_acl_drop_rule_removal(rand_selected_dut, ptfadapter, packets=generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), packets_dropped=False, - src_port=setup["scale_port_indices"][2], - skip_traffic_test=skip_traffic_test) + src_port=setup["scale_port_indices"][2]) def test_gcu_acl_forward_rule_priority_respected(rand_selected_dut, @@ -1185,8 +1171,7 @@ def test_gcu_acl_forward_rule_priority_respected(rand_selected_dut, ptfadapter, setup, dynamic_acl_create_table, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Test that forward rules and drop rules can be created at the same time, with the forward rules having higher priority than drop. Then, perform a traffic test to confirm that packets that match both the forward and drop rules are correctly forwarded, as the forwarding rules have higher priority""" @@ -1195,10 +1180,10 @@ def test_gcu_acl_forward_rule_priority_respected(rand_selected_dut, dynamic_acl_create_secondary_drop_rule(rand_selected_dut, setup) dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup), - packets_dropped=False, skip_traffic_test=skip_traffic_test) + packets_dropped=False) dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), - packets_dropped=True, skip_traffic_test=skip_traffic_test) + packets_dropped=True) def test_gcu_acl_forward_rule_replacement(rand_selected_dut, @@ -1206,8 +1191,7 @@ def test_gcu_acl_forward_rule_replacement(rand_selected_dut, ptfadapter, setup, dynamic_acl_create_table, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Test that forward rules can be created, and then afterwards can have their match pattern updated to a new value. Confirm that packets sent that match this new value are correctly forwarded, and that packets that are sent that match the old, replaced value are correctly dropped.""" @@ -1221,10 +1205,8 @@ def test_gcu_acl_forward_rule_replacement(rand_selected_dut, packets=generate_packets(setup, DST_IP_FORWARDED_REPLACEMENT, DST_IPV6_FORWARDED_REPLACEMENT), - packets_dropped=False, - skip_traffic_test=skip_traffic_test) - dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup), packets_dropped=True, - skip_traffic_test=skip_traffic_test) + packets_dropped=False) + dynamic_acl_verify_packets(setup, ptfadapter, packets=generate_packets(setup), packets_dropped=True) @pytest.mark.parametrize("ip_type", ["IPV4", "IPV6"]) @@ -1234,8 +1216,7 @@ def test_gcu_acl_forward_rule_removal(rand_selected_dut, setup, ip_type, dynamic_acl_create_table, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Test that if a forward rule is created, and then removed, that packets associated with that rule are properly no longer forwarded, and packets associated with the remaining rule are forwarded""" @@ -1252,15 +1233,12 @@ def test_gcu_acl_forward_rule_removal(rand_selected_dut, # generate_packets returns ipv4 and ipv6 packets. remove vals from two dicts so that only correct packets remain drop_packets.pop(other_type) forward_packets.pop(ip_type) - dynamic_acl_verify_packets(setup, ptfadapter, drop_packets, packets_dropped=True, - skip_traffic_test=skip_traffic_test) - dynamic_acl_verify_packets(setup, ptfadapter, forward_packets, packets_dropped=False, - skip_traffic_test=skip_traffic_test) + dynamic_acl_verify_packets(setup, ptfadapter, drop_packets, packets_dropped=True) + dynamic_acl_verify_packets(setup, ptfadapter, forward_packets, packets_dropped=False) def test_gcu_acl_scale_rules(rand_selected_dut, rand_unselected_dut, ptfadapter, setup, dynamic_acl_create_table, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Perform a scale test, creating 150 forward rules with top priority, and then creating a drop rule for every single VLAN port on our device. Select any one of our blocked ports, as well as the ips for two of our forward rules, @@ -1280,27 +1258,23 @@ def test_gcu_acl_scale_rules(rand_selected_dut, rand_unselected_dut, ptfadapter, ptfadapter, generate_packets(setup, v4_dest, v6_dest), packets_dropped=False, - src_port=blocked_scale_port, - skip_traffic_test=skip_traffic_test) + src_port=blocked_scale_port) dynamic_acl_verify_packets(setup, ptfadapter, generate_packets(setup, DST_IP_BLOCKED, DST_IPV6_BLOCKED), packets_dropped=True, - src_port=blocked_scale_port, - skip_traffic_test=skip_traffic_test) + src_port=blocked_scale_port) def test_gcu_acl_nonexistent_rule_replacement(rand_selected_dut, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup, - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + setup): """Confirm that replacing a nonexistent rule results in operation failure""" dynamic_acl_replace_nonexistent_rule(rand_selected_dut, setup) def test_gcu_acl_nonexistent_table_removal(rand_selected_dut, - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup, - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 + setup): """Confirm that removing a nonexistent table results in operation failure""" dynamic_acl_remove_nonexistent_table(rand_selected_dut, setup) From 3ae670e155f858028049a8845ca50fca5855652d Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:25:52 +0800 Subject: [PATCH 102/221] Remove skip_traffic_test fixture in fib tests (#15433) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in fib tests --- tests/fib/test_fib.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tests/fib/test_fib.py b/tests/fib/test_fib.py index c1e8f47bfbb..e65b90d81e2 100644 --- a/tests/fib/test_fib.py +++ b/tests/fib/test_fib.py @@ -10,7 +10,6 @@ from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 from tests.common.fixtures.ptfhost_utils import set_ptf_port_mapping_mode # noqa F401 from tests.common.fixtures.ptfhost_utils import ptf_test_port_map_active_active, ptf_test_port_map -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.ptf_runner import ptf_runner from tests.common.dualtor.mux_simulator_control import mux_server_url # noqa F401 @@ -84,8 +83,7 @@ def test_basic_fib(duthosts, ptfhost, ipv4, ipv6, mtu, mux_status_from_nic_simulator, ignore_ttl, single_fib_for_duts, # noqa F401 duts_running_config_facts, duts_minigraph_facts, - validate_active_active_dualtor_setup, # noqa F401 - skip_traffic_test): # noqa F811 + validate_active_active_dualtor_setup): # noqa F811 if 'dualtor' in updated_tbinfo['topo']['name']: wait(30, 'Wait some time for mux active/standby state to be stable after toggled mux state') @@ -105,8 +103,6 @@ def test_basic_fib(duthosts, ptfhost, ipv4, ipv6, mtu, log_file = "/tmp/fib_test.FibTest.ipv4.{}.ipv6.{}.{}.log".format( ipv4, ipv6, timestamp) logging.info("PTF log file: %s" % log_file) - if skip_traffic_test is True: - return ptf_runner( ptfhost, "ptftests", @@ -319,7 +315,7 @@ def test_hash(add_default_route_to_dut, duthosts, fib_info_files_per_function, s hash_keys, ptfhost, ipver, toggle_all_simulator_ports_to_rand_selected_tor_m, # noqa F811 updated_tbinfo, mux_server_url, mux_status_from_nic_simulator, ignore_ttl, # noqa F811 single_fib_for_duts, duts_running_config_facts, duts_minigraph_facts, # noqa F811 - setup_active_active_ports, active_active_ports, skip_traffic_test): # noqa F811 + setup_active_active_ports, active_active_ports): # noqa F811 if 'dualtor' in updated_tbinfo['topo']['name']: wait(30, 'Wait some time for mux active/standby state to be stable after toggled mux state') @@ -335,8 +331,6 @@ def test_hash(add_default_route_to_dut, duthosts, fib_info_files_per_function, s else: src_ip_range = SRC_IPV6_RANGE dst_ip_range = DST_IPV6_RANGE - if skip_traffic_test is True: - return ptf_runner( ptfhost, "ptftests", @@ -371,7 +365,7 @@ def test_hash(add_default_route_to_dut, duthosts, fib_info_files_per_function, s def test_ipinip_hash(add_default_route_to_dut, duthost, duthosts, fib_info_files_per_function, # noqa F811 hash_keys, ptfhost, ipver, tbinfo, mux_server_url, # noqa F811 ignore_ttl, single_fib_for_duts, duts_running_config_facts, # noqa F811 - duts_minigraph_facts, skip_traffic_test): # noqa F811 + duts_minigraph_facts): # noqa F811 # Skip test on none T1 testbed pytest_require('t1' == tbinfo['topo']['type'], "The test case runs on T1 topology") @@ -385,8 +379,6 @@ def test_ipinip_hash(add_default_route_to_dut, duthost, duthosts, fib_info_files else: src_ip_range = SRC_IPV6_RANGE dst_ip_range = DST_IPV6_RANGE - if skip_traffic_test is True: - return ptf_runner(ptfhost, "ptftests", "hash_test.IPinIPHashTest", @@ -413,8 +405,7 @@ def test_ipinip_hash(add_default_route_to_dut, duthost, duthosts, fib_info_files def test_ipinip_hash_negative(add_default_route_to_dut, duthosts, fib_info_files_per_function, # noqa F811 ptfhost, ipver, tbinfo, mux_server_url, ignore_ttl, single_fib_for_duts, # noqa F811 - duts_running_config_facts, duts_minigraph_facts, mux_status_from_nic_simulator, - skip_traffic_test): # noqa F811 + duts_running_config_facts, duts_minigraph_facts, mux_status_from_nic_simulator): hash_keys = ['inner_length'] timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') log_file = "/tmp/hash_test.IPinIPHashTest.{}.{}.log".format( @@ -426,8 +417,6 @@ def test_ipinip_hash_negative(add_default_route_to_dut, duthosts, fib_info_files else: src_ip_range = SRC_IPV6_RANGE dst_ip_range = DST_IPV6_RANGE - if skip_traffic_test is True: - return ptf_runner(ptfhost, "ptftests", "hash_test.IPinIPHashTest", From f7d704f1fd67c65e95462e8e8ffb7553455475cf Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:26:29 +0800 Subject: [PATCH 103/221] Remove skip_traffic_test fixture in everflow tests (#15432) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in everflow tests --- tests/everflow/everflow_test_utilities.py | 17 ++- tests/everflow/test_everflow_ipv6.py | 139 ++++++------------ tests/everflow/test_everflow_per_interface.py | 7 +- tests/everflow/test_everflow_testbed.py | 91 ++++-------- 4 files changed, 85 insertions(+), 169 deletions(-) diff --git a/tests/everflow/everflow_test_utilities.py b/tests/everflow/everflow_test_utilities.py index 97e80743fea..8377cb40548 100644 --- a/tests/everflow/everflow_test_utilities.py +++ b/tests/everflow/everflow_test_utilities.py @@ -753,8 +753,7 @@ def send_and_check_mirror_packets(self, src_port=None, dest_ports=None, expect_recv=True, - valid_across_namespace=True, - skip_traffic_test=False): + valid_across_namespace=True): # In Below logic idea is to send traffic in such a way so that mirror traffic # will need to go across namespaces and within namespace. If source and mirror destination @@ -789,9 +788,6 @@ def send_and_check_mirror_packets(self, src_port_set.add(dest_ports[0]) src_port_metadata_map[dest_ports[0]] = (None, 2) - if skip_traffic_test is True: - logging.info("Skipping traffic test") - return # Loop through Source Port Set and send traffic on each source port of the set for src_port in src_port_set: expected_mirror_packet = BaseEverflowTest.get_expected_mirror_packet(mirror_session, @@ -810,10 +806,15 @@ def send_and_check_mirror_packets(self, if expect_recv: time.sleep(STABILITY_BUFFER) - _, received_packet = testutils.verify_packet_any_port(ptfadapter, - expected_mirror_packet, - ports=dest_ports) + result = testutils.verify_packet_any_port(ptfadapter, + expected_mirror_packet, + ports=dest_ports) + if isinstance(result, bool): + logging.info("Using dummy testutils to skip traffic test, skip following checks") + return + + _, received_packet = result logging.info("Received packet: %s", packet.Ether(received_packet).summary()) inner_packet = self._extract_mirror_payload(received_packet, len(mirror_packet_sent)) diff --git a/tests/everflow/test_everflow_ipv6.py b/tests/everflow/test_everflow_ipv6.py index 6ffd720f287..df3a4b0e3a3 100644 --- a/tests/everflow/test_everflow_ipv6.py +++ b/tests/everflow/test_everflow_ipv6.py @@ -13,7 +13,6 @@ # Module-level fixtures from .everflow_test_utilities import setup_info # noqa: F401 from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa: F401 pytestmark = [ pytest.mark.topology("t0", "t1", "t2", "m0") @@ -155,8 +154,7 @@ def background_traffic(run_count=None): def test_src_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on Source IPv6 addresses.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -170,13 +168,11 @@ def test_src_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_dst_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on Destination IPv6 addresses.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -190,13 +186,11 @@ def test_dst_ipv6_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_next_header_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on the Next Header field.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, next_header=0x7E) @@ -205,13 +199,11 @@ def test_next_header_mirroring(self, setup_info, setup_mirror_session, ptfadapte ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_l4_src_port_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on the L4 Source Port.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, sport=9000) @@ -220,13 +212,11 @@ def test_l4_src_port_mirroring(self, setup_info, setup_mirror_session, ptfadapte ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_l4_dst_port_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on the L4 Destination Port.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, dport=9001) @@ -235,14 +225,12 @@ def test_l4_dst_port_mirroring(self, setup_info, setup_mirror_session, ptfadapte ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_l4_src_port_range_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on a range of L4 Source Ports.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, sport=10200) @@ -251,14 +239,12 @@ def test_l4_src_port_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_l4_dst_port_range_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on a range of L4 Destination Ports.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, dport=10700) @@ -267,13 +253,11 @@ def test_l4_dst_port_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_tcp_flags_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on TCP Flags.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, flags=0x1B) @@ -282,13 +266,11 @@ def test_tcp_flags_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_dscp_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match on DSCP.""" test_packet = self._base_tcpv6_packet(everflow_direction, ptfadapter, setup_info, dscp=37) @@ -297,13 +279,11 @@ def test_dscp_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ever ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_l4_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match from a source port to a range of destination ports and vice-versa.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -320,8 +300,7 @@ def test_l4_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_tcpv6_packet( everflow_direction, @@ -338,13 +317,11 @@ def test_l4_range_mirroring(self, setup_info, setup_mirror_session, ptfadapter, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_tcp_response_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match a SYN -> SYN-ACK pattern.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -360,8 +337,7 @@ def test_tcp_response_mirroring(self, setup_info, setup_mirror_session, ptfadapt ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_tcpv6_packet( everflow_direction, @@ -377,14 +353,12 @@ def test_tcp_response_mirroring(self, setup_info, setup_mirror_session, ptfadapt ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match a TCP handshake between a client and server.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -402,8 +376,7 @@ def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_tcpv6_packet( everflow_direction, @@ -421,14 +394,12 @@ def test_tcp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_udp_application_mirroring(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match UDP traffic between a client and server application.""" test_packet = self._base_udpv6_packet( everflow_direction, @@ -446,8 +417,7 @@ def test_udp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_udpv6_packet( everflow_direction, ptfadapter, @@ -464,13 +434,11 @@ def test_udp_application_mirroring(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that the protocol number is ignored if it is not specified in the ACL rule.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -485,8 +453,7 @@ def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_udpv6_packet( everflow_direction, @@ -501,8 +468,7 @@ def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_udpv6_packet( everflow_direction, @@ -518,14 +484,12 @@ def test_any_protocol(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_any_transport_protocol(self, setup_info, setup_mirror_session, # noqa F811 ptfadapter, everflow_dut, everflow_direction, setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that src port and dst port rules match regardless of whether TCP or UDP traffic is sent.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -542,8 +506,7 @@ def test_any_transport_protocol(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) test_packet = self._base_udpv6_packet( everflow_direction, @@ -560,13 +523,11 @@ def test_any_transport_protocol(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_invalid_tcp_rule(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that the ASIC does not reject rules with TCP flags if the protocol is not TCP.""" pass @@ -577,8 +538,7 @@ def test_invalid_tcp_rule(self, setup_info, setup_mirror_session, ptfadapter, ev def test_source_subnet(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match packets with a Source IPv6 Subnet.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -595,13 +555,11 @@ def test_source_subnet(self, setup_info, setup_mirror_session, ptfadapter, everf ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_dest_subnet(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match packets with a Destination IPv6 Subnet.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -618,13 +576,11 @@ def test_dest_subnet(self, setup_info, setup_mirror_session, ptfadapter, everflo ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_both_subnets(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match packets with both source and destination subnets.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -641,13 +597,11 @@ def test_both_subnets(self, setup_info, setup_mirror_session, ptfadapter, everfl ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def test_fuzzy_subnets(self, setup_info, setup_mirror_session, ptfadapter, everflow_dut, # noqa F811 setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - skip_traffic_test): # noqa F811 + everflow_direction, toggle_all_simulator_ports_to_rand_selected_tor): # noqa F811 """Verify that we can match packets with non-standard subnet sizes.""" test_packet = self._base_tcpv6_packet( everflow_direction, @@ -664,8 +618,7 @@ def test_fuzzy_subnets(self, setup_info, setup_mirror_session, ptfadapter, everf ptfadapter, everflow_dut, test_packet, everflow_direction, src_port=EverflowIPv6Tests.rx_port_ptf_id, - dest_ports=EverflowIPv6Tests.tx_port_ids, - skip_traffic_test=skip_traffic_test) + dest_ports=EverflowIPv6Tests.tx_port_ids) def _base_tcpv6_packet(self, direction, diff --git a/tests/everflow/test_everflow_per_interface.py b/tests/everflow/test_everflow_per_interface.py index 820513d6675..8bef2b5ed78 100644 --- a/tests/everflow/test_everflow_per_interface.py +++ b/tests/everflow/test_everflow_per_interface.py @@ -13,7 +13,6 @@ from .everflow_test_utilities import setup_info, EVERFLOW_DSCP_RULES # noqa: F401 from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa: F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa: F401 pytestmark = [ pytest.mark.topology("any") @@ -181,8 +180,7 @@ def send_and_verify_packet(ptfadapter, packet, expected_packet, tx_port, rx_port def test_everflow_per_interface(ptfadapter, setup_info, apply_acl_rule, tbinfo, # noqa F811 - toggle_all_simulator_ports_to_rand_selected_tor, ip_ver, # noqa F811 - skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor, ip_ver): # noqa F811 """Verify packet ingress from candidate ports are captured by EVERFLOW, while packets ingress from unselected ports are not captured """ @@ -192,9 +190,6 @@ def test_everflow_per_interface(ptfadapter, setup_info, apply_acl_rule, tbinfo, setup_info[UP_STREAM]['ingress_router_mac'], setup_info, ip_ver) uplink_ports = everflow_config["monitor_port_ptf_ids"] - if skip_traffic_test: - return - # Verify that packet ingressed from INPUT_PORTS (candidate ports) are mirrored for port, ptf_idx in list(everflow_config['candidate_ports'].items()): logger.info("Verifying packet ingress from {} is mirrored".format(port)) diff --git a/tests/everflow/test_everflow_testbed.py b/tests/everflow/test_everflow_testbed.py index 1e0777dcd58..cfe3c8f109e 100644 --- a/tests/everflow/test_everflow_testbed.py +++ b/tests/everflow/test_everflow_testbed.py @@ -15,7 +15,6 @@ # Module-level fixtures from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa: F401 from tests.common.fixtures.ptfhost_utils import copy_acstests_directory # noqa: F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa: F401 from .everflow_test_utilities import setup_info, setup_arp_responder, EVERFLOW_DSCP_RULES # noqa: F401 from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py # noqa: F401 from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor # noqa: F401 @@ -135,8 +134,7 @@ def add_dest_routes(self, setup_info, tbinfo, dest_port_type): # noqa F811 def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - skip_traffic_test): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 """ Verify basic forwarding scenarios for the Everflow feature. @@ -170,8 +168,7 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Add a (better) unresolved route to the mirror session destination IP @@ -188,8 +185,7 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Remove the unresolved route @@ -212,8 +208,7 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Remove the better route. @@ -230,8 +225,7 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( @@ -241,8 +235,7 @@ def test_everflow_basic_forwarding(self, setup_info, setup_mirror_session, def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - skip_traffic_test): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 """Verify that session destination MAC address is changed after neighbor MAC address update.""" everflow_dut = setup_info[dest_port_type]['everflow_dut'] @@ -265,8 +258,7 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Update the MAC on the neighbor interface for the route we installed @@ -286,8 +278,7 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) finally: @@ -308,15 +299,13 @@ def test_everflow_neighbor_mac_change(self, setup_info, setup_mirror_session, everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - skip_traffic_test): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 """Verify that session is still active after removal of next hop from ECMP route that was not in use.""" everflow_dut = setup_info[dest_port_type]['everflow_dut'] @@ -348,8 +337,7 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses everflow_dut, rx_port_ptf_id, tx_port_ptf_ids, - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Remaining Scenario not applicable for this topology @@ -374,8 +362,7 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses [tx_port_ptf_id], dest_port_type, expect_recv=False, - valid_across_namespace=False, - skip_traffic_test=skip_traffic_test + valid_across_namespace=False ) # Remove the extra hop @@ -393,8 +380,7 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses [tx_port_ptf_id], dest_port_type, expect_recv=False, - valid_across_namespace=False, - skip_traffic_test=skip_traffic_test + valid_across_namespace=False ) # Verify that mirrored traffic is still sent to one of the original next hops @@ -405,15 +391,13 @@ def test_everflow_remove_unused_ecmp_next_hop(self, setup_info, setup_mirror_ses everflow_dut, rx_port_ptf_id, tx_port_ptf_ids, - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_session, # noqa F811 dest_port_type, ptfadapter, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - skip_traffic_test): # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally): # noqa F811 """Verify that session is still active after removal of next hop from ECMP route that was in use.""" everflow_dut = setup_info[dest_port_type]['everflow_dut'] @@ -444,8 +428,7 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Add two new ECMP next hops @@ -469,8 +452,7 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi rx_port_ptf_id, [tx_port_ptf_id], dest_port_type, - valid_across_namespace=False, - skip_traffic_test=skip_traffic_test + valid_across_namespace=False ) # Verify that traffic is not sent along either of the new next hops @@ -487,8 +469,7 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi tx_port_ptf_ids, dest_port_type, expect_recv=False, - valid_across_namespace=False, - skip_traffic_test=skip_traffic_test + valid_across_namespace=False ) # Remove the original next hop @@ -505,8 +486,7 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi rx_port_ptf_id, [tx_port_ptf_id], dest_port_type, - expect_recv=False, - skip_traffic_test=skip_traffic_test + expect_recv=False ) # Verify that mirrored traffis is now sent along either of the new next hops @@ -517,8 +497,7 @@ def test_everflow_remove_used_ecmp_next_hop(self, setup_info, setup_mirror_sessi everflow_dut, rx_port_ptf_id, tx_port_ptf_ids, - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) def test_everflow_dscp_with_policer( @@ -530,8 +509,7 @@ def test_everflow_dscp_with_policer( config_method, tbinfo, toggle_all_simulator_ports_to_rand_selected_tor, # noqa F811 - setup_standby_ports_on_rand_unselected_tor_unconditionally, # noqa F811 - skip_traffic_test # noqa F811 + setup_standby_ports_on_rand_unselected_tor_unconditionally # noqa F811 ): """Verify that we can rate-limit mirrored traffic from the MIRROR_DSCP table. This tests single rate three color policer mode and specifically checks CIR value @@ -617,9 +595,6 @@ def test_everflow_dscp_with_policer( config_method, rules=EVERFLOW_DSCP_RULES) - if skip_traffic_test is True: - return - # Run test with expected CIR/CBS in packets/sec and tolerance % partial_ptf_runner(setup_info, dest_port_type, @@ -635,8 +610,7 @@ def test_everflow_dscp_with_policer( cir=rate_limit, cbs=rate_limit, send_time=send_time, - tolerance=everflow_tolerance, - skip_traffic_test=skip_traffic_test) + tolerance=everflow_tolerance) finally: # Clean up ACL rules and routes BaseEverflowTest.remove_acl_rule_config(everflow_dut, table_name, config_method) @@ -651,8 +625,7 @@ def test_everflow_dscp_with_policer( def test_everflow_frwd_with_bkg_trf(self, setup_info, # noqa F811 setup_mirror_session, - dest_port_type, ptfadapter, tbinfo, - skip_traffic_test # noqa F811 + dest_port_type, ptfadapter, tbinfo ): """ Verify basic forwarding scenarios for the Everflow feature with background traffic. @@ -743,8 +716,7 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Add a (better) unresolved route to the mirror session destination IP @@ -762,8 +734,7 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Remove the unresolved route @@ -786,8 +757,7 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) # Remove the better route. @@ -804,8 +774,7 @@ def background_traffic(run_count=None): everflow_dut, rx_port_ptf_id, [tx_port_ptf_id], - dest_port_type, - skip_traffic_test=skip_traffic_test + dest_port_type ) remote_dut.shell(remote_dut.get_vtysh_cmd_for_namespace( @@ -820,8 +789,7 @@ def background_traffic(run_count=None): background_traffic(run_count=1) def _run_everflow_test_scenarios(self, ptfadapter, setup, mirror_session, duthost, rx_port, - tx_ports, direction, expect_recv=True, valid_across_namespace=True, - skip_traffic_test=False): # noqa F811 + tx_ports, direction, expect_recv=True, valid_across_namespace=True): # FIXME: In the ptf_runner version of these tests, LAGs were passed down to the tests # as comma-separated strings of LAG member port IDs (e.g. portchannel0001 -> "2,3"). # Because the DSCP test is still using ptf_runner we will preserve this for now, @@ -859,8 +827,7 @@ def _run_everflow_test_scenarios(self, ptfadapter, setup, mirror_session, duthos src_port=rx_port, dest_ports=tx_port_ids, expect_recv=expect_recv, - valid_across_namespace=valid_across_namespace, - skip_traffic_test=skip_traffic_test, + valid_across_namespace=valid_across_namespace ) def _base_tcp_packet( From cdfd82733e2e2621703cea8ef7dc32e4046264d5 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:32:06 +0800 Subject: [PATCH 104/221] Remove skip_traffic_test fixture in drop_packets tests (#15430) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in drop_packets tests How did you verify/test it? --- tests/drop_packets/drop_packets.py | 84 ++++++++++-------------- tests/drop_packets/test_drop_counters.py | 42 +++++------- 2 files changed, 51 insertions(+), 75 deletions(-) diff --git a/tests/drop_packets/drop_packets.py b/tests/drop_packets/drop_packets.py index 9948968af0c..6cfa62c922a 100644 --- a/tests/drop_packets/drop_packets.py +++ b/tests/drop_packets/drop_packets.py @@ -15,7 +15,6 @@ from tests.common.helpers.constants import DEFAULT_NAMESPACE from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer, LogAnalyzerError from tests.common import config_reload -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.helpers.dut_utils import is_mellanox_fanout RX_DRP = "RX_DRP" @@ -516,7 +515,7 @@ def send_packets(pkt, ptfadapter, ptf_tx_port_id, num_packets=1): def test_equal_smac_dmac_drop(do_test, ptfadapter, setup, fanouthost, - pkt_fields, ports_info, enum_fanout_graph_facts, skip_traffic_test): # noqa F811 + pkt_fields, ports_info, enum_fanout_graph_facts): # noqa F811 """ @summary: Create a packet with equal SMAC and DMAC. """ @@ -555,7 +554,7 @@ def test_equal_smac_dmac_drop(do_test, ptfadapter, setup, fanouthost, group = "L2" do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - comparable_pkt=comparable_pkt, skip_traffic_test=skip_traffic_test) + comparable_pkt=comparable_pkt) def test_multicast_smac_drop(do_test, ptfadapter, setup, fanouthost, @@ -599,11 +598,11 @@ def test_multicast_smac_drop(do_test, ptfadapter, setup, fanouthost, group = "L2" do_test(group, pkt, ptfadapter, ports_info, - setup["neighbor_sniff_ports"], comparable_pkt=comparable_pkt, skip_traffic_test=skip_traffic_test) + setup["neighbor_sniff_ports"], comparable_pkt=comparable_pkt) def test_not_expected_vlan_tag_drop(do_test, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, setup, pkt_fields, ports_info, skip_traffic_test): + ptfadapter, setup, pkt_fields, ports_info): """ @summary: Create a VLAN tagged packet which VLAN ID does not match ingress port VLAN ID. """ @@ -636,11 +635,10 @@ def test_not_expected_vlan_tag_drop(do_test, duthosts, enum_rand_one_per_hwsku_f ) group = "L2" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"]) -def test_dst_ip_is_loopback_addr(do_test, ptfadapter, setup, pkt_fields, tx_dut_ports, ports_info, skip_traffic_test): +def test_dst_ip_is_loopback_addr(do_test, ptfadapter, setup, pkt_fields, tx_dut_ports, ports_info): """ @summary: Create a packet with loopback destination IP adress. """ @@ -658,11 +656,10 @@ def test_dst_ip_is_loopback_addr(do_test, ptfadapter, setup, pkt_fields, tx_dut_ tcp_dport=pkt_fields["tcp_dport"]) group = "L3" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) -def test_src_ip_is_loopback_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info, skip_traffic_test): +def test_src_ip_is_loopback_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info): """ @summary: Create a packet with loopback source IP adress. """ @@ -680,11 +677,10 @@ def test_src_ip_is_loopback_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_f tcp_dport=pkt_fields["tcp_dport"]) group = "L3" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) -def test_dst_ip_absent(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info, skip_traffic_test): +def test_dst_ip_absent(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info): """ @summary: Create a packet with absent destination IP address. """ @@ -712,13 +708,12 @@ def test_dst_ip_absent(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, por group = "L3" print(("msm group {}, setup {}".format(group, setup))) - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) @pytest.mark.parametrize("ip_addr", ["ipv4", "ipv6"]) def test_src_ip_is_multicast_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ip_addr, - ports_info, skip_traffic_test): + ports_info): """ @summary: Create a packet with multicast source IP adress. """ @@ -752,11 +747,11 @@ def test_src_ip_is_multicast_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_ group = "L3" do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, ip_ver=ip_addr, skip_traffic_test=skip_traffic_test) + tx_dut_ports, ip_ver=ip_addr) def test_src_ip_is_class_e(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - setup, tx_dut_ports, pkt_fields, ports_info, skip_traffic_test): + setup, tx_dut_ports, pkt_fields, ports_info): """ @summary: Create a packet with source IP address in class E. """ @@ -779,14 +774,12 @@ def test_src_ip_is_class_e(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsk tcp_dport=pkt_fields["tcp_dport"]) group = "L3" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) @pytest.mark.parametrize("addr_type, addr_direction", [("ipv4", "src"), ("ipv6", "src"), ("ipv4", "dst"), ("ipv6", "dst")]) -def test_ip_is_zero_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, addr_type, addr_direction, - ports_info, skip_traffic_test): +def test_ip_is_zero_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, addr_type, addr_direction, ports_info): """ @summary: Create a packet with "0.0.0.0" source or destination IP address. """ @@ -833,11 +826,11 @@ def test_ip_is_zero_addr(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, a pytest.skip("Src IP zero packets are not dropped on Broadcom DNX platform currently") do_test(group, pkt, ptfadapter, ports_info, list(setup["dut_to_ptf_port_map"].values()), tx_dut_ports, - ip_ver=addr_type, skip_traffic_test=skip_traffic_test) + ip_ver=addr_type) def test_dst_ip_link_local(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - setup, tx_dut_ports, pkt_fields, ports_info, skip_traffic_test): + setup, tx_dut_ports, pkt_fields, ports_info): """ @summary: Create a packet with link-local address "169.254.0.0/16". """ @@ -860,11 +853,10 @@ def test_dst_ip_link_local(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsk group = "L3" logger.info(pkt_params) - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) -def test_loopback_filter(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info, skip_traffic_test): +def test_loopback_filter(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info): """ @summary: Create a packet drops by loopback-filter. Loop-back filter means that route to the host with DST IP of received packet exists on received interface @@ -892,13 +884,11 @@ def test_loopback_filter(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, p group = "L3" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) def test_ip_pkt_with_expired_ttl(duthost, do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, - ports_info, sai_acl_drop_adj_enabled, configure_copp_drop_for_ttl_error, - skip_traffic_test): + ports_info, sai_acl_drop_adj_enabled, configure_copp_drop_for_ttl_error): """ @summary: Create an IP packet with TTL=0. """ @@ -916,12 +906,12 @@ def test_ip_pkt_with_expired_ttl(duthost, do_test, ptfadapter, setup, tx_dut_por group = "L3" do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_counter_check=sai_acl_drop_adj_enabled, skip_traffic_test=skip_traffic_test) + tx_dut_ports, skip_counter_check=sai_acl_drop_adj_enabled) @pytest.mark.parametrize("pkt_field, value", [("version", 1), ("chksum", 10), ("ihl", 1)]) def test_broken_ip_header(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, pkt_field, - value, ports_info, sai_acl_drop_adj_enabled, skip_traffic_test): + value, ports_info, sai_acl_drop_adj_enabled): """ @summary: Create a packet with broken IP header. """ @@ -940,11 +930,11 @@ def test_broken_ip_header(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, group = "L3" do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_counter_check=sai_acl_drop_adj_enabled, skip_traffic_test=skip_traffic_test) + tx_dut_ports, skip_counter_check=sai_acl_drop_adj_enabled) def test_absent_ip_header(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, ports_info, - sai_acl_drop_adj_enabled, skip_traffic_test): + sai_acl_drop_adj_enabled): """ @summary: Create packets with absent IP header. """ @@ -967,12 +957,12 @@ def test_absent_ip_header(do_test, ptfadapter, setup, tx_dut_ports, pkt_fields, group = "L3" do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_counter_check=sai_acl_drop_adj_enabled, skip_traffic_test=skip_traffic_test) + tx_dut_ports, skip_counter_check=sai_acl_drop_adj_enabled) @pytest.mark.parametrize("eth_dst", ["01:00:5e:00:01:02", "ff:ff:ff:ff:ff:ff"]) def test_unicast_ip_incorrect_eth_dst(do_test, ptfadapter, setup, tx_dut_ports, - pkt_fields, eth_dst, ports_info, skip_traffic_test): + pkt_fields, eth_dst, ports_info): """ @summary: Create packets with multicast/broadcast ethernet dst. """ @@ -992,15 +982,14 @@ def test_unicast_ip_incorrect_eth_dst(do_test, ptfadapter, setup, tx_dut_ports, ) group = "L3" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) @pytest.mark.parametrize("igmp_version,msg_type", [("v1", "general_query"), ("v3", "general_query"), ("v1", "membership_report"), ("v2", "membership_report"), ("v3", "membership_report"), ("v2", "leave_group")]) def test_non_routable_igmp_pkts(do_test, ptfadapter, setup, fanouthost, tx_dut_ports, - pkt_fields, igmp_version, msg_type, ports_info, skip_traffic_test): + pkt_fields, igmp_version, msg_type, ports_info): """ @summary: Create an IGMP non-routable packets. """ @@ -1085,12 +1074,11 @@ def test_non_routable_igmp_pkts(do_test, ptfadapter, setup, fanouthost, tx_dut_p pkt.getlayer("IP").dst, pkt_fields["ipv4_src"]) group = "L3" - do_test(group, pkt, ptfadapter, ports_info, list(setup["dut_to_ptf_port_map"].values()), - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, list(setup["dut_to_ptf_port_map"].values()), tx_dut_ports) def test_acl_drop(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - setup, tx_dut_ports, pkt_fields, acl_ingress, ports_info, skip_traffic_test): + setup, tx_dut_ports, pkt_fields, acl_ingress, ports_info): """ @summary: Verify that DUT drops packet with SRC IP 20.0.0.0/24 matched by ingress ACL """ @@ -1114,12 +1102,11 @@ def test_acl_drop(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_fronten tcp_dport=pkt_fields["tcp_dport"] ) - do_test("ACL", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test("ACL", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) def test_acl_egress_drop(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - setup, tx_dut_ports, pkt_fields, acl_egress, ports_info, skip_traffic_test): + setup, tx_dut_ports, pkt_fields, acl_egress, ports_info): """ @summary: Verify that DUT drops packet with DST IP 192.168.144.1/24 matched by egress ACL and ACL drop counter incremented @@ -1145,5 +1132,4 @@ def test_acl_egress_drop(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_ ip_ttl=64 ) do_test(discard_group="ACL", pkt=pkt, ptfadapter=ptfadapter, ports_info=ports_info, - sniff_ports=setup["neighbor_sniff_ports"], tx_dut_ports=tx_dut_ports, drop_information="OUTDATAACL", - skip_traffic_test=skip_traffic_test) + sniff_ports=setup["neighbor_sniff_ports"], tx_dut_ports=tx_dut_ports, drop_information="OUTDATAACL") diff --git a/tests/drop_packets/test_drop_counters.py b/tests/drop_packets/test_drop_counters.py index c1835fb8e89..ff12f8ee865 100755 --- a/tests/drop_packets/test_drop_counters.py +++ b/tests/drop_packets/test_drop_counters.py @@ -22,7 +22,6 @@ test_acl_egress_drop # noqa F401 from tests.common.helpers.constants import DEFAULT_NAMESPACE from tests.common.fixtures.conn_graph_facts import enum_fanout_graph_facts # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 pytestmark = [ pytest.mark.topology("any") @@ -141,8 +140,7 @@ def handle_backend_acl(duthost, tbinfo): def base_verification(discard_group, pkt, ptfadapter, duthosts, asic_index, ports_info, # noqa F811 - tx_dut_ports=None, skip_counter_check=False, drop_information=None, # noqa F811 - skip_traffic_test=False): # noqa F811 + tx_dut_ports=None, skip_counter_check=False, drop_information=None): # noqa F811 """ Base test function for verification of L2 or L3 packet drops. Verification type depends on 'discard_group' value. Supported 'discard_group' values: 'L2', 'L3', 'ACL', 'NO_DROPS' @@ -162,9 +160,6 @@ def base_verification(discard_group, pkt, ptfadapter, duthosts, asic_index, port if skip_counter_check: logger.info("Skipping counter check") return None - if skip_traffic_test is True: - logger.info("Skipping traffic test") - return None if discard_group == "L2": verify_drop_counters(duthosts, asic_index, ports_info["dut_iface"], @@ -297,8 +292,7 @@ def check_if_skip(): @pytest.fixture(scope='module') def do_test(duthosts): def do_counters_test(discard_group, pkt, ptfadapter, ports_info, sniff_ports, tx_dut_ports=None, # noqa F811 - comparable_pkt=None, skip_counter_check=False, drop_information=None, ip_ver='ipv4', - skip_traffic_test=False): # noqa F811 + comparable_pkt=None, skip_counter_check=False, drop_information=None, ip_ver='ipv4'): """ Execute test - send packet, check that expected discard counters were incremented and packet was dropped @param discard_group: Supported 'discard_group' values: 'L2', 'L3', 'ACL', 'NO_DROPS' @@ -310,24 +304,24 @@ def do_counters_test(discard_group, pkt, ptfadapter, ports_info, sniff_ports, tx @param ip_ver: A string, ipv4 or ipv6 """ check_if_skip() + asic_type = duthosts[0].facts["asic_type"] + if asic_type == "vs": + skip_counter_check = True + asic_index = ports_info["asic_index"] base_verification(discard_group, pkt, ptfadapter, duthosts, asic_index, ports_info, tx_dut_ports, - skip_counter_check=skip_counter_check, drop_information=drop_information, - skip_traffic_test=skip_traffic_test) + skip_counter_check=skip_counter_check, drop_information=drop_information) # Verify packets were not egresed the DUT if discard_group != "NO_DROPS": exp_pkt = expected_packet_mask(pkt, ip_ver=ip_ver) - if skip_traffic_test is True: - logger.info("Skipping traffic test") - return testutils.verify_no_packet_any(ptfadapter, exp_pkt, ports=sniff_ports) return do_counters_test def test_reserved_dmac_drop(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - setup, fanouthost, pkt_fields, ports_info, skip_traffic_test): # noqa F811 + setup, fanouthost, pkt_fields, ports_info): # noqa F811 """ @summary: Verify that packet with reserved DMAC is dropped and L2 drop counter incremented @used_mac_address: @@ -361,12 +355,11 @@ def test_reserved_dmac_drop(do_test, ptfadapter, duthosts, enum_rand_one_per_hws ) group = "L2" - do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - skip_traffic_test=skip_traffic_test) + do_test(group, pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"]) -def test_no_egress_drop_on_down_link(do_test, ptfadapter, setup, tx_dut_ports, # noqa F811 - pkt_fields, rif_port_down, ports_info, skip_traffic_test): # noqa F811 +def test_no_egress_drop_on_down_link(do_test, ptfadapter, setup, tx_dut_ports, # noqa F811 + pkt_fields, rif_port_down, ports_info): # noqa F811 """ @summary: Verify that packets on ingress port are not dropped when egress RIF link is down and check that drop counters not incremented @@ -384,12 +377,11 @@ def test_no_egress_drop_on_down_link(do_test, ptfadapter, setup, tx_dut_ports, tcp_dport=pkt_fields["tcp_dport"] ) - do_test("NO_DROPS", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test("NO_DROPS", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) def test_src_ip_link_local(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - setup, tx_dut_ports, pkt_fields, ports_info, skip_traffic_test): # noqa F811 + setup, tx_dut_ports, pkt_fields, ports_info): # noqa F811 """ @summary: Verify that packet with link-local address "169.254.0.0/16" is dropped and L3 drop counter incremented """ @@ -412,12 +404,11 @@ def test_src_ip_link_local(do_test, ptfadapter, duthosts, enum_rand_one_per_hwsk pkt = testutils.simple_tcp_packet(**pkt_params) logger.info(pkt_params) - do_test("L3", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - tx_dut_ports, skip_traffic_test=skip_traffic_test) + do_test("L3", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], tx_dut_ports) def test_ip_pkt_with_exceeded_mtu(do_test, ptfadapter, setup, tx_dut_ports, # noqa F811 - pkt_fields, mtu_config, ports_info, skip_traffic_test): # noqa F811 + pkt_fields, mtu_config, ports_info): # noqa F811 """ @summary: Verify that IP packet with exceeded MTU is dropped and L3 drop counter incremented """ @@ -447,7 +438,6 @@ def test_ip_pkt_with_exceeded_mtu(do_test, ptfadapter, setup, tx_dut_ports, ) L2_COL_KEY = RX_ERR try: - do_test("L2", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"], - skip_traffic_test=skip_traffic_test) + do_test("L2", pkt, ptfadapter, ports_info, setup["neighbor_sniff_ports"]) finally: L2_COL_KEY = RX_DRP From 1cc1b8157fc39f66452f6e781e4619e507ea7fdc Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:32:27 +0800 Subject: [PATCH 105/221] Remove skip_traffic_test fixture in decap tests (#15429) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in decap tests How did you verify/test it? --- tests/decap/test_decap.py | 7 +------ tests/decap/test_subnet_decap.py | 15 +++++---------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/tests/decap/test_decap.py b/tests/decap/test_decap.py index 9464ce15a5b..41264bb894a 100644 --- a/tests/decap/test_decap.py +++ b/tests/decap/test_decap.py @@ -21,7 +21,6 @@ from tests.common.fixtures.ptfhost_utils import remove_ip_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 from tests.common.fixtures.ptfhost_utils import set_ptf_port_mapping_mode # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.fixtures.ptfhost_utils import ptf_test_port_map_active_active from tests.common.fixtures.fib_utils import fib_info_files # noqa F401 from tests.common.fixtures.fib_utils import single_fib_for_duts # noqa F401 @@ -193,8 +192,7 @@ def simulate_vxlan_teardown(duthosts, ptfhost, tbinfo): def test_decap(tbinfo, duthosts, ptfhost, setup_teardown, mux_server_url, # noqa F811 toggle_all_simulator_ports_to_random_side, supported_ttl_dscp_params, ip_ver, loopback_ips, # noqa F811 - duts_running_config_facts, duts_minigraph_facts, mux_status_from_nic_simulator, # noqa F811 - skip_traffic_test): # noqa F811 + duts_running_config_facts, duts_minigraph_facts, mux_status_from_nic_simulator): # noqa F811 setup_info = setup_teardown asic_type = duthosts[0].facts["asic_type"] ecn_mode = "copy_from_outer" @@ -214,9 +212,6 @@ def test_decap(tbinfo, duthosts, ptfhost, setup_teardown, mux_server_url, else: apply_decap_cfg(duthosts, ip_ver, loopback_ips, ttl_mode, dscp_mode, ecn_mode, 'SET') - if skip_traffic_test: - return - if 'dualtor' in tbinfo['topo']['name']: wait(30, 'Wait some time for mux active/standby state to be stable after toggled mux state') diff --git a/tests/decap/test_subnet_decap.py b/tests/decap/test_subnet_decap.py index bed66fbe68a..7c2b48486b6 100644 --- a/tests/decap/test_subnet_decap.py +++ b/tests/decap/test_subnet_decap.py @@ -9,7 +9,6 @@ import ptf.testutils as testutils from ptf.mask import Mask from tests.common.dualtor.dual_tor_utils import rand_selected_interface # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py # noqa F401 from tests.common.config_reload import config_reload @@ -192,23 +191,20 @@ def build_expected_vlan_subnet_packet(encapsulated_packet, ip_version, stage, de def verify_packet_with_expected(ptfadapter, stage, pkt, exp_pkt, send_port, - recv_ports=[], recv_port=None, timeout=10, skip_traffic_test=False): # noqa F811 - if skip_traffic_test is True: - logger.info("Skip traffic test") - return + recv_ports=[], recv_port=None, timeout=10): # noqa F811 ptfadapter.dataplane.flush() testutils.send(ptfadapter, send_port, pkt) if stage == "positive": - testutils.verify_packet_any_port(ptfadapter, exp_pkt, recv_ports, timeout=10) + testutils.verify_packet_any_port(ptfadapter, exp_pkt, recv_ports, timeout=timeout) elif stage == "negative": - testutils.verify_packet(ptfadapter, exp_pkt, recv_port, timeout=10) + testutils.verify_packet(ptfadapter, exp_pkt, recv_port, timeout=timeout) @pytest.mark.parametrize("ip_version", ["IPv4", "IPv6"]) @pytest.mark.parametrize("stage", ["positive", "negative"]) def test_vlan_subnet_decap(request, rand_selected_dut, tbinfo, ptfhost, ptfadapter, ip_version, stage, prepare_subnet_decap_config, prepare_vlan_subnet_test_port, - prepare_negative_ip_port_map, setup_arp_responder, skip_traffic_test): # noqa F811 + prepare_negative_ip_port_map, setup_arp_responder): # noqa F811 ptf_src_port, _, upstream_port_ids = prepare_vlan_subnet_test_port encapsulated_packet = build_encapsulated_vlan_subnet_packet(ptfadapter, rand_selected_dut, ip_version, stage) @@ -221,5 +217,4 @@ def test_vlan_subnet_decap(request, rand_selected_dut, tbinfo, ptfhost, ptfadapt ptf_target_port = None verify_packet_with_expected(ptfadapter, stage, encapsulated_packet, exp_pkt, - ptf_src_port, recv_ports=upstream_port_ids, recv_port=ptf_target_port, - skip_traffic_test=skip_traffic_test) + ptf_src_port, recv_ports=upstream_port_ids, recv_port=ptf_target_port) From 27f029656b5349ab299a2735c647548c8f597693 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:32:53 +0800 Subject: [PATCH 106/221] Remove skip_traffic_test fixture in copp tests (#15428) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in copp tests --- tests/copp/test_copp.py | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/tests/copp/test_copp.py b/tests/copp/test_copp.py index d96526e2c59..324a3e6679e 100644 --- a/tests/copp/test_copp.py +++ b/tests/copp/test_copp.py @@ -41,7 +41,6 @@ # Module-level fixtures from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 pytestmark = [ pytest.mark.topology("t0", "t1", "t2", "m0", "mx") @@ -84,7 +83,7 @@ class TestCOPP(object): "LLDP", "UDLD"]) def test_policer(self, protocol, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfhost, copp_testbed, dut_type, skip_traffic_test): # noqa F811 + ptfhost, copp_testbed, dut_type): """ Validates that rate-limited COPP groups work as expected. @@ -96,13 +95,11 @@ def test_policer(self, protocol, duthosts, enum_rand_one_per_hwsku_frontend_host ptfhost, protocol, copp_testbed, - dut_type, - skip_traffic_test=skip_traffic_test) + dut_type) @pytest.mark.disable_loganalyzer def test_add_new_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfhost, check_image_version, copp_testbed, dut_type, backup_restore_config_db, - skip_traffic_test): # noqa F811 + ptfhost, check_image_version, copp_testbed, dut_type, backup_restore_config_db): """ Validates that one new trap(bgp) can be installed @@ -125,16 +122,14 @@ def test_add_new_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, self.trap_id.upper(), copp_testbed, dut_type, - has_trap=False, - skip_traffic_test=skip_traffic_test) + has_trap=False) logger.info("Set always_enabled of {} to true".format(self.trap_id)) copp_utils.configure_always_enabled_for_trap(duthost, self.trap_id, "true") logger.info("Verify {} trap status is installed by sending traffic".format(self.trap_id)) pytest_assert( - wait_until(60, 20, 0, _copp_runner, duthost, ptfhost, self.trap_id.upper(), copp_testbed, dut_type, - skip_traffic_test=skip_traffic_test), + wait_until(60, 20, 0, _copp_runner, duthost, ptfhost, self.trap_id.upper(), copp_testbed, dut_type), "Installing {} trap fail".format(self.trap_id)) @pytest.mark.disable_loganalyzer @@ -142,7 +137,7 @@ def test_add_new_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, "disable_feature_status"]) def test_remove_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, check_image_version, copp_testbed, dut_type, - backup_restore_config_db, remove_trap_type, skip_traffic_test): # noqa F811 + backup_restore_config_db, remove_trap_type): """ Validates that The trap(bgp) can be uninstalled after deleting the corresponding entry from the feature table @@ -160,7 +155,7 @@ def test_remove_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, copp_utils.uninstall_trap(duthost, "ip2me", "ip2me") logger.info("Pre condition: make trap {} is installed".format(self.feature_name)) - pre_condition_install_trap(ptfhost, duthost, copp_testbed, self.trap_id, self.feature_name, skip_traffic_test) + pre_condition_install_trap(ptfhost, duthost, copp_testbed, self.trap_id, self.feature_name) if remove_trap_type == "delete_feature_entry": logger.info("Remove feature entry: {}".format(self.feature_name)) @@ -172,13 +167,13 @@ def test_remove_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, logger.info("Verify {} trap status is uninstalled by sending traffic".format(self.trap_id)) pytest_assert( wait_until(100, 20, 0, _copp_runner, duthost, ptfhost, self.trap_id.upper(), - copp_testbed, dut_type, has_trap=False, skip_traffic_test=skip_traffic_test), + copp_testbed, dut_type, has_trap=False), "uninstalling {} trap fail".format(self.trap_id)) @pytest.mark.disable_loganalyzer def test_trap_config_save_after_reboot(self, duthosts, localhost, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, check_image_version, copp_testbed, dut_type, - backup_restore_config_db, request, skip_traffic_test): # noqa F811 + backup_restore_config_db, request): # noqa F811 """ Validates that the trap configuration is saved or not after reboot(reboot, fast-reboot, warm-reboot) @@ -207,8 +202,7 @@ def test_trap_config_save_after_reboot(self, duthosts, localhost, enum_rand_one_ copp_utils.verify_always_enable_value(duthost, self.trap_id, "true") logger.info("Verify {} trap status is installed by sending traffic".format(self.trap_id)) pytest_assert( - wait_until(200, 20, 0, _copp_runner, duthost, ptfhost, self.trap_id.upper(), copp_testbed, dut_type, - skip_traffic_test=skip_traffic_test), + wait_until(200, 20, 0, _copp_runner, duthost, ptfhost, self.trap_id.upper(), copp_testbed, dut_type), "Installing {} trap fail".format(self.trap_id)) @@ -279,7 +273,7 @@ def ignore_expected_loganalyzer_exceptions(enum_rand_one_per_hwsku_frontend_host loganalyzer[enum_rand_one_per_hwsku_frontend_hostname].ignore_regex.extend(ignoreRegex) -def _copp_runner(dut, ptf, protocol, test_params, dut_type, has_trap=True, skip_traffic_test=False): # noqa F811 +def _copp_runner(dut, ptf, protocol, test_params, dut_type, has_trap=True): """ Configures and runs the PTF test cases. """ @@ -299,9 +293,6 @@ def _copp_runner(dut, ptf, protocol, test_params, dut_type, has_trap=True, skip_ device_sockets = ["0-{}@tcp://127.0.0.1:10900".format(test_params.nn_target_port), "1-{}@tcp://{}:10900".format(test_params.nn_target_port, dut_ip)] - if skip_traffic_test is True: - logger.info("Skipping traffic test.") - return True # NOTE: debug_level can actually slow the PTF down enough to fail the test cases # that are not rate limited. Until this is addressed, do not use this flag as part of # nightly test runs. @@ -497,15 +488,14 @@ def backup_restore_config_db(duthosts, enum_rand_one_per_hwsku_frontend_hostname copp_utils.restore_config_db(duthost) -def pre_condition_install_trap(ptfhost, duthost, copp_testbed, trap_id, feature_name, skip_traffic_test): # noqa F811 +def pre_condition_install_trap(ptfhost, duthost, copp_testbed, trap_id, feature_name): # noqa F811 copp_utils.install_trap(duthost, feature_name) logger.info("Set always_enabled of {} to false".format(trap_id)) copp_utils.configure_always_enabled_for_trap(duthost, trap_id, "false") logger.info("Verify {} trap status is installed by sending traffic in pre_condition".format(trap_id)) pytest_assert( - wait_until(100, 20, 0, _copp_runner, duthost, ptfhost, trap_id.upper(), copp_testbed, dut_type, - skip_traffic_test=skip_traffic_test), + wait_until(100, 20, 0, _copp_runner, duthost, ptfhost, trap_id.upper(), copp_testbed, dut_type), "Installing {} trap fail".format(trap_id)) From 1b583ae39483e2f17c0c478fd2ff517bc77b38d4 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:33:16 +0800 Subject: [PATCH 107/221] Remove skip_traffic_test fixture in arp tests (#15427) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in arp tests How did you verify/test it? --- tests/arp/test_stress_arp.py | 13 ++++++------- tests/arp/test_unknown_mac.py | 12 +++++------- tests/arp/test_wr_arp.py | 10 ++++------ tests/common/arp_utils.py | 5 ++--- tests/vxlan/test_vnet_vxlan.py | 9 ++------- 5 files changed, 19 insertions(+), 30 deletions(-) diff --git a/tests/arp/test_stress_arp.py b/tests/arp/test_stress_arp.py index 9461448a4ce..c6dcd250261 100644 --- a/tests/arp/test_stress_arp.py +++ b/tests/arp/test_stress_arp.py @@ -9,7 +9,6 @@ in6_getnsma, inet_pton, inet_ntop, socket from ipaddress import ip_address, ip_network from tests.common.utilities import wait_until, increment_ipv6_addr -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.errors import RunAnsibleModuleFail ARP_BASE_IP = "172.16.0.1/16" @@ -86,7 +85,7 @@ def genrate_ipv4_ip(): def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, - ptfadapter, get_function_completeness_level, skip_traffic_test): # noqa F811 + ptfadapter, get_function_completeness_level): """ Send gratuitous ARP (GARP) packet sfrom the PTF to the DUT @@ -95,7 +94,7 @@ def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, normalized_level = get_function_completeness_level if normalized_level is None: normalized_level = "debug" - + asic_type = duthost.facts['asic_type'] ipv4_avaliable = get_crm_resources(duthost, "ipv4_neighbor", "available") fdb_avaliable = get_crm_resources(duthost, "fdb_entry", "available") pytest_assert(ipv4_avaliable > 0 and fdb_avaliable > 0, "Entries have been filled") @@ -113,7 +112,7 @@ def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, loop_times -= 1 try: add_arp(ptf_intf_ipv4_hosts, intf1_index, ptfadapter) - if not skip_traffic_test: + if asic_type != 'vs': # There is a certain probability of hash collision, we set the percentage as 1% here # The entries we add will not exceed 10000, so the number we tolerate is 100 logger.debug("Expected route number: {}, real route number {}" @@ -175,7 +174,7 @@ def add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_avaliable): def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, - ptfadapter, get_function_completeness_level, proxy_arp_enabled, skip_traffic_test): # noqa F811 + ptfadapter, get_function_completeness_level, proxy_arp_enabled): _, _, ptf_intf_ipv6_addr, _, ptf_intf_index = ip_and_intf_info ptf_intf_ipv6_addr = increment_ipv6_addr(ptf_intf_ipv6_addr) pytest_require(proxy_arp_enabled, 'Proxy ARP not enabled for all VLANs') @@ -184,7 +183,7 @@ def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, normalized_level = get_function_completeness_level if normalized_level is None: normalized_level = "debug" - + asic_type = duthost.facts['asic_type'] loop_times = LOOP_TIMES_LEVEL_MAP[normalized_level] ipv6_avaliable = get_crm_resources(duthost, "ipv6_neighbor", "available") fdb_avaliable = get_crm_resources(duthost, "fdb_entry", "available") @@ -196,7 +195,7 @@ def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, loop_times -= 1 try: add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_avaliable) - if not skip_traffic_test: + if asic_type != 'vs': # There is a certain probability of hash collision, we set the percentage as 1% here # The entries we add will not exceed 10000, so the number we tolerate is 100 logger.debug("Expected route number: {}, real route number {}" diff --git a/tests/arp/test_unknown_mac.py b/tests/arp/test_unknown_mac.py index 109addaa32a..99d53249265 100644 --- a/tests/arp/test_unknown_mac.py +++ b/tests/arp/test_unknown_mac.py @@ -14,7 +14,6 @@ from tests.common import constants from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.helpers.assertions import pytest_assert, pytest_require from tests.common.dualtor.dual_tor_utils import mux_cable_server_ip from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor_m # noqa F401 @@ -260,7 +259,7 @@ class TrafficSendVerify(object): """ Send traffic and check interface counters and ptf ports """ @initClassVars def __init__(self, duthost, ptfadapter, dst_ip, ptf_dst_port, ptf_vlan_ports, - intfs, ptf_ports, arp_entry, dscp, skip_traffic_test): # noqa F811 + intfs, ptf_ports, arp_entry, dscp): # noqa F811 """ Args: duthost(AnsibleHost) : dut instance @@ -278,7 +277,6 @@ def __init__(self, duthost, ptfadapter, dst_ip, ptf_dst_port, ptf_vlan_ports, self.pkt_map = dict() self.pre_rx_drops = dict() self.dut_mac = duthost.facts['router_mac'] - self.skip_traffic_test = skip_traffic_test def _constructPacket(self): """ @@ -361,7 +359,8 @@ def runTest(self): self._constructPacket() logger.info("Clear all counters before test run") self.duthost.command("sonic-clear counters") - if not self.skip_traffic_test: + asic_type = self.duthost.facts["asic_type"] + if asic_type != "vs": time.sleep(1) logger.info("Collect drop counters before test run") self._verifyIntfCounters(pretest=True) @@ -378,7 +377,7 @@ def runTest(self): class TestUnknownMac(object): @pytest.mark.parametrize("dscp", ["dscp-3", "dscp-4", "dscp-8"]) - def test_unknown_mac(self, unknownMacSetup, dscp, duthosts, rand_one_dut_hostname, ptfadapter, skip_traffic_test): # noqa F811 + def test_unknown_mac(self, unknownMacSetup, dscp, duthosts, rand_one_dut_hostname, ptfadapter): """ Verify unknown mac behavior for lossless and lossy priority @@ -404,7 +403,6 @@ def test_unknown_mac(self, unknownMacSetup, dscp, duthosts, rand_one_dut_hostnam self.ptf_vlan_ports = setup['ptf_vlan_ports'] self.intfs = setup['intfs'] self.ptf_ports = setup['ptf_ports'] - self.skip_traffic_test = skip_traffic_test self.validateEntries() self.run() @@ -422,5 +420,5 @@ def run(self): thandle = TrafficSendVerify(self.duthost, self.ptfadapter, self.dst_ip, self.ptf_dst_port, self.ptf_vlan_ports, self.intfs, self.ptf_ports, - self.arp_entry, self.dscp, self.skip_traffic_test) + self.arp_entry, self.dscp) thandle.runTest() diff --git a/tests/arp/test_wr_arp.py b/tests/arp/test_wr_arp.py index 92dd027220d..edc163d8ad3 100644 --- a/tests/arp/test_wr_arp.py +++ b/tests/arp/test_wr_arp.py @@ -4,7 +4,6 @@ from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import remove_ip_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.storage_backend.backend_utils import skip_test_module_over_backend_topologies # noqa F401 from tests.ptf_runner import ptf_runner from tests.common.utilities import wait_until @@ -68,7 +67,7 @@ def warmRebootSystemFlag(duthost): duthost.shell(cmd='sonic-db-cli STATE_DB hset "WARM_RESTART_ENABLE_TABLE|system" enable false') -def test_wr_arp(request, duthost, ptfhost, creds, skip_traffic_test): # noqa F811 +def test_wr_arp(request, duthost, ptfhost, creds): ''' Control Plane Assistant test for Warm-Reboot. @@ -85,10 +84,10 @@ def test_wr_arp(request, duthost, ptfhost, creds, skip_traffic_test): # noqa F Returns: None ''' - testWrArp(request, duthost, ptfhost, creds, skip_traffic_test) + testWrArp(request, duthost, ptfhost, creds) -def test_wr_arp_advance(request, duthost, ptfhost, creds, skip_traffic_test): # noqa F811 +def test_wr_arp_advance(request, duthost, ptfhost, creds): testDuration = request.config.getoption('--test_duration', default=DEFAULT_TEST_DURATION) ptfIp = ptfhost.host.options['inventory_manager'].get_host(ptfhost.hostname).vars['ansible_host'] dutIp = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] @@ -96,8 +95,7 @@ def test_wr_arp_advance(request, duthost, ptfhost, creds, skip_traffic_test): logger.info('Warm-Reboot Control-Plane assist feature') sonicadmin_alt_password = duthost.host.options['variable_manager'].\ _hostvars[duthost.hostname]['sonic_default_passwords'] - if skip_traffic_test is True: - return + ptf_runner( ptfhost, 'ptftests', diff --git a/tests/common/arp_utils.py b/tests/common/arp_utils.py index 280819ae413..05186267f84 100644 --- a/tests/common/arp_utils.py +++ b/tests/common/arp_utils.py @@ -179,7 +179,7 @@ def tear_down(duthost, route, ptfIp, gwIp): teardownRouteToPtfhost(duthost, route, ptfIp, gwIp) -def testWrArp(request, duthost, ptfhost, creds, skip_traffic_test): +def testWrArp(request, duthost, ptfhost, creds): testDuration = request.config.getoption('--test_duration', default=DEFAULT_TEST_DURATION) ptfIp = ptfhost.host.options['inventory_manager'].get_host(ptfhost.hostname).vars['ansible_host'] dutIp = duthost.host.options['inventory_manager'].get_host(duthost.hostname).vars['ansible_host'] @@ -187,8 +187,7 @@ def testWrArp(request, duthost, ptfhost, creds, skip_traffic_test): logger.info('Warm-Reboot Control-Plane assist feature') sonicadmin_alt_password = duthost.host.options['variable_manager']. \ _hostvars[duthost.hostname]['sonic_default_passwords'] - if skip_traffic_test is True: - return + ptf_runner( ptfhost, 'ptftests', diff --git a/tests/vxlan/test_vnet_vxlan.py b/tests/vxlan/test_vnet_vxlan.py index 41413003f9c..108b4283b70 100644 --- a/tests/vxlan/test_vnet_vxlan.py +++ b/tests/vxlan/test_vnet_vxlan.py @@ -15,8 +15,6 @@ from tests.common.flow_counter.flow_counter_utils import RouteFlowCounterTestContext, is_route_flow_counter_supported # noqa F401 from tests.common.arp_utils import set_up, tear_down, testWrArp -from tests.common.fixtures.ptfhost_utils import skip_traffic_test - from tests.common.config_reload import config_reload logger = logging.getLogger(__name__) @@ -159,7 +157,7 @@ def vxlan_status(setup, request, duthosts, rand_one_dut_hostname, elif request.param == "WR_ARP": route, ptfIp, gwIp = set_up(duthost, ptfhost, tbinfo) try: - testWrArp(request, duthost, ptfhost, creds, skip_traffic_test) + testWrArp(request, duthost, ptfhost, creds) finally: tear_down(duthost, route, ptfIp, gwIp) @@ -190,7 +188,7 @@ def is_neigh_reachable(duthost, vnet_config): def test_vnet_vxlan(setup, vxlan_status, duthosts, rand_one_dut_hostname, ptfhost, - vnet_test_params, creds, is_route_flow_counter_supported, skip_traffic_test): # noqa F811 + vnet_test_params, creds, is_route_flow_counter_supported): # noqa F811 """ Test case for VNET VxLAN @@ -229,9 +227,6 @@ def test_vnet_vxlan(setup, vxlan_status, duthosts, rand_one_dut_hostname, ptfhos logger.info("Skipping cleanup") pytest.skip("Skip cleanup specified") - if skip_traffic_test is True: - logger.info("Skipping traffic test") - return logger.debug("Starting PTF runner") if scenario == 'Enabled' and vxlan_enabled: route_pattern = 'Vnet1|100.1.1.1/32' From 4467b33a479d4da6afebbb9b1ca0cdf4f8d6c72e Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:33:43 +0800 Subject: [PATCH 108/221] Remove skip_traffic_test fixture in dualtor tests (#15392) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test in dualtor testcases How did you verify/test it? Any platform specific information? --- tests/common/dualtor/data_plane_utils.py | 44 ++++---- tests/common/dualtor/dual_tor_utils.py | 29 ++--- tests/common/dualtor/server_traffic_utils.py | 10 +- tests/common/dualtor/tunnel_traffic_utils.py | 6 +- tests/dualtor/test_ipinip.py | 16 +-- .../test_orchagent_active_tor_downstream.py | 23 ++-- tests/dualtor/test_orchagent_mac_move.py | 24 ++-- tests/dualtor/test_orchagent_slb.py | 23 ++-- .../test_orchagent_standby_tor_downstream.py | 24 ++-- .../test_standby_tor_upstream_mux_toggle.py | 13 +-- tests/dualtor/test_tor_ecn.py | 32 +++--- tests/dualtor/test_tunnel_memory_leak.py | 12 +- tests/dualtor_io/test_heartbeat_failure.py | 35 +++--- tests/dualtor_io/test_link_drop.py | 38 +++---- tests/dualtor_io/test_link_failure.py | 67 +++++------- tests/dualtor_io/test_normal_op.py | 103 ++++++------------ tests/dualtor_io/test_tor_bgp_failure.py | 29 ++--- tests/dualtor_mgmt/test_ingress_drop.py | 8 +- 18 files changed, 210 insertions(+), 326 deletions(-) diff --git a/tests/common/dualtor/data_plane_utils.py b/tests/common/dualtor/data_plane_utils.py index cb15313a9e7..febaa97d841 100644 --- a/tests/common/dualtor/data_plane_utils.py +++ b/tests/common/dualtor/data_plane_utils.py @@ -241,7 +241,7 @@ def save_pcap(request, pytestconfig): @pytest.fixture def send_t1_to_server_with_action(duthosts, ptfhost, ptfadapter, tbinfo, - cable_type, vmhost, save_pcap, skip_traffic_test=False): # noqa F811 + cable_type, vmhost, save_pcap): # noqa F811 """ Starts IO test from T1 router to server. As part of IO test the background thread sends and sniffs packets. @@ -263,8 +263,7 @@ def send_t1_to_server_with_action(duthosts, ptfhost, ptfadapter, tbinfo, def t1_to_server_io_test(activehost, tor_vlan_port=None, delay=0, allowed_disruption=0, action=None, verify=False, send_interval=0.1, - stop_after=None, allow_disruption_before_traffic=False, - skip_traffic_test=False): + stop_after=None, allow_disruption_before_traffic=False): """ Helper method for `send_t1_to_server_with_action`. Starts sender and sniffer before performing the action on the tor host. @@ -299,9 +298,6 @@ def t1_to_server_io_test(activehost, tor_vlan_port=None, if delay and not allowed_disruption: allowed_disruption = 1 - if skip_traffic_test is True: - logging.info("Skipping traffic test") - return return verify_and_report(tor_IO, verify, delay, allowed_disruption, allow_disruption_before_traffic) yield t1_to_server_io_test @@ -311,7 +307,7 @@ def t1_to_server_io_test(activehost, tor_vlan_port=None, @pytest.fixture def send_server_to_t1_with_action(duthosts, ptfhost, ptfadapter, tbinfo, - cable_type, vmhost, save_pcap, skip_traffic_test=False): # noqa F811 + cable_type, vmhost, save_pcap): # noqa F811 """ Starts IO test from server to T1 router. As part of IO test the background thread sends and sniffs packets. @@ -334,7 +330,7 @@ def send_server_to_t1_with_action(duthosts, ptfhost, ptfadapter, tbinfo, def server_to_t1_io_test(activehost, tor_vlan_port=None, delay=0, allowed_disruption=0, action=None, verify=False, send_interval=0.01, - stop_after=None, skip_traffic_test=False): + stop_after=None): """ Helper method for `send_server_to_t1_with_action`. Starts sender and sniffer before performing the action on the tor host. @@ -368,8 +364,9 @@ def server_to_t1_io_test(activehost, tor_vlan_port=None, if delay and not allowed_disruption: allowed_disruption = 1 - if skip_traffic_test is True: - logging.info("Skipping traffic test") + asic_type = duthosts[0].facts["asic_type"] + if asic_type == "vs": + logging.info("Skipping verify on VS platform") return return verify_and_report(tor_IO, verify, delay, allowed_disruption) @@ -380,13 +377,13 @@ def server_to_t1_io_test(activehost, tor_vlan_port=None, @pytest.fixture def send_soc_to_t1_with_action(duthosts, ptfhost, ptfadapter, tbinfo, - cable_type, vmhost, save_pcap, skip_traffic_test=False): # noqa F811 + cable_type, vmhost, save_pcap): # noqa F811 arp_setup(ptfhost) def soc_to_t1_io_test(activehost, tor_vlan_port=None, delay=0, allowed_disruption=0, action=None, verify=False, send_interval=0.01, - stop_after=None, skip_traffic_test=False): + stop_after=None): tor_IO = run_test(duthosts, activehost, ptfhost, ptfadapter, vmhost, action, tbinfo, tor_vlan_port, send_interval, @@ -396,8 +393,9 @@ def soc_to_t1_io_test(activehost, tor_vlan_port=None, if delay and not allowed_disruption: allowed_disruption = 1 - if skip_traffic_test is True: - logging.info("Skipping traffic test") + asic_type = duthosts[0].facts["asic_type"] + if asic_type == "vs": + logging.info("Skipping verify on VS platform") return return verify_and_report(tor_IO, verify, delay, allowed_disruption) @@ -408,13 +406,13 @@ def soc_to_t1_io_test(activehost, tor_vlan_port=None, @pytest.fixture def send_t1_to_soc_with_action(duthosts, ptfhost, ptfadapter, tbinfo, - cable_type, vmhost, save_pcap, skip_traffic_test=False): # noqa F811 + cable_type, vmhost, save_pcap): # noqa F811 arp_setup(ptfhost) def t1_to_soc_io_test(activehost, tor_vlan_port=None, delay=0, allowed_disruption=0, action=None, verify=False, send_interval=0.01, - stop_after=None, skip_traffic_test=False): + stop_after=None): tor_IO = run_test(duthosts, activehost, ptfhost, ptfadapter, vmhost, action, tbinfo, tor_vlan_port, send_interval, @@ -426,8 +424,9 @@ def t1_to_soc_io_test(activehost, tor_vlan_port=None, if delay and not allowed_disruption: allowed_disruption = 1 - if skip_traffic_test is True: - logging.info("Skipping traffic test") + asic_type = duthosts[0].facts["asic_type"] + if asic_type == "vs": + logging.info("Skipping verify on VS platform") return return verify_and_report(tor_IO, verify, delay, allowed_disruption) @@ -454,13 +453,13 @@ def _select_test_mux_ports(cable_type, count): @pytest.fixture def send_server_to_server_with_action(duthosts, ptfhost, ptfadapter, tbinfo, - cable_type, vmhost, save_pcap, skip_traffic_test=False): # noqa F811 + cable_type, vmhost, save_pcap): # noqa F811 arp_setup(ptfhost) def server_to_server_io_test(activehost, test_mux_ports, delay=0, allowed_disruption=0, action=None, - verify=False, send_interval=0.01, stop_after=None, skip_traffic_test=False): + verify=False, send_interval=0.01, stop_after=None): tor_IO = run_test(duthosts, activehost, ptfhost, ptfadapter, vmhost, action, tbinfo, test_mux_ports, send_interval, traffic_direction="server_to_server", stop_after=stop_after, @@ -471,8 +470,9 @@ def server_to_server_io_test(activehost, test_mux_ports, delay=0, if delay and not allowed_disruption: allowed_disruption = 1 - if skip_traffic_test is True: - logging.info("Skipping traffic test") + asic_type = duthosts[0].facts["asic_type"] + if asic_type == "vs": + logging.info("Skipping verify on VS platform") return return verify_and_report(tor_IO, verify, delay, allowed_disruption) diff --git a/tests/common/dualtor/dual_tor_utils.py b/tests/common/dualtor/dual_tor_utils.py index bb028a1144c..ee76923be5d 100644 --- a/tests/common/dualtor/dual_tor_utils.py +++ b/tests/common/dualtor/dual_tor_utils.py @@ -883,7 +883,7 @@ def mux_cable_server_ip(dut): def check_tunnel_balance(ptfhost, standby_tor_mac, vlan_mac, active_tor_ip, standby_tor_ip, selected_port, target_server_ip, target_server_ipv6, target_server_port, ptf_portchannel_indices, - completeness_level, check_ipv6=False, skip_traffic_test=False): + completeness_level, check_ipv6=False): """ Function for testing traffic distribution among all avtive T1. A test script will be running on ptf to generate traffic to standby interface, and the traffic will be forwarded to @@ -901,9 +901,6 @@ def check_tunnel_balance(ptfhost, standby_tor_mac, vlan_mac, active_tor_ip, Returns: None. """ - if skip_traffic_test is True: - logging.info("Skip checking tunnel balance due to traffic test was skipped") - return HASH_KEYS = ["src-port", "dst-port", "src-ip"] params = { "server_ip": target_server_ip, @@ -1158,7 +1155,7 @@ def check_nexthops_balance(rand_selected_dut, ptfadapter, dst_server_addr, pc)) -def check_nexthops_single_uplink(portchannel_ports, port_packet_count, expect_packet_num, skip_traffic_test=False): +def check_nexthops_single_uplink(portchannel_ports, port_packet_count, expect_packet_num): for pc, intfs in portchannel_ports.items(): count = 0 # Collect the packets count within a single portchannel @@ -1167,16 +1164,14 @@ def check_nexthops_single_uplink(portchannel_ports, port_packet_count, expect_pa count = count + port_packet_count.get(uplink_int, 0) logging.info("Packets received on portchannel {}: {}".format(pc, count)) - if skip_traffic_test is True: - logging.info("Skip checking single uplink balance due to traffic test was skipped") - continue if count > 0 and count != expect_packet_num: pytest.fail("Packets not sent up single standby port {}".format(pc)) # verify nexthops are only sent to single active or standby mux def check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_addr, - tbinfo, downlink_ints, skip_traffic_test=False): + tbinfo, downlink_ints): + asic_type = rand_selected_dut.facts["asic_type"] HASH_KEYS = ["src-port", "dst-port", "src-ip"] expect_packet_num = 1000 expect_packet_num_high = expect_packet_num * (0.90) @@ -1191,9 +1186,7 @@ def check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_add port_packet_count = dict() packets_to_send = generate_hashed_packet_to_server(ptfadapter, rand_selected_dut, HASH_KEYS, dst_server_addr, expect_packet_num) - if skip_traffic_test is True: - logging.info("Skip checking single downlink balance due to traffic test was skipped") - return + for send_packet, exp_pkt, exp_tunnel_pkt in packets_to_send: testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), send_packet, count=1) # expect multi-mux nexthops to focus packets to one downlink @@ -1204,6 +1197,10 @@ def check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_add for ptf_idx, pkt_count in ptf_port_count.items(): port_packet_count[ptf_idx] = port_packet_count.get(ptf_idx, 0) + pkt_count + if asic_type == "vs": + logging.info("Skipping validation on VS platform") + return + logging.info("Received packets in ports: {}".format(str(port_packet_count))) for downlink_int in expected_downlink_ports: # packets should be either 0 or expect_packet_num: @@ -1215,11 +1212,11 @@ def check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_add if len(downlink_ints) == 0: # All nexthops are now connected to standby mux, and the packets will be sent towards a single portchanel int # Check if uplink distribution is towards a single portchannel - check_nexthops_single_uplink(portchannel_ports, port_packet_count, expect_packet_num, skip_traffic_test) + check_nexthops_single_uplink(portchannel_ports, port_packet_count, expect_packet_num) def verify_upstream_traffic(host, ptfadapter, tbinfo, itfs, server_ip, - pkt_num=100, drop=False, skip_traffic_test=False): + pkt_num=100, drop=False): """ @summary: Helper function for verifying upstream packets @param host: The dut host @@ -1272,9 +1269,7 @@ def verify_upstream_traffic(host, ptfadapter, tbinfo, itfs, server_ip, logger.info("Verifying upstream traffic. packet number = {} interface = {} \ server_ip = {} expect_drop = {}".format(pkt_num, itfs, server_ip, drop)) - if skip_traffic_test is True: - logger.info("Skip verifying upstream traffic due to traffic test was skipped") - return + for i in range(0, pkt_num): ptfadapter.dataplane.flush() testutils.send(ptfadapter, tx_port, pkt, count=1) diff --git a/tests/common/dualtor/server_traffic_utils.py b/tests/common/dualtor/server_traffic_utils.py index 33e0293b3ce..a0be517354d 100644 --- a/tests/common/dualtor/server_traffic_utils.py +++ b/tests/common/dualtor/server_traffic_utils.py @@ -56,8 +56,7 @@ class ServerTrafficMonitor(object): VLAN_INTERFACE_TEMPLATE = "{external_port}.{vlan_id}" def __init__(self, duthost, ptfhost, vmhost, tbinfo, dut_iface, - conn_graph_facts, exp_pkt, existing=True, is_mocked=False, - skip_traffic_test=False): + conn_graph_facts, exp_pkt, existing=True, is_mocked=False): """ @summary: Initialize the monitor. @@ -82,7 +81,7 @@ def __init__(self, duthost, ptfhost, vmhost, tbinfo, dut_iface, self.conn_graph_facts = conn_graph_facts self.captured_packets = [] self.matched_packets = [] - self.skip_traffic_test = skip_traffic_test + if is_mocked: mg_facts = self.duthost.get_extended_minigraph_facts(self.tbinfo) ptf_iface = "eth%s" % mg_facts['minigraph_ptf_indices'][self.dut_iface] @@ -128,8 +127,9 @@ def __exit__(self, exc_type, exc_value, traceback): logging.info("the expected packet:\n%s", str(self.exp_pkt)) self.matched_packets = [p for p in self.captured_packets if match_exp_pkt(self.exp_pkt, p)] logging.info("received %d matched packets", len(self.matched_packets)) - if self.skip_traffic_test is True: - logging.info("Skip matched_packets verify due to traffic test was skipped.") + asic_type = self.duthost.facts["asic_type"] + if asic_type == "vs": + logging.info("Skipping matched_packets verify on VS platform.") return if self.matched_packets: logging.info( diff --git a/tests/common/dualtor/tunnel_traffic_utils.py b/tests/common/dualtor/tunnel_traffic_utils.py index 14b4f7786e4..059ca8ad703 100644 --- a/tests/common/dualtor/tunnel_traffic_utils.py +++ b/tests/common/dualtor/tunnel_traffic_utils.py @@ -250,7 +250,7 @@ def _disassemble_ip_tos(tos): return " ,".join(check_res) def __init__(self, standby_tor, active_tor=None, existing=True, inner_packet=None, - check_items=("ttl", "tos", "queue"), packet_count=10, skip_traffic_test=False): + check_items=("ttl", "tos", "queue"), packet_count=10): """ Init the tunnel traffic monitor. @@ -262,7 +262,6 @@ def __init__(self, standby_tor, active_tor=None, existing=True, inner_packet=Non self.listen_ports = sorted(self._get_t1_ptf_port_indexes(standby_tor, tbinfo)) self.ptfadapter = ptfadapter self.packet_count = packet_count - self.skip_traffic_test = skip_traffic_test standby_tor_cfg_facts = self.standby_tor.config_facts( host=self.standby_tor.hostname, source="running" @@ -293,9 +292,6 @@ def __enter__(self): def __exit__(self, *exc_info): if exc_info[0]: return - if self.skip_traffic_test is True: - logging.info("Skip tunnel traffic verify due to traffic test was skipped.") - return try: result = testutils.verify_packet_any_port( ptfadapter, diff --git a/tests/dualtor/test_ipinip.py b/tests/dualtor/test_ipinip.py index d5e0b15476b..33d62946d75 100644 --- a/tests/dualtor/test_ipinip.py +++ b/tests/dualtor/test_ipinip.py @@ -28,7 +28,6 @@ from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 from tests.common.fixtures.ptfhost_utils import run_garp_service # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.utilities import dump_scapy_packet_show_output from tests.common.dualtor.dual_tor_utils import config_active_active_dualtor_active_standby # noqa F401 from tests.common.dualtor.dual_tor_utils import validate_active_active_dualtor_setup # noqa F401 @@ -105,7 +104,7 @@ def build_expected_packet_to_server(encapsulated_packet, decrease_ttl=False): def test_decap_active_tor( build_encapsulated_packet, request, ptfhost, rand_selected_interface, ptfadapter, # noqa F401 - tbinfo, rand_selected_dut, tunnel_traffic_monitor, skip_traffic_test): # noqa F811 + tbinfo, rand_selected_dut, tunnel_traffic_monitor): # noqa F811 @contextlib.contextmanager def stop_garp(ptfhost): @@ -129,9 +128,6 @@ def stop_garp(ptfhost): ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send encapsulated packet from ptf t1 interface %s", ptf_t1_intf) - if skip_traffic_test is True: - logging.info("Skip following traffic test") - return with stop_garp(ptfhost): ptfadapter.dataplane.flush() testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), encapsulated_packet) @@ -141,7 +137,7 @@ def stop_garp(ptfhost): def test_decap_standby_tor( build_encapsulated_packet, request, rand_selected_interface, ptfadapter, # noqa F401 - tbinfo, rand_selected_dut, tunnel_traffic_monitor, skip_traffic_test # noqa F401 + tbinfo, rand_selected_dut, tunnel_traffic_monitor # noqa F401 ): def verify_downstream_packet_to_server(ptfadapter, port, exp_pkt): @@ -170,9 +166,6 @@ def verify_downstream_packet_to_server(ptfadapter, port, exp_pkt): ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send encapsulated packet from ptf t1 interface %s", ptf_t1_intf) - if skip_traffic_test is True: - logging.info("Skip following traffic test") - return with tunnel_traffic_monitor(tor, existing=False): testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), encapsulated_packet, count=10) time.sleep(2) @@ -302,7 +295,7 @@ def setup_active_active_ports(active_active_ports, rand_selected_dut, rand_unsel def test_encap_with_mirror_session(rand_selected_dut, rand_selected_interface, # noqa F811 ptfadapter, tbinfo, setup_mirror_session, toggle_all_simulator_ports_to_rand_unselected_tor, # noqa F811 - tunnel_traffic_monitor, skip_traffic_test, # noqa F811 + tunnel_traffic_monitor, # noqa F811 setup_standby_ports_on_rand_selected_tor): # noqa F811 """ A test case to verify the bounced back packet from Standby ToR to T1 doesn't have an unexpected vlan id (4095) @@ -321,8 +314,5 @@ def test_encap_with_mirror_session(rand_selected_dut, rand_selected_interface, logging.info("Sending packet from ptf t1 interface {}".format(src_port_id)) inner_packet = pkt_to_server[scapy.all.IP].copy() inner_packet[IP].ttl -= 1 - if skip_traffic_test is True: - logging.info("Skip following traffic test") - return with tunnel_traffic_monitor(rand_selected_dut, inner_packet=inner_packet, check_items=()): testutils.send(ptfadapter, src_port_id, pkt_to_server) diff --git a/tests/dualtor/test_orchagent_active_tor_downstream.py b/tests/dualtor/test_orchagent_active_tor_downstream.py index 45d3506eaf8..ddb6854a34a 100644 --- a/tests/dualtor/test_orchagent_active_tor_downstream.py +++ b/tests/dualtor/test_orchagent_active_tor_downstream.py @@ -5,7 +5,6 @@ from ipaddress import ip_address from ptf import testutils -from tests.common.dualtor.dual_tor_mock import * # noqa F403 from tests.common.dualtor.dual_tor_utils import dualtor_info from tests.common.dualtor.dual_tor_utils import flush_neighbor from tests.common.dualtor.dual_tor_utils import get_t1_ptf_ports @@ -15,13 +14,13 @@ from tests.common.dualtor.dual_tor_utils import check_nexthops_single_downlink from tests.common.dualtor.dual_tor_utils import add_nexthop_routes, remove_static_routes from tests.common.dualtor.dual_tor_mock import set_mux_state +from tests.common.dualtor.dual_tor_mock import is_mocked_dualtor from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports # noqa F401 from tests.common.dualtor.server_traffic_utils import ServerTrafficMonitor from tests.common.dualtor.tunnel_traffic_utils import tunnel_traffic_monitor # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 from tests.common.fixtures.ptfhost_utils import run_garp_service # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until @@ -68,7 +67,7 @@ def neighbor_reachable(duthost, neighbor_ip): def test_active_tor_remove_neighbor_downstream_active( conn_graph_facts, ptfadapter, ptfhost, testbed_setup, rand_selected_dut, tbinfo, set_crm_polling_interval, - tunnel_traffic_monitor, vmhost, skip_traffic_test # noqa F811 + tunnel_traffic_monitor, vmhost # noqa F811 ): """ @Verify those two scenarios: @@ -103,9 +102,9 @@ def remove_neighbor(ptfhost, duthost, server_ip, ip_version, neighbor_details): logging.info("send traffic to server %s from ptf t1 interface %s", server_ip, ptf_t1_intf) server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=True, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=True, is_mocked=is_mocked_dualtor(tbinfo) ) - tunnel_monitor = tunnel_traffic_monitor(tor, existing=False, skip_traffic_test=skip_traffic_test) + tunnel_monitor = tunnel_traffic_monitor(tor, existing=False) with crm_neighbor_checker(tor, ip_version, expect_change=ip_version == "ipv6"), \ tunnel_monitor, server_traffic_monitor: testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), pkt, count=10) @@ -113,7 +112,7 @@ def remove_neighbor(ptfhost, duthost, server_ip, ip_version, neighbor_details): logging.info("send traffic to server %s after removing neighbor entry", server_ip) server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=False, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=False, is_mocked=is_mocked_dualtor(tbinfo) ) remove_neighbor_ct = remove_neighbor(ptfhost, tor, server_ip, ip_version, removed_neighbor) with crm_neighbor_checker(tor, ip_version, expect_change=ip_version == "ipv6"), \ @@ -126,7 +125,7 @@ def remove_neighbor(ptfhost, duthost, server_ip, ip_version, neighbor_details): logging.info("send traffic to server %s after neighbor entry is restored", server_ip) server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=True, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=True, is_mocked=is_mocked_dualtor(tbinfo) ) with crm_neighbor_checker(tor, ip_version, expect_change=ip_version == "ipv6"), \ tunnel_monitor, server_traffic_monitor: @@ -146,10 +145,10 @@ def remove_neighbor(ptfhost, duthost, server_ip, ip_version, neighbor_details): def test_downstream_ecmp_nexthops( ptfadapter, rand_selected_dut, tbinfo, - toggle_all_simulator_ports, tor_mux_intfs, ip_version, skip_traffic_test # noqa F811 + toggle_all_simulator_ports, tor_mux_intfs, ip_version # noqa F811 ): nexthops_count = 4 - set_mux_state(rand_selected_dut, tbinfo, 'active', tor_mux_intfs, toggle_all_simulator_ports) # noqa F405 + set_mux_state(rand_selected_dut, tbinfo, 'active', tor_mux_intfs, toggle_all_simulator_ports) iface_server_map = get_interface_server_map(rand_selected_dut, nexthops_count) if ip_version == "ipv4": @@ -172,7 +171,7 @@ def test_downstream_ecmp_nexthops( try: logging.info("Verify traffic to this route destination is sent to single downlink or uplink") check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_addr, - tbinfo, nexthop_interfaces, skip_traffic_test) + tbinfo, nexthop_interfaces) nexthop_interfaces_copy = nexthop_interfaces.copy() @@ -183,7 +182,7 @@ def test_downstream_ecmp_nexthops( nexthop_interfaces_copy.remove(interface) logging.info("Verify traffic to this route destination is sent to single downlink or uplink") check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_addr, - tbinfo, nexthop_interfaces_copy, skip_traffic_test) + tbinfo, nexthop_interfaces_copy) # Revert two mux states to active for index, interface in reversed(list(enumerate(nexthop_interfaces))): @@ -192,7 +191,7 @@ def test_downstream_ecmp_nexthops( nexthop_interfaces_copy.append(interface) logging.info("Verify traffic to this route destination is sent to single downlink or uplink") check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_addr, - tbinfo, nexthop_interfaces_copy, skip_traffic_test) + tbinfo, nexthop_interfaces_copy) finally: # Remove the nexthop route remove_static_routes(rand_selected_dut, dst_server_addr) diff --git a/tests/dualtor/test_orchagent_mac_move.py b/tests/dualtor/test_orchagent_mac_move.py index 7aa0a25e39d..93c18c4d14b 100644 --- a/tests/dualtor/test_orchagent_mac_move.py +++ b/tests/dualtor/test_orchagent_mac_move.py @@ -3,7 +3,8 @@ import random from ptf import testutils -from tests.common.dualtor.dual_tor_mock import * # noqa F403 +from tests.common.dualtor.dual_tor_mock import is_mocked_dualtor +from tests.common.dualtor.dual_tor_mock import set_dual_tor_state_to_orchagent from tests.common.dualtor.dual_tor_utils import get_t1_ptf_ports from tests.common.dualtor.dual_tor_utils import crm_neighbor_checker from tests.common.dualtor.dual_tor_utils import build_packet_to_server @@ -13,7 +14,6 @@ from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 from tests.common.fixtures.ptfhost_utils import run_garp_service # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.utilities import dump_scapy_packet_show_output @@ -85,7 +85,7 @@ def test_mac_move( announce_new_neighbor, apply_active_state_to_orchagent, conn_graph_facts, ptfadapter, ptfhost, rand_selected_dut, set_crm_polling_interval, - tbinfo, tunnel_traffic_monitor, vmhost, skip_traffic_test # noqa F811 + tbinfo, tunnel_traffic_monitor, vmhost # noqa F811 ): tor = rand_selected_dut ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) @@ -96,23 +96,23 @@ def test_mac_move( announce_new_neighbor.send(None) logging.info("let new neighbor learnt on active port %s", test_port) pkt, exp_pkt = build_packet_to_server(tor, ptfadapter, NEW_NEIGHBOR_IPV4_ADDR) - tunnel_monitor = tunnel_traffic_monitor(tor, existing=False, skip_traffic_test=skip_traffic_test) + tunnel_monitor = tunnel_traffic_monitor(tor, existing=False) server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=True, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=True, is_mocked=is_mocked_dualtor(tbinfo) ) with crm_neighbor_checker(tor), tunnel_monitor, server_traffic_monitor: testutils.send(ptfadapter, ptf_t1_intf_index, pkt, count=10) # mac move to a standby port test_port = next(announce_new_neighbor) - announce_new_neighbor.send(lambda iface: set_dual_tor_state_to_orchagent(tor, "standby", [iface])) # noqa F405 + announce_new_neighbor.send(lambda iface: set_dual_tor_state_to_orchagent(tor, "standby", [iface])) logging.info("mac move to a standby port %s", test_port) pkt, exp_pkt = build_packet_to_server(tor, ptfadapter, NEW_NEIGHBOR_IPV4_ADDR) - tunnel_monitor = tunnel_traffic_monitor(tor, existing=True, skip_traffic_test=skip_traffic_test) + tunnel_monitor = tunnel_traffic_monitor(tor, existing=True) server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=False, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=False, is_mocked=is_mocked_dualtor(tbinfo) ) with crm_neighbor_checker(tor), tunnel_monitor, server_traffic_monitor: testutils.send(ptfadapter, ptf_t1_intf_index, pkt, count=10) @@ -121,7 +121,7 @@ def test_mac_move( tor.shell("fdbclear") server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=False, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=False, is_mocked=is_mocked_dualtor(tbinfo) ) with crm_neighbor_checker(tor), tunnel_monitor, server_traffic_monitor: testutils.send(ptfadapter, ptf_t1_intf_index, pkt, count=10) @@ -131,10 +131,10 @@ def test_mac_move( announce_new_neighbor.send(None) logging.info("mac move to another active port %s", test_port) pkt, exp_pkt = build_packet_to_server(tor, ptfadapter, NEW_NEIGHBOR_IPV4_ADDR) - tunnel_monitor = tunnel_traffic_monitor(tor, existing=False, skip_traffic_test=skip_traffic_test) + tunnel_monitor = tunnel_traffic_monitor(tor, existing=False) server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=True, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=True, is_mocked=is_mocked_dualtor(tbinfo) ) with crm_neighbor_checker(tor), tunnel_monitor, server_traffic_monitor: testutils.send(ptfadapter, ptf_t1_intf_index, pkt, count=10) @@ -145,7 +145,7 @@ def test_mac_move( tor.shell("fdbclear") server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_port, conn_graph_facts, exp_pkt, - existing=False, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test # noqa F405 + existing=False, is_mocked=is_mocked_dualtor(tbinfo) ) with crm_neighbor_checker(tor), tunnel_monitor, server_traffic_monitor: testutils.send(ptfadapter, ptf_t1_intf_index, pkt, count=10) diff --git a/tests/dualtor/test_orchagent_slb.py b/tests/dualtor/test_orchagent_slb.py index 4b0aeb89627..19e88996746 100644 --- a/tests/dualtor/test_orchagent_slb.py +++ b/tests/dualtor/test_orchagent_slb.py @@ -2,7 +2,6 @@ import pytest import random import time -import logging import scapy.all as scapyall from ptf import testutils @@ -20,7 +19,6 @@ from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.helpers import bgp from tests.common.utilities import is_ipv4_address @@ -217,7 +215,7 @@ def test_orchagent_slb( force_active_tor, upper_tor_host, lower_tor_host, # noqa F811 ptfadapter, ptfhost, setup_interfaces, toggle_all_simulator_ports_to_upper_tor, tbinfo, # noqa F811 - tunnel_traffic_monitor, vmhost, skip_traffic_test # noqa F811 + tunnel_traffic_monitor, vmhost # noqa F811 ): def verify_bgp_session(duthost, bgp_neighbor): @@ -235,11 +233,8 @@ def verify_route(duthost, route, existing=True): else: assert len(existing_route["nexthops"]) == 0 - def verify_traffic(duthost, connection, route, is_duthost_active=True, is_route_existed=True, - skip_traffic_test=skip_traffic_test): - if skip_traffic_test is True: - logging.info("Skip traffic test.") - return + def verify_traffic(duthost, connection, route, is_duthost_active=True, is_route_existed=True): + prefix = ipaddress.ip_network(route["prefix"]) dst_host = str(next(prefix.hosts())) pkt, exp_pkt = build_packet_to_server(duthost, ptfadapter, dst_host) @@ -295,11 +290,11 @@ def verify_traffic(duthost, connection, route, is_duthost_active=True, is_route_ # STEP 3: verify the route by sending some downstream traffic verify_traffic( upper_tor_host, connections["upper_tor"], constants.route, - is_duthost_active=True, is_route_existed=True, skip_traffic_test=skip_traffic_test + is_duthost_active=True, is_route_existed=True ) verify_traffic( lower_tor_host, connections["lower_tor"], constants.route, - is_duthost_active=False, is_route_existed=True, skip_traffic_test=skip_traffic_test + is_duthost_active=False, is_route_existed=True ) # STEP 4: withdraw the announced route to both ToRs @@ -314,11 +309,11 @@ def verify_traffic(duthost, connection, route, is_duthost_active=True, is_route_ # STEP 5: verify the route is removed by verifying that downstream traffic is dropped verify_traffic( upper_tor_host, connections["upper_tor"], constants.route, - is_duthost_active=True, is_route_existed=False, skip_traffic_test=skip_traffic_test + is_duthost_active=True, is_route_existed=False ) verify_traffic( lower_tor_host, connections["lower_tor"], constants.route, - is_duthost_active=False, is_route_existed=False, skip_traffic_test=skip_traffic_test + is_duthost_active=False, is_route_existed=False ) # STEP 6: toggle mux state change @@ -341,11 +336,11 @@ def verify_traffic(duthost, connection, route, is_duthost_active=True, is_route_ # STEP 8: verify the route by sending some downstream traffic verify_traffic( upper_tor_host, connections["upper_tor"], constants.route, - is_duthost_active=False, is_route_existed=True, skip_traffic_test=skip_traffic_test + is_duthost_active=False, is_route_existed=True ) verify_traffic( lower_tor_host, connections["lower_tor"], constants.route, - is_duthost_active=True, is_route_existed=True, skip_traffic_test=skip_traffic_test + is_duthost_active=True, is_route_existed=True ) # STEP 9: verify teardown diff --git a/tests/dualtor/test_orchagent_standby_tor_downstream.py b/tests/dualtor/test_orchagent_standby_tor_downstream.py index 1d26d74187b..b59e6f4cc1b 100644 --- a/tests/dualtor/test_orchagent_standby_tor_downstream.py +++ b/tests/dualtor/test_orchagent_standby_tor_downstream.py @@ -19,7 +19,6 @@ from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import run_garp_service # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.helpers.assertions import pytest_assert as pt_assert from tests.common.dualtor.tunnel_traffic_utils import tunnel_traffic_monitor # noqa F401 from tests.common.dualtor.server_traffic_utils import ServerTrafficMonitor @@ -62,13 +61,12 @@ def get_function_completeness_level(pytestconfig): @pytest.fixture def get_testbed_params(ptfhost, rand_selected_dut, rand_unselected_dut, tbinfo, - ip_version, setup_testbed_ipv6, get_function_completeness_level, skip_traffic_test): # noqa F811 + ip_version, setup_testbed_ipv6, get_function_completeness_level): # noqa F811 """Return a function to get testbed params.""" def _get_testbed_params(): params = dualtor_info(ptfhost, rand_selected_dut, rand_unselected_dut, tbinfo, get_function_completeness_level) params["check_ipv6"] = (ip_version == "ipv6") - params["skip_traffic_test"] = skip_traffic_test return params return _get_testbed_params @@ -275,8 +273,7 @@ def test_standby_tor_remove_neighbor_downstream_standby( conn_graph_facts, ptfadapter, ptfhost, rand_selected_dut, rand_unselected_dut, tbinfo, set_crm_polling_interval, tunnel_traffic_monitor, # noqa: F811 - vmhost, get_testbed_params, - ip_version, skip_traffic_test # noqa: F811 + vmhost, get_testbed_params, ip_version ): """ @summary: Verify that after removing neighbor entry for a server over standby @@ -307,7 +304,7 @@ def stop_neighbor_advertiser(ptfhost, ip_version): pkt, exp_pkt = build_packet_to_server(tor, ptfadapter, target_server) ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send traffic to server %s from ptf t1 interface %s", target_server, ptf_t1_intf) - tunnel_monitor = tunnel_traffic_monitor(tor, existing=True, skip_traffic_test=skip_traffic_test) + tunnel_monitor = tunnel_traffic_monitor(tor, existing=True) with tunnel_monitor: testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), pkt, count=10) @@ -315,7 +312,7 @@ def stop_neighbor_advertiser(ptfhost, ip_version): tunnel_monitor.existing = False server_traffic_monitor = ServerTrafficMonitor( tor, ptfhost, vmhost, tbinfo, test_params["selected_port"], conn_graph_facts, exp_pkt, - existing=False, is_mocked=is_mocked_dualtor(tbinfo), skip_traffic_test=skip_traffic_test + existing=False, is_mocked=is_mocked_dualtor(tbinfo) ) # for real dualtor testbed, leave the neighbor restoration to garp service flush_neighbor_ct = flush_neighbor(tor, target_server, restore=is_t0_mocked_dualtor) @@ -334,7 +331,7 @@ def test_downstream_standby_mux_toggle_active( rand_selected_dut, rand_unselected_dut, tbinfo, tunnel_traffic_monitor, vmhost, # noqa: F811 toggle_all_simulator_ports, tor_mux_intfs, # noqa: F811 - ip_version, get_testbed_params, skip_traffic_test # noqa: F811 + ip_version, get_testbed_params ): # set rand_selected_dut as standby and rand_unselected_dut to active tor test_params = get_testbed_params() @@ -349,9 +346,8 @@ def test_downstream_standby_mux_toggle_active( ptf_t1_intf = random.choice(get_t1_ptf_ports(rand_selected_dut, tbinfo)) def monitor_tunnel_and_server_traffic(torhost, expect_tunnel_traffic=True, - expect_server_traffic=True, skip_traffic_test=False): - if skip_traffic_test is True: - return + expect_server_traffic=True): + tunnel_monitor = tunnel_traffic_monitor(rand_selected_dut, existing=True) server_traffic_monitor = ServerTrafficMonitor( torhost, ptfhost, vmhost, tbinfo, test_params["selected_port"], @@ -370,7 +366,7 @@ def monitor_tunnel_and_server_traffic(torhost, expect_tunnel_traffic=True, logger.info("Step 1.2: Verify traffic to this route dst is forwarded to Active ToR and equally distributed") check_tunnel_balance(**test_params) monitor_tunnel_and_server_traffic(rand_selected_dut, expect_server_traffic=False, - expect_tunnel_traffic=True, skip_traffic_test=skip_traffic_test) + expect_tunnel_traffic=True) logger.info("Stage 2: Verify Active Forwarding") logger.info("Step 2.1: Simulate Mux state change to active") @@ -378,7 +374,7 @@ def monitor_tunnel_and_server_traffic(torhost, expect_tunnel_traffic=True, time.sleep(30) logger.info("Step 2.2: Verify traffic to this route dst is forwarded directly to server") monitor_tunnel_and_server_traffic(rand_selected_dut, expect_server_traffic=True, - expect_tunnel_traffic=False, skip_traffic_test=skip_traffic_test) + expect_tunnel_traffic=False) logger.info("Stage 3: Verify Standby Forwarding Again") logger.info("Step 3.1: Simulate Mux state change to standby") @@ -387,7 +383,7 @@ def monitor_tunnel_and_server_traffic(torhost, expect_tunnel_traffic=True, logger.info("Step 3.2: Verify traffic to this route dst \ is now redirected back to Active ToR and equally distributed") monitor_tunnel_and_server_traffic(rand_selected_dut, expect_server_traffic=False, - expect_tunnel_traffic=True, skip_traffic_test=skip_traffic_test) + expect_tunnel_traffic=True) check_tunnel_balance(**test_params) remove_static_routes(rand_selected_dut, random_dst_ip) diff --git a/tests/dualtor/test_standby_tor_upstream_mux_toggle.py b/tests/dualtor/test_standby_tor_upstream_mux_toggle.py index e7765412292..99ff89f88b6 100644 --- a/tests/dualtor/test_standby_tor_upstream_mux_toggle.py +++ b/tests/dualtor/test_standby_tor_upstream_mux_toggle.py @@ -10,7 +10,7 @@ from tests.common.config_reload import config_reload from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses, run_garp_service, \ - run_icmp_responder, skip_traffic_test # noqa F401 + run_icmp_responder # noqa F401 logger = logging.getLogger(__file__) @@ -34,7 +34,7 @@ def test_cleanup(rand_selected_dut): def test_standby_tor_upstream_mux_toggle( rand_selected_dut, tbinfo, ptfadapter, rand_selected_interface, # noqa F811 - toggle_all_simulator_ports, set_crm_polling_interval, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports, set_crm_polling_interval): # noqa F811 itfs, ip = rand_selected_interface PKT_NUM = 100 # Step 1. Set mux state to standby and verify traffic is dropped by ACL rule and drop counters incremented @@ -49,8 +49,7 @@ def test_standby_tor_upstream_mux_toggle( itfs=itfs, server_ip=ip['server_ipv4'].split('/')[0], pkt_num=PKT_NUM, - drop=True, - skip_traffic_test=skip_traffic_test) + drop=True) time.sleep(5) # Step 2. Toggle mux state to active, and verify traffic is not dropped by ACL and fwd-ed to uplinks; @@ -65,8 +64,7 @@ def test_standby_tor_upstream_mux_toggle( itfs=itfs, server_ip=ip['server_ipv4'].split('/')[0], pkt_num=PKT_NUM, - drop=False, - skip_traffic_test=skip_traffic_test) + drop=False) # Step 3. Toggle mux state to standby, and verify traffic is dropped by ACL; # verify CRM show and no nexthop objects are stale @@ -80,8 +78,7 @@ def test_standby_tor_upstream_mux_toggle( itfs=itfs, server_ip=ip['server_ipv4'].split('/')[0], pkt_num=PKT_NUM, - drop=True, - skip_traffic_test=skip_traffic_test) + drop=True) crm_facts1 = rand_selected_dut.get_crm_facts() unmatched_crm_facts = compare_crm_facts(crm_facts0, crm_facts1) pt_assert(len(unmatched_crm_facts) == 0, 'Unmatched CRM facts: {}' diff --git a/tests/dualtor/test_tor_ecn.py b/tests/dualtor/test_tor_ecn.py index 5e965dde253..07e5aafc710 100644 --- a/tests/dualtor/test_tor_ecn.py +++ b/tests/dualtor/test_tor_ecn.py @@ -28,7 +28,6 @@ from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 from tests.common.fixtures.ptfhost_utils import run_garp_service # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.utilities import dump_scapy_packet_show_output from tests.common.dualtor.tunnel_traffic_utils import derive_queue_id_from_dscp, derive_out_dscp_from_inner_dscp from tests.common.dualtor.dual_tor_utils import config_active_active_dualtor_active_standby # noqa F401 @@ -254,7 +253,12 @@ def verify_ecn_on_received_packet( """ Verify ECN value on the received packet w.r.t expected packet """ - _, rec_pkt = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[exp_ptf_port_index], timeout=10) + result = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[exp_ptf_port_index], timeout=10) + if isinstance(result, tuple): + _, rec_pkt = result + elif isinstance(result, bool): + logging.info("Using dummy testutils to skip traffic test, skip following verify steps.") + return rec_pkt = Ether(rec_pkt) logging.info("received packet:\n%s", dump_scapy_packet_show_output(rec_pkt)) @@ -276,7 +280,7 @@ def test_dscp_to_queue_during_decap_on_active( inner_dscp, ptfhost, setup_dualtor_tor_active, request, rand_selected_interface, ptfadapter, # noqa F811 tbinfo, rand_selected_dut, tunnel_traffic_monitor, # noqa F811 - duthosts, rand_one_dut_hostname, skip_traffic_test # noqa F811 + duthosts, rand_one_dut_hostname ): """ Test if DSCP to Q mapping for inner header is matching with outer header during decap on active @@ -296,9 +300,6 @@ def test_dscp_to_queue_during_decap_on_active( duthost.shell('sonic-clear queuecounters') logging.info("Clearing queue counters before starting traffic") - if skip_traffic_test is True: - logging.info("Skip following test due traffic test skipped") - return with stop_garp(ptfhost): ptfadapter.dataplane.flush() ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) @@ -309,7 +310,12 @@ def test_dscp_to_queue_during_decap_on_active( exp_dscp = exp_tos >> 2 exp_queue = derive_queue_id_from_dscp(duthost, exp_dscp, False) - _, rec_pkt = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[exp_ptf_port_index], timeout=10) + result = testutils.verify_packet_any_port(ptfadapter, exp_pkt, ports=[exp_ptf_port_index], timeout=10) + if isinstance(result, tuple): + _, rec_pkt = result + elif isinstance(result, bool): + logging.info("Using dummy testutils to skip traffic test, skip following verify steps.") + return rec_pkt = Ether(rec_pkt) logging.info("received decap packet:\n%s", dump_scapy_packet_show_output(rec_pkt)) @@ -351,7 +357,6 @@ def test_dscp_to_queue_during_encap_on_standby( rand_one_dut_hostname, write_standby, setup_standby_ports_on_rand_selected_tor, # noqa F811 - skip_traffic_test # noqa F811 ): """ Test if DSCP to Q mapping for outer header is matching with inner header during encap on standby @@ -372,9 +377,6 @@ def test_dscp_to_queue_during_encap_on_standby( ptfadapter.dataplane.flush() ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send IP packet from ptf t1 interface %s", ptf_t1_intf) - if skip_traffic_test is True: - logging.info("Skip following test due traffic test skipped") - return with tunnel_traffic_monitor(tor, existing=True, packet_count=PACKET_NUM): testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), non_encapsulated_packet, count=PACKET_NUM) @@ -384,7 +386,6 @@ def test_ecn_during_decap_on_active( inner_dscp, ptfhost, setup_dualtor_tor_active, request, rand_selected_interface, ptfadapter, # noqa F811 tbinfo, rand_selected_dut, tunnel_traffic_monitor, # noqa F811 - skip_traffic_test # noqa F811 ): """ Test if the ECN stamping on inner header is matching with outer during decap on active @@ -405,9 +406,6 @@ def test_ecn_during_decap_on_active( exp_tos = encapsulated_packet[IP].payload[IP].tos exp_ecn = exp_tos & 3 - if skip_traffic_test is True: - logging.info("Skip following test due traffic test skipped") - return with stop_garp(ptfhost): tor.shell("portstat -c") tor.shell("show arp") @@ -425,7 +423,6 @@ def test_ecn_during_encap_on_standby( tbinfo, rand_selected_dut, tunnel_traffic_monitor, # noqa F811 write_standby, setup_standby_ports_on_rand_selected_tor, # noqa F811 - skip_traffic_test # noqa F811 ): """ Test if the ECN stamping on outer header is matching with inner during encap on standby @@ -440,8 +437,5 @@ def test_ecn_during_encap_on_standby( ptf_t1_intf = random.choice(get_t1_ptf_ports(tor, tbinfo)) logging.info("send IP packet from ptf t1 interface %s", ptf_t1_intf) - if skip_traffic_test is True: - logging.info("Skip following test due traffic test skipped") - return with tunnel_traffic_monitor(tor, existing=True, packet_count=PACKET_NUM): testutils.send(ptfadapter, int(ptf_t1_intf.strip("eth")), non_encapsulated_packet, count=PACKET_NUM) diff --git a/tests/dualtor/test_tunnel_memory_leak.py b/tests/dualtor/test_tunnel_memory_leak.py index dbb46638433..357554cc00a 100644 --- a/tests/dualtor/test_tunnel_memory_leak.py +++ b/tests/dualtor/test_tunnel_memory_leak.py @@ -22,7 +22,6 @@ from tests.common.dualtor.dual_tor_utils import delete_neighbor from tests.common.helpers.dut_utils import get_program_info from tests.common.fixtures.ptfhost_utils import run_garp_service, run_icmp_responder # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.utilities import wait_until @@ -118,8 +117,7 @@ def _check_memory(duthost): def test_tunnel_memory_leak(toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - ptfhost, ptfadapter, conn_graph_facts, tbinfo, vmhost, run_arp_responder, # noqa F811 - skip_traffic_test): # noqa F811 + ptfhost, ptfadapter, conn_graph_facts, tbinfo, vmhost, run_arp_responder): # noqa F811 """ Test if there is memory leak for service tunnel_packet_handler. Send ip packets from standby TOR T1 to Server, standby TOR will @@ -155,6 +153,7 @@ def prepare_services(ptfhost): all_servers_ips = mux_cable_server_ip(upper_tor_host) unexpected_count = 0 expected_count = 0 + asic_type = upper_tor_host.facts["asic_type"] with prepare_services(ptfhost): # Delete the neighbors @@ -173,9 +172,10 @@ def prepare_services(ptfhost): pkt, exp_pkt = build_packet_to_server(lower_tor_host, ptfadapter, server_ipv4) - if skip_traffic_test is True: - logging.info("Skip traffic test.") - continue + if asic_type == "vs": + logging.info("ServerTrafficMonitor do not support on KVM dualtor, skip following steps.") + return + server_traffic_monitor = ServerTrafficMonitor( upper_tor_host, ptfhost, vmhost, tbinfo, iface, conn_graph_facts, exp_pkt, existing=True, is_mocked=False diff --git a/tests/dualtor_io/test_heartbeat_failure.py b/tests/dualtor_io/test_heartbeat_failure.py index 49afb7994ad..eddcf71e51b 100644 --- a/tests/dualtor_io/test_heartbeat_failure.py +++ b/tests/dualtor_io/test_heartbeat_failure.py @@ -1,5 +1,4 @@ import pytest -import logging from tests.common.dualtor.control_plane_utils import verify_tor_states from tests.common.dualtor.data_plane_utils import send_t1_to_server_with_action, \ @@ -10,7 +9,6 @@ from tests.common.dualtor.tor_failure_utils import shutdown_tor_heartbeat # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder, run_garp_service, \ copy_ptftests_directory, change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.dualtor.constants import MUX_SIM_ALLOWED_DISRUPTION_SEC from tests.common.dualtor.dual_tor_common import cable_type # noqa F401 from tests.common.dualtor.dual_tor_common import CableType @@ -36,18 +34,16 @@ def ignore_expected_loganalyzer_exception(loganalyzer, duthosts): def test_active_tor_heartbeat_failure_upstream( - toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - send_server_to_t1_with_action, shutdown_tor_heartbeat, cable_type, skip_traffic_test # noqa F811 + toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 + send_server_to_t1_with_action, shutdown_tor_heartbeat, cable_type # noqa F811 ): """ Send upstream traffic and stop the LinkProber module on the active ToR. Confirm switchover and disruption lasts < 1 second. """ - logging.info("skip_traffic_test: {}".format(skip_traffic_test)) send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: shutdown_tor_heartbeat(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_tor_heartbeat(upper_tor_host) ) if cable_type == CableType.active_standby: @@ -68,7 +64,7 @@ def test_active_tor_heartbeat_failure_upstream( @pytest.mark.enable_active_active def test_active_tor_heartbeat_failure_downstream_active( toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - send_t1_to_server_with_action, shutdown_tor_heartbeat, cable_type, skip_traffic_test # noqa F811 + send_t1_to_server_with_action, shutdown_tor_heartbeat, cable_type # noqa F811 ): """ Send downstream traffic from T1 to the active ToR and stop the LinkProber module on the active ToR. @@ -76,8 +72,7 @@ def test_active_tor_heartbeat_failure_downstream_active( """ send_t1_to_server_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: shutdown_tor_heartbeat(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_tor_heartbeat(upper_tor_host) ) if cable_type == CableType.active_standby: @@ -97,15 +92,14 @@ def test_active_tor_heartbeat_failure_downstream_active( def test_active_tor_heartbeat_failure_downstream_standby( toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - send_t1_to_server_with_action, shutdown_tor_heartbeat, skip_traffic_test): # noqa F811 + send_t1_to_server_with_action, shutdown_tor_heartbeat): # noqa F811 """ Send downstream traffic from T1 to the standby ToR and stop the LinkProber module on the active ToR. Confirm switchover and disruption lasts < 1 second. """ send_t1_to_server_with_action( lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: shutdown_tor_heartbeat(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_tor_heartbeat(upper_tor_host) ) verify_tor_states( expected_active_host=lower_tor_host, @@ -115,15 +109,14 @@ def test_active_tor_heartbeat_failure_downstream_standby( def test_standby_tor_heartbeat_failure_upstream( toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - send_server_to_t1_with_action, shutdown_tor_heartbeat, skip_traffic_test): # noqa F811 + send_server_to_t1_with_action, shutdown_tor_heartbeat): # noqa F811 """ Send upstream traffic and stop the LinkProber module on the standby ToR. Confirm no switchover and no disruption. """ send_server_to_t1_with_action( upper_tor_host, verify=True, - action=lambda: shutdown_tor_heartbeat(lower_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_tor_heartbeat(lower_tor_host) ) verify_tor_states( expected_active_host=upper_tor_host, @@ -133,15 +126,14 @@ def test_standby_tor_heartbeat_failure_upstream( def test_standby_tor_heartbeat_failure_downstream_active( toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - send_t1_to_server_with_action, shutdown_tor_heartbeat, skip_traffic_test): # noqa F811 + send_t1_to_server_with_action, shutdown_tor_heartbeat): # noqa F811 """ Send downstream traffic from T1 to the active ToR and stop the LinkProber module on the standby ToR. Confirm no switchover and no disruption. """ send_t1_to_server_with_action( upper_tor_host, verify=True, - action=lambda: shutdown_tor_heartbeat(lower_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_tor_heartbeat(lower_tor_host) ) verify_tor_states( expected_active_host=upper_tor_host, @@ -151,15 +143,14 @@ def test_standby_tor_heartbeat_failure_downstream_active( def test_standby_tor_heartbeat_failure_downstream_standby( toggle_all_simulator_ports_to_upper_tor, upper_tor_host, lower_tor_host, # noqa F811 - send_t1_to_server_with_action, shutdown_tor_heartbeat, skip_traffic_test): # noqa F811 + send_t1_to_server_with_action, shutdown_tor_heartbeat): # noqa F811 """ Send downstream traffic from T1 to the standby ToR and stop the LinkProber module on the standby ToR. Confirm no switchover and no disruption. """ send_t1_to_server_with_action( lower_tor_host, verify=True, - action=lambda: shutdown_tor_heartbeat(lower_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_tor_heartbeat(lower_tor_host) ) verify_tor_states( expected_active_host=upper_tor_host, diff --git a/tests/dualtor_io/test_link_drop.py b/tests/dualtor_io/test_link_drop.py index 27909f13026..5330af7d6a8 100644 --- a/tests/dualtor_io/test_link_drop.py +++ b/tests/dualtor_io/test_link_drop.py @@ -18,7 +18,6 @@ from tests.common.fixtures.ptfhost_utils import run_icmp_responder, run_garp_service # noqa F401 from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.dualtor.constants import MUX_SIM_ALLOWED_DISRUPTION_SEC from tests.common.dualtor.dual_tor_common import ActiveActivePortID from tests.common.dualtor.dual_tor_common import active_active_ports # noqa F401 @@ -97,7 +96,7 @@ def _drop_flow_upper_tor_active_active(): def test_active_link_drop_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, drop_flow_upper_tor_all, # noqa F811 - drop_flow_upper_tor_active_active, cable_type, skip_traffic_test # noqa F811 + drop_flow_upper_tor_active_active, cable_type # noqa F811 ): """ Send traffic from servers to T1 and remove the flow between the servers and the active ToR. @@ -109,8 +108,7 @@ def test_active_link_drop_upstream( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=3, - action=drop_flow_upper_tor_all, - skip_traffic_test=skip_traffic_test + action=drop_flow_upper_tor_all ) verify_tor_states( expected_active_host=lower_tor_host, @@ -125,8 +123,7 @@ def test_active_link_drop_upstream( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=1, - action=drop_flow_upper_tor_active_active, - skip_traffic_test=skip_traffic_test + action=drop_flow_upper_tor_active_active ) verify_tor_states( expected_active_host=lower_tor_host, @@ -141,7 +138,7 @@ def test_active_link_drop_upstream( def test_active_link_drop_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, drop_flow_upper_tor_all, # noqa F811 - drop_flow_upper_tor_active_active, cable_type, skip_traffic_test # noqa F811 + drop_flow_upper_tor_active_active, cable_type # noqa F811 ): """ Send traffic from the T1s to the servers via the active Tor and remove the flow between the @@ -154,8 +151,7 @@ def test_active_link_drop_downstream_active( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=3, - action=drop_flow_upper_tor_all, - skip_traffic_test=skip_traffic_test + action=drop_flow_upper_tor_all ) verify_tor_states( expected_active_host=lower_tor_host, @@ -170,8 +166,7 @@ def test_active_link_drop_downstream_active( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=1, - action=drop_flow_upper_tor_active_active, - skip_traffic_test=skip_traffic_test + action=drop_flow_upper_tor_active_active ) verify_tor_states( expected_active_host=lower_tor_host, @@ -184,8 +179,7 @@ def test_active_link_drop_downstream_active( def test_active_link_drop_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, drop_flow_upper_tor_all, # noqa F811 - skip_traffic_test # noqa F811 + toggle_all_simulator_ports_to_upper_tor, drop_flow_upper_tor_all # noqa F811 ): """ Send traffic from the T1s to the servers via the standby Tor and remove the flow between the @@ -197,8 +191,7 @@ def test_active_link_drop_downstream_standby( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=3, - action=drop_flow_upper_tor_all, - skip_traffic_test=skip_traffic_test + action=drop_flow_upper_tor_all ) verify_tor_states( expected_active_host=lower_tor_host, @@ -210,7 +203,7 @@ def test_active_link_drop_downstream_standby( def test_standby_link_drop_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 check_simulator_flap_counter, drop_flow_lower_tor_all, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test # noqa F811 + toggle_all_simulator_ports_to_upper_tor # noqa F811 ): """ Send traffic from servers to T1 and remove the flow between the servers and the standby ToR. @@ -221,8 +214,7 @@ def test_standby_link_drop_upstream( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=2, - action=drop_flow_lower_tor_all, - skip_traffic_test=skip_traffic_test + action=drop_flow_lower_tor_all ) verify_tor_states( expected_active_host=upper_tor_host, @@ -235,7 +227,7 @@ def test_standby_link_drop_upstream( def test_standby_link_drop_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 check_simulator_flap_counter, drop_flow_lower_tor_all, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test # noqa F811 + toggle_all_simulator_ports_to_upper_tor # noqa F811 ): """ Send traffic from the T1s to the servers via the active Tor and remove the flow between the @@ -247,8 +239,7 @@ def test_standby_link_drop_downstream_active( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=2, - action=drop_flow_lower_tor_all, - skip_traffic_test=skip_traffic_test + action=drop_flow_lower_tor_all ) verify_tor_states( expected_active_host=upper_tor_host, @@ -261,7 +252,7 @@ def test_standby_link_drop_downstream_active( def test_standby_link_drop_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 check_simulator_flap_counter, drop_flow_lower_tor_all, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, skip_traffic_test # noqa F811 + toggle_all_simulator_ports_to_upper_tor # noqa F811 ): """ Send traffic from the T1s to the servers via the standby Tor and remove the flow between the @@ -273,8 +264,7 @@ def test_standby_link_drop_downstream_standby( verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, allowed_disruption=2, - action=drop_flow_lower_tor_all, - skip_traffic_test=skip_traffic_test + action=drop_flow_lower_tor_all ) verify_tor_states( expected_active_host=upper_tor_host, diff --git a/tests/dualtor_io/test_link_failure.py b/tests/dualtor_io/test_link_failure.py index 580f73d805d..54aada394b5 100644 --- a/tests/dualtor_io/test_link_failure.py +++ b/tests/dualtor_io/test_link_failure.py @@ -11,7 +11,6 @@ from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_upper_tor # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder, run_garp_service, \ copy_ptftests_directory, change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.dualtor.constants import MUX_SIM_ALLOWED_DISRUPTION_SEC from tests.common.dualtor.dual_tor_common import active_active_ports # noqa F401 from tests.common.dualtor.dual_tor_common import cable_type # noqa F401 @@ -28,7 +27,7 @@ def test_active_link_down_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_fanout_upper_tor_intfs, cable_type, skip_traffic_test # noqa F811 + shutdown_fanout_upper_tor_intfs, cable_type # noqa F811 ): """ Send traffic from server to T1 and shutdown the active ToR link. @@ -37,8 +36,7 @@ def test_active_link_down_upstream( if cable_type == CableType.active_active: send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_fanout_upper_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_fanout_upper_tor_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -51,8 +49,7 @@ def test_active_link_down_upstream( if cable_type == CableType.active_standby: send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=3, action=shutdown_fanout_upper_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=3, action=shutdown_fanout_upper_tor_intfs ) verify_tor_states( @@ -67,7 +64,7 @@ def test_active_link_down_upstream( def test_active_link_down_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_fanout_upper_tor_intfs, cable_type, skip_traffic_test # noqa F811 + shutdown_fanout_upper_tor_intfs, cable_type # noqa F811 ): """ Send traffic from T1 to active ToR and shutdown the active ToR link. @@ -76,8 +73,7 @@ def test_active_link_down_downstream_active( if cable_type == CableType.active_standby: send_t1_to_server_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=3, action=shutdown_fanout_upper_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=3, action=shutdown_fanout_upper_tor_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -88,8 +84,7 @@ def test_active_link_down_downstream_active( if cable_type == CableType.active_active: send_t1_to_server_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_fanout_upper_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_fanout_upper_tor_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -103,7 +98,7 @@ def test_active_link_down_downstream_active( def test_active_link_down_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_fanout_upper_tor_intfs, skip_traffic_test # noqa F811 + shutdown_fanout_upper_tor_intfs # noqa F811 ): """ Send traffic from T1 to standby ToR and shutdown the active ToR link. @@ -111,8 +106,7 @@ def test_active_link_down_downstream_standby( """ send_t1_to_server_with_action( lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=3, action=shutdown_fanout_upper_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=3, action=shutdown_fanout_upper_tor_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -124,7 +118,7 @@ def test_active_link_down_downstream_standby( def test_standby_link_down_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_fanout_lower_tor_intfs, skip_traffic_test # noqa F811 + shutdown_fanout_lower_tor_intfs # noqa F811 ): """ Send traffic from server to T1 and shutdown the standby ToR link. @@ -132,8 +126,7 @@ def test_standby_link_down_upstream( """ send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=2, action=shutdown_fanout_lower_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=2, action=shutdown_fanout_lower_tor_intfs ) verify_tor_states( expected_active_host=upper_tor_host, @@ -145,7 +138,7 @@ def test_standby_link_down_upstream( def test_standby_link_down_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_fanout_lower_tor_intfs, skip_traffic_test # noqa F811 + shutdown_fanout_lower_tor_intfs # noqa F811 ): """ Send traffic from T1 to active ToR and shutdown the standby ToR link. @@ -153,8 +146,7 @@ def test_standby_link_down_downstream_active( """ send_t1_to_server_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=2, action=shutdown_fanout_lower_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=2, action=shutdown_fanout_lower_tor_intfs ) verify_tor_states( expected_active_host=upper_tor_host, @@ -166,7 +158,7 @@ def test_standby_link_down_downstream_active( def test_standby_link_down_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_fanout_lower_tor_intfs, skip_traffic_test # noqa F811 + shutdown_fanout_lower_tor_intfs # noqa F811 ): """ Send traffic from T1 to standby ToR and shutdwon the standby ToR link. @@ -174,8 +166,7 @@ def test_standby_link_down_downstream_standby( """ send_t1_to_server_with_action( lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=2, action=shutdown_fanout_lower_tor_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=2, action=shutdown_fanout_lower_tor_intfs ) verify_tor_states( expected_active_host=upper_tor_host, @@ -187,7 +178,7 @@ def test_standby_link_down_downstream_standby( def test_active_tor_downlink_down_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_upper_tor_downlink_intfs, skip_traffic_test # noqa F811 + shutdown_upper_tor_downlink_intfs # noqa F811 ): """ Send traffic from server to T1 and shutdown the active ToR downlink on DUT. @@ -195,8 +186,7 @@ def test_active_tor_downlink_down_upstream( """ send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_upper_tor_downlink_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_upper_tor_downlink_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -208,7 +198,7 @@ def test_active_tor_downlink_down_upstream( def test_active_tor_downlink_down_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_upper_tor_downlink_intfs, skip_traffic_test # noqa F811 + shutdown_upper_tor_downlink_intfs # noqa F811 ): """ Send traffic from T1 to active ToR and shutdown the active ToR downlink on DUT. @@ -216,8 +206,7 @@ def test_active_tor_downlink_down_downstream_active( """ send_t1_to_server_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_upper_tor_downlink_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_upper_tor_downlink_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -229,7 +218,7 @@ def test_active_tor_downlink_down_downstream_active( def test_active_tor_downlink_down_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_upper_tor_downlink_intfs, skip_traffic_test # noqa F811 + shutdown_upper_tor_downlink_intfs # noqa F811 ): """ Send traffic from T1 to standby ToR and shutdown the active ToR downlink on DUT. @@ -237,8 +226,7 @@ def test_active_tor_downlink_down_downstream_standby( """ send_t1_to_server_with_action( lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_upper_tor_downlink_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_upper_tor_downlink_intfs ) verify_tor_states( expected_active_host=lower_tor_host, @@ -250,7 +238,7 @@ def test_active_tor_downlink_down_downstream_standby( def test_standby_tor_downlink_down_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_lower_tor_downlink_intfs, skip_traffic_test # noqa F811 + shutdown_lower_tor_downlink_intfs # noqa F811 ): """ Send traffic from server to T1 and shutdown the standby ToR downlink on DUT. @@ -258,8 +246,7 @@ def test_standby_tor_downlink_down_upstream( """ send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_lower_tor_downlink_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_lower_tor_downlink_intfs ) verify_tor_states( expected_active_host=upper_tor_host, @@ -271,7 +258,7 @@ def test_standby_tor_downlink_down_upstream( def test_standby_tor_downlink_down_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_lower_tor_downlink_intfs, skip_traffic_test # noqa F811 + shutdown_lower_tor_downlink_intfs # noqa F811 ): """ Send traffic from T1 to active ToR and shutdown the standby ToR downlink on DUT. @@ -279,8 +266,7 @@ def test_standby_tor_downlink_down_downstream_active( """ send_t1_to_server_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_lower_tor_downlink_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_lower_tor_downlink_intfs ) verify_tor_states( expected_active_host=upper_tor_host, @@ -292,7 +278,7 @@ def test_standby_tor_downlink_down_downstream_active( def test_standby_tor_downlink_down_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_lower_tor_downlink_intfs, skip_traffic_test # noqa F811 + shutdown_lower_tor_downlink_intfs # noqa F811 ): """ Send traffic from T1 to standby ToR and shutdwon the standby ToR downlink on DUT. @@ -300,8 +286,7 @@ def test_standby_tor_downlink_down_downstream_standby( """ send_t1_to_server_with_action( lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - allowed_disruption=1, action=shutdown_lower_tor_downlink_intfs, - skip_traffic_test=skip_traffic_test + allowed_disruption=1, action=shutdown_lower_tor_downlink_intfs ) verify_tor_states( expected_active_host=upper_tor_host, diff --git a/tests/dualtor_io/test_normal_op.py b/tests/dualtor_io/test_normal_op.py index 20781585e6e..e71df5097e6 100644 --- a/tests/dualtor_io/test_normal_op.py +++ b/tests/dualtor_io/test_normal_op.py @@ -14,7 +14,6 @@ from tests.common.dualtor.dual_tor_utils import check_simulator_flap_counter # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder, run_garp_service, \ copy_ptftests_directory, change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.dualtor.constants import MUX_SIM_ALLOWED_DISRUPTION_SEC, CONFIG_RELOAD_ALLOWED_DISRUPTION_SEC from tests.common.utilities import wait_until from tests.common.helpers.assertions import pytest_assert @@ -29,19 +28,16 @@ def test_normal_op_upstream(upper_tor_host, lower_tor_host, # noqa F811 send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """Send upstream traffic and confirm no disruption or switchover occurs""" if cable_type == CableType.active_standby: - send_server_to_t1_with_action(upper_tor_host, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_server_to_t1_with_action(upper_tor_host, verify=True, stop_after=60) verify_tor_states(expected_active_host=upper_tor_host, expected_standby_host=lower_tor_host, skip_tunnel_route=False) if cable_type == CableType.active_active: - send_server_to_t1_with_action(upper_tor_host, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_server_to_t1_with_action(upper_tor_host, verify=True, stop_after=60) verify_tor_states(expected_active_host=[upper_tor_host, lower_tor_host], expected_standby_host=None, cable_type=cable_type, @@ -52,21 +48,18 @@ def test_normal_op_upstream(upper_tor_host, lower_tor_host, # noqa F def test_normal_op_downstream_upper_tor(upper_tor_host, lower_tor_host, # noqa F811 send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send downstream traffic to the upper ToR and confirm no disruption or switchover occurs """ if cable_type == CableType.active_standby: - send_t1_to_server_with_action(upper_tor_host, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_t1_to_server_with_action(upper_tor_host, verify=True, stop_after=60) verify_tor_states(expected_active_host=upper_tor_host, expected_standby_host=lower_tor_host) if cable_type == CableType.active_active: - send_t1_to_server_with_action(upper_tor_host, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_t1_to_server_with_action(upper_tor_host, verify=True, stop_after=60) verify_tor_states(expected_active_host=[upper_tor_host, lower_tor_host], expected_standby_host=None, cable_type=cable_type) @@ -76,21 +69,18 @@ def test_normal_op_downstream_upper_tor(upper_tor_host, lower_tor_host, def test_normal_op_downstream_lower_tor(upper_tor_host, lower_tor_host, # noqa F811 send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send downstream traffic to the lower ToR and confirm no disruption or switchover occurs """ if cable_type == CableType.active_standby: - send_t1_to_server_with_action(lower_tor_host, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_t1_to_server_with_action(lower_tor_host, verify=True, stop_after=60) verify_tor_states(expected_active_host=upper_tor_host, expected_standby_host=lower_tor_host) if cable_type == CableType.active_active: - send_t1_to_server_with_action(lower_tor_host, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_t1_to_server_with_action(lower_tor_host, verify=True, stop_after=60) verify_tor_states(expected_active_host=[upper_tor_host, lower_tor_host], expected_standby_host=None, cable_type=cable_type) @@ -101,8 +91,7 @@ def test_normal_op_active_server_to_active_server(upper_tor_host, lower_tor_host send_server_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 cable_type, # noqa F811 - select_test_mux_ports, # noqa F811 - skip_traffic_test): # noqa F811 + select_test_mux_ports): # noqa F811 """ Send server to server traffic in active-active setup and confirm no disruption or switchover occurs. """ @@ -110,15 +99,13 @@ def test_normal_op_active_server_to_active_server(upper_tor_host, lower_tor_host test_mux_ports = select_test_mux_ports(cable_type, 2) if cable_type == CableType.active_standby: - send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, stop_after=60) verify_tor_states(expected_active_host=upper_tor_host, expected_standby_host=lower_tor_host, skip_tunnel_route=False) if cable_type == CableType.active_active: - send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, stop_after=60) verify_tor_states(expected_active_host=[upper_tor_host, lower_tor_host], expected_standby_host=None, cable_type=cable_type, @@ -130,8 +117,7 @@ def test_normal_op_active_server_to_standby_server(upper_tor_host, lower_tor_hos send_server_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 cable_type, force_standby_tor, # noqa F811 - select_test_mux_ports, # noqa F811 - skip_traffic_test): # noqa F811 + select_test_mux_ports): # noqa F811 """ Send server to server traffic in active-standby setup and confirm no disruption or switchover occurs. """ @@ -147,12 +133,10 @@ def _is_mux_port_standby(duthost, mux_port): "failed to toggle mux port %s to standby on DUT %s" % (tx_mux_port, upper_tor_host.hostname)) if cable_type == CableType.active_standby: - send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, stop_after=60) if cable_type == CableType.active_active: - send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, - stop_after=60, skip_traffic_test=skip_traffic_test) + send_server_to_server_with_action(upper_tor_host, test_mux_ports, verify=True, stop_after=60) # TODO: Add per-port db check @@ -162,8 +146,7 @@ def _is_mux_port_standby(duthost, mux_port): def test_upper_tor_config_reload_upstream(upper_tor_host, lower_tor_host, # noqa F811 send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send upstream traffic and `config reload` the active ToR. Confirm switchover occurs and disruption lasted < 1 second for active-standby ports. @@ -171,15 +154,13 @@ def test_upper_tor_config_reload_upstream(upper_tor_host, lower_tor_host, """ if cable_type == CableType.active_standby: send_server_to_t1_with_action(upper_tor_host, verify=True, delay=CONFIG_RELOAD_ALLOWED_DISRUPTION_SEC, - action=lambda: config_reload(upper_tor_host, wait=0), - skip_traffic_test=skip_traffic_test) + action=lambda: config_reload(upper_tor_host, wait=0)) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host) if cable_type == CableType.active_active: send_server_to_t1_with_action(upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: config_reload(upper_tor_host, wait=0), - skip_traffic_test=skip_traffic_test) + action=lambda: config_reload(upper_tor_host, wait=0)) verify_tor_states(expected_active_host=[upper_tor_host, lower_tor_host], expected_standby_host=None, cable_type=cable_type) @@ -189,16 +170,14 @@ def test_upper_tor_config_reload_upstream(upper_tor_host, lower_tor_host, def test_lower_tor_config_reload_upstream(upper_tor_host, lower_tor_host, # noqa F811 send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send upstream traffic and `config reload` the lower ToR. Confirm no switchover occurs and no disruption. """ if cable_type == CableType.active_standby: send_server_to_t1_with_action(upper_tor_host, verify=True, - action=lambda: config_reload(lower_tor_host, wait=0), - skip_traffic_test=skip_traffic_test) + action=lambda: config_reload(lower_tor_host, wait=0)) verify_tor_states(expected_active_host=upper_tor_host, expected_standby_host=lower_tor_host) @@ -208,23 +187,20 @@ def test_lower_tor_config_reload_upstream(upper_tor_host, lower_tor_host, def test_lower_tor_config_reload_downstream_upper_tor(upper_tor_host, lower_tor_host, # noqa F811 send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send downstream traffic to the upper ToR and `config reload` the lower ToR. Confirm no switchover occurs and no disruption """ if cable_type == CableType.active_standby: send_t1_to_server_with_action(upper_tor_host, verify=True, - action=lambda: config_reload(lower_tor_host, wait=0), - skip_traffic_test=skip_traffic_test) + action=lambda: config_reload(lower_tor_host, wait=0)) verify_tor_states(expected_active_host=upper_tor_host, expected_standby_host=lower_tor_host) if cable_type == CableType.active_active: send_t1_to_server_with_action(upper_tor_host, verify=True, - action=lambda: config_reload(lower_tor_host, wait=0), - skip_traffic_test=skip_traffic_test) + action=lambda: config_reload(lower_tor_host, wait=0)) verify_tor_states(expected_active_host=[upper_tor_host, lower_tor_host], expected_standby_host=None, cable_type=cable_type) @@ -234,8 +210,7 @@ def test_lower_tor_config_reload_downstream_upper_tor(upper_tor_host, lower_tor_ def test_upper_tor_config_reload_downstream_lower_tor(upper_tor_host, lower_tor_host, # noqa F811 send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send downstream traffic to the lower ToR and `config reload` the upper ToR. Confirm switchover occurs and disruption lasts < 1 second for active-standby ports. @@ -243,8 +218,7 @@ def test_upper_tor_config_reload_downstream_lower_tor(upper_tor_host, lower_tor_ """ if cable_type == CableType.active_standby: send_t1_to_server_with_action(lower_tor_host, verify=True, delay=CONFIG_RELOAD_ALLOWED_DISRUPTION_SEC, - action=lambda: config_reload(upper_tor_host, wait=0), - skip_traffic_test=skip_traffic_test) + action=lambda: config_reload(upper_tor_host, wait=0)) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host) @@ -254,8 +228,7 @@ def test_tor_switch_upstream(upper_tor_host, lower_tor_host, # no send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 force_active_tor, force_standby_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send upstream traffic and perform switchover via CLI. Confirm switchover occurs and disruption lasts < 1 second for active-standby ports. @@ -263,15 +236,13 @@ def test_tor_switch_upstream(upper_tor_host, lower_tor_host, # no """ if cable_type == CableType.active_standby: send_server_to_t1_with_action(upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: force_active_tor(lower_tor_host, 'all'), - skip_traffic_test=skip_traffic_test) + action=lambda: force_active_tor(lower_tor_host, 'all')) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host) if cable_type == CableType.active_active: send_server_to_t1_with_action(upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: force_standby_tor(upper_tor_host, 'all'), - skip_traffic_test=skip_traffic_test) + action=lambda: force_standby_tor(upper_tor_host, 'all')) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host, expected_standby_health="healthy", @@ -283,8 +254,7 @@ def test_tor_switch_downstream_active(upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 force_active_tor, force_standby_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send downstream traffic to the upper ToR and perform switchover via CLI. Confirm switchover occurs and disruption lasts < 1 second for active-standby ports. @@ -292,15 +262,13 @@ def test_tor_switch_downstream_active(upper_tor_host, lower_tor_host, """ if cable_type == CableType.active_standby: send_t1_to_server_with_action(upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: force_active_tor(lower_tor_host, 'all'), - skip_traffic_test=skip_traffic_test) + action=lambda: force_active_tor(lower_tor_host, 'all')) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host) if cable_type == CableType.active_active: send_t1_to_server_with_action(upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: force_standby_tor(upper_tor_host, 'all'), - skip_traffic_test=skip_traffic_test) + action=lambda: force_standby_tor(upper_tor_host, 'all')) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host, expected_standby_health="healthy", @@ -312,8 +280,7 @@ def test_tor_switch_downstream_standby(upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 force_active_tor, force_standby_tor, # noqa F811 - cable_type, # noqa F811 - skip_traffic_test): # noqa F811 + cable_type): # noqa F811 """ Send downstream traffic to the lower ToR and perform switchover via CLI. Confirm switchover occurs and disruption lasts < 1 second for active-standby ports. @@ -321,15 +288,13 @@ def test_tor_switch_downstream_standby(upper_tor_host, lower_tor_host, """ if cable_type == CableType.active_standby: send_t1_to_server_with_action(lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: force_active_tor(lower_tor_host, 'all'), - skip_traffic_test=skip_traffic_test) + action=lambda: force_active_tor(lower_tor_host, 'all')) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host) if cable_type == CableType.active_active: send_t1_to_server_with_action(lower_tor_host, verify=True, - action=lambda: force_standby_tor(upper_tor_host, 'all'), - skip_traffic_test=skip_traffic_test) + action=lambda: force_standby_tor(upper_tor_host, 'all')) verify_tor_states(expected_active_host=lower_tor_host, expected_standby_host=upper_tor_host, expected_standby_health="healthy", diff --git a/tests/dualtor_io/test_tor_bgp_failure.py b/tests/dualtor_io/test_tor_bgp_failure.py index 91783bd14fe..c6643a08134 100644 --- a/tests/dualtor_io/test_tor_bgp_failure.py +++ b/tests/dualtor_io/test_tor_bgp_failure.py @@ -11,7 +11,6 @@ from tests.common.dualtor.tor_failure_utils import shutdown_bgp_sessions_on_duthost from tests.common.fixtures.ptfhost_utils import run_icmp_responder, run_garp_service, \ copy_ptftests_directory, change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.dualtor.tunnel_traffic_utils import tunnel_traffic_monitor # noqa F401 from tests.common.dualtor.constants import MUX_SIM_ALLOWED_DISRUPTION_SEC from tests.common.dualtor.dual_tor_common import cable_type # noqa F401 @@ -80,7 +79,7 @@ def ignore_expected_loganalyzer_exception(loganalyzer, duthosts): def test_active_tor_kill_bgpd_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, kill_bgpd, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_upper_tor, kill_bgpd): # noqa F811 ''' Case: Server -> ToR -> T1 (Active ToR BGP Down) Action: Shutdown all BGP sessions on the active ToR @@ -92,8 +91,7 @@ def test_active_tor_kill_bgpd_upstream( ''' send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: kill_bgpd(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: kill_bgpd(upper_tor_host) ) verify_tor_states( expected_active_host=lower_tor_host, @@ -103,7 +101,7 @@ def test_active_tor_kill_bgpd_upstream( def test_standby_tor_kill_bgpd_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 - toggle_all_simulator_ports_to_upper_tor, kill_bgpd, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_upper_tor, kill_bgpd): # noqa F811 ''' Case: Server -> ToR -> T1 (Standby ToR BGP Down) Action: Shutdown all BGP sessions on the standby ToR @@ -114,8 +112,7 @@ def test_standby_tor_kill_bgpd_upstream( ''' send_server_to_t1_with_action( upper_tor_host, verify=True, - action=lambda: kill_bgpd(lower_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: kill_bgpd(lower_tor_host) ) verify_tor_states( expected_active_host=upper_tor_host, @@ -126,7 +123,7 @@ def test_standby_tor_kill_bgpd_upstream( def test_standby_tor_kill_bgpd_downstream_active( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, kill_bgpd, # noqa F811 - tunnel_traffic_monitor, skip_traffic_test): # noqa F811 + tunnel_traffic_monitor): # noqa F811 ''' Case: T1 -> Active ToR -> Server (Standby ToR BGP Down) Action: Shutdown all BGP sessions on the standby ToR @@ -137,8 +134,7 @@ def test_standby_tor_kill_bgpd_downstream_active( with tunnel_traffic_monitor(lower_tor_host, existing=False): send_t1_to_server_with_action( upper_tor_host, verify=True, - action=lambda: kill_bgpd(lower_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: kill_bgpd(lower_tor_host) ) verify_tor_states( expected_active_host=upper_tor_host, @@ -149,7 +145,7 @@ def test_standby_tor_kill_bgpd_downstream_active( def test_active_tor_kill_bgpd_downstream_standby( upper_tor_host, lower_tor_host, send_t1_to_server_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, kill_bgpd, # noqa F811 - tunnel_traffic_monitor, skip_traffic_test): # noqa F811 + tunnel_traffic_monitor): # noqa F811 ''' Case: T1 -> Standby ToR -> Server (Active ToR BGP Down) Action: Shutdown all BGP sessions on the active ToR @@ -160,8 +156,7 @@ def test_active_tor_kill_bgpd_downstream_standby( ''' send_t1_to_server_with_action( lower_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: kill_bgpd(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: kill_bgpd(upper_tor_host) ) verify_tor_states( expected_active_host=lower_tor_host, @@ -173,7 +168,7 @@ def test_active_tor_kill_bgpd_downstream_standby( def test_active_tor_shutdown_bgp_sessions_upstream( upper_tor_host, lower_tor_host, send_server_to_t1_with_action, # noqa F811 toggle_all_simulator_ports_to_upper_tor, # noqa F811 - shutdown_bgp_sessions, cable_type, skip_traffic_test # noqa F811 + shutdown_bgp_sessions, cable_type # noqa F811 ): """ Case: Server -> ToR -> T1 (Active ToR BGP Down) @@ -187,15 +182,13 @@ def test_active_tor_shutdown_bgp_sessions_upstream( if cable_type == CableType.active_standby: send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: shutdown_bgp_sessions(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_bgp_sessions(upper_tor_host) ) if cable_type == CableType.active_active: send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: shutdown_bgp_sessions(upper_tor_host), - skip_traffic_test=skip_traffic_test + action=lambda: shutdown_bgp_sessions(upper_tor_host) ) if cable_type == CableType.active_active: diff --git a/tests/dualtor_mgmt/test_ingress_drop.py b/tests/dualtor_mgmt/test_ingress_drop.py index c98be9db041..75169847743 100644 --- a/tests/dualtor_mgmt/test_ingress_drop.py +++ b/tests/dualtor_mgmt/test_ingress_drop.py @@ -16,8 +16,6 @@ from tests.common.dualtor.nic_simulator_control import mux_status_from_nic_simulator # noqa F401 from tests.common.dualtor.nic_simulator_control import stop_nic_simulator # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 - from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until @@ -104,7 +102,7 @@ def selected_mux_port(cable_type, active_active_ports, active_standby_ports): @pytest.mark.enable_active_active -def test_ingress_drop(cable_type, ptfadapter, setup_mux, tbinfo, selected_mux_port, upper_tor_host, skip_traffic_test): # noqa F811 +def test_ingress_drop(cable_type, ptfadapter, setup_mux, tbinfo, selected_mux_port, upper_tor_host): # noqa F811 """ Aims to verify if orchagent installs ingress drop ACL when the port comes to standby. @@ -131,7 +129,7 @@ def test_ingress_drop(cable_type, ptfadapter, setup_mux, tbinfo, selected_mux_po if cable_type == CableType.active_active: verify_upstream_traffic(upper_tor_host, ptfadapter, tbinfo, selected_mux_port, - server_ip, pkt_num=10, drop=False, skip_traffic_test=skip_traffic_test) + server_ip, pkt_num=10, drop=False) elif cable_type == CableType.active_standby: verify_upstream_traffic(upper_tor_host, ptfadapter, tbinfo, selected_mux_port, - server_ip, pkt_num=10, drop=True, skip_traffic_test=skip_traffic_test) + server_ip, pkt_num=10, drop=True) From 1a10ecdf5a6529a354366366d305ff9616ea99fe Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 08:34:06 +0800 Subject: [PATCH 109/221] Remove skip_traffic_test fixture in ecmp tests (#15431) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in ecmp tests How did you verify/test it? --- .../ecmp/inner_hashing/test_inner_hashing.py | 40 ++++---- .../inner_hashing/test_inner_hashing_lag.py | 5 +- .../inner_hashing/test_wr_inner_hashing.py | 93 +++++++++---------- .../test_wr_inner_hashing_lag.py | 50 +++++----- 4 files changed, 88 insertions(+), 100 deletions(-) diff --git a/tests/ecmp/inner_hashing/test_inner_hashing.py b/tests/ecmp/inner_hashing/test_inner_hashing.py index fe45fe66169..896520b26a5 100644 --- a/tests/ecmp/inner_hashing/test_inner_hashing.py +++ b/tests/ecmp/inner_hashing/test_inner_hashing.py @@ -13,7 +13,6 @@ from tests.ptf_runner import ptf_runner from tests.ecmp.inner_hashing.conftest import get_src_dst_ip_range, FIB_INFO_FILE_DST,\ VXLAN_PORT, PTF_QLEN, check_pbh_counters, OUTER_ENCAP_FORMATS, NVGRE_TNI, IP_VERSIONS_LIST, config_pbh -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 logger = logging.getLogger(__name__) @@ -35,7 +34,7 @@ def setup_dynamic_pbh(self, duthost, vlan_ptf_ports, tbinfo): def test_inner_hashing(self, request, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, duthost, lag_mem_ptf_ports_groups, - get_function_completeness_level, skip_traffic_test): # noqa F811 + get_function_completeness_level): logging.info("Executing dynamic inner hash test for outer {} and inner {} with symmetric_hashing set to {}" .format(outer_ipver, inner_ipver, str(symmetric_hashing))) with allure.step('Run ptf test InnerHashTest'): @@ -73,22 +72,22 @@ def test_inner_hashing(self, request, hash_keys, ptfhost, outer_ipver, inner_ipv "symmetric_hashing": symmetric_hashing} duthost.shell("sonic-clear pbh statistics") - if not skip_traffic_test: - ptf_runner(ptfhost, - "ptftests", - "inner_hash_test.InnerHashTest", - platform_dir="ptftests", - params=ptf_params, - log_file=log_file, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True) - retry_call(check_pbh_counters, - fargs=[duthost, outer_ipver, inner_ipver, balancing_test_times, - symmetric_hashing, hash_keys, lag_mem_ptf_ports_groups], - tries=5, - delay=5) + ptf_runner(ptfhost, + "ptftests", + "inner_hash_test.InnerHashTest", + platform_dir="ptftests", + params=ptf_params, + log_file=log_file, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True) + + retry_call(check_pbh_counters, + fargs=[duthost, outer_ipver, inner_ipver, balancing_test_times, + symmetric_hashing, hash_keys, lag_mem_ptf_ports_groups], + tries=5, + delay=5) if update_outer_ipver == outer_ipver and update_inner_ipver == inner_ipver: logging.info("Validate dynamic inner hash Edit Flow for outer {} and inner {} ip versions with" @@ -105,8 +104,7 @@ def test_inner_hashing(self, request, hash_keys, ptfhost, outer_ipver, inner_ipv with allure.step('Run again the ptf test InnerHashTest after updating the rules'): logging.info('Run again the ptf test InnerHashTest after updating the rules') duthost.shell("sonic-clear pbh statistics") - if skip_traffic_test is True: - return + ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", @@ -128,7 +126,7 @@ def test_inner_hashing(self, request, hash_keys, ptfhost, outer_ipver, inner_ipv class TestStaticInnerHashing(): def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, - vlan_ptf_ports, symmetric_hashing, lag_mem_ptf_ports_groups, skip_traffic_test): # noqa F811 + vlan_ptf_ports, symmetric_hashing, lag_mem_ptf_ports_groups): logging.info("Executing static inner hash test for outer {} and inner {} with symmetric_hashing set to {}" .format(outer_ipver, inner_ipver, str(symmetric_hashing))) timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') @@ -138,8 +136,6 @@ def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, route outer_src_ip_range, outer_dst_ip_range = get_src_dst_ip_range(outer_ipver) inner_src_ip_range, inner_dst_ip_range = get_src_dst_ip_range(inner_ipver) - if skip_traffic_test is True: - return ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", diff --git a/tests/ecmp/inner_hashing/test_inner_hashing_lag.py b/tests/ecmp/inner_hashing/test_inner_hashing_lag.py index ed616569865..7c1ccc2f00f 100644 --- a/tests/ecmp/inner_hashing/test_inner_hashing_lag.py +++ b/tests/ecmp/inner_hashing/test_inner_hashing_lag.py @@ -12,7 +12,6 @@ from tests.ptf_runner import ptf_runner from tests.ecmp.inner_hashing.conftest import get_src_dst_ip_range, FIB_INFO_FILE_DST,\ VXLAN_PORT, PTF_QLEN, check_pbh_counters, OUTER_ENCAP_FORMATS, NVGRE_TNI, setup_lag_config, config_pbh_lag -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 logger = logging.getLogger(__name__) @@ -33,7 +32,7 @@ def setup_dynamic_pbh(self, duthost, lag_port_map, lag_ip_map): def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, duthost, lag_mem_ptf_ports_groups, - get_function_completeness_level, skip_traffic_test): # noqa F811 + get_function_completeness_level): logging.info("Executing dynamic inner hash test for outer {} and inner {} with symmetric_hashing set to {}" .format(outer_ipver, inner_ipver, str(symmetric_hashing))) with allure.step('Run ptf test InnerHashTest'): @@ -54,8 +53,6 @@ def test_inner_hashing(self, hash_keys, ptfhost, outer_ipver, inner_ipver, route balancing_test_times = 20 balancing_range = 0.5 - if skip_traffic_test is True: - return ptf_runner(ptfhost, "ptftests", "inner_hash_test.InnerHashTest", diff --git a/tests/ecmp/inner_hashing/test_wr_inner_hashing.py b/tests/ecmp/inner_hashing/test_wr_inner_hashing.py index 02d697cea33..28325423dc3 100644 --- a/tests/ecmp/inner_hashing/test_wr_inner_hashing.py +++ b/tests/ecmp/inner_hashing/test_wr_inner_hashing.py @@ -9,7 +9,6 @@ from tests.ecmp.inner_hashing.conftest import get_src_dst_ip_range, FIB_INFO_FILE_DST, VXLAN_PORT,\ PTF_QLEN, OUTER_ENCAP_FORMATS, NVGRE_TNI, config_pbh from tests.ptf_runner import ptf_runner -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 logger = logging.getLogger(__name__) @@ -29,7 +28,7 @@ def setup_dynamic_pbh(self, duthost, vlan_ptf_ports, tbinfo): def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, localhost, lag_mem_ptf_ports_groups, - get_function_completeness_level, skip_traffic_test): # noqa F811 + get_function_completeness_level): logging.info("Executing warm boot dynamic inner hash test for outer {} and inner {} with symmetric_hashing" " set to {}".format(outer_ipver, inner_ipver, str(symmetric_hashing))) with allure.step('Run ptf test InnerHashTest and warm-reboot in parallel'): @@ -57,30 +56,29 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm', 10, 0, 0, True, True,)) reboot_thr.start() - if not skip_traffic_test: - ptf_runner(ptfhost, - "ptftests", - "inner_hash_test.InnerHashTest", - platform_dir="ptftests", - params={"fib_info": FIB_INFO_FILE_DST, - "router_mac": router_mac, - "src_ports": vlan_ptf_ports, - "exp_port_groups": lag_mem_ptf_ports_groups, - "hash_keys": hash_keys, - "vxlan_port": VXLAN_PORT, - "inner_src_ip_range": ",".join(inner_src_ip_range), - "inner_dst_ip_range": ",".join(inner_dst_ip_range), - "outer_src_ip_range": ",".join(outer_src_ip_range), - "outer_dst_ip_range": ",".join(outer_dst_ip_range), - "balancing_test_times": balancing_test_times, - "balancing_range": balancing_range, - "outer_encap_formats": outer_encap_format, - "nvgre_tni": NVGRE_TNI, - "symmetric_hashing": symmetric_hashing}, - log_file=log_file, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True) + ptf_runner(ptfhost, + "ptftests", + "inner_hash_test.InnerHashTest", + platform_dir="ptftests", + params={"fib_info": FIB_INFO_FILE_DST, + "router_mac": router_mac, + "src_ports": vlan_ptf_ports, + "exp_port_groups": lag_mem_ptf_ports_groups, + "hash_keys": hash_keys, + "vxlan_port": VXLAN_PORT, + "inner_src_ip_range": ",".join(inner_src_ip_range), + "inner_dst_ip_range": ",".join(inner_dst_ip_range), + "outer_src_ip_range": ",".join(outer_src_ip_range), + "outer_dst_ip_range": ",".join(outer_dst_ip_range), + "balancing_test_times": balancing_test_times, + "balancing_range": balancing_range, + "outer_encap_formats": outer_encap_format, + "nvgre_tni": NVGRE_TNI, + "symmetric_hashing": symmetric_hashing}, + log_file=log_file, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True) reboot_thr.join() @@ -88,7 +86,7 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv class TestWRStaticInnerHashing(): def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, - vlan_ptf_ports, symmetric_hashing, localhost, lag_mem_ptf_ports_groups, skip_traffic_test): # noqa F811 + vlan_ptf_ports, symmetric_hashing, localhost, lag_mem_ptf_ports_groups): logging.info("Executing static inner hash test for outer {} and inner {} with symmetric_hashing set to {}" .format(outer_ipver, inner_ipver, str(symmetric_hashing))) timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') @@ -102,25 +100,24 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm', 10, 0, 0, True, True,)) reboot_thr.start() - if not skip_traffic_test: - ptf_runner(ptfhost, - "ptftests", - "inner_hash_test.InnerHashTest", - platform_dir="ptftests", - params={"fib_info": FIB_INFO_FILE_DST, - "router_mac": router_mac, - "src_ports": vlan_ptf_ports, - "exp_port_groups": lag_mem_ptf_ports_groups, - "hash_keys": hash_keys, - "vxlan_port": VXLAN_PORT, - "inner_src_ip_range": ",".join(inner_src_ip_range), - "inner_dst_ip_range": ",".join(inner_dst_ip_range), - "outer_src_ip_range": ",".join(outer_src_ip_range), - "outer_dst_ip_range": ",".join(outer_dst_ip_range), - "outer_encap_formats": OUTER_ENCAP_FORMATS, - "symmetric_hashing": symmetric_hashing}, - log_file=log_file, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True) + ptf_runner(ptfhost, + "ptftests", + "inner_hash_test.InnerHashTest", + platform_dir="ptftests", + params={"fib_info": FIB_INFO_FILE_DST, + "router_mac": router_mac, + "src_ports": vlan_ptf_ports, + "exp_port_groups": lag_mem_ptf_ports_groups, + "hash_keys": hash_keys, + "vxlan_port": VXLAN_PORT, + "inner_src_ip_range": ",".join(inner_src_ip_range), + "inner_dst_ip_range": ",".join(inner_dst_ip_range), + "outer_src_ip_range": ",".join(outer_src_ip_range), + "outer_dst_ip_range": ",".join(outer_dst_ip_range), + "outer_encap_formats": OUTER_ENCAP_FORMATS, + "symmetric_hashing": symmetric_hashing}, + log_file=log_file, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True) reboot_thr.join() diff --git a/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py b/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py index 6ce69b57d71..e6371e9a06d 100644 --- a/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py +++ b/tests/ecmp/inner_hashing/test_wr_inner_hashing_lag.py @@ -9,7 +9,6 @@ from tests.ecmp.inner_hashing.conftest import get_src_dst_ip_range, FIB_INFO_FILE_DST, VXLAN_PORT,\ PTF_QLEN, OUTER_ENCAP_FORMATS, NVGRE_TNI, setup_lag_config, config_pbh_lag from tests.ptf_runner import ptf_runner -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 logger = logging.getLogger(__name__) @@ -31,7 +30,7 @@ def setup_dynamic_pbh(self, duthost, lag_port_map, lag_ip_map): def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipver, router_mac, vlan_ptf_ports, symmetric_hashing, localhost, lag_mem_ptf_ports_groups, - get_function_completeness_level, skip_traffic_test): # noqa F811 + get_function_completeness_level): logging.info("Executing warm boot dynamic inner hash test for outer {} and inner {} with symmetric_hashing" " set to {}".format(outer_ipver, inner_ipver, str(symmetric_hashing))) timestamp = datetime.now().strftime('%Y-%m-%d-%H:%M:%S') @@ -58,28 +57,27 @@ def test_inner_hashing(self, duthost, hash_keys, ptfhost, outer_ipver, inner_ipv reboot_thr = threading.Thread(target=reboot, args=(duthost, localhost, 'warm', 10, 0, 0, True, True,)) reboot_thr.start() - if not skip_traffic_test: - ptf_runner(ptfhost, - "ptftests", - "inner_hash_test.InnerHashTest", - platform_dir="ptftests", - params={"fib_info": FIB_INFO_FILE_DST, - "router_mac": router_mac, - "src_ports": vlan_ptf_ports, - "exp_port_groups": lag_mem_ptf_ports_groups, - "hash_keys": hash_keys, - "vxlan_port": VXLAN_PORT, - "inner_src_ip_range": ",".join(inner_src_ip_range), - "inner_dst_ip_range": ",".join(inner_dst_ip_range), - "outer_src_ip_range": ",".join(outer_src_ip_range), - "outer_dst_ip_range": ",".join(outer_dst_ip_range), - "balancing_test_times": balancing_test_times, - "balancing_range": balancing_range, - "outer_encap_formats": outer_encap_format, - "nvgre_tni": NVGRE_TNI, - "symmetric_hashing": symmetric_hashing}, - log_file=log_file, - qlen=PTF_QLEN, - socket_recv_size=16384, - is_python3=True) + ptf_runner(ptfhost, + "ptftests", + "inner_hash_test.InnerHashTest", + platform_dir="ptftests", + params={"fib_info": FIB_INFO_FILE_DST, + "router_mac": router_mac, + "src_ports": vlan_ptf_ports, + "exp_port_groups": lag_mem_ptf_ports_groups, + "hash_keys": hash_keys, + "vxlan_port": VXLAN_PORT, + "inner_src_ip_range": ",".join(inner_src_ip_range), + "inner_dst_ip_range": ",".join(inner_dst_ip_range), + "outer_src_ip_range": ",".join(outer_src_ip_range), + "outer_dst_ip_range": ",".join(outer_dst_ip_range), + "balancing_test_times": balancing_test_times, + "balancing_range": balancing_range, + "outer_encap_formats": outer_encap_format, + "nvgre_tni": NVGRE_TNI, + "symmetric_hashing": symmetric_hashing}, + log_file=log_file, + qlen=PTF_QLEN, + socket_recv_size=16384, + is_python3=True) reboot_thr.join() From 7a193b7ada25b20b8d8610f90d164759999492a1 Mon Sep 17 00:00:00 2001 From: Riff Date: Thu, 7 Nov 2024 16:48:37 -0800 Subject: [PATCH 110/221] Add topo generator and t1-isolated-d128 topo. (#15402) * Add topo generator and isolated d128 topo. * minor update. * Minor fix and regenerate the topo. * Fix downlink asn to make them rotate from the base number. --- ansible/generate_topo.py | 194 ++ ansible/templates/topo_t1-isolated.j2 | 47 + ansible/vars/topo_t1-isolated-d128.yml | 2964 ++++++++++++++++++++++++ 3 files changed, 3205 insertions(+) create mode 100755 ansible/generate_topo.py create mode 100644 ansible/templates/topo_t1-isolated.j2 create mode 100644 ansible/vars/topo_t1-isolated-d128.yml diff --git a/ansible/generate_topo.py b/ansible/generate_topo.py new file mode 100755 index 00000000000..b78b15bf724 --- /dev/null +++ b/ansible/generate_topo.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 + +from typing import Any, Dict, List +import ipaddress +import click +import jinja2 + +# Define the roles for the devices in the topology +roles_cfg = { + "t0": { + "asn": 65100, + "downlink": None, + "uplink": {"role": "t1", "asn": 64600}, + "peer": {"role": "pt0", "asn": 65100}, + }, + "t1": { + "asn": 65100, + "downlink": {"role": "t0", "asn": 64000}, + "uplink": {"role": "t2", "asn": 65200}, + "peer": None, + }, +} + + +# Utility functions to calculate IP addresses +def calc_ipv4_pair(subnet_str, port_id): + subnet = ipaddress.IPv4Network(subnet_str) + return (str(subnet.network_address + 2*port_id), str(subnet.network_address + 2*port_id + 1)) + + +def calc_ipv6_pair(subnet_str, port_id): + subnet = ipaddress.IPv6Network(subnet_str) + return (str(subnet.network_address + 4*port_id+1), str(subnet.network_address + 4*port_id + 2)) + + +def calc_ipv4(subnet_str, port_id): + subnet = ipaddress.IPv4Network(subnet_str) + return str(subnet.network_address + port_id) + + +def calc_ipv6(subnet_str, port_id): + subnet = ipaddress.IPv6Network(subnet_str) + return str(subnet.network_address + port_id) + + +class VM: + """ Class to represent a VM in the topology """ + def __init__(self, + port_id: int, + vm_id: int, + name_id: int, + dut_asn: int, + role_cfg: Dict[str, Any], + ip_offset: int = None): + + self.role = role_cfg["role"] + + # IDs of the VM + self.port_id = port_id + self.vm_offset = vm_id + self.ip_offset = vm_id if ip_offset is None else ip_offset + self.name = f"ARISTA{name_id:02d}{self.role.upper()}" + + # VLAN configuration + self.vlans = [port_id] + + # BGP configuration + self.asn = role_cfg["asn"] + self.peer_asn = dut_asn + + # IP addresses + self.dut_intf_ipv4, self.pc_intf_ipv4 = calc_ipv4_pair("10.0.0.0", self.ip_offset) + self.dut_intf_ipv6, self.pc_intf_ipv6 = calc_ipv6_pair("FC00::", self.ip_offset) + self.loopback_ipv4 = calc_ipv4("100.1.0.0", self.ip_offset+1) + self.loopback_ipv6 = calc_ipv6("2064:100::", self.ip_offset+1) + + # Backplane IPs will go with the VM ID + self.bp_ipv4 = calc_ipv4("10.10.246.1", self.vm_offset+1) + self.bp_ipv6 = calc_ipv6("fc0a::1", (self.vm_offset+1)) + + +class HostInterface: + """ Class to represent a host interface in the topology """ + def __init__(self, port_id: int): + self.port_id = port_id + + +def generate_topo(role: str, port_count: int, uplink_ports: List[int], peer_ports: List[int]): + dut_role_cfg = roles_cfg[role] + + vm_list = [] + hostif_list = [] + per_role_vm_count = {} + for port_id in range(0, port_count): + vm = None + hostif = None + + # Get the VM configuration based on the port ID + vm_role_cfg = None + if port_id in uplink_ports: + if dut_role_cfg["uplink"] is None: + raise ValueError("Uplink port specified for a role that doesn't have an uplink") + + vm_role_cfg = dut_role_cfg["uplink"] + + elif port_id in peer_ports: + if dut_role_cfg["peer"] is None: + raise ValueError("Peer port specified for a role that doesn't have a peer") + + vm_role_cfg = dut_role_cfg["peer"] + + else: + # If downlink is not specified, we consider it is host interface + if dut_role_cfg["downlink"] is not None: + vm_role_cfg = dut_role_cfg["downlink"] + vm_role_cfg["asn"] += 1 + + # Create the VM or host interface based on the configuration + if vm_role_cfg is not None: + if vm_role_cfg["role"] not in per_role_vm_count: + per_role_vm_count[vm_role_cfg["role"]] = 0 + per_role_vm_count[vm_role_cfg["role"]] += 1 + + vm = VM(port_id, len(vm_list), per_role_vm_count[vm_role_cfg["role"]], dut_role_cfg["asn"], vm_role_cfg) + vm_list.append(vm) + + else: + hostif = HostInterface(port_id) + hostif_list.append(hostif) + + return vm_list, hostif_list + + +def generate_topo_file_content(role: str, + template_file: str, + vm_list: List[VM], + hostif_list: List[HostInterface]): + + with open(template_file) as f: + template = jinja2.Template(f.read()) + + output = template.render(role=role, + dut=roles_cfg[role], + vm_list=vm_list, + hostif_list=hostif_list) + + return output + + +def output_topo_file(role: str, + keyword: str, + downlink_port_count: int, + uplink_port_count: int, + peer_port_count: int, + file_content: str): + downlink_keyword = f"d{downlink_port_count}" if downlink_port_count > 0 else "" + uplink_keyword = f"u{uplink_port_count}" if uplink_port_count > 0 else "" + peer_keyword = f"s{peer_port_count}" if peer_port_count > 0 else "" + + file_path = f"vars/topo_{role}-{keyword}-{downlink_keyword}{uplink_keyword}{peer_keyword}.yml" + + with open(file_path, "w") as f: + f.write(file_content) + + print(f"Generated topology file: {file_path}") + + +@click.command() +@click.option("--role", "-r", required=True, type=click.Choice(['t1']), help="Role of the device") +@click.option("--keyword", "-k", required=True, type=str, help="Keyword for the topology file") +@click.option("--template", "-t", required=True, type=str, help="Path to the Jinja template file") +@click.option("--port-count", "-c", required=True, type=int, help="Number of ports on the device") +@click.option("--uplinks", "-u", required=False, type=str, default="", help="Comma-separated list of uplink ports") +@click.option("--peers", "-p", required=False, type=str, default="", help="Comma-separated list of peer ports") +def main(role: str, keyword: str, template: str, port_count: int, uplinks: str, peers: str): + """ + Generate a topology file for a device: + + \b + Examples (in the ansible directory): + - ./generate_topo.py -r t1 -k isolated -t t1-isolated -c 128 + - ./generate_topo.py -r t1 -k isolated -t t1-isolated -c 232 -u 48,49,58,59,164,165,174,175 + """ + uplink_ports = [int(port) for port in uplinks.split(",")] if uplinks != "" else [] + peer_ports = [int(port) for port in peers.split(",")] if peers != "" else [] + + vm_list, hostif_list = generate_topo(role, port_count, uplink_ports, peer_ports) + file_content = generate_topo_file_content(role, f"templates/topo_{template}.j2", vm_list, hostif_list) + output_topo_file(role, keyword, port_count - len(uplink_ports) - len(peer_ports), len(uplink_ports), + len(peer_ports), file_content) + + +if __name__ == "__main__": + main() diff --git a/ansible/templates/topo_t1-isolated.j2 b/ansible/templates/topo_t1-isolated.j2 new file mode 100644 index 00000000000..0c58680063d --- /dev/null +++ b/ansible/templates/topo_t1-isolated.j2 @@ -0,0 +1,47 @@ +topology: + VMs: +{%- for vm in vm_list %} + {{ vm.name }}: + vlans: + - {{ vm.vlans[0] }} + vm_offset: {{ vm.vm_offset }} +{%- endfor %} + +configuration_properties: + common: + dut_asn: {{ dut.asn }} + dut_type: LeafRouter + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine: + swrole: spine + tor: + swrole: tor + +configuration: +{%- for vm in vm_list %} + {{vm.name}}: + properties: + - common + bgp: + asn: {{vm.asn}} + peers: + {{vm.peer_asn}}: + - {{vm.dut_intf_ipv4}} + - {{vm.dut_intf_ipv6}} + interfaces: + Loopback0: + ipv4: {{vm.loopback_ipv4}}/32 + ipv6: {{vm.loopback_ipv6}}/128 + Ethernet1: + ipv4: {{vm.pc_intf_ipv4}}/31 + ipv6: {{vm.pc_intf_ipv6}}/126 + bp_interfaces: + ipv4: {{vm.bp_ipv4}}/24 + ipv6: {{vm.bp_ipv6}}/64 +{%- endfor %} diff --git a/ansible/vars/topo_t1-isolated-d128.yml b/ansible/vars/topo_t1-isolated-d128.yml new file mode 100644 index 00000000000..1873728bd2e --- /dev/null +++ b/ansible/vars/topo_t1-isolated-d128.yml @@ -0,0 +1,2964 @@ +topology: + VMs: + ARISTA01T0: + vlans: + - 0 + vm_offset: 0 + ARISTA02T0: + vlans: + - 1 + vm_offset: 1 + ARISTA03T0: + vlans: + - 2 + vm_offset: 2 + ARISTA04T0: + vlans: + - 3 + vm_offset: 3 + ARISTA05T0: + vlans: + - 4 + vm_offset: 4 + ARISTA06T0: + vlans: + - 5 + vm_offset: 5 + ARISTA07T0: + vlans: + - 6 + vm_offset: 6 + ARISTA08T0: + vlans: + - 7 + vm_offset: 7 + ARISTA09T0: + vlans: + - 8 + vm_offset: 8 + ARISTA10T0: + vlans: + - 9 + vm_offset: 9 + ARISTA11T0: + vlans: + - 10 + vm_offset: 10 + ARISTA12T0: + vlans: + - 11 + vm_offset: 11 + ARISTA13T0: + vlans: + - 12 + vm_offset: 12 + ARISTA14T0: + vlans: + - 13 + vm_offset: 13 + ARISTA15T0: + vlans: + - 14 + vm_offset: 14 + ARISTA16T0: + vlans: + - 15 + vm_offset: 15 + ARISTA17T0: + vlans: + - 16 + vm_offset: 16 + ARISTA18T0: + vlans: + - 17 + vm_offset: 17 + ARISTA19T0: + vlans: + - 18 + vm_offset: 18 + ARISTA20T0: + vlans: + - 19 + vm_offset: 19 + ARISTA21T0: + vlans: + - 20 + vm_offset: 20 + ARISTA22T0: + vlans: + - 21 + vm_offset: 21 + ARISTA23T0: + vlans: + - 22 + vm_offset: 22 + ARISTA24T0: + vlans: + - 23 + vm_offset: 23 + ARISTA25T0: + vlans: + - 24 + vm_offset: 24 + ARISTA26T0: + vlans: + - 25 + vm_offset: 25 + ARISTA27T0: + vlans: + - 26 + vm_offset: 26 + ARISTA28T0: + vlans: + - 27 + vm_offset: 27 + ARISTA29T0: + vlans: + - 28 + vm_offset: 28 + ARISTA30T0: + vlans: + - 29 + vm_offset: 29 + ARISTA31T0: + vlans: + - 30 + vm_offset: 30 + ARISTA32T0: + vlans: + - 31 + vm_offset: 31 + ARISTA33T0: + vlans: + - 32 + vm_offset: 32 + ARISTA34T0: + vlans: + - 33 + vm_offset: 33 + ARISTA35T0: + vlans: + - 34 + vm_offset: 34 + ARISTA36T0: + vlans: + - 35 + vm_offset: 35 + ARISTA37T0: + vlans: + - 36 + vm_offset: 36 + ARISTA38T0: + vlans: + - 37 + vm_offset: 37 + ARISTA39T0: + vlans: + - 38 + vm_offset: 38 + ARISTA40T0: + vlans: + - 39 + vm_offset: 39 + ARISTA41T0: + vlans: + - 40 + vm_offset: 40 + ARISTA42T0: + vlans: + - 41 + vm_offset: 41 + ARISTA43T0: + vlans: + - 42 + vm_offset: 42 + ARISTA44T0: + vlans: + - 43 + vm_offset: 43 + ARISTA45T0: + vlans: + - 44 + vm_offset: 44 + ARISTA46T0: + vlans: + - 45 + vm_offset: 45 + ARISTA47T0: + vlans: + - 46 + vm_offset: 46 + ARISTA48T0: + vlans: + - 47 + vm_offset: 47 + ARISTA49T0: + vlans: + - 48 + vm_offset: 48 + ARISTA50T0: + vlans: + - 49 + vm_offset: 49 + ARISTA51T0: + vlans: + - 50 + vm_offset: 50 + ARISTA52T0: + vlans: + - 51 + vm_offset: 51 + ARISTA53T0: + vlans: + - 52 + vm_offset: 52 + ARISTA54T0: + vlans: + - 53 + vm_offset: 53 + ARISTA55T0: + vlans: + - 54 + vm_offset: 54 + ARISTA56T0: + vlans: + - 55 + vm_offset: 55 + ARISTA57T0: + vlans: + - 56 + vm_offset: 56 + ARISTA58T0: + vlans: + - 57 + vm_offset: 57 + ARISTA59T0: + vlans: + - 58 + vm_offset: 58 + ARISTA60T0: + vlans: + - 59 + vm_offset: 59 + ARISTA61T0: + vlans: + - 60 + vm_offset: 60 + ARISTA62T0: + vlans: + - 61 + vm_offset: 61 + ARISTA63T0: + vlans: + - 62 + vm_offset: 62 + ARISTA64T0: + vlans: + - 63 + vm_offset: 63 + ARISTA65T0: + vlans: + - 64 + vm_offset: 64 + ARISTA66T0: + vlans: + - 65 + vm_offset: 65 + ARISTA67T0: + vlans: + - 66 + vm_offset: 66 + ARISTA68T0: + vlans: + - 67 + vm_offset: 67 + ARISTA69T0: + vlans: + - 68 + vm_offset: 68 + ARISTA70T0: + vlans: + - 69 + vm_offset: 69 + ARISTA71T0: + vlans: + - 70 + vm_offset: 70 + ARISTA72T0: + vlans: + - 71 + vm_offset: 71 + ARISTA73T0: + vlans: + - 72 + vm_offset: 72 + ARISTA74T0: + vlans: + - 73 + vm_offset: 73 + ARISTA75T0: + vlans: + - 74 + vm_offset: 74 + ARISTA76T0: + vlans: + - 75 + vm_offset: 75 + ARISTA77T0: + vlans: + - 76 + vm_offset: 76 + ARISTA78T0: + vlans: + - 77 + vm_offset: 77 + ARISTA79T0: + vlans: + - 78 + vm_offset: 78 + ARISTA80T0: + vlans: + - 79 + vm_offset: 79 + ARISTA81T0: + vlans: + - 80 + vm_offset: 80 + ARISTA82T0: + vlans: + - 81 + vm_offset: 81 + ARISTA83T0: + vlans: + - 82 + vm_offset: 82 + ARISTA84T0: + vlans: + - 83 + vm_offset: 83 + ARISTA85T0: + vlans: + - 84 + vm_offset: 84 + ARISTA86T0: + vlans: + - 85 + vm_offset: 85 + ARISTA87T0: + vlans: + - 86 + vm_offset: 86 + ARISTA88T0: + vlans: + - 87 + vm_offset: 87 + ARISTA89T0: + vlans: + - 88 + vm_offset: 88 + ARISTA90T0: + vlans: + - 89 + vm_offset: 89 + ARISTA91T0: + vlans: + - 90 + vm_offset: 90 + ARISTA92T0: + vlans: + - 91 + vm_offset: 91 + ARISTA93T0: + vlans: + - 92 + vm_offset: 92 + ARISTA94T0: + vlans: + - 93 + vm_offset: 93 + ARISTA95T0: + vlans: + - 94 + vm_offset: 94 + ARISTA96T0: + vlans: + - 95 + vm_offset: 95 + ARISTA97T0: + vlans: + - 96 + vm_offset: 96 + ARISTA98T0: + vlans: + - 97 + vm_offset: 97 + ARISTA99T0: + vlans: + - 98 + vm_offset: 98 + ARISTA100T0: + vlans: + - 99 + vm_offset: 99 + ARISTA101T0: + vlans: + - 100 + vm_offset: 100 + ARISTA102T0: + vlans: + - 101 + vm_offset: 101 + ARISTA103T0: + vlans: + - 102 + vm_offset: 102 + ARISTA104T0: + vlans: + - 103 + vm_offset: 103 + ARISTA105T0: + vlans: + - 104 + vm_offset: 104 + ARISTA106T0: + vlans: + - 105 + vm_offset: 105 + ARISTA107T0: + vlans: + - 106 + vm_offset: 106 + ARISTA108T0: + vlans: + - 107 + vm_offset: 107 + ARISTA109T0: + vlans: + - 108 + vm_offset: 108 + ARISTA110T0: + vlans: + - 109 + vm_offset: 109 + ARISTA111T0: + vlans: + - 110 + vm_offset: 110 + ARISTA112T0: + vlans: + - 111 + vm_offset: 111 + ARISTA113T0: + vlans: + - 112 + vm_offset: 112 + ARISTA114T0: + vlans: + - 113 + vm_offset: 113 + ARISTA115T0: + vlans: + - 114 + vm_offset: 114 + ARISTA116T0: + vlans: + - 115 + vm_offset: 115 + ARISTA117T0: + vlans: + - 116 + vm_offset: 116 + ARISTA118T0: + vlans: + - 117 + vm_offset: 117 + ARISTA119T0: + vlans: + - 118 + vm_offset: 118 + ARISTA120T0: + vlans: + - 119 + vm_offset: 119 + ARISTA121T0: + vlans: + - 120 + vm_offset: 120 + ARISTA122T0: + vlans: + - 121 + vm_offset: 121 + ARISTA123T0: + vlans: + - 122 + vm_offset: 122 + ARISTA124T0: + vlans: + - 123 + vm_offset: 123 + ARISTA125T0: + vlans: + - 124 + vm_offset: 124 + ARISTA126T0: + vlans: + - 125 + vm_offset: 125 + ARISTA127T0: + vlans: + - 126 + vm_offset: 126 + ARISTA128T0: + vlans: + - 127 + vm_offset: 127 + +configuration_properties: + common: + dut_asn: 65100 + dut_type: LeafRouter + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine: + swrole: spine + tor: + swrole: tor + +configuration: + ARISTA01T0: + properties: + - common + bgp: + asn: 64001 + peers: + 65100: + - 10.0.0.0 + - fc00::1 + interfaces: + Loopback0: + ipv4: 100.1.0.1/32 + ipv6: 2064:100::1/128 + Ethernet1: + ipv4: 10.0.0.1/31 + ipv6: fc00::2/126 + bp_interfaces: + ipv4: 10.10.246.2/24 + ipv6: fc0a::2/64 + ARISTA02T0: + properties: + - common + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.2 + - fc00::5 + interfaces: + Loopback0: + ipv4: 100.1.0.2/32 + ipv6: 2064:100::2/128 + Ethernet1: + ipv4: 10.0.0.3/31 + ipv6: fc00::6/126 + bp_interfaces: + ipv4: 10.10.246.3/24 + ipv6: fc0a::3/64 + ARISTA03T0: + properties: + - common + bgp: + asn: 64003 + peers: + 65100: + - 10.0.0.4 + - fc00::9 + interfaces: + Loopback0: + ipv4: 100.1.0.3/32 + ipv6: 2064:100::3/128 + Ethernet1: + ipv4: 10.0.0.5/31 + ipv6: fc00::a/126 + bp_interfaces: + ipv4: 10.10.246.4/24 + ipv6: fc0a::4/64 + ARISTA04T0: + properties: + - common + bgp: + asn: 64004 + peers: + 65100: + - 10.0.0.6 + - fc00::d + interfaces: + Loopback0: + ipv4: 100.1.0.4/32 + ipv6: 2064:100::4/128 + Ethernet1: + ipv4: 10.0.0.7/31 + ipv6: fc00::e/126 + bp_interfaces: + ipv4: 10.10.246.5/24 + ipv6: fc0a::5/64 + ARISTA05T0: + properties: + - common + bgp: + asn: 64005 + peers: + 65100: + - 10.0.0.8 + - fc00::11 + interfaces: + Loopback0: + ipv4: 100.1.0.5/32 + ipv6: 2064:100::5/128 + Ethernet1: + ipv4: 10.0.0.9/31 + ipv6: fc00::12/126 + bp_interfaces: + ipv4: 10.10.246.6/24 + ipv6: fc0a::6/64 + ARISTA06T0: + properties: + - common + bgp: + asn: 64006 + peers: + 65100: + - 10.0.0.10 + - fc00::15 + interfaces: + Loopback0: + ipv4: 100.1.0.6/32 + ipv6: 2064:100::6/128 + Ethernet1: + ipv4: 10.0.0.11/31 + ipv6: fc00::16/126 + bp_interfaces: + ipv4: 10.10.246.7/24 + ipv6: fc0a::7/64 + ARISTA07T0: + properties: + - common + bgp: + asn: 64007 + peers: + 65100: + - 10.0.0.12 + - fc00::19 + interfaces: + Loopback0: + ipv4: 100.1.0.7/32 + ipv6: 2064:100::7/128 + Ethernet1: + ipv4: 10.0.0.13/31 + ipv6: fc00::1a/126 + bp_interfaces: + ipv4: 10.10.246.8/24 + ipv6: fc0a::8/64 + ARISTA08T0: + properties: + - common + bgp: + asn: 64008 + peers: + 65100: + - 10.0.0.14 + - fc00::1d + interfaces: + Loopback0: + ipv4: 100.1.0.8/32 + ipv6: 2064:100::8/128 + Ethernet1: + ipv4: 10.0.0.15/31 + ipv6: fc00::1e/126 + bp_interfaces: + ipv4: 10.10.246.9/24 + ipv6: fc0a::9/64 + ARISTA09T0: + properties: + - common + bgp: + asn: 64009 + peers: + 65100: + - 10.0.0.16 + - fc00::21 + interfaces: + Loopback0: + ipv4: 100.1.0.9/32 + ipv6: 2064:100::9/128 + Ethernet1: + ipv4: 10.0.0.17/31 + ipv6: fc00::22/126 + bp_interfaces: + ipv4: 10.10.246.10/24 + ipv6: fc0a::a/64 + ARISTA10T0: + properties: + - common + bgp: + asn: 64010 + peers: + 65100: + - 10.0.0.18 + - fc00::25 + interfaces: + Loopback0: + ipv4: 100.1.0.10/32 + ipv6: 2064:100::a/128 + Ethernet1: + ipv4: 10.0.0.19/31 + ipv6: fc00::26/126 + bp_interfaces: + ipv4: 10.10.246.11/24 + ipv6: fc0a::b/64 + ARISTA11T0: + properties: + - common + bgp: + asn: 64011 + peers: + 65100: + - 10.0.0.20 + - fc00::29 + interfaces: + Loopback0: + ipv4: 100.1.0.11/32 + ipv6: 2064:100::b/128 + Ethernet1: + ipv4: 10.0.0.21/31 + ipv6: fc00::2a/126 + bp_interfaces: + ipv4: 10.10.246.12/24 + ipv6: fc0a::c/64 + ARISTA12T0: + properties: + - common + bgp: + asn: 64012 + peers: + 65100: + - 10.0.0.22 + - fc00::2d + interfaces: + Loopback0: + ipv4: 100.1.0.12/32 + ipv6: 2064:100::c/128 + Ethernet1: + ipv4: 10.0.0.23/31 + ipv6: fc00::2e/126 + bp_interfaces: + ipv4: 10.10.246.13/24 + ipv6: fc0a::d/64 + ARISTA13T0: + properties: + - common + bgp: + asn: 64013 + peers: + 65100: + - 10.0.0.24 + - fc00::31 + interfaces: + Loopback0: + ipv4: 100.1.0.13/32 + ipv6: 2064:100::d/128 + Ethernet1: + ipv4: 10.0.0.25/31 + ipv6: fc00::32/126 + bp_interfaces: + ipv4: 10.10.246.14/24 + ipv6: fc0a::e/64 + ARISTA14T0: + properties: + - common + bgp: + asn: 64014 + peers: + 65100: + - 10.0.0.26 + - fc00::35 + interfaces: + Loopback0: + ipv4: 100.1.0.14/32 + ipv6: 2064:100::e/128 + Ethernet1: + ipv4: 10.0.0.27/31 + ipv6: fc00::36/126 + bp_interfaces: + ipv4: 10.10.246.15/24 + ipv6: fc0a::f/64 + ARISTA15T0: + properties: + - common + bgp: + asn: 64015 + peers: + 65100: + - 10.0.0.28 + - fc00::39 + interfaces: + Loopback0: + ipv4: 100.1.0.15/32 + ipv6: 2064:100::f/128 + Ethernet1: + ipv4: 10.0.0.29/31 + ipv6: fc00::3a/126 + bp_interfaces: + ipv4: 10.10.246.16/24 + ipv6: fc0a::10/64 + ARISTA16T0: + properties: + - common + bgp: + asn: 64016 + peers: + 65100: + - 10.0.0.30 + - fc00::3d + interfaces: + Loopback0: + ipv4: 100.1.0.16/32 + ipv6: 2064:100::10/128 + Ethernet1: + ipv4: 10.0.0.31/31 + ipv6: fc00::3e/126 + bp_interfaces: + ipv4: 10.10.246.17/24 + ipv6: fc0a::11/64 + ARISTA17T0: + properties: + - common + bgp: + asn: 64017 + peers: + 65100: + - 10.0.0.32 + - fc00::41 + interfaces: + Loopback0: + ipv4: 100.1.0.17/32 + ipv6: 2064:100::11/128 + Ethernet1: + ipv4: 10.0.0.33/31 + ipv6: fc00::42/126 + bp_interfaces: + ipv4: 10.10.246.18/24 + ipv6: fc0a::12/64 + ARISTA18T0: + properties: + - common + bgp: + asn: 64018 + peers: + 65100: + - 10.0.0.34 + - fc00::45 + interfaces: + Loopback0: + ipv4: 100.1.0.18/32 + ipv6: 2064:100::12/128 + Ethernet1: + ipv4: 10.0.0.35/31 + ipv6: fc00::46/126 + bp_interfaces: + ipv4: 10.10.246.19/24 + ipv6: fc0a::13/64 + ARISTA19T0: + properties: + - common + bgp: + asn: 64019 + peers: + 65100: + - 10.0.0.36 + - fc00::49 + interfaces: + Loopback0: + ipv4: 100.1.0.19/32 + ipv6: 2064:100::13/128 + Ethernet1: + ipv4: 10.0.0.37/31 + ipv6: fc00::4a/126 + bp_interfaces: + ipv4: 10.10.246.20/24 + ipv6: fc0a::14/64 + ARISTA20T0: + properties: + - common + bgp: + asn: 64020 + peers: + 65100: + - 10.0.0.38 + - fc00::4d + interfaces: + Loopback0: + ipv4: 100.1.0.20/32 + ipv6: 2064:100::14/128 + Ethernet1: + ipv4: 10.0.0.39/31 + ipv6: fc00::4e/126 + bp_interfaces: + ipv4: 10.10.246.21/24 + ipv6: fc0a::15/64 + ARISTA21T0: + properties: + - common + bgp: + asn: 64021 + peers: + 65100: + - 10.0.0.40 + - fc00::51 + interfaces: + Loopback0: + ipv4: 100.1.0.21/32 + ipv6: 2064:100::15/128 + Ethernet1: + ipv4: 10.0.0.41/31 + ipv6: fc00::52/126 + bp_interfaces: + ipv4: 10.10.246.22/24 + ipv6: fc0a::16/64 + ARISTA22T0: + properties: + - common + bgp: + asn: 64022 + peers: + 65100: + - 10.0.0.42 + - fc00::55 + interfaces: + Loopback0: + ipv4: 100.1.0.22/32 + ipv6: 2064:100::16/128 + Ethernet1: + ipv4: 10.0.0.43/31 + ipv6: fc00::56/126 + bp_interfaces: + ipv4: 10.10.246.23/24 + ipv6: fc0a::17/64 + ARISTA23T0: + properties: + - common + bgp: + asn: 64023 + peers: + 65100: + - 10.0.0.44 + - fc00::59 + interfaces: + Loopback0: + ipv4: 100.1.0.23/32 + ipv6: 2064:100::17/128 + Ethernet1: + ipv4: 10.0.0.45/31 + ipv6: fc00::5a/126 + bp_interfaces: + ipv4: 10.10.246.24/24 + ipv6: fc0a::18/64 + ARISTA24T0: + properties: + - common + bgp: + asn: 64024 + peers: + 65100: + - 10.0.0.46 + - fc00::5d + interfaces: + Loopback0: + ipv4: 100.1.0.24/32 + ipv6: 2064:100::18/128 + Ethernet1: + ipv4: 10.0.0.47/31 + ipv6: fc00::5e/126 + bp_interfaces: + ipv4: 10.10.246.25/24 + ipv6: fc0a::19/64 + ARISTA25T0: + properties: + - common + bgp: + asn: 64025 + peers: + 65100: + - 10.0.0.48 + - fc00::61 + interfaces: + Loopback0: + ipv4: 100.1.0.25/32 + ipv6: 2064:100::19/128 + Ethernet1: + ipv4: 10.0.0.49/31 + ipv6: fc00::62/126 + bp_interfaces: + ipv4: 10.10.246.26/24 + ipv6: fc0a::1a/64 + ARISTA26T0: + properties: + - common + bgp: + asn: 64026 + peers: + 65100: + - 10.0.0.50 + - fc00::65 + interfaces: + Loopback0: + ipv4: 100.1.0.26/32 + ipv6: 2064:100::1a/128 + Ethernet1: + ipv4: 10.0.0.51/31 + ipv6: fc00::66/126 + bp_interfaces: + ipv4: 10.10.246.27/24 + ipv6: fc0a::1b/64 + ARISTA27T0: + properties: + - common + bgp: + asn: 64027 + peers: + 65100: + - 10.0.0.52 + - fc00::69 + interfaces: + Loopback0: + ipv4: 100.1.0.27/32 + ipv6: 2064:100::1b/128 + Ethernet1: + ipv4: 10.0.0.53/31 + ipv6: fc00::6a/126 + bp_interfaces: + ipv4: 10.10.246.28/24 + ipv6: fc0a::1c/64 + ARISTA28T0: + properties: + - common + bgp: + asn: 64028 + peers: + 65100: + - 10.0.0.54 + - fc00::6d + interfaces: + Loopback0: + ipv4: 100.1.0.28/32 + ipv6: 2064:100::1c/128 + Ethernet1: + ipv4: 10.0.0.55/31 + ipv6: fc00::6e/126 + bp_interfaces: + ipv4: 10.10.246.29/24 + ipv6: fc0a::1d/64 + ARISTA29T0: + properties: + - common + bgp: + asn: 64029 + peers: + 65100: + - 10.0.0.56 + - fc00::71 + interfaces: + Loopback0: + ipv4: 100.1.0.29/32 + ipv6: 2064:100::1d/128 + Ethernet1: + ipv4: 10.0.0.57/31 + ipv6: fc00::72/126 + bp_interfaces: + ipv4: 10.10.246.30/24 + ipv6: fc0a::1e/64 + ARISTA30T0: + properties: + - common + bgp: + asn: 64030 + peers: + 65100: + - 10.0.0.58 + - fc00::75 + interfaces: + Loopback0: + ipv4: 100.1.0.30/32 + ipv6: 2064:100::1e/128 + Ethernet1: + ipv4: 10.0.0.59/31 + ipv6: fc00::76/126 + bp_interfaces: + ipv4: 10.10.246.31/24 + ipv6: fc0a::1f/64 + ARISTA31T0: + properties: + - common + bgp: + asn: 64031 + peers: + 65100: + - 10.0.0.60 + - fc00::79 + interfaces: + Loopback0: + ipv4: 100.1.0.31/32 + ipv6: 2064:100::1f/128 + Ethernet1: + ipv4: 10.0.0.61/31 + ipv6: fc00::7a/126 + bp_interfaces: + ipv4: 10.10.246.32/24 + ipv6: fc0a::20/64 + ARISTA32T0: + properties: + - common + bgp: + asn: 64032 + peers: + 65100: + - 10.0.0.62 + - fc00::7d + interfaces: + Loopback0: + ipv4: 100.1.0.32/32 + ipv6: 2064:100::20/128 + Ethernet1: + ipv4: 10.0.0.63/31 + ipv6: fc00::7e/126 + bp_interfaces: + ipv4: 10.10.246.33/24 + ipv6: fc0a::21/64 + ARISTA33T0: + properties: + - common + bgp: + asn: 64033 + peers: + 65100: + - 10.0.0.64 + - fc00::81 + interfaces: + Loopback0: + ipv4: 100.1.0.33/32 + ipv6: 2064:100::21/128 + Ethernet1: + ipv4: 10.0.0.65/31 + ipv6: fc00::82/126 + bp_interfaces: + ipv4: 10.10.246.34/24 + ipv6: fc0a::22/64 + ARISTA34T0: + properties: + - common + bgp: + asn: 64034 + peers: + 65100: + - 10.0.0.66 + - fc00::85 + interfaces: + Loopback0: + ipv4: 100.1.0.34/32 + ipv6: 2064:100::22/128 + Ethernet1: + ipv4: 10.0.0.67/31 + ipv6: fc00::86/126 + bp_interfaces: + ipv4: 10.10.246.35/24 + ipv6: fc0a::23/64 + ARISTA35T0: + properties: + - common + bgp: + asn: 64035 + peers: + 65100: + - 10.0.0.68 + - fc00::89 + interfaces: + Loopback0: + ipv4: 100.1.0.35/32 + ipv6: 2064:100::23/128 + Ethernet1: + ipv4: 10.0.0.69/31 + ipv6: fc00::8a/126 + bp_interfaces: + ipv4: 10.10.246.36/24 + ipv6: fc0a::24/64 + ARISTA36T0: + properties: + - common + bgp: + asn: 64036 + peers: + 65100: + - 10.0.0.70 + - fc00::8d + interfaces: + Loopback0: + ipv4: 100.1.0.36/32 + ipv6: 2064:100::24/128 + Ethernet1: + ipv4: 10.0.0.71/31 + ipv6: fc00::8e/126 + bp_interfaces: + ipv4: 10.10.246.37/24 + ipv6: fc0a::25/64 + ARISTA37T0: + properties: + - common + bgp: + asn: 64037 + peers: + 65100: + - 10.0.0.72 + - fc00::91 + interfaces: + Loopback0: + ipv4: 100.1.0.37/32 + ipv6: 2064:100::25/128 + Ethernet1: + ipv4: 10.0.0.73/31 + ipv6: fc00::92/126 + bp_interfaces: + ipv4: 10.10.246.38/24 + ipv6: fc0a::26/64 + ARISTA38T0: + properties: + - common + bgp: + asn: 64038 + peers: + 65100: + - 10.0.0.74 + - fc00::95 + interfaces: + Loopback0: + ipv4: 100.1.0.38/32 + ipv6: 2064:100::26/128 + Ethernet1: + ipv4: 10.0.0.75/31 + ipv6: fc00::96/126 + bp_interfaces: + ipv4: 10.10.246.39/24 + ipv6: fc0a::27/64 + ARISTA39T0: + properties: + - common + bgp: + asn: 64039 + peers: + 65100: + - 10.0.0.76 + - fc00::99 + interfaces: + Loopback0: + ipv4: 100.1.0.39/32 + ipv6: 2064:100::27/128 + Ethernet1: + ipv4: 10.0.0.77/31 + ipv6: fc00::9a/126 + bp_interfaces: + ipv4: 10.10.246.40/24 + ipv6: fc0a::28/64 + ARISTA40T0: + properties: + - common + bgp: + asn: 64040 + peers: + 65100: + - 10.0.0.78 + - fc00::9d + interfaces: + Loopback0: + ipv4: 100.1.0.40/32 + ipv6: 2064:100::28/128 + Ethernet1: + ipv4: 10.0.0.79/31 + ipv6: fc00::9e/126 + bp_interfaces: + ipv4: 10.10.246.41/24 + ipv6: fc0a::29/64 + ARISTA41T0: + properties: + - common + bgp: + asn: 64041 + peers: + 65100: + - 10.0.0.80 + - fc00::a1 + interfaces: + Loopback0: + ipv4: 100.1.0.41/32 + ipv6: 2064:100::29/128 + Ethernet1: + ipv4: 10.0.0.81/31 + ipv6: fc00::a2/126 + bp_interfaces: + ipv4: 10.10.246.42/24 + ipv6: fc0a::2a/64 + ARISTA42T0: + properties: + - common + bgp: + asn: 64042 + peers: + 65100: + - 10.0.0.82 + - fc00::a5 + interfaces: + Loopback0: + ipv4: 100.1.0.42/32 + ipv6: 2064:100::2a/128 + Ethernet1: + ipv4: 10.0.0.83/31 + ipv6: fc00::a6/126 + bp_interfaces: + ipv4: 10.10.246.43/24 + ipv6: fc0a::2b/64 + ARISTA43T0: + properties: + - common + bgp: + asn: 64043 + peers: + 65100: + - 10.0.0.84 + - fc00::a9 + interfaces: + Loopback0: + ipv4: 100.1.0.43/32 + ipv6: 2064:100::2b/128 + Ethernet1: + ipv4: 10.0.0.85/31 + ipv6: fc00::aa/126 + bp_interfaces: + ipv4: 10.10.246.44/24 + ipv6: fc0a::2c/64 + ARISTA44T0: + properties: + - common + bgp: + asn: 64044 + peers: + 65100: + - 10.0.0.86 + - fc00::ad + interfaces: + Loopback0: + ipv4: 100.1.0.44/32 + ipv6: 2064:100::2c/128 + Ethernet1: + ipv4: 10.0.0.87/31 + ipv6: fc00::ae/126 + bp_interfaces: + ipv4: 10.10.246.45/24 + ipv6: fc0a::2d/64 + ARISTA45T0: + properties: + - common + bgp: + asn: 64045 + peers: + 65100: + - 10.0.0.88 + - fc00::b1 + interfaces: + Loopback0: + ipv4: 100.1.0.45/32 + ipv6: 2064:100::2d/128 + Ethernet1: + ipv4: 10.0.0.89/31 + ipv6: fc00::b2/126 + bp_interfaces: + ipv4: 10.10.246.46/24 + ipv6: fc0a::2e/64 + ARISTA46T0: + properties: + - common + bgp: + asn: 64046 + peers: + 65100: + - 10.0.0.90 + - fc00::b5 + interfaces: + Loopback0: + ipv4: 100.1.0.46/32 + ipv6: 2064:100::2e/128 + Ethernet1: + ipv4: 10.0.0.91/31 + ipv6: fc00::b6/126 + bp_interfaces: + ipv4: 10.10.246.47/24 + ipv6: fc0a::2f/64 + ARISTA47T0: + properties: + - common + bgp: + asn: 64047 + peers: + 65100: + - 10.0.0.92 + - fc00::b9 + interfaces: + Loopback0: + ipv4: 100.1.0.47/32 + ipv6: 2064:100::2f/128 + Ethernet1: + ipv4: 10.0.0.93/31 + ipv6: fc00::ba/126 + bp_interfaces: + ipv4: 10.10.246.48/24 + ipv6: fc0a::30/64 + ARISTA48T0: + properties: + - common + bgp: + asn: 64048 + peers: + 65100: + - 10.0.0.94 + - fc00::bd + interfaces: + Loopback0: + ipv4: 100.1.0.48/32 + ipv6: 2064:100::30/128 + Ethernet1: + ipv4: 10.0.0.95/31 + ipv6: fc00::be/126 + bp_interfaces: + ipv4: 10.10.246.49/24 + ipv6: fc0a::31/64 + ARISTA49T0: + properties: + - common + bgp: + asn: 64049 + peers: + 65100: + - 10.0.0.96 + - fc00::c1 + interfaces: + Loopback0: + ipv4: 100.1.0.49/32 + ipv6: 2064:100::31/128 + Ethernet1: + ipv4: 10.0.0.97/31 + ipv6: fc00::c2/126 + bp_interfaces: + ipv4: 10.10.246.50/24 + ipv6: fc0a::32/64 + ARISTA50T0: + properties: + - common + bgp: + asn: 64050 + peers: + 65100: + - 10.0.0.98 + - fc00::c5 + interfaces: + Loopback0: + ipv4: 100.1.0.50/32 + ipv6: 2064:100::32/128 + Ethernet1: + ipv4: 10.0.0.99/31 + ipv6: fc00::c6/126 + bp_interfaces: + ipv4: 10.10.246.51/24 + ipv6: fc0a::33/64 + ARISTA51T0: + properties: + - common + bgp: + asn: 64051 + peers: + 65100: + - 10.0.0.100 + - fc00::c9 + interfaces: + Loopback0: + ipv4: 100.1.0.51/32 + ipv6: 2064:100::33/128 + Ethernet1: + ipv4: 10.0.0.101/31 + ipv6: fc00::ca/126 + bp_interfaces: + ipv4: 10.10.246.52/24 + ipv6: fc0a::34/64 + ARISTA52T0: + properties: + - common + bgp: + asn: 64052 + peers: + 65100: + - 10.0.0.102 + - fc00::cd + interfaces: + Loopback0: + ipv4: 100.1.0.52/32 + ipv6: 2064:100::34/128 + Ethernet1: + ipv4: 10.0.0.103/31 + ipv6: fc00::ce/126 + bp_interfaces: + ipv4: 10.10.246.53/24 + ipv6: fc0a::35/64 + ARISTA53T0: + properties: + - common + bgp: + asn: 64053 + peers: + 65100: + - 10.0.0.104 + - fc00::d1 + interfaces: + Loopback0: + ipv4: 100.1.0.53/32 + ipv6: 2064:100::35/128 + Ethernet1: + ipv4: 10.0.0.105/31 + ipv6: fc00::d2/126 + bp_interfaces: + ipv4: 10.10.246.54/24 + ipv6: fc0a::36/64 + ARISTA54T0: + properties: + - common + bgp: + asn: 64054 + peers: + 65100: + - 10.0.0.106 + - fc00::d5 + interfaces: + Loopback0: + ipv4: 100.1.0.54/32 + ipv6: 2064:100::36/128 + Ethernet1: + ipv4: 10.0.0.107/31 + ipv6: fc00::d6/126 + bp_interfaces: + ipv4: 10.10.246.55/24 + ipv6: fc0a::37/64 + ARISTA55T0: + properties: + - common + bgp: + asn: 64055 + peers: + 65100: + - 10.0.0.108 + - fc00::d9 + interfaces: + Loopback0: + ipv4: 100.1.0.55/32 + ipv6: 2064:100::37/128 + Ethernet1: + ipv4: 10.0.0.109/31 + ipv6: fc00::da/126 + bp_interfaces: + ipv4: 10.10.246.56/24 + ipv6: fc0a::38/64 + ARISTA56T0: + properties: + - common + bgp: + asn: 64056 + peers: + 65100: + - 10.0.0.110 + - fc00::dd + interfaces: + Loopback0: + ipv4: 100.1.0.56/32 + ipv6: 2064:100::38/128 + Ethernet1: + ipv4: 10.0.0.111/31 + ipv6: fc00::de/126 + bp_interfaces: + ipv4: 10.10.246.57/24 + ipv6: fc0a::39/64 + ARISTA57T0: + properties: + - common + bgp: + asn: 64057 + peers: + 65100: + - 10.0.0.112 + - fc00::e1 + interfaces: + Loopback0: + ipv4: 100.1.0.57/32 + ipv6: 2064:100::39/128 + Ethernet1: + ipv4: 10.0.0.113/31 + ipv6: fc00::e2/126 + bp_interfaces: + ipv4: 10.10.246.58/24 + ipv6: fc0a::3a/64 + ARISTA58T0: + properties: + - common + bgp: + asn: 64058 + peers: + 65100: + - 10.0.0.114 + - fc00::e5 + interfaces: + Loopback0: + ipv4: 100.1.0.58/32 + ipv6: 2064:100::3a/128 + Ethernet1: + ipv4: 10.0.0.115/31 + ipv6: fc00::e6/126 + bp_interfaces: + ipv4: 10.10.246.59/24 + ipv6: fc0a::3b/64 + ARISTA59T0: + properties: + - common + bgp: + asn: 64059 + peers: + 65100: + - 10.0.0.116 + - fc00::e9 + interfaces: + Loopback0: + ipv4: 100.1.0.59/32 + ipv6: 2064:100::3b/128 + Ethernet1: + ipv4: 10.0.0.117/31 + ipv6: fc00::ea/126 + bp_interfaces: + ipv4: 10.10.246.60/24 + ipv6: fc0a::3c/64 + ARISTA60T0: + properties: + - common + bgp: + asn: 64060 + peers: + 65100: + - 10.0.0.118 + - fc00::ed + interfaces: + Loopback0: + ipv4: 100.1.0.60/32 + ipv6: 2064:100::3c/128 + Ethernet1: + ipv4: 10.0.0.119/31 + ipv6: fc00::ee/126 + bp_interfaces: + ipv4: 10.10.246.61/24 + ipv6: fc0a::3d/64 + ARISTA61T0: + properties: + - common + bgp: + asn: 64061 + peers: + 65100: + - 10.0.0.120 + - fc00::f1 + interfaces: + Loopback0: + ipv4: 100.1.0.61/32 + ipv6: 2064:100::3d/128 + Ethernet1: + ipv4: 10.0.0.121/31 + ipv6: fc00::f2/126 + bp_interfaces: + ipv4: 10.10.246.62/24 + ipv6: fc0a::3e/64 + ARISTA62T0: + properties: + - common + bgp: + asn: 64062 + peers: + 65100: + - 10.0.0.122 + - fc00::f5 + interfaces: + Loopback0: + ipv4: 100.1.0.62/32 + ipv6: 2064:100::3e/128 + Ethernet1: + ipv4: 10.0.0.123/31 + ipv6: fc00::f6/126 + bp_interfaces: + ipv4: 10.10.246.63/24 + ipv6: fc0a::3f/64 + ARISTA63T0: + properties: + - common + bgp: + asn: 64063 + peers: + 65100: + - 10.0.0.124 + - fc00::f9 + interfaces: + Loopback0: + ipv4: 100.1.0.63/32 + ipv6: 2064:100::3f/128 + Ethernet1: + ipv4: 10.0.0.125/31 + ipv6: fc00::fa/126 + bp_interfaces: + ipv4: 10.10.246.64/24 + ipv6: fc0a::40/64 + ARISTA64T0: + properties: + - common + bgp: + asn: 64064 + peers: + 65100: + - 10.0.0.126 + - fc00::fd + interfaces: + Loopback0: + ipv4: 100.1.0.64/32 + ipv6: 2064:100::40/128 + Ethernet1: + ipv4: 10.0.0.127/31 + ipv6: fc00::fe/126 + bp_interfaces: + ipv4: 10.10.246.65/24 + ipv6: fc0a::41/64 + ARISTA65T0: + properties: + - common + bgp: + asn: 64065 + peers: + 65100: + - 10.0.0.128 + - fc00::101 + interfaces: + Loopback0: + ipv4: 100.1.0.65/32 + ipv6: 2064:100::41/128 + Ethernet1: + ipv4: 10.0.0.129/31 + ipv6: fc00::102/126 + bp_interfaces: + ipv4: 10.10.246.66/24 + ipv6: fc0a::42/64 + ARISTA66T0: + properties: + - common + bgp: + asn: 64066 + peers: + 65100: + - 10.0.0.130 + - fc00::105 + interfaces: + Loopback0: + ipv4: 100.1.0.66/32 + ipv6: 2064:100::42/128 + Ethernet1: + ipv4: 10.0.0.131/31 + ipv6: fc00::106/126 + bp_interfaces: + ipv4: 10.10.246.67/24 + ipv6: fc0a::43/64 + ARISTA67T0: + properties: + - common + bgp: + asn: 64067 + peers: + 65100: + - 10.0.0.132 + - fc00::109 + interfaces: + Loopback0: + ipv4: 100.1.0.67/32 + ipv6: 2064:100::43/128 + Ethernet1: + ipv4: 10.0.0.133/31 + ipv6: fc00::10a/126 + bp_interfaces: + ipv4: 10.10.246.68/24 + ipv6: fc0a::44/64 + ARISTA68T0: + properties: + - common + bgp: + asn: 64068 + peers: + 65100: + - 10.0.0.134 + - fc00::10d + interfaces: + Loopback0: + ipv4: 100.1.0.68/32 + ipv6: 2064:100::44/128 + Ethernet1: + ipv4: 10.0.0.135/31 + ipv6: fc00::10e/126 + bp_interfaces: + ipv4: 10.10.246.69/24 + ipv6: fc0a::45/64 + ARISTA69T0: + properties: + - common + bgp: + asn: 64069 + peers: + 65100: + - 10.0.0.136 + - fc00::111 + interfaces: + Loopback0: + ipv4: 100.1.0.69/32 + ipv6: 2064:100::45/128 + Ethernet1: + ipv4: 10.0.0.137/31 + ipv6: fc00::112/126 + bp_interfaces: + ipv4: 10.10.246.70/24 + ipv6: fc0a::46/64 + ARISTA70T0: + properties: + - common + bgp: + asn: 64070 + peers: + 65100: + - 10.0.0.138 + - fc00::115 + interfaces: + Loopback0: + ipv4: 100.1.0.70/32 + ipv6: 2064:100::46/128 + Ethernet1: + ipv4: 10.0.0.139/31 + ipv6: fc00::116/126 + bp_interfaces: + ipv4: 10.10.246.71/24 + ipv6: fc0a::47/64 + ARISTA71T0: + properties: + - common + bgp: + asn: 64071 + peers: + 65100: + - 10.0.0.140 + - fc00::119 + interfaces: + Loopback0: + ipv4: 100.1.0.71/32 + ipv6: 2064:100::47/128 + Ethernet1: + ipv4: 10.0.0.141/31 + ipv6: fc00::11a/126 + bp_interfaces: + ipv4: 10.10.246.72/24 + ipv6: fc0a::48/64 + ARISTA72T0: + properties: + - common + bgp: + asn: 64072 + peers: + 65100: + - 10.0.0.142 + - fc00::11d + interfaces: + Loopback0: + ipv4: 100.1.0.72/32 + ipv6: 2064:100::48/128 + Ethernet1: + ipv4: 10.0.0.143/31 + ipv6: fc00::11e/126 + bp_interfaces: + ipv4: 10.10.246.73/24 + ipv6: fc0a::49/64 + ARISTA73T0: + properties: + - common + bgp: + asn: 64073 + peers: + 65100: + - 10.0.0.144 + - fc00::121 + interfaces: + Loopback0: + ipv4: 100.1.0.73/32 + ipv6: 2064:100::49/128 + Ethernet1: + ipv4: 10.0.0.145/31 + ipv6: fc00::122/126 + bp_interfaces: + ipv4: 10.10.246.74/24 + ipv6: fc0a::4a/64 + ARISTA74T0: + properties: + - common + bgp: + asn: 64074 + peers: + 65100: + - 10.0.0.146 + - fc00::125 + interfaces: + Loopback0: + ipv4: 100.1.0.74/32 + ipv6: 2064:100::4a/128 + Ethernet1: + ipv4: 10.0.0.147/31 + ipv6: fc00::126/126 + bp_interfaces: + ipv4: 10.10.246.75/24 + ipv6: fc0a::4b/64 + ARISTA75T0: + properties: + - common + bgp: + asn: 64075 + peers: + 65100: + - 10.0.0.148 + - fc00::129 + interfaces: + Loopback0: + ipv4: 100.1.0.75/32 + ipv6: 2064:100::4b/128 + Ethernet1: + ipv4: 10.0.0.149/31 + ipv6: fc00::12a/126 + bp_interfaces: + ipv4: 10.10.246.76/24 + ipv6: fc0a::4c/64 + ARISTA76T0: + properties: + - common + bgp: + asn: 64076 + peers: + 65100: + - 10.0.0.150 + - fc00::12d + interfaces: + Loopback0: + ipv4: 100.1.0.76/32 + ipv6: 2064:100::4c/128 + Ethernet1: + ipv4: 10.0.0.151/31 + ipv6: fc00::12e/126 + bp_interfaces: + ipv4: 10.10.246.77/24 + ipv6: fc0a::4d/64 + ARISTA77T0: + properties: + - common + bgp: + asn: 64077 + peers: + 65100: + - 10.0.0.152 + - fc00::131 + interfaces: + Loopback0: + ipv4: 100.1.0.77/32 + ipv6: 2064:100::4d/128 + Ethernet1: + ipv4: 10.0.0.153/31 + ipv6: fc00::132/126 + bp_interfaces: + ipv4: 10.10.246.78/24 + ipv6: fc0a::4e/64 + ARISTA78T0: + properties: + - common + bgp: + asn: 64078 + peers: + 65100: + - 10.0.0.154 + - fc00::135 + interfaces: + Loopback0: + ipv4: 100.1.0.78/32 + ipv6: 2064:100::4e/128 + Ethernet1: + ipv4: 10.0.0.155/31 + ipv6: fc00::136/126 + bp_interfaces: + ipv4: 10.10.246.79/24 + ipv6: fc0a::4f/64 + ARISTA79T0: + properties: + - common + bgp: + asn: 64079 + peers: + 65100: + - 10.0.0.156 + - fc00::139 + interfaces: + Loopback0: + ipv4: 100.1.0.79/32 + ipv6: 2064:100::4f/128 + Ethernet1: + ipv4: 10.0.0.157/31 + ipv6: fc00::13a/126 + bp_interfaces: + ipv4: 10.10.246.80/24 + ipv6: fc0a::50/64 + ARISTA80T0: + properties: + - common + bgp: + asn: 64080 + peers: + 65100: + - 10.0.0.158 + - fc00::13d + interfaces: + Loopback0: + ipv4: 100.1.0.80/32 + ipv6: 2064:100::50/128 + Ethernet1: + ipv4: 10.0.0.159/31 + ipv6: fc00::13e/126 + bp_interfaces: + ipv4: 10.10.246.81/24 + ipv6: fc0a::51/64 + ARISTA81T0: + properties: + - common + bgp: + asn: 64081 + peers: + 65100: + - 10.0.0.160 + - fc00::141 + interfaces: + Loopback0: + ipv4: 100.1.0.81/32 + ipv6: 2064:100::51/128 + Ethernet1: + ipv4: 10.0.0.161/31 + ipv6: fc00::142/126 + bp_interfaces: + ipv4: 10.10.246.82/24 + ipv6: fc0a::52/64 + ARISTA82T0: + properties: + - common + bgp: + asn: 64082 + peers: + 65100: + - 10.0.0.162 + - fc00::145 + interfaces: + Loopback0: + ipv4: 100.1.0.82/32 + ipv6: 2064:100::52/128 + Ethernet1: + ipv4: 10.0.0.163/31 + ipv6: fc00::146/126 + bp_interfaces: + ipv4: 10.10.246.83/24 + ipv6: fc0a::53/64 + ARISTA83T0: + properties: + - common + bgp: + asn: 64083 + peers: + 65100: + - 10.0.0.164 + - fc00::149 + interfaces: + Loopback0: + ipv4: 100.1.0.83/32 + ipv6: 2064:100::53/128 + Ethernet1: + ipv4: 10.0.0.165/31 + ipv6: fc00::14a/126 + bp_interfaces: + ipv4: 10.10.246.84/24 + ipv6: fc0a::54/64 + ARISTA84T0: + properties: + - common + bgp: + asn: 64084 + peers: + 65100: + - 10.0.0.166 + - fc00::14d + interfaces: + Loopback0: + ipv4: 100.1.0.84/32 + ipv6: 2064:100::54/128 + Ethernet1: + ipv4: 10.0.0.167/31 + ipv6: fc00::14e/126 + bp_interfaces: + ipv4: 10.10.246.85/24 + ipv6: fc0a::55/64 + ARISTA85T0: + properties: + - common + bgp: + asn: 64085 + peers: + 65100: + - 10.0.0.168 + - fc00::151 + interfaces: + Loopback0: + ipv4: 100.1.0.85/32 + ipv6: 2064:100::55/128 + Ethernet1: + ipv4: 10.0.0.169/31 + ipv6: fc00::152/126 + bp_interfaces: + ipv4: 10.10.246.86/24 + ipv6: fc0a::56/64 + ARISTA86T0: + properties: + - common + bgp: + asn: 64086 + peers: + 65100: + - 10.0.0.170 + - fc00::155 + interfaces: + Loopback0: + ipv4: 100.1.0.86/32 + ipv6: 2064:100::56/128 + Ethernet1: + ipv4: 10.0.0.171/31 + ipv6: fc00::156/126 + bp_interfaces: + ipv4: 10.10.246.87/24 + ipv6: fc0a::57/64 + ARISTA87T0: + properties: + - common + bgp: + asn: 64087 + peers: + 65100: + - 10.0.0.172 + - fc00::159 + interfaces: + Loopback0: + ipv4: 100.1.0.87/32 + ipv6: 2064:100::57/128 + Ethernet1: + ipv4: 10.0.0.173/31 + ipv6: fc00::15a/126 + bp_interfaces: + ipv4: 10.10.246.88/24 + ipv6: fc0a::58/64 + ARISTA88T0: + properties: + - common + bgp: + asn: 64088 + peers: + 65100: + - 10.0.0.174 + - fc00::15d + interfaces: + Loopback0: + ipv4: 100.1.0.88/32 + ipv6: 2064:100::58/128 + Ethernet1: + ipv4: 10.0.0.175/31 + ipv6: fc00::15e/126 + bp_interfaces: + ipv4: 10.10.246.89/24 + ipv6: fc0a::59/64 + ARISTA89T0: + properties: + - common + bgp: + asn: 64089 + peers: + 65100: + - 10.0.0.176 + - fc00::161 + interfaces: + Loopback0: + ipv4: 100.1.0.89/32 + ipv6: 2064:100::59/128 + Ethernet1: + ipv4: 10.0.0.177/31 + ipv6: fc00::162/126 + bp_interfaces: + ipv4: 10.10.246.90/24 + ipv6: fc0a::5a/64 + ARISTA90T0: + properties: + - common + bgp: + asn: 64090 + peers: + 65100: + - 10.0.0.178 + - fc00::165 + interfaces: + Loopback0: + ipv4: 100.1.0.90/32 + ipv6: 2064:100::5a/128 + Ethernet1: + ipv4: 10.0.0.179/31 + ipv6: fc00::166/126 + bp_interfaces: + ipv4: 10.10.246.91/24 + ipv6: fc0a::5b/64 + ARISTA91T0: + properties: + - common + bgp: + asn: 64091 + peers: + 65100: + - 10.0.0.180 + - fc00::169 + interfaces: + Loopback0: + ipv4: 100.1.0.91/32 + ipv6: 2064:100::5b/128 + Ethernet1: + ipv4: 10.0.0.181/31 + ipv6: fc00::16a/126 + bp_interfaces: + ipv4: 10.10.246.92/24 + ipv6: fc0a::5c/64 + ARISTA92T0: + properties: + - common + bgp: + asn: 64092 + peers: + 65100: + - 10.0.0.182 + - fc00::16d + interfaces: + Loopback0: + ipv4: 100.1.0.92/32 + ipv6: 2064:100::5c/128 + Ethernet1: + ipv4: 10.0.0.183/31 + ipv6: fc00::16e/126 + bp_interfaces: + ipv4: 10.10.246.93/24 + ipv6: fc0a::5d/64 + ARISTA93T0: + properties: + - common + bgp: + asn: 64093 + peers: + 65100: + - 10.0.0.184 + - fc00::171 + interfaces: + Loopback0: + ipv4: 100.1.0.93/32 + ipv6: 2064:100::5d/128 + Ethernet1: + ipv4: 10.0.0.185/31 + ipv6: fc00::172/126 + bp_interfaces: + ipv4: 10.10.246.94/24 + ipv6: fc0a::5e/64 + ARISTA94T0: + properties: + - common + bgp: + asn: 64094 + peers: + 65100: + - 10.0.0.186 + - fc00::175 + interfaces: + Loopback0: + ipv4: 100.1.0.94/32 + ipv6: 2064:100::5e/128 + Ethernet1: + ipv4: 10.0.0.187/31 + ipv6: fc00::176/126 + bp_interfaces: + ipv4: 10.10.246.95/24 + ipv6: fc0a::5f/64 + ARISTA95T0: + properties: + - common + bgp: + asn: 64095 + peers: + 65100: + - 10.0.0.188 + - fc00::179 + interfaces: + Loopback0: + ipv4: 100.1.0.95/32 + ipv6: 2064:100::5f/128 + Ethernet1: + ipv4: 10.0.0.189/31 + ipv6: fc00::17a/126 + bp_interfaces: + ipv4: 10.10.246.96/24 + ipv6: fc0a::60/64 + ARISTA96T0: + properties: + - common + bgp: + asn: 64096 + peers: + 65100: + - 10.0.0.190 + - fc00::17d + interfaces: + Loopback0: + ipv4: 100.1.0.96/32 + ipv6: 2064:100::60/128 + Ethernet1: + ipv4: 10.0.0.191/31 + ipv6: fc00::17e/126 + bp_interfaces: + ipv4: 10.10.246.97/24 + ipv6: fc0a::61/64 + ARISTA97T0: + properties: + - common + bgp: + asn: 64097 + peers: + 65100: + - 10.0.0.192 + - fc00::181 + interfaces: + Loopback0: + ipv4: 100.1.0.97/32 + ipv6: 2064:100::61/128 + Ethernet1: + ipv4: 10.0.0.193/31 + ipv6: fc00::182/126 + bp_interfaces: + ipv4: 10.10.246.98/24 + ipv6: fc0a::62/64 + ARISTA98T0: + properties: + - common + bgp: + asn: 64098 + peers: + 65100: + - 10.0.0.194 + - fc00::185 + interfaces: + Loopback0: + ipv4: 100.1.0.98/32 + ipv6: 2064:100::62/128 + Ethernet1: + ipv4: 10.0.0.195/31 + ipv6: fc00::186/126 + bp_interfaces: + ipv4: 10.10.246.99/24 + ipv6: fc0a::63/64 + ARISTA99T0: + properties: + - common + bgp: + asn: 64099 + peers: + 65100: + - 10.0.0.196 + - fc00::189 + interfaces: + Loopback0: + ipv4: 100.1.0.99/32 + ipv6: 2064:100::63/128 + Ethernet1: + ipv4: 10.0.0.197/31 + ipv6: fc00::18a/126 + bp_interfaces: + ipv4: 10.10.246.100/24 + ipv6: fc0a::64/64 + ARISTA100T0: + properties: + - common + bgp: + asn: 64100 + peers: + 65100: + - 10.0.0.198 + - fc00::18d + interfaces: + Loopback0: + ipv4: 100.1.0.100/32 + ipv6: 2064:100::64/128 + Ethernet1: + ipv4: 10.0.0.199/31 + ipv6: fc00::18e/126 + bp_interfaces: + ipv4: 10.10.246.101/24 + ipv6: fc0a::65/64 + ARISTA101T0: + properties: + - common + bgp: + asn: 64101 + peers: + 65100: + - 10.0.0.200 + - fc00::191 + interfaces: + Loopback0: + ipv4: 100.1.0.101/32 + ipv6: 2064:100::65/128 + Ethernet1: + ipv4: 10.0.0.201/31 + ipv6: fc00::192/126 + bp_interfaces: + ipv4: 10.10.246.102/24 + ipv6: fc0a::66/64 + ARISTA102T0: + properties: + - common + bgp: + asn: 64102 + peers: + 65100: + - 10.0.0.202 + - fc00::195 + interfaces: + Loopback0: + ipv4: 100.1.0.102/32 + ipv6: 2064:100::66/128 + Ethernet1: + ipv4: 10.0.0.203/31 + ipv6: fc00::196/126 + bp_interfaces: + ipv4: 10.10.246.103/24 + ipv6: fc0a::67/64 + ARISTA103T0: + properties: + - common + bgp: + asn: 64103 + peers: + 65100: + - 10.0.0.204 + - fc00::199 + interfaces: + Loopback0: + ipv4: 100.1.0.103/32 + ipv6: 2064:100::67/128 + Ethernet1: + ipv4: 10.0.0.205/31 + ipv6: fc00::19a/126 + bp_interfaces: + ipv4: 10.10.246.104/24 + ipv6: fc0a::68/64 + ARISTA104T0: + properties: + - common + bgp: + asn: 64104 + peers: + 65100: + - 10.0.0.206 + - fc00::19d + interfaces: + Loopback0: + ipv4: 100.1.0.104/32 + ipv6: 2064:100::68/128 + Ethernet1: + ipv4: 10.0.0.207/31 + ipv6: fc00::19e/126 + bp_interfaces: + ipv4: 10.10.246.105/24 + ipv6: fc0a::69/64 + ARISTA105T0: + properties: + - common + bgp: + asn: 64105 + peers: + 65100: + - 10.0.0.208 + - fc00::1a1 + interfaces: + Loopback0: + ipv4: 100.1.0.105/32 + ipv6: 2064:100::69/128 + Ethernet1: + ipv4: 10.0.0.209/31 + ipv6: fc00::1a2/126 + bp_interfaces: + ipv4: 10.10.246.106/24 + ipv6: fc0a::6a/64 + ARISTA106T0: + properties: + - common + bgp: + asn: 64106 + peers: + 65100: + - 10.0.0.210 + - fc00::1a5 + interfaces: + Loopback0: + ipv4: 100.1.0.106/32 + ipv6: 2064:100::6a/128 + Ethernet1: + ipv4: 10.0.0.211/31 + ipv6: fc00::1a6/126 + bp_interfaces: + ipv4: 10.10.246.107/24 + ipv6: fc0a::6b/64 + ARISTA107T0: + properties: + - common + bgp: + asn: 64107 + peers: + 65100: + - 10.0.0.212 + - fc00::1a9 + interfaces: + Loopback0: + ipv4: 100.1.0.107/32 + ipv6: 2064:100::6b/128 + Ethernet1: + ipv4: 10.0.0.213/31 + ipv6: fc00::1aa/126 + bp_interfaces: + ipv4: 10.10.246.108/24 + ipv6: fc0a::6c/64 + ARISTA108T0: + properties: + - common + bgp: + asn: 64108 + peers: + 65100: + - 10.0.0.214 + - fc00::1ad + interfaces: + Loopback0: + ipv4: 100.1.0.108/32 + ipv6: 2064:100::6c/128 + Ethernet1: + ipv4: 10.0.0.215/31 + ipv6: fc00::1ae/126 + bp_interfaces: + ipv4: 10.10.246.109/24 + ipv6: fc0a::6d/64 + ARISTA109T0: + properties: + - common + bgp: + asn: 64109 + peers: + 65100: + - 10.0.0.216 + - fc00::1b1 + interfaces: + Loopback0: + ipv4: 100.1.0.109/32 + ipv6: 2064:100::6d/128 + Ethernet1: + ipv4: 10.0.0.217/31 + ipv6: fc00::1b2/126 + bp_interfaces: + ipv4: 10.10.246.110/24 + ipv6: fc0a::6e/64 + ARISTA110T0: + properties: + - common + bgp: + asn: 64110 + peers: + 65100: + - 10.0.0.218 + - fc00::1b5 + interfaces: + Loopback0: + ipv4: 100.1.0.110/32 + ipv6: 2064:100::6e/128 + Ethernet1: + ipv4: 10.0.0.219/31 + ipv6: fc00::1b6/126 + bp_interfaces: + ipv4: 10.10.246.111/24 + ipv6: fc0a::6f/64 + ARISTA111T0: + properties: + - common + bgp: + asn: 64111 + peers: + 65100: + - 10.0.0.220 + - fc00::1b9 + interfaces: + Loopback0: + ipv4: 100.1.0.111/32 + ipv6: 2064:100::6f/128 + Ethernet1: + ipv4: 10.0.0.221/31 + ipv6: fc00::1ba/126 + bp_interfaces: + ipv4: 10.10.246.112/24 + ipv6: fc0a::70/64 + ARISTA112T0: + properties: + - common + bgp: + asn: 64112 + peers: + 65100: + - 10.0.0.222 + - fc00::1bd + interfaces: + Loopback0: + ipv4: 100.1.0.112/32 + ipv6: 2064:100::70/128 + Ethernet1: + ipv4: 10.0.0.223/31 + ipv6: fc00::1be/126 + bp_interfaces: + ipv4: 10.10.246.113/24 + ipv6: fc0a::71/64 + ARISTA113T0: + properties: + - common + bgp: + asn: 64113 + peers: + 65100: + - 10.0.0.224 + - fc00::1c1 + interfaces: + Loopback0: + ipv4: 100.1.0.113/32 + ipv6: 2064:100::71/128 + Ethernet1: + ipv4: 10.0.0.225/31 + ipv6: fc00::1c2/126 + bp_interfaces: + ipv4: 10.10.246.114/24 + ipv6: fc0a::72/64 + ARISTA114T0: + properties: + - common + bgp: + asn: 64114 + peers: + 65100: + - 10.0.0.226 + - fc00::1c5 + interfaces: + Loopback0: + ipv4: 100.1.0.114/32 + ipv6: 2064:100::72/128 + Ethernet1: + ipv4: 10.0.0.227/31 + ipv6: fc00::1c6/126 + bp_interfaces: + ipv4: 10.10.246.115/24 + ipv6: fc0a::73/64 + ARISTA115T0: + properties: + - common + bgp: + asn: 64115 + peers: + 65100: + - 10.0.0.228 + - fc00::1c9 + interfaces: + Loopback0: + ipv4: 100.1.0.115/32 + ipv6: 2064:100::73/128 + Ethernet1: + ipv4: 10.0.0.229/31 + ipv6: fc00::1ca/126 + bp_interfaces: + ipv4: 10.10.246.116/24 + ipv6: fc0a::74/64 + ARISTA116T0: + properties: + - common + bgp: + asn: 64116 + peers: + 65100: + - 10.0.0.230 + - fc00::1cd + interfaces: + Loopback0: + ipv4: 100.1.0.116/32 + ipv6: 2064:100::74/128 + Ethernet1: + ipv4: 10.0.0.231/31 + ipv6: fc00::1ce/126 + bp_interfaces: + ipv4: 10.10.246.117/24 + ipv6: fc0a::75/64 + ARISTA117T0: + properties: + - common + bgp: + asn: 64117 + peers: + 65100: + - 10.0.0.232 + - fc00::1d1 + interfaces: + Loopback0: + ipv4: 100.1.0.117/32 + ipv6: 2064:100::75/128 + Ethernet1: + ipv4: 10.0.0.233/31 + ipv6: fc00::1d2/126 + bp_interfaces: + ipv4: 10.10.246.118/24 + ipv6: fc0a::76/64 + ARISTA118T0: + properties: + - common + bgp: + asn: 64118 + peers: + 65100: + - 10.0.0.234 + - fc00::1d5 + interfaces: + Loopback0: + ipv4: 100.1.0.118/32 + ipv6: 2064:100::76/128 + Ethernet1: + ipv4: 10.0.0.235/31 + ipv6: fc00::1d6/126 + bp_interfaces: + ipv4: 10.10.246.119/24 + ipv6: fc0a::77/64 + ARISTA119T0: + properties: + - common + bgp: + asn: 64119 + peers: + 65100: + - 10.0.0.236 + - fc00::1d9 + interfaces: + Loopback0: + ipv4: 100.1.0.119/32 + ipv6: 2064:100::77/128 + Ethernet1: + ipv4: 10.0.0.237/31 + ipv6: fc00::1da/126 + bp_interfaces: + ipv4: 10.10.246.120/24 + ipv6: fc0a::78/64 + ARISTA120T0: + properties: + - common + bgp: + asn: 64120 + peers: + 65100: + - 10.0.0.238 + - fc00::1dd + interfaces: + Loopback0: + ipv4: 100.1.0.120/32 + ipv6: 2064:100::78/128 + Ethernet1: + ipv4: 10.0.0.239/31 + ipv6: fc00::1de/126 + bp_interfaces: + ipv4: 10.10.246.121/24 + ipv6: fc0a::79/64 + ARISTA121T0: + properties: + - common + bgp: + asn: 64121 + peers: + 65100: + - 10.0.0.240 + - fc00::1e1 + interfaces: + Loopback0: + ipv4: 100.1.0.121/32 + ipv6: 2064:100::79/128 + Ethernet1: + ipv4: 10.0.0.241/31 + ipv6: fc00::1e2/126 + bp_interfaces: + ipv4: 10.10.246.122/24 + ipv6: fc0a::7a/64 + ARISTA122T0: + properties: + - common + bgp: + asn: 64122 + peers: + 65100: + - 10.0.0.242 + - fc00::1e5 + interfaces: + Loopback0: + ipv4: 100.1.0.122/32 + ipv6: 2064:100::7a/128 + Ethernet1: + ipv4: 10.0.0.243/31 + ipv6: fc00::1e6/126 + bp_interfaces: + ipv4: 10.10.246.123/24 + ipv6: fc0a::7b/64 + ARISTA123T0: + properties: + - common + bgp: + asn: 64123 + peers: + 65100: + - 10.0.0.244 + - fc00::1e9 + interfaces: + Loopback0: + ipv4: 100.1.0.123/32 + ipv6: 2064:100::7b/128 + Ethernet1: + ipv4: 10.0.0.245/31 + ipv6: fc00::1ea/126 + bp_interfaces: + ipv4: 10.10.246.124/24 + ipv6: fc0a::7c/64 + ARISTA124T0: + properties: + - common + bgp: + asn: 64124 + peers: + 65100: + - 10.0.0.246 + - fc00::1ed + interfaces: + Loopback0: + ipv4: 100.1.0.124/32 + ipv6: 2064:100::7c/128 + Ethernet1: + ipv4: 10.0.0.247/31 + ipv6: fc00::1ee/126 + bp_interfaces: + ipv4: 10.10.246.125/24 + ipv6: fc0a::7d/64 + ARISTA125T0: + properties: + - common + bgp: + asn: 64125 + peers: + 65100: + - 10.0.0.248 + - fc00::1f1 + interfaces: + Loopback0: + ipv4: 100.1.0.125/32 + ipv6: 2064:100::7d/128 + Ethernet1: + ipv4: 10.0.0.249/31 + ipv6: fc00::1f2/126 + bp_interfaces: + ipv4: 10.10.246.126/24 + ipv6: fc0a::7e/64 + ARISTA126T0: + properties: + - common + bgp: + asn: 64126 + peers: + 65100: + - 10.0.0.250 + - fc00::1f5 + interfaces: + Loopback0: + ipv4: 100.1.0.126/32 + ipv6: 2064:100::7e/128 + Ethernet1: + ipv4: 10.0.0.251/31 + ipv6: fc00::1f6/126 + bp_interfaces: + ipv4: 10.10.246.127/24 + ipv6: fc0a::7f/64 + ARISTA127T0: + properties: + - common + bgp: + asn: 64127 + peers: + 65100: + - 10.0.0.252 + - fc00::1f9 + interfaces: + Loopback0: + ipv4: 100.1.0.127/32 + ipv6: 2064:100::7f/128 + Ethernet1: + ipv4: 10.0.0.253/31 + ipv6: fc00::1fa/126 + bp_interfaces: + ipv4: 10.10.246.128/24 + ipv6: fc0a::80/64 + ARISTA128T0: + properties: + - common + bgp: + asn: 64128 + peers: + 65100: + - 10.0.0.254 + - fc00::1fd + interfaces: + Loopback0: + ipv4: 100.1.0.128/32 + ipv6: 2064:100::80/128 + Ethernet1: + ipv4: 10.0.0.255/31 + ipv6: fc00::1fe/126 + bp_interfaces: + ipv4: 10.10.246.129/24 + ipv6: fc0a::81/64 From 4a494feee9b75040df05e2209ab6e82532c58d70 Mon Sep 17 00:00:00 2001 From: Riff Date: Thu, 7 Nov 2024 16:50:52 -0800 Subject: [PATCH 111/221] Fix VM name and downlink ASN numbers in t1-isolated-d224u8 topology (#15447) * Rename. * Fix the VM names, downlink ASN and VLAN offset. --- ...224u8.yaml => topo_t1-isolated-d224u8.yml} | 3738 ++++++++--------- 1 file changed, 1869 insertions(+), 1869 deletions(-) rename ansible/vars/{topo_t1-isolated-d224u8.yaml => topo_t1-isolated-d224u8.yml} (91%) diff --git a/ansible/vars/topo_t1-isolated-d224u8.yaml b/ansible/vars/topo_t1-isolated-d224u8.yml similarity index 91% rename from ansible/vars/topo_t1-isolated-d224u8.yaml rename to ansible/vars/topo_t1-isolated-d224u8.yml index 5f97f7fd713..f2f809366d5 100644 --- a/ansible/vars/topo_t1-isolated-d224u8.yaml +++ b/ansible/vars/topo_t1-isolated-d224u8.yml @@ -192,741 +192,741 @@ topology: vlans: - 47 vm_offset: 47 - ARISTA49T2: + ARISTA01T2: vlans: - 48 vm_offset: 48 - ARISTA50T2: + ARISTA02T2: vlans: - 49 vm_offset: 49 - ARISTA51T0: + ARISTA49T0: vlans: - - 56 + - 50 vm_offset: 50 - ARISTA52T0: + ARISTA50T0: vlans: - - 57 + - 51 vm_offset: 51 - ARISTA53T0: + ARISTA51T0: vlans: - - 58 + - 52 vm_offset: 52 - ARISTA54T0: + ARISTA52T0: vlans: - - 59 + - 53 vm_offset: 53 - ARISTA55T0: + ARISTA53T0: vlans: - - 60 + - 54 vm_offset: 54 - ARISTA56T0: + ARISTA54T0: vlans: - - 61 + - 55 vm_offset: 55 - ARISTA57T0: + ARISTA55T0: vlans: - - 62 + - 56 vm_offset: 56 - ARISTA58T0: + ARISTA56T0: vlans: - - 63 + - 57 vm_offset: 57 - ARISTA59T2: + ARISTA03T2: vlans: - - 64 + - 58 vm_offset: 58 - ARISTA60T2: + ARISTA04T2: vlans: - - 65 + - 59 vm_offset: 59 - ARISTA61T0: + ARISTA57T0: vlans: - - 72 + - 60 vm_offset: 60 - ARISTA62T0: + ARISTA58T0: vlans: - - 73 + - 61 vm_offset: 61 - ARISTA63T0: + ARISTA59T0: vlans: - - 74 + - 62 vm_offset: 62 - ARISTA64T0: + ARISTA60T0: vlans: - - 75 + - 63 vm_offset: 63 - ARISTA65T0: + ARISTA61T0: vlans: - - 76 + - 64 vm_offset: 64 - ARISTA66T0: + ARISTA62T0: vlans: - - 77 + - 65 vm_offset: 65 - ARISTA67T0: + ARISTA63T0: vlans: - - 78 + - 66 vm_offset: 66 - ARISTA68T0: + ARISTA64T0: vlans: - - 79 + - 67 vm_offset: 67 - ARISTA69T0: + ARISTA65T0: vlans: - - 80 + - 68 vm_offset: 68 - ARISTA70T0: + ARISTA66T0: vlans: - - 81 + - 69 vm_offset: 69 - ARISTA71T0: + ARISTA67T0: vlans: - - 82 + - 70 vm_offset: 70 - ARISTA72T0: + ARISTA68T0: vlans: - - 83 + - 71 vm_offset: 71 - ARISTA73T0: + ARISTA69T0: vlans: - - 84 + - 72 vm_offset: 72 - ARISTA74T0: + ARISTA70T0: vlans: - - 85 + - 73 vm_offset: 73 - ARISTA75T0: + ARISTA71T0: vlans: - - 86 + - 74 vm_offset: 74 - ARISTA76T0: + ARISTA72T0: vlans: - - 87 + - 75 vm_offset: 75 - ARISTA77T0: + ARISTA73T0: vlans: - - 88 + - 76 vm_offset: 76 - ARISTA78T0: + ARISTA74T0: vlans: - - 89 + - 77 vm_offset: 77 - ARISTA79T0: + ARISTA75T0: vlans: - - 90 + - 78 vm_offset: 78 - ARISTA80T0: + ARISTA76T0: vlans: - - 91 + - 79 vm_offset: 79 - ARISTA81T0: + ARISTA77T0: vlans: - - 92 + - 80 vm_offset: 80 - ARISTA82T0: + ARISTA78T0: vlans: - - 93 + - 81 vm_offset: 81 - ARISTA83T0: + ARISTA79T0: vlans: - - 94 + - 82 vm_offset: 82 - ARISTA84T0: + ARISTA80T0: vlans: - - 95 + - 83 vm_offset: 83 - ARISTA85T0: + ARISTA81T0: vlans: - - 96 + - 84 vm_offset: 84 - ARISTA86T0: + ARISTA82T0: vlans: - - 97 + - 85 vm_offset: 85 - ARISTA87T0: + ARISTA83T0: vlans: - - 98 + - 86 vm_offset: 86 - ARISTA88T0: + ARISTA84T0: vlans: - - 99 + - 87 vm_offset: 87 - ARISTA89T0: + ARISTA85T0: vlans: - - 100 + - 88 vm_offset: 88 - ARISTA90T0: + ARISTA86T0: vlans: - - 101 + - 89 vm_offset: 89 - ARISTA91T0: + ARISTA87T0: vlans: - - 102 + - 90 vm_offset: 90 - ARISTA92T0: + ARISTA88T0: vlans: - - 103 + - 91 vm_offset: 91 - ARISTA93T0: + ARISTA89T0: vlans: - - 104 + - 92 vm_offset: 92 - ARISTA94T0: + ARISTA90T0: vlans: - - 105 + - 93 vm_offset: 93 - ARISTA95T0: + ARISTA91T0: vlans: - - 106 + - 94 vm_offset: 94 - ARISTA96T0: + ARISTA92T0: vlans: - - 107 + - 95 vm_offset: 95 - ARISTA97T0: + ARISTA93T0: vlans: - - 108 + - 96 vm_offset: 96 - ARISTA98T0: + ARISTA94T0: vlans: - - 109 + - 97 vm_offset: 97 - ARISTA99T0: + ARISTA95T0: vlans: - - 110 + - 98 vm_offset: 98 - ARISTA100T0: + ARISTA96T0: vlans: - - 111 + - 99 vm_offset: 99 - ARISTA101T0: + ARISTA97T0: vlans: - - 112 + - 100 vm_offset: 100 - ARISTA102T0: + ARISTA98T0: vlans: - - 113 + - 101 vm_offset: 101 - ARISTA103T0: + ARISTA99T0: vlans: - - 114 + - 102 vm_offset: 102 - ARISTA104T0: + ARISTA100T0: vlans: - - 115 + - 103 vm_offset: 103 - ARISTA105T0: + ARISTA101T0: vlans: - - 116 + - 104 vm_offset: 104 - ARISTA106T0: + ARISTA102T0: vlans: - - 117 + - 105 vm_offset: 105 - ARISTA107T0: + ARISTA103T0: vlans: - - 118 + - 106 vm_offset: 106 - ARISTA108T0: + ARISTA104T0: vlans: - - 119 + - 107 vm_offset: 107 - ARISTA109T0: + ARISTA105T0: vlans: - - 120 + - 108 vm_offset: 108 - ARISTA110T0: + ARISTA106T0: vlans: - - 121 + - 109 vm_offset: 109 - ARISTA111T0: + ARISTA107T0: vlans: - - 122 + - 110 vm_offset: 110 - ARISTA112T0: + ARISTA108T0: vlans: - - 123 + - 111 vm_offset: 111 - ARISTA113T0: + ARISTA109T0: vlans: - - 124 + - 112 vm_offset: 112 - ARISTA114T0: + ARISTA110T0: vlans: - - 125 + - 113 vm_offset: 113 - ARISTA115T0: + ARISTA111T0: vlans: - - 126 + - 114 vm_offset: 114 - ARISTA116T0: + ARISTA112T0: vlans: - - 127 + - 115 vm_offset: 115 - ARISTA117T0: + ARISTA113T0: vlans: - - 128 + - 116 vm_offset: 116 - ARISTA118T0: + ARISTA114T0: vlans: - - 129 + - 117 vm_offset: 117 - ARISTA119T0: + ARISTA115T0: vlans: - - 130 + - 118 vm_offset: 118 - ARISTA120T0: + ARISTA116T0: vlans: - - 131 + - 119 vm_offset: 119 - ARISTA121T0: + ARISTA117T0: vlans: - - 132 + - 120 vm_offset: 120 - ARISTA122T0: + ARISTA118T0: vlans: - - 133 + - 121 vm_offset: 121 - ARISTA123T0: + ARISTA119T0: vlans: - - 134 + - 122 vm_offset: 122 - ARISTA124T0: + ARISTA120T0: vlans: - - 135 + - 123 vm_offset: 123 - ARISTA125T0: + ARISTA121T0: vlans: - - 136 + - 124 vm_offset: 124 - ARISTA126T0: + ARISTA122T0: vlans: - - 137 + - 125 vm_offset: 125 - ARISTA127T0: + ARISTA123T0: vlans: - - 138 + - 126 vm_offset: 126 - ARISTA128T0: + ARISTA124T0: vlans: - - 139 + - 127 vm_offset: 127 - ARISTA129T0: + ARISTA125T0: vlans: - - 140 + - 128 vm_offset: 128 - ARISTA130T0: + ARISTA126T0: vlans: - - 141 + - 129 vm_offset: 129 - ARISTA131T0: + ARISTA127T0: vlans: - - 142 + - 130 vm_offset: 130 - ARISTA132T0: + ARISTA128T0: vlans: - - 143 + - 131 vm_offset: 131 - ARISTA133T0: + ARISTA129T0: vlans: - - 144 + - 132 vm_offset: 132 - ARISTA134T0: + ARISTA130T0: vlans: - - 145 + - 133 vm_offset: 133 - ARISTA135T0: + ARISTA131T0: vlans: - - 146 + - 134 vm_offset: 134 - ARISTA136T0: + ARISTA132T0: vlans: - - 147 + - 135 vm_offset: 135 - ARISTA137T0: + ARISTA133T0: vlans: - - 148 + - 136 vm_offset: 136 - ARISTA138T0: + ARISTA134T0: vlans: - - 149 + - 137 vm_offset: 137 - ARISTA139T0: + ARISTA135T0: vlans: - - 150 + - 138 vm_offset: 138 - ARISTA140T0: + ARISTA136T0: vlans: - - 151 + - 139 vm_offset: 139 - ARISTA141T0: + ARISTA137T0: vlans: - - 152 + - 140 vm_offset: 140 - ARISTA142T0: + ARISTA138T0: vlans: - - 153 + - 141 vm_offset: 141 - ARISTA143T0: + ARISTA139T0: vlans: - - 154 + - 142 vm_offset: 142 - ARISTA144T0: + ARISTA140T0: vlans: - - 155 + - 143 vm_offset: 143 - ARISTA145T0: + ARISTA141T0: vlans: - - 156 + - 144 vm_offset: 144 - ARISTA146T0: + ARISTA142T0: vlans: - - 157 + - 145 vm_offset: 145 - ARISTA147T0: + ARISTA143T0: vlans: - - 158 + - 146 vm_offset: 146 - ARISTA148T0: + ARISTA144T0: vlans: - - 159 + - 147 vm_offset: 147 - ARISTA149T0: + ARISTA145T0: vlans: - - 160 + - 148 vm_offset: 148 - ARISTA150T0: + ARISTA146T0: vlans: - - 161 + - 149 vm_offset: 149 - ARISTA151T0: + ARISTA147T0: vlans: - - 162 + - 150 vm_offset: 150 - ARISTA152T0: + ARISTA148T0: vlans: - - 163 + - 151 vm_offset: 151 - ARISTA153T0: + ARISTA149T0: vlans: - - 164 + - 152 vm_offset: 152 - ARISTA154T0: + ARISTA150T0: vlans: - - 165 + - 153 vm_offset: 153 - ARISTA155T0: + ARISTA151T0: vlans: - - 166 + - 154 vm_offset: 154 - ARISTA156T0: + ARISTA152T0: vlans: - - 167 + - 155 vm_offset: 155 - ARISTA157T0: + ARISTA153T0: vlans: - - 168 + - 156 vm_offset: 156 - ARISTA158T0: + ARISTA154T0: vlans: - - 169 + - 157 vm_offset: 157 - ARISTA159T0: + ARISTA155T0: vlans: - - 170 + - 158 vm_offset: 158 - ARISTA160T0: + ARISTA156T0: vlans: - - 171 + - 159 vm_offset: 159 - ARISTA161T0: + ARISTA157T0: vlans: - - 172 + - 160 vm_offset: 160 - ARISTA162T0: + ARISTA158T0: vlans: - - 173 + - 161 vm_offset: 161 - ARISTA163T0: + ARISTA159T0: vlans: - - 174 + - 162 vm_offset: 162 - ARISTA164T0: + ARISTA160T0: vlans: - - 175 + - 163 vm_offset: 163 - ARISTA165T2: + ARISTA05T2: vlans: - - 176 + - 164 vm_offset: 164 - ARISTA166T2: + ARISTA06T2: vlans: - - 177 + - 165 vm_offset: 165 - ARISTA167T0: + ARISTA161T0: vlans: - - 184 + - 166 vm_offset: 166 - ARISTA168T0: + ARISTA162T0: vlans: - - 185 + - 167 vm_offset: 167 - ARISTA169T0: + ARISTA163T0: vlans: - - 186 + - 168 vm_offset: 168 - ARISTA170T0: + ARISTA164T0: vlans: - - 187 + - 169 vm_offset: 169 - ARISTA171T0: + ARISTA165T0: vlans: - - 188 + - 170 vm_offset: 170 - ARISTA172T0: + ARISTA166T0: vlans: - - 189 + - 171 vm_offset: 171 - ARISTA173T0: + ARISTA167T0: vlans: - - 190 + - 172 vm_offset: 172 - ARISTA174T0: + ARISTA168T0: vlans: - - 191 + - 173 vm_offset: 173 - ARISTA175T2: + ARISTA07T2: vlans: - - 192 + - 174 vm_offset: 174 - ARISTA176T2: + ARISTA08T2: vlans: - - 193 + - 175 vm_offset: 175 - ARISTA177T0: + ARISTA169T0: vlans: - - 200 + - 176 vm_offset: 176 - ARISTA178T0: + ARISTA170T0: vlans: - - 201 + - 177 vm_offset: 177 - ARISTA179T0: + ARISTA171T0: vlans: - - 202 + - 178 vm_offset: 178 - ARISTA180T0: + ARISTA172T0: vlans: - - 203 + - 179 vm_offset: 179 - ARISTA181T0: + ARISTA173T0: vlans: - - 204 + - 180 vm_offset: 180 - ARISTA182T0: + ARISTA174T0: vlans: - - 205 + - 181 vm_offset: 181 - ARISTA183T0: + ARISTA175T0: vlans: - - 206 + - 182 vm_offset: 182 - ARISTA184T0: + ARISTA176T0: vlans: - - 207 + - 183 vm_offset: 183 - ARISTA185T0: + ARISTA177T0: vlans: - - 208 + - 184 vm_offset: 184 - ARISTA186T0: + ARISTA178T0: vlans: - - 209 + - 185 vm_offset: 185 - ARISTA187T0: + ARISTA179T0: vlans: - - 210 + - 186 vm_offset: 186 - ARISTA188T0: + ARISTA180T0: vlans: - - 211 + - 187 vm_offset: 187 - ARISTA189T0: + ARISTA181T0: vlans: - - 212 + - 188 vm_offset: 188 - ARISTA190T0: + ARISTA182T0: vlans: - - 213 + - 189 vm_offset: 189 - ARISTA191T0: + ARISTA183T0: vlans: - - 214 + - 190 vm_offset: 190 - ARISTA192T0: + ARISTA184T0: vlans: - - 215 + - 191 vm_offset: 191 - ARISTA193T0: + ARISTA185T0: vlans: - - 216 + - 192 vm_offset: 192 - ARISTA194T0: + ARISTA186T0: vlans: - - 217 + - 193 vm_offset: 193 - ARISTA195T0: + ARISTA187T0: vlans: - - 218 + - 194 vm_offset: 194 - ARISTA196T0: + ARISTA188T0: vlans: - - 219 + - 195 vm_offset: 195 - ARISTA197T0: + ARISTA189T0: vlans: - - 220 + - 196 vm_offset: 196 - ARISTA198T0: + ARISTA190T0: vlans: - - 221 + - 197 vm_offset: 197 - ARISTA199T0: + ARISTA191T0: vlans: - - 222 + - 198 vm_offset: 198 - ARISTA200T0: + ARISTA192T0: vlans: - - 223 + - 199 vm_offset: 199 - ARISTA201T0: + ARISTA193T0: vlans: - - 224 + - 200 vm_offset: 200 - ARISTA202T0: + ARISTA194T0: vlans: - - 225 + - 201 vm_offset: 201 - ARISTA203T0: + ARISTA195T0: vlans: - - 226 + - 202 vm_offset: 202 - ARISTA204T0: + ARISTA196T0: vlans: - - 227 + - 203 vm_offset: 203 - ARISTA205T0: + ARISTA197T0: vlans: - - 228 + - 204 vm_offset: 204 - ARISTA206T0: + ARISTA198T0: vlans: - - 229 + - 205 vm_offset: 205 - ARISTA207T0: + ARISTA199T0: vlans: - - 230 + - 206 vm_offset: 206 - ARISTA208T0: + ARISTA200T0: vlans: - - 231 + - 207 vm_offset: 207 - ARISTA209T0: + ARISTA201T0: vlans: - - 232 + - 208 vm_offset: 208 - ARISTA210T0: + ARISTA202T0: vlans: - - 233 + - 209 vm_offset: 209 - ARISTA211T0: + ARISTA203T0: vlans: - - 234 + - 210 vm_offset: 210 - ARISTA212T0: + ARISTA204T0: vlans: - - 235 + - 211 vm_offset: 211 - ARISTA213T0: + ARISTA205T0: vlans: - - 236 + - 212 vm_offset: 212 - ARISTA214T0: + ARISTA206T0: vlans: - - 237 + - 213 vm_offset: 213 - ARISTA215T0: + ARISTA207T0: vlans: - - 238 + - 214 vm_offset: 214 - ARISTA216T0: + ARISTA208T0: vlans: - - 239 + - 215 vm_offset: 215 - ARISTA217T0: + ARISTA209T0: vlans: - - 240 + - 216 vm_offset: 216 - ARISTA218T0: + ARISTA210T0: vlans: - - 241 + - 217 vm_offset: 217 - ARISTA219T0: + ARISTA211T0: vlans: - - 242 + - 218 vm_offset: 218 - ARISTA220T0: + ARISTA212T0: vlans: - - 243 + - 219 vm_offset: 219 - ARISTA221T0: + ARISTA213T0: vlans: - - 244 + - 220 vm_offset: 220 - ARISTA222T0: + ARISTA214T0: vlans: - - 245 + - 221 vm_offset: 221 - ARISTA223T0: + ARISTA215T0: vlans: - - 246 + - 222 vm_offset: 222 - ARISTA224T0: + ARISTA216T0: vlans: - - 247 + - 223 vm_offset: 223 - ARISTA225T0: + ARISTA217T0: vlans: - - 248 + - 224 vm_offset: 224 - ARISTA226T0: + ARISTA218T0: vlans: - - 249 + - 225 vm_offset: 225 - ARISTA227T0: + ARISTA219T0: vlans: - - 250 + - 226 vm_offset: 226 - ARISTA228T0: + ARISTA220T0: vlans: - - 251 + - 227 vm_offset: 227 - ARISTA229T0: + ARISTA221T0: vlans: - - 252 + - 228 vm_offset: 228 - ARISTA230T0: + ARISTA222T0: vlans: - - 253 + - 229 vm_offset: 229 - ARISTA231T0: + ARISTA223T0: vlans: - - 254 + - 230 vm_offset: 230 - ARISTA232T0: + ARISTA224T0: vlans: - - 255 + - 231 vm_offset: 231 configuration_properties: @@ -950,7 +950,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64001 peers: 65100: - 10.0.0.0 @@ -988,7 +988,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64003 peers: 65100: - 10.0.0.4 @@ -1007,7 +1007,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64004 peers: 65100: - 10.0.0.6 @@ -1026,7 +1026,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64005 peers: 65100: - 10.0.0.8 @@ -1045,7 +1045,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64006 peers: 65100: - 10.0.0.10 @@ -1064,7 +1064,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64007 peers: 65100: - 10.0.0.12 @@ -1083,7 +1083,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64008 peers: 65100: - 10.0.0.14 @@ -1102,7 +1102,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64009 peers: 65100: - 10.0.0.16 @@ -1121,7 +1121,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64010 peers: 65100: - 10.0.0.18 @@ -1140,7 +1140,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64011 peers: 65100: - 10.0.0.20 @@ -1159,7 +1159,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64012 peers: 65100: - 10.0.0.22 @@ -1178,7 +1178,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64013 peers: 65100: - 10.0.0.24 @@ -1197,7 +1197,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64014 peers: 65100: - 10.0.0.26 @@ -1216,7 +1216,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64015 peers: 65100: - 10.0.0.28 @@ -1235,7 +1235,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64016 peers: 65100: - 10.0.0.30 @@ -1254,7 +1254,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64017 peers: 65100: - 10.0.0.32 @@ -1273,7 +1273,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64018 peers: 65100: - 10.0.0.34 @@ -1292,7 +1292,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64019 peers: 65100: - 10.0.0.36 @@ -1311,7 +1311,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64020 peers: 65100: - 10.0.0.38 @@ -1330,7 +1330,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64021 peers: 65100: - 10.0.0.40 @@ -1349,7 +1349,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64022 peers: 65100: - 10.0.0.42 @@ -1368,7 +1368,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64023 peers: 65100: - 10.0.0.44 @@ -1387,7 +1387,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64024 peers: 65100: - 10.0.0.46 @@ -1406,7 +1406,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64025 peers: 65100: - 10.0.0.48 @@ -1425,7 +1425,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64026 peers: 65100: - 10.0.0.50 @@ -1444,7 +1444,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64027 peers: 65100: - 10.0.0.52 @@ -1463,7 +1463,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64028 peers: 65100: - 10.0.0.54 @@ -1482,7 +1482,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64029 peers: 65100: - 10.0.0.56 @@ -1501,7 +1501,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64030 peers: 65100: - 10.0.0.58 @@ -1520,7 +1520,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64031 peers: 65100: - 10.0.0.60 @@ -1539,7 +1539,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64032 peers: 65100: - 10.0.0.62 @@ -1558,7 +1558,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64033 peers: 65100: - 10.0.0.64 @@ -1577,7 +1577,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64034 peers: 65100: - 10.0.0.66 @@ -1596,7 +1596,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64035 peers: 65100: - 10.0.0.68 @@ -1615,7 +1615,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64036 peers: 65100: - 10.0.0.70 @@ -1634,7 +1634,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64037 peers: 65100: - 10.0.0.72 @@ -1653,7 +1653,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64038 peers: 65100: - 10.0.0.74 @@ -1672,7 +1672,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64039 peers: 65100: - 10.0.0.76 @@ -1691,7 +1691,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64040 peers: 65100: - 10.0.0.78 @@ -1710,7 +1710,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64041 peers: 65100: - 10.0.0.80 @@ -1729,7 +1729,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64042 peers: 65100: - 10.0.0.82 @@ -1748,7 +1748,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64043 peers: 65100: - 10.0.0.84 @@ -1767,7 +1767,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64044 peers: 65100: - 10.0.0.86 @@ -1786,7 +1786,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64045 peers: 65100: - 10.0.0.88 @@ -1805,7 +1805,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64046 peers: 65100: - 10.0.0.90 @@ -1824,7 +1824,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64047 peers: 65100: - 10.0.0.92 @@ -1843,7 +1843,7 @@ configuration: properties: - common bgp: - asn: 64002 + asn: 64048 peers: 65100: - 10.0.0.94 @@ -1858,7 +1858,7 @@ configuration: bp_interfaces: ipv4: 10.10.246.49/24 ipv6: fc0a::31/64 - ARISTA49T2: + ARISTA01T2: properties: - common bgp: @@ -1877,7 +1877,7 @@ configuration: bp_interfaces: ipv4: 10.10.246.50/24 ipv6: fc0a::32/64 - ARISTA50T2: + ARISTA02T2: properties: - common bgp: @@ -1896,3461 +1896,3461 @@ configuration: bp_interfaces: ipv4: 10.10.246.51/24 ipv6: fc0a::33/64 - ARISTA51T0: + ARISTA49T0: properties: - common bgp: - asn: 64002 + asn: 64049 peers: 65100: - - 10.0.0.112 - - fc00::e1 + - 10.0.0.100 + - fc00::c9 interfaces: Loopback0: - ipv4: 100.1.0.57/32 - ipv6: 2064:100::39/128 + ipv4: 100.1.0.51/32 + ipv6: 2064:100::33/128 Ethernet1: - ipv4: 10.0.0.113/31 - ipv6: fc00::e2/126 + ipv4: 10.0.0.101/31 + ipv6: fc00::ca/126 bp_interfaces: ipv4: 10.10.246.52/24 ipv6: fc0a::34/64 - ARISTA52T0: + ARISTA50T0: properties: - common bgp: - asn: 64002 + asn: 64050 peers: 65100: - - 10.0.0.114 - - fc00::e5 + - 10.0.0.102 + - fc00::cd interfaces: Loopback0: - ipv4: 100.1.0.58/32 - ipv6: 2064:100::3a/128 + ipv4: 100.1.0.52/32 + ipv6: 2064:100::34/128 Ethernet1: - ipv4: 10.0.0.115/31 - ipv6: fc00::e6/126 + ipv4: 10.0.0.103/31 + ipv6: fc00::ce/126 bp_interfaces: ipv4: 10.10.246.53/24 ipv6: fc0a::35/64 - ARISTA53T0: + ARISTA51T0: properties: - common bgp: - asn: 64002 + asn: 64051 peers: 65100: - - 10.0.0.116 - - fc00::e9 + - 10.0.0.104 + - fc00::d1 interfaces: Loopback0: - ipv4: 100.1.0.59/32 - ipv6: 2064:100::3b/128 + ipv4: 100.1.0.53/32 + ipv6: 2064:100::35/128 Ethernet1: - ipv4: 10.0.0.117/31 - ipv6: fc00::ea/126 + ipv4: 10.0.0.105/31 + ipv6: fc00::d2/126 bp_interfaces: ipv4: 10.10.246.54/24 ipv6: fc0a::36/64 - ARISTA54T0: + ARISTA52T0: properties: - common bgp: - asn: 64002 + asn: 64052 peers: 65100: - - 10.0.0.118 - - fc00::ed + - 10.0.0.106 + - fc00::d5 interfaces: Loopback0: - ipv4: 100.1.0.60/32 - ipv6: 2064:100::3c/128 + ipv4: 100.1.0.54/32 + ipv6: 2064:100::36/128 Ethernet1: - ipv4: 10.0.0.119/31 - ipv6: fc00::ee/126 + ipv4: 10.0.0.107/31 + ipv6: fc00::d6/126 bp_interfaces: ipv4: 10.10.246.55/24 ipv6: fc0a::37/64 - ARISTA55T0: + ARISTA53T0: properties: - common bgp: - asn: 64002 + asn: 64053 peers: 65100: - - 10.0.0.120 - - fc00::f1 + - 10.0.0.108 + - fc00::d9 interfaces: Loopback0: - ipv4: 100.1.0.61/32 - ipv6: 2064:100::3d/128 + ipv4: 100.1.0.55/32 + ipv6: 2064:100::37/128 Ethernet1: - ipv4: 10.0.0.121/31 - ipv6: fc00::f2/126 + ipv4: 10.0.0.109/31 + ipv6: fc00::da/126 bp_interfaces: ipv4: 10.10.246.56/24 ipv6: fc0a::38/64 - ARISTA56T0: + ARISTA54T0: properties: - common bgp: - asn: 64002 + asn: 64054 peers: 65100: - - 10.0.0.122 - - fc00::f5 + - 10.0.0.110 + - fc00::dd interfaces: Loopback0: - ipv4: 100.1.0.62/32 - ipv6: 2064:100::3e/128 + ipv4: 100.1.0.56/32 + ipv6: 2064:100::38/128 Ethernet1: - ipv4: 10.0.0.123/31 - ipv6: fc00::f6/126 + ipv4: 10.0.0.111/31 + ipv6: fc00::de/126 bp_interfaces: ipv4: 10.10.246.57/24 ipv6: fc0a::39/64 - ARISTA57T0: + ARISTA55T0: properties: - common bgp: - asn: 64002 + asn: 64055 peers: 65100: - - 10.0.0.124 - - fc00::f9 + - 10.0.0.112 + - fc00::e1 interfaces: Loopback0: - ipv4: 100.1.0.63/32 - ipv6: 2064:100::3f/128 + ipv4: 100.1.0.57/32 + ipv6: 2064:100::39/128 Ethernet1: - ipv4: 10.0.0.125/31 - ipv6: fc00::fa/126 + ipv4: 10.0.0.113/31 + ipv6: fc00::e2/126 bp_interfaces: ipv4: 10.10.246.58/24 ipv6: fc0a::3a/64 - ARISTA58T0: + ARISTA56T0: properties: - common bgp: - asn: 64002 + asn: 64056 peers: 65100: - - 10.0.0.126 - - fc00::fd + - 10.0.0.114 + - fc00::e5 interfaces: Loopback0: - ipv4: 100.1.0.64/32 - ipv6: 2064:100::40/128 + ipv4: 100.1.0.58/32 + ipv6: 2064:100::3a/128 Ethernet1: - ipv4: 10.0.0.127/31 - ipv6: fc00::fe/126 + ipv4: 10.0.0.115/31 + ipv6: fc00::e6/126 bp_interfaces: ipv4: 10.10.246.59/24 ipv6: fc0a::3b/64 - ARISTA59T2: + ARISTA03T2: properties: - common bgp: asn: 65200 peers: 65100: - - 10.0.0.128 - - fc00::101 + - 10.0.0.116 + - fc00::e9 interfaces: Loopback0: - ipv4: 100.1.0.65/32 - ipv6: 2064:100::41/128 + ipv4: 100.1.0.59/32 + ipv6: 2064:100::3b/128 Ethernet1: - ipv4: 10.0.0.129/31 - ipv6: fc00::102/126 + ipv4: 10.0.0.117/31 + ipv6: fc00::ea/126 bp_interfaces: ipv4: 10.10.246.60/24 ipv6: fc0a::3c/64 - ARISTA60T2: + ARISTA04T2: properties: - common bgp: asn: 65200 peers: 65100: - - 10.0.0.130 - - fc00::105 + - 10.0.0.118 + - fc00::ed interfaces: Loopback0: - ipv4: 100.1.0.66/32 - ipv6: 2064:100::42/128 + ipv4: 100.1.0.60/32 + ipv6: 2064:100::3c/128 Ethernet1: - ipv4: 10.0.0.131/31 - ipv6: fc00::106/126 + ipv4: 10.0.0.119/31 + ipv6: fc00::ee/126 bp_interfaces: ipv4: 10.10.246.61/24 ipv6: fc0a::3d/64 - ARISTA61T0: + ARISTA57T0: properties: - common bgp: - asn: 64002 + asn: 64057 peers: - 65100: - - 10.0.0.144 - - fc00::121 + 65100: + - 10.0.0.120 + - fc00::f1 interfaces: Loopback0: - ipv4: 100.1.0.73/32 - ipv6: 2064:100::49/128 + ipv4: 100.1.0.61/32 + ipv6: 2064:100::3d/128 Ethernet1: - ipv4: 10.0.0.145/31 - ipv6: fc00::122/126 + ipv4: 10.0.0.121/31 + ipv6: fc00::f2/126 bp_interfaces: ipv4: 10.10.246.62/24 ipv6: fc0a::3e/64 - ARISTA62T0: + ARISTA58T0: properties: - common bgp: - asn: 64002 + asn: 64058 peers: 65100: - - 10.0.0.146 - - fc00::125 + - 10.0.0.122 + - fc00::f5 interfaces: Loopback0: - ipv4: 100.1.0.74/32 - ipv6: 2064:100::4a/128 + ipv4: 100.1.0.62/32 + ipv6: 2064:100::3e/128 Ethernet1: - ipv4: 10.0.0.147/31 - ipv6: fc00::126/126 + ipv4: 10.0.0.123/31 + ipv6: fc00::f6/126 bp_interfaces: ipv4: 10.10.246.63/24 ipv6: fc0a::3f/64 - ARISTA63T0: + ARISTA59T0: properties: - common bgp: - asn: 64002 + asn: 64059 peers: 65100: - - 10.0.0.148 - - fc00::129 + - 10.0.0.124 + - fc00::f9 interfaces: Loopback0: - ipv4: 100.1.0.75/32 - ipv6: 2064:100::4b/128 + ipv4: 100.1.0.63/32 + ipv6: 2064:100::3f/128 Ethernet1: - ipv4: 10.0.0.149/31 - ipv6: fc00::12a/126 + ipv4: 10.0.0.125/31 + ipv6: fc00::fa/126 bp_interfaces: ipv4: 10.10.246.64/24 ipv6: fc0a::40/64 - ARISTA64T0: + ARISTA60T0: properties: - common bgp: - asn: 64002 + asn: 64060 peers: 65100: - - 10.0.0.150 - - fc00::12d + - 10.0.0.126 + - fc00::fd interfaces: Loopback0: - ipv4: 100.1.0.76/32 - ipv6: 2064:100::4c/128 + ipv4: 100.1.0.64/32 + ipv6: 2064:100::40/128 Ethernet1: - ipv4: 10.0.0.151/31 - ipv6: fc00::12e/126 + ipv4: 10.0.0.127/31 + ipv6: fc00::fe/126 bp_interfaces: ipv4: 10.10.246.65/24 ipv6: fc0a::41/64 - ARISTA65T0: + ARISTA61T0: properties: - common bgp: - asn: 64002 + asn: 64061 peers: 65100: - - 10.0.0.152 - - fc00::131 + - 10.0.0.128 + - fc00::101 interfaces: Loopback0: - ipv4: 100.1.0.77/32 - ipv6: 2064:100::4d/128 + ipv4: 100.1.0.65/32 + ipv6: 2064:100::41/128 Ethernet1: - ipv4: 10.0.0.153/31 - ipv6: fc00::132/126 + ipv4: 10.0.0.129/31 + ipv6: fc00::102/126 bp_interfaces: ipv4: 10.10.246.66/24 ipv6: fc0a::42/64 - ARISTA66T0: + ARISTA62T0: properties: - common bgp: - asn: 64002 + asn: 64062 peers: 65100: - - 10.0.0.154 - - fc00::135 + - 10.0.0.130 + - fc00::105 interfaces: Loopback0: - ipv4: 100.1.0.78/32 - ipv6: 2064:100::4e/128 + ipv4: 100.1.0.66/32 + ipv6: 2064:100::42/128 Ethernet1: - ipv4: 10.0.0.155/31 - ipv6: fc00::136/126 + ipv4: 10.0.0.131/31 + ipv6: fc00::106/126 bp_interfaces: ipv4: 10.10.246.67/24 ipv6: fc0a::43/64 - ARISTA67T0: + ARISTA63T0: properties: - common bgp: - asn: 64002 + asn: 64063 peers: 65100: - - 10.0.0.156 - - fc00::139 + - 10.0.0.132 + - fc00::109 interfaces: Loopback0: - ipv4: 100.1.0.79/32 - ipv6: 2064:100::4f/128 + ipv4: 100.1.0.67/32 + ipv6: 2064:100::43/128 Ethernet1: - ipv4: 10.0.0.157/31 - ipv6: fc00::13a/126 + ipv4: 10.0.0.133/31 + ipv6: fc00::10a/126 bp_interfaces: ipv4: 10.10.246.68/24 ipv6: fc0a::44/64 - ARISTA68T0: + ARISTA64T0: properties: - common bgp: - asn: 64002 + asn: 64064 peers: 65100: - - 10.0.0.158 - - fc00::13d + - 10.0.0.134 + - fc00::10d interfaces: Loopback0: - ipv4: 100.1.0.80/32 - ipv6: 2064:100::50/128 + ipv4: 100.1.0.68/32 + ipv6: 2064:100::44/128 Ethernet1: - ipv4: 10.0.0.159/31 - ipv6: fc00::13e/126 + ipv4: 10.0.0.135/31 + ipv6: fc00::10e/126 bp_interfaces: ipv4: 10.10.246.69/24 ipv6: fc0a::45/64 - ARISTA69T0: + ARISTA65T0: properties: - common bgp: - asn: 64002 + asn: 64065 peers: 65100: - - 10.0.0.160 - - fc00::141 + - 10.0.0.136 + - fc00::111 interfaces: Loopback0: - ipv4: 100.1.0.81/32 - ipv6: 2064:100::51/128 + ipv4: 100.1.0.69/32 + ipv6: 2064:100::45/128 Ethernet1: - ipv4: 10.0.0.161/31 - ipv6: fc00::142/126 + ipv4: 10.0.0.137/31 + ipv6: fc00::112/126 bp_interfaces: ipv4: 10.10.246.70/24 ipv6: fc0a::46/64 - ARISTA70T0: + ARISTA66T0: properties: - common bgp: - asn: 64002 + asn: 64066 peers: 65100: - - 10.0.0.162 - - fc00::145 + - 10.0.0.138 + - fc00::115 interfaces: Loopback0: - ipv4: 100.1.0.82/32 - ipv6: 2064:100::52/128 + ipv4: 100.1.0.70/32 + ipv6: 2064:100::46/128 Ethernet1: - ipv4: 10.0.0.163/31 - ipv6: fc00::146/126 + ipv4: 10.0.0.139/31 + ipv6: fc00::116/126 bp_interfaces: ipv4: 10.10.246.71/24 ipv6: fc0a::47/64 - ARISTA71T0: + ARISTA67T0: properties: - common bgp: - asn: 64002 + asn: 64067 peers: 65100: - - 10.0.0.164 - - fc00::149 + - 10.0.0.140 + - fc00::119 interfaces: Loopback0: - ipv4: 100.1.0.83/32 - ipv6: 2064:100::53/128 + ipv4: 100.1.0.71/32 + ipv6: 2064:100::47/128 Ethernet1: - ipv4: 10.0.0.165/31 - ipv6: fc00::14a/126 + ipv4: 10.0.0.141/31 + ipv6: fc00::11a/126 bp_interfaces: ipv4: 10.10.246.72/24 ipv6: fc0a::48/64 - ARISTA72T0: + ARISTA68T0: properties: - common bgp: - asn: 64002 + asn: 64068 peers: 65100: - - 10.0.0.166 - - fc00::14d + - 10.0.0.142 + - fc00::11d interfaces: Loopback0: - ipv4: 100.1.0.84/32 - ipv6: 2064:100::54/128 + ipv4: 100.1.0.72/32 + ipv6: 2064:100::48/128 Ethernet1: - ipv4: 10.0.0.167/31 - ipv6: fc00::14e/126 + ipv4: 10.0.0.143/31 + ipv6: fc00::11e/126 bp_interfaces: ipv4: 10.10.246.73/24 ipv6: fc0a::49/64 - ARISTA73T0: + ARISTA69T0: properties: - common bgp: - asn: 64002 + asn: 64069 peers: 65100: - - 10.0.0.168 - - fc00::151 + - 10.0.0.144 + - fc00::121 interfaces: Loopback0: - ipv4: 100.1.0.85/32 - ipv6: 2064:100::55/128 + ipv4: 100.1.0.73/32 + ipv6: 2064:100::49/128 Ethernet1: - ipv4: 10.0.0.169/31 - ipv6: fc00::152/126 + ipv4: 10.0.0.145/31 + ipv6: fc00::122/126 bp_interfaces: ipv4: 10.10.246.74/24 ipv6: fc0a::4a/64 - ARISTA74T0: + ARISTA70T0: properties: - common bgp: - asn: 64002 + asn: 64070 peers: 65100: - - 10.0.0.170 - - fc00::155 + - 10.0.0.146 + - fc00::125 interfaces: Loopback0: - ipv4: 100.1.0.86/32 - ipv6: 2064:100::56/128 + ipv4: 100.1.0.74/32 + ipv6: 2064:100::4a/128 Ethernet1: - ipv4: 10.0.0.171/31 - ipv6: fc00::156/126 + ipv4: 10.0.0.147/31 + ipv6: fc00::126/126 bp_interfaces: ipv4: 10.10.246.75/24 ipv6: fc0a::4b/64 - ARISTA75T0: + ARISTA71T0: properties: - common bgp: - asn: 64002 + asn: 64071 peers: 65100: - - 10.0.0.172 - - fc00::159 + - 10.0.0.148 + - fc00::129 interfaces: Loopback0: - ipv4: 100.1.0.87/32 - ipv6: 2064:100::57/128 + ipv4: 100.1.0.75/32 + ipv6: 2064:100::4b/128 Ethernet1: - ipv4: 10.0.0.173/31 - ipv6: fc00::15a/126 + ipv4: 10.0.0.149/31 + ipv6: fc00::12a/126 bp_interfaces: ipv4: 10.10.246.76/24 ipv6: fc0a::4c/64 - ARISTA76T0: + ARISTA72T0: properties: - common bgp: - asn: 64002 + asn: 64072 peers: 65100: - - 10.0.0.174 - - fc00::15d + - 10.0.0.150 + - fc00::12d interfaces: Loopback0: - ipv4: 100.1.0.88/32 - ipv6: 2064:100::58/128 + ipv4: 100.1.0.76/32 + ipv6: 2064:100::4c/128 Ethernet1: - ipv4: 10.0.0.175/31 - ipv6: fc00::15e/126 + ipv4: 10.0.0.151/31 + ipv6: fc00::12e/126 bp_interfaces: ipv4: 10.10.246.77/24 ipv6: fc0a::4d/64 - ARISTA77T0: + ARISTA73T0: properties: - common bgp: - asn: 64002 + asn: 64073 peers: 65100: - - 10.0.0.176 - - fc00::161 + - 10.0.0.152 + - fc00::131 interfaces: Loopback0: - ipv4: 100.1.0.89/32 - ipv6: 2064:100::59/128 + ipv4: 100.1.0.77/32 + ipv6: 2064:100::4d/128 Ethernet1: - ipv4: 10.0.0.177/31 - ipv6: fc00::162/126 + ipv4: 10.0.0.153/31 + ipv6: fc00::132/126 bp_interfaces: ipv4: 10.10.246.78/24 ipv6: fc0a::4e/64 - ARISTA78T0: + ARISTA74T0: properties: - common bgp: - asn: 64002 + asn: 64074 peers: 65100: - - 10.0.0.178 - - fc00::165 + - 10.0.0.154 + - fc00::135 interfaces: Loopback0: - ipv4: 100.1.0.90/32 - ipv6: 2064:100::5a/128 + ipv4: 100.1.0.78/32 + ipv6: 2064:100::4e/128 Ethernet1: - ipv4: 10.0.0.179/31 - ipv6: fc00::166/126 + ipv4: 10.0.0.155/31 + ipv6: fc00::136/126 bp_interfaces: ipv4: 10.10.246.79/24 ipv6: fc0a::4f/64 - ARISTA79T0: + ARISTA75T0: properties: - common bgp: - asn: 64002 + asn: 64075 peers: 65100: - - 10.0.0.180 - - fc00::169 + - 10.0.0.156 + - fc00::139 interfaces: Loopback0: - ipv4: 100.1.0.91/32 - ipv6: 2064:100::5b/128 + ipv4: 100.1.0.79/32 + ipv6: 2064:100::4f/128 Ethernet1: - ipv4: 10.0.0.181/31 - ipv6: fc00::16a/126 + ipv4: 10.0.0.157/31 + ipv6: fc00::13a/126 bp_interfaces: ipv4: 10.10.246.80/24 ipv6: fc0a::50/64 - ARISTA80T0: + ARISTA76T0: properties: - common bgp: - asn: 64002 + asn: 64076 peers: 65100: - - 10.0.0.182 - - fc00::16d + - 10.0.0.158 + - fc00::13d interfaces: Loopback0: - ipv4: 100.1.0.92/32 - ipv6: 2064:100::5c/128 + ipv4: 100.1.0.80/32 + ipv6: 2064:100::50/128 Ethernet1: - ipv4: 10.0.0.183/31 - ipv6: fc00::16e/126 + ipv4: 10.0.0.159/31 + ipv6: fc00::13e/126 bp_interfaces: ipv4: 10.10.246.81/24 ipv6: fc0a::51/64 - ARISTA81T0: + ARISTA77T0: properties: - common bgp: - asn: 64002 + asn: 64077 peers: 65100: - - 10.0.0.184 - - fc00::171 + - 10.0.0.160 + - fc00::141 interfaces: Loopback0: - ipv4: 100.1.0.93/32 - ipv6: 2064:100::5d/128 + ipv4: 100.1.0.81/32 + ipv6: 2064:100::51/128 Ethernet1: - ipv4: 10.0.0.185/31 - ipv6: fc00::172/126 + ipv4: 10.0.0.161/31 + ipv6: fc00::142/126 bp_interfaces: ipv4: 10.10.246.82/24 ipv6: fc0a::52/64 - ARISTA82T0: + ARISTA78T0: properties: - common bgp: - asn: 64002 + asn: 64078 peers: 65100: - - 10.0.0.186 - - fc00::175 + - 10.0.0.162 + - fc00::145 interfaces: Loopback0: - ipv4: 100.1.0.94/32 - ipv6: 2064:100::5e/128 + ipv4: 100.1.0.82/32 + ipv6: 2064:100::52/128 Ethernet1: - ipv4: 10.0.0.187/31 - ipv6: fc00::176/126 + ipv4: 10.0.0.163/31 + ipv6: fc00::146/126 bp_interfaces: ipv4: 10.10.246.83/24 ipv6: fc0a::53/64 - ARISTA83T0: + ARISTA79T0: properties: - common bgp: - asn: 64002 + asn: 64079 peers: 65100: - - 10.0.0.188 - - fc00::179 + - 10.0.0.164 + - fc00::149 interfaces: Loopback0: - ipv4: 100.1.0.95/32 - ipv6: 2064:100::5f/128 + ipv4: 100.1.0.83/32 + ipv6: 2064:100::53/128 Ethernet1: - ipv4: 10.0.0.189/31 - ipv6: fc00::17a/126 + ipv4: 10.0.0.165/31 + ipv6: fc00::14a/126 bp_interfaces: ipv4: 10.10.246.84/24 ipv6: fc0a::54/64 - ARISTA84T0: + ARISTA80T0: properties: - common bgp: - asn: 64002 + asn: 64080 peers: 65100: - - 10.0.0.190 - - fc00::17d + - 10.0.0.166 + - fc00::14d interfaces: Loopback0: - ipv4: 100.1.0.96/32 - ipv6: 2064:100::60/128 + ipv4: 100.1.0.84/32 + ipv6: 2064:100::54/128 Ethernet1: - ipv4: 10.0.0.191/31 - ipv6: fc00::17e/126 + ipv4: 10.0.0.167/31 + ipv6: fc00::14e/126 bp_interfaces: ipv4: 10.10.246.85/24 ipv6: fc0a::55/64 - ARISTA85T0: + ARISTA81T0: properties: - common bgp: - asn: 64002 + asn: 64081 peers: 65100: - - 10.0.0.192 - - fc00::181 + - 10.0.0.168 + - fc00::151 interfaces: Loopback0: - ipv4: 100.1.0.97/32 - ipv6: 2064:100::61/128 + ipv4: 100.1.0.85/32 + ipv6: 2064:100::55/128 Ethernet1: - ipv4: 10.0.0.193/31 - ipv6: fc00::182/126 + ipv4: 10.0.0.169/31 + ipv6: fc00::152/126 bp_interfaces: ipv4: 10.10.246.86/24 ipv6: fc0a::56/64 - ARISTA86T0: + ARISTA82T0: properties: - common bgp: - asn: 64002 + asn: 64082 peers: 65100: - - 10.0.0.194 - - fc00::185 + - 10.0.0.170 + - fc00::155 interfaces: Loopback0: - ipv4: 100.1.0.98/32 - ipv6: 2064:100::62/128 + ipv4: 100.1.0.86/32 + ipv6: 2064:100::56/128 Ethernet1: - ipv4: 10.0.0.195/31 - ipv6: fc00::186/126 + ipv4: 10.0.0.171/31 + ipv6: fc00::156/126 bp_interfaces: ipv4: 10.10.246.87/24 ipv6: fc0a::57/64 - ARISTA87T0: + ARISTA83T0: properties: - common bgp: - asn: 64002 + asn: 64083 peers: 65100: - - 10.0.0.196 - - fc00::189 + - 10.0.0.172 + - fc00::159 interfaces: Loopback0: - ipv4: 100.1.0.99/32 - ipv6: 2064:100::63/128 + ipv4: 100.1.0.87/32 + ipv6: 2064:100::57/128 Ethernet1: - ipv4: 10.0.0.197/31 - ipv6: fc00::18a/126 + ipv4: 10.0.0.173/31 + ipv6: fc00::15a/126 bp_interfaces: ipv4: 10.10.246.88/24 ipv6: fc0a::58/64 - ARISTA88T0: + ARISTA84T0: properties: - common bgp: - asn: 64002 + asn: 64084 peers: 65100: - - 10.0.0.198 - - fc00::18d + - 10.0.0.174 + - fc00::15d interfaces: Loopback0: - ipv4: 100.1.0.100/32 - ipv6: 2064:100::64/128 + ipv4: 100.1.0.88/32 + ipv6: 2064:100::58/128 Ethernet1: - ipv4: 10.0.0.199/31 - ipv6: fc00::18e/126 + ipv4: 10.0.0.175/31 + ipv6: fc00::15e/126 bp_interfaces: ipv4: 10.10.246.89/24 ipv6: fc0a::59/64 - ARISTA89T0: + ARISTA85T0: properties: - common bgp: - asn: 64002 + asn: 64085 peers: 65100: - - 10.0.0.200 - - fc00::191 + - 10.0.0.176 + - fc00::161 interfaces: Loopback0: - ipv4: 100.1.0.101/32 - ipv6: 2064:100::65/128 + ipv4: 100.1.0.89/32 + ipv6: 2064:100::59/128 Ethernet1: - ipv4: 10.0.0.201/31 - ipv6: fc00::192/126 + ipv4: 10.0.0.177/31 + ipv6: fc00::162/126 bp_interfaces: ipv4: 10.10.246.90/24 ipv6: fc0a::5a/64 - ARISTA90T0: + ARISTA86T0: properties: - common bgp: - asn: 64002 + asn: 64086 peers: 65100: - - 10.0.0.202 - - fc00::195 + - 10.0.0.178 + - fc00::165 interfaces: Loopback0: - ipv4: 100.1.0.102/32 - ipv6: 2064:100::66/128 + ipv4: 100.1.0.90/32 + ipv6: 2064:100::5a/128 Ethernet1: - ipv4: 10.0.0.203/31 - ipv6: fc00::196/126 + ipv4: 10.0.0.179/31 + ipv6: fc00::166/126 bp_interfaces: ipv4: 10.10.246.91/24 ipv6: fc0a::5b/64 - ARISTA91T0: + ARISTA87T0: properties: - common bgp: - asn: 64002 + asn: 64087 peers: 65100: - - 10.0.0.204 - - fc00::199 + - 10.0.0.180 + - fc00::169 interfaces: Loopback0: - ipv4: 100.1.0.103/32 - ipv6: 2064:100::67/128 + ipv4: 100.1.0.91/32 + ipv6: 2064:100::5b/128 Ethernet1: - ipv4: 10.0.0.205/31 - ipv6: fc00::19a/126 + ipv4: 10.0.0.181/31 + ipv6: fc00::16a/126 bp_interfaces: ipv4: 10.10.246.92/24 ipv6: fc0a::5c/64 - ARISTA92T0: + ARISTA88T0: properties: - common bgp: - asn: 64002 + asn: 64088 peers: 65100: - - 10.0.0.206 - - fc00::19d + - 10.0.0.182 + - fc00::16d interfaces: Loopback0: - ipv4: 100.1.0.104/32 - ipv6: 2064:100::68/128 + ipv4: 100.1.0.92/32 + ipv6: 2064:100::5c/128 Ethernet1: - ipv4: 10.0.0.207/31 - ipv6: fc00::19e/126 + ipv4: 10.0.0.183/31 + ipv6: fc00::16e/126 bp_interfaces: ipv4: 10.10.246.93/24 ipv6: fc0a::5d/64 - ARISTA93T0: + ARISTA89T0: properties: - common bgp: - asn: 64002 + asn: 64089 peers: 65100: - - 10.0.0.208 - - fc00::1a1 + - 10.0.0.184 + - fc00::171 interfaces: Loopback0: - ipv4: 100.1.0.105/32 - ipv6: 2064:100::69/128 + ipv4: 100.1.0.93/32 + ipv6: 2064:100::5d/128 Ethernet1: - ipv4: 10.0.0.209/31 - ipv6: fc00::1a2/126 + ipv4: 10.0.0.185/31 + ipv6: fc00::172/126 bp_interfaces: ipv4: 10.10.246.94/24 ipv6: fc0a::5e/64 - ARISTA94T0: + ARISTA90T0: properties: - common bgp: - asn: 64002 + asn: 64090 peers: 65100: - - 10.0.0.210 - - fc00::1a5 + - 10.0.0.186 + - fc00::175 interfaces: Loopback0: - ipv4: 100.1.0.106/32 - ipv6: 2064:100::6a/128 + ipv4: 100.1.0.94/32 + ipv6: 2064:100::5e/128 Ethernet1: - ipv4: 10.0.0.211/31 - ipv6: fc00::1a6/126 + ipv4: 10.0.0.187/31 + ipv6: fc00::176/126 bp_interfaces: ipv4: 10.10.246.95/24 ipv6: fc0a::5f/64 - ARISTA95T0: + ARISTA91T0: properties: - common bgp: - asn: 64002 + asn: 64091 peers: 65100: - - 10.0.0.212 - - fc00::1a9 + - 10.0.0.188 + - fc00::179 interfaces: Loopback0: - ipv4: 100.1.0.107/32 - ipv6: 2064:100::6b/128 + ipv4: 100.1.0.95/32 + ipv6: 2064:100::5f/128 Ethernet1: - ipv4: 10.0.0.213/31 - ipv6: fc00::1aa/126 + ipv4: 10.0.0.189/31 + ipv6: fc00::17a/126 bp_interfaces: ipv4: 10.10.246.96/24 ipv6: fc0a::60/64 - ARISTA96T0: + ARISTA92T0: properties: - common bgp: - asn: 64002 + asn: 64092 peers: 65100: - - 10.0.0.214 - - fc00::1ad + - 10.0.0.190 + - fc00::17d interfaces: Loopback0: - ipv4: 100.1.0.108/32 - ipv6: 2064:100::6c/128 + ipv4: 100.1.0.96/32 + ipv6: 2064:100::60/128 Ethernet1: - ipv4: 10.0.0.215/31 - ipv6: fc00::1ae/126 + ipv4: 10.0.0.191/31 + ipv6: fc00::17e/126 bp_interfaces: ipv4: 10.10.246.97/24 ipv6: fc0a::61/64 - ARISTA97T0: + ARISTA93T0: properties: - common bgp: - asn: 64002 + asn: 64093 peers: 65100: - - 10.0.0.216 - - fc00::1b1 + - 10.0.0.192 + - fc00::181 interfaces: Loopback0: - ipv4: 100.1.0.109/32 - ipv6: 2064:100::6d/128 - Ethernet1: - ipv4: 10.0.0.217/31 - ipv6: fc00::1b2/126 + ipv4: 100.1.0.97/32 + ipv6: 2064:100::61/128 + Ethernet1: + ipv4: 10.0.0.193/31 + ipv6: fc00::182/126 bp_interfaces: ipv4: 10.10.246.98/24 ipv6: fc0a::62/64 - ARISTA98T0: + ARISTA94T0: properties: - common bgp: - asn: 64002 + asn: 64094 peers: 65100: - - 10.0.0.218 - - fc00::1b5 + - 10.0.0.194 + - fc00::185 interfaces: Loopback0: - ipv4: 100.1.0.110/32 - ipv6: 2064:100::6e/128 + ipv4: 100.1.0.98/32 + ipv6: 2064:100::62/128 Ethernet1: - ipv4: 10.0.0.219/31 - ipv6: fc00::1b6/126 + ipv4: 10.0.0.195/31 + ipv6: fc00::186/126 bp_interfaces: ipv4: 10.10.246.99/24 ipv6: fc0a::63/64 - ARISTA99T0: + ARISTA95T0: properties: - common bgp: - asn: 64002 + asn: 64095 peers: 65100: - - 10.0.0.220 - - fc00::1b9 + - 10.0.0.196 + - fc00::189 interfaces: Loopback0: - ipv4: 100.1.0.111/32 - ipv6: 2064:100::6f/128 + ipv4: 100.1.0.99/32 + ipv6: 2064:100::63/128 Ethernet1: - ipv4: 10.0.0.221/31 - ipv6: fc00::1ba/126 + ipv4: 10.0.0.197/31 + ipv6: fc00::18a/126 bp_interfaces: ipv4: 10.10.246.100/24 ipv6: fc0a::64/64 - ARISTA100T0: + ARISTA96T0: properties: - common bgp: - asn: 64002 + asn: 64096 peers: 65100: - - 10.0.0.222 - - fc00::1bd + - 10.0.0.198 + - fc00::18d interfaces: Loopback0: - ipv4: 100.1.0.112/32 - ipv6: 2064:100::70/128 + ipv4: 100.1.0.100/32 + ipv6: 2064:100::64/128 Ethernet1: - ipv4: 10.0.0.223/31 - ipv6: fc00::1be/126 + ipv4: 10.0.0.199/31 + ipv6: fc00::18e/126 bp_interfaces: ipv4: 10.10.246.101/24 ipv6: fc0a::65/64 - ARISTA101T0: + ARISTA97T0: properties: - common bgp: - asn: 64002 + asn: 64097 peers: 65100: - - 10.0.0.224 - - fc00::1c1 + - 10.0.0.200 + - fc00::191 interfaces: Loopback0: - ipv4: 100.1.0.113/32 - ipv6: 2064:100::71/128 + ipv4: 100.1.0.101/32 + ipv6: 2064:100::65/128 Ethernet1: - ipv4: 10.0.0.225/31 - ipv6: fc00::1c2/126 + ipv4: 10.0.0.201/31 + ipv6: fc00::192/126 bp_interfaces: ipv4: 10.10.246.102/24 ipv6: fc0a::66/64 - ARISTA102T0: + ARISTA98T0: properties: - common bgp: - asn: 64002 + asn: 64098 peers: 65100: - - 10.0.0.226 - - fc00::1c5 + - 10.0.0.202 + - fc00::195 interfaces: Loopback0: - ipv4: 100.1.0.114/32 - ipv6: 2064:100::72/128 + ipv4: 100.1.0.102/32 + ipv6: 2064:100::66/128 Ethernet1: - ipv4: 10.0.0.227/31 - ipv6: fc00::1c6/126 + ipv4: 10.0.0.203/31 + ipv6: fc00::196/126 bp_interfaces: ipv4: 10.10.246.103/24 ipv6: fc0a::67/64 - ARISTA103T0: + ARISTA99T0: properties: - common bgp: - asn: 64002 + asn: 64099 peers: 65100: - - 10.0.0.228 - - fc00::1c9 + - 10.0.0.204 + - fc00::199 interfaces: Loopback0: - ipv4: 100.1.0.115/32 - ipv6: 2064:100::73/128 + ipv4: 100.1.0.103/32 + ipv6: 2064:100::67/128 Ethernet1: - ipv4: 10.0.0.229/31 - ipv6: fc00::1ca/126 + ipv4: 10.0.0.205/31 + ipv6: fc00::19a/126 bp_interfaces: ipv4: 10.10.246.104/24 ipv6: fc0a::68/64 - ARISTA104T0: + ARISTA100T0: properties: - common bgp: - asn: 64002 + asn: 64100 peers: 65100: - - 10.0.0.230 - - fc00::1cd + - 10.0.0.206 + - fc00::19d interfaces: Loopback0: - ipv4: 100.1.0.116/32 - ipv6: 2064:100::74/128 + ipv4: 100.1.0.104/32 + ipv6: 2064:100::68/128 Ethernet1: - ipv4: 10.0.0.231/31 - ipv6: fc00::1ce/126 + ipv4: 10.0.0.207/31 + ipv6: fc00::19e/126 bp_interfaces: ipv4: 10.10.246.105/24 ipv6: fc0a::69/64 - ARISTA105T0: + ARISTA101T0: properties: - common bgp: - asn: 64002 + asn: 64101 peers: 65100: - - 10.0.0.232 - - fc00::1d1 + - 10.0.0.208 + - fc00::1a1 interfaces: Loopback0: - ipv4: 100.1.0.117/32 - ipv6: 2064:100::75/128 + ipv4: 100.1.0.105/32 + ipv6: 2064:100::69/128 Ethernet1: - ipv4: 10.0.0.233/31 - ipv6: fc00::1d2/126 + ipv4: 10.0.0.209/31 + ipv6: fc00::1a2/126 bp_interfaces: ipv4: 10.10.246.106/24 ipv6: fc0a::6a/64 - ARISTA106T0: + ARISTA102T0: properties: - common bgp: - asn: 64002 + asn: 64102 peers: 65100: - - 10.0.0.234 - - fc00::1d5 + - 10.0.0.210 + - fc00::1a5 interfaces: Loopback0: - ipv4: 100.1.0.118/32 - ipv6: 2064:100::76/128 + ipv4: 100.1.0.106/32 + ipv6: 2064:100::6a/128 Ethernet1: - ipv4: 10.0.0.235/31 - ipv6: fc00::1d6/126 + ipv4: 10.0.0.211/31 + ipv6: fc00::1a6/126 bp_interfaces: ipv4: 10.10.246.107/24 ipv6: fc0a::6b/64 - ARISTA107T0: + ARISTA103T0: properties: - common bgp: - asn: 64002 + asn: 64103 peers: 65100: - - 10.0.0.236 - - fc00::1d9 + - 10.0.0.212 + - fc00::1a9 interfaces: Loopback0: - ipv4: 100.1.0.119/32 - ipv6: 2064:100::77/128 + ipv4: 100.1.0.107/32 + ipv6: 2064:100::6b/128 Ethernet1: - ipv4: 10.0.0.237/31 - ipv6: fc00::1da/126 + ipv4: 10.0.0.213/31 + ipv6: fc00::1aa/126 bp_interfaces: ipv4: 10.10.246.108/24 ipv6: fc0a::6c/64 - ARISTA108T0: + ARISTA104T0: properties: - common bgp: - asn: 64002 + asn: 64104 peers: 65100: - - 10.0.0.238 - - fc00::1dd + - 10.0.0.214 + - fc00::1ad interfaces: Loopback0: - ipv4: 100.1.0.120/32 - ipv6: 2064:100::78/128 + ipv4: 100.1.0.108/32 + ipv6: 2064:100::6c/128 Ethernet1: - ipv4: 10.0.0.239/31 - ipv6: fc00::1de/126 + ipv4: 10.0.0.215/31 + ipv6: fc00::1ae/126 bp_interfaces: ipv4: 10.10.246.109/24 ipv6: fc0a::6d/64 - ARISTA109T0: + ARISTA105T0: properties: - common bgp: - asn: 64002 + asn: 64105 peers: 65100: - - 10.0.0.240 - - fc00::1e1 + - 10.0.0.216 + - fc00::1b1 interfaces: Loopback0: - ipv4: 100.1.0.121/32 - ipv6: 2064:100::79/128 + ipv4: 100.1.0.109/32 + ipv6: 2064:100::6d/128 Ethernet1: - ipv4: 10.0.0.241/31 - ipv6: fc00::1e2/126 + ipv4: 10.0.0.217/31 + ipv6: fc00::1b2/126 bp_interfaces: ipv4: 10.10.246.110/24 ipv6: fc0a::6e/64 - ARISTA110T0: + ARISTA106T0: properties: - common bgp: - asn: 64002 + asn: 64106 peers: 65100: - - 10.0.0.242 - - fc00::1e5 + - 10.0.0.218 + - fc00::1b5 interfaces: Loopback0: - ipv4: 100.1.0.122/32 - ipv6: 2064:100::7a/128 + ipv4: 100.1.0.110/32 + ipv6: 2064:100::6e/128 Ethernet1: - ipv4: 10.0.0.243/31 - ipv6: fc00::1e6/126 + ipv4: 10.0.0.219/31 + ipv6: fc00::1b6/126 bp_interfaces: ipv4: 10.10.246.111/24 ipv6: fc0a::6f/64 - ARISTA111T0: + ARISTA107T0: properties: - common bgp: - asn: 64002 + asn: 64107 peers: 65100: - - 10.0.0.244 - - fc00::1e9 + - 10.0.0.220 + - fc00::1b9 interfaces: Loopback0: - ipv4: 100.1.0.123/32 - ipv6: 2064:100::7b/128 + ipv4: 100.1.0.111/32 + ipv6: 2064:100::6f/128 Ethernet1: - ipv4: 10.0.0.245/31 - ipv6: fc00::1ea/126 + ipv4: 10.0.0.221/31 + ipv6: fc00::1ba/126 bp_interfaces: ipv4: 10.10.246.112/24 ipv6: fc0a::70/64 - ARISTA112T0: + ARISTA108T0: properties: - common bgp: - asn: 64002 + asn: 64108 peers: 65100: - - 10.0.0.246 - - fc00::1ed + - 10.0.0.222 + - fc00::1bd interfaces: Loopback0: - ipv4: 100.1.0.124/32 - ipv6: 2064:100::7c/128 + ipv4: 100.1.0.112/32 + ipv6: 2064:100::70/128 Ethernet1: - ipv4: 10.0.0.247/31 - ipv6: fc00::1ee/126 + ipv4: 10.0.0.223/31 + ipv6: fc00::1be/126 bp_interfaces: ipv4: 10.10.246.113/24 ipv6: fc0a::71/64 - ARISTA113T0: + ARISTA109T0: properties: - common bgp: - asn: 64002 + asn: 64109 peers: 65100: - - 10.0.0.248 - - fc00::1f1 + - 10.0.0.224 + - fc00::1c1 interfaces: Loopback0: - ipv4: 100.1.0.125/32 - ipv6: 2064:100::7d/128 + ipv4: 100.1.0.113/32 + ipv6: 2064:100::71/128 Ethernet1: - ipv4: 10.0.0.249/31 - ipv6: fc00::1f2/126 + ipv4: 10.0.0.225/31 + ipv6: fc00::1c2/126 bp_interfaces: ipv4: 10.10.246.114/24 ipv6: fc0a::72/64 - ARISTA114T0: + ARISTA110T0: properties: - common bgp: - asn: 64002 + asn: 64110 peers: 65100: - - 10.0.0.250 - - fc00::1f5 + - 10.0.0.226 + - fc00::1c5 interfaces: Loopback0: - ipv4: 100.1.0.126/32 - ipv6: 2064:100::7e/128 + ipv4: 100.1.0.114/32 + ipv6: 2064:100::72/128 Ethernet1: - ipv4: 10.0.0.251/31 - ipv6: fc00::1f6/126 + ipv4: 10.0.0.227/31 + ipv6: fc00::1c6/126 bp_interfaces: ipv4: 10.10.246.115/24 ipv6: fc0a::73/64 - ARISTA115T0: + ARISTA111T0: properties: - common bgp: - asn: 64002 + asn: 64111 peers: 65100: - - 10.0.0.252 - - fc00::1f9 + - 10.0.0.228 + - fc00::1c9 interfaces: Loopback0: - ipv4: 100.1.0.127/32 - ipv6: 2064:100::7f/128 + ipv4: 100.1.0.115/32 + ipv6: 2064:100::73/128 Ethernet1: - ipv4: 10.0.0.253/31 - ipv6: fc00::1fa/126 + ipv4: 10.0.0.229/31 + ipv6: fc00::1ca/126 bp_interfaces: ipv4: 10.10.246.116/24 ipv6: fc0a::74/64 - ARISTA116T0: + ARISTA112T0: properties: - common bgp: - asn: 64002 + asn: 64112 peers: 65100: - - 10.0.0.254 - - fc00::1fd + - 10.0.0.230 + - fc00::1cd interfaces: Loopback0: - ipv4: 100.1.0.128/32 - ipv6: 2064:100::80/128 + ipv4: 100.1.0.116/32 + ipv6: 2064:100::74/128 Ethernet1: - ipv4: 10.0.0.255/31 - ipv6: fc00::1fe/126 + ipv4: 10.0.0.231/31 + ipv6: fc00::1ce/126 bp_interfaces: ipv4: 10.10.246.117/24 ipv6: fc0a::75/64 - ARISTA117T0: + ARISTA113T0: properties: - common bgp: - asn: 64002 + asn: 64113 peers: 65100: - - 10.0.1.0 - - fc00::201 + - 10.0.0.232 + - fc00::1d1 interfaces: Loopback0: - ipv4: 100.1.0.129/32 - ipv6: 2064:100::81/128 + ipv4: 100.1.0.117/32 + ipv6: 2064:100::75/128 Ethernet1: - ipv4: 10.0.1.1/31 - ipv6: fc00::202/126 + ipv4: 10.0.0.233/31 + ipv6: fc00::1d2/126 bp_interfaces: ipv4: 10.10.246.118/24 ipv6: fc0a::76/64 - ARISTA118T0: + ARISTA114T0: properties: - common bgp: - asn: 64002 + asn: 64114 peers: 65100: - - 10.0.1.2 - - fc00::205 + - 10.0.0.234 + - fc00::1d5 interfaces: Loopback0: - ipv4: 100.1.0.130/32 - ipv6: 2064:100::82/128 + ipv4: 100.1.0.118/32 + ipv6: 2064:100::76/128 Ethernet1: - ipv4: 10.0.1.3/31 - ipv6: fc00::206/126 + ipv4: 10.0.0.235/31 + ipv6: fc00::1d6/126 bp_interfaces: ipv4: 10.10.246.119/24 ipv6: fc0a::77/64 - ARISTA119T0: + ARISTA115T0: properties: - common bgp: - asn: 64002 + asn: 64115 peers: 65100: - - 10.0.1.4 - - fc00::209 + - 10.0.0.236 + - fc00::1d9 interfaces: Loopback0: - ipv4: 100.1.0.131/32 - ipv6: 2064:100::83/128 + ipv4: 100.1.0.119/32 + ipv6: 2064:100::77/128 Ethernet1: - ipv4: 10.0.1.5/31 - ipv6: fc00::20a/126 + ipv4: 10.0.0.237/31 + ipv6: fc00::1da/126 bp_interfaces: ipv4: 10.10.246.120/24 ipv6: fc0a::78/64 - ARISTA120T0: + ARISTA116T0: properties: - common bgp: - asn: 64002 + asn: 64116 peers: 65100: - - 10.0.1.6 - - fc00::20d + - 10.0.0.238 + - fc00::1dd interfaces: Loopback0: - ipv4: 100.1.0.132/32 - ipv6: 2064:100::84/128 + ipv4: 100.1.0.120/32 + ipv6: 2064:100::78/128 Ethernet1: - ipv4: 10.0.1.7/31 - ipv6: fc00::20e/126 + ipv4: 10.0.0.239/31 + ipv6: fc00::1de/126 bp_interfaces: ipv4: 10.10.246.121/24 ipv6: fc0a::79/64 - ARISTA121T0: + ARISTA117T0: properties: - common bgp: - asn: 64002 + asn: 64117 peers: 65100: - - 10.0.1.8 - - fc00::211 + - 10.0.0.240 + - fc00::1e1 interfaces: Loopback0: - ipv4: 100.1.0.133/32 - ipv6: 2064:100::85/128 + ipv4: 100.1.0.121/32 + ipv6: 2064:100::79/128 Ethernet1: - ipv4: 10.0.1.9/31 - ipv6: fc00::212/126 + ipv4: 10.0.0.241/31 + ipv6: fc00::1e2/126 bp_interfaces: ipv4: 10.10.246.122/24 ipv6: fc0a::7a/64 - ARISTA122T0: + ARISTA118T0: properties: - common bgp: - asn: 64002 + asn: 64118 peers: 65100: - - 10.0.1.10 - - fc00::215 + - 10.0.0.242 + - fc00::1e5 interfaces: Loopback0: - ipv4: 100.1.0.134/32 - ipv6: 2064:100::86/128 + ipv4: 100.1.0.122/32 + ipv6: 2064:100::7a/128 Ethernet1: - ipv4: 10.0.1.11/31 - ipv6: fc00::216/126 + ipv4: 10.0.0.243/31 + ipv6: fc00::1e6/126 bp_interfaces: ipv4: 10.10.246.123/24 ipv6: fc0a::7b/64 - ARISTA123T0: + ARISTA119T0: properties: - common bgp: - asn: 64002 + asn: 64119 peers: 65100: - - 10.0.1.12 - - fc00::219 + - 10.0.0.244 + - fc00::1e9 interfaces: Loopback0: - ipv4: 100.1.0.135/32 - ipv6: 2064:100::87/128 + ipv4: 100.1.0.123/32 + ipv6: 2064:100::7b/128 Ethernet1: - ipv4: 10.0.1.13/31 - ipv6: fc00::21a/126 + ipv4: 10.0.0.245/31 + ipv6: fc00::1ea/126 bp_interfaces: ipv4: 10.10.246.124/24 ipv6: fc0a::7c/64 - ARISTA124T0: + ARISTA120T0: properties: - common bgp: - asn: 64002 + asn: 64120 peers: 65100: - - 10.0.1.14 - - fc00::21d + - 10.0.0.246 + - fc00::1ed interfaces: Loopback0: - ipv4: 100.1.0.136/32 - ipv6: 2064:100::88/128 + ipv4: 100.1.0.124/32 + ipv6: 2064:100::7c/128 Ethernet1: - ipv4: 10.0.1.15/31 - ipv6: fc00::21e/126 + ipv4: 10.0.0.247/31 + ipv6: fc00::1ee/126 bp_interfaces: ipv4: 10.10.246.125/24 ipv6: fc0a::7d/64 - ARISTA125T0: + ARISTA121T0: properties: - common bgp: - asn: 64002 + asn: 64121 peers: 65100: - - 10.0.1.16 - - fc00::221 + - 10.0.0.248 + - fc00::1f1 interfaces: Loopback0: - ipv4: 100.1.0.137/32 - ipv6: 2064:100::89/128 + ipv4: 100.1.0.125/32 + ipv6: 2064:100::7d/128 Ethernet1: - ipv4: 10.0.1.17/31 - ipv6: fc00::222/126 + ipv4: 10.0.0.249/31 + ipv6: fc00::1f2/126 bp_interfaces: ipv4: 10.10.246.126/24 ipv6: fc0a::7e/64 - ARISTA126T0: + ARISTA122T0: properties: - common bgp: - asn: 64002 + asn: 64122 peers: 65100: - - 10.0.1.18 - - fc00::225 + - 10.0.0.250 + - fc00::1f5 interfaces: Loopback0: - ipv4: 100.1.0.138/32 - ipv6: 2064:100::8a/128 + ipv4: 100.1.0.126/32 + ipv6: 2064:100::7e/128 Ethernet1: - ipv4: 10.0.1.19/31 - ipv6: fc00::226/126 + ipv4: 10.0.0.251/31 + ipv6: fc00::1f6/126 bp_interfaces: ipv4: 10.10.246.127/24 ipv6: fc0a::7f/64 - ARISTA127T0: + ARISTA123T0: properties: - common bgp: - asn: 64002 + asn: 64123 peers: 65100: - - 10.0.1.20 - - fc00::229 + - 10.0.0.252 + - fc00::1f9 interfaces: Loopback0: - ipv4: 100.1.0.139/32 - ipv6: 2064:100::8b/128 + ipv4: 100.1.0.127/32 + ipv6: 2064:100::7f/128 Ethernet1: - ipv4: 10.0.1.21/31 - ipv6: fc00::22a/126 + ipv4: 10.0.0.253/31 + ipv6: fc00::1fa/126 bp_interfaces: ipv4: 10.10.246.128/24 ipv6: fc0a::80/64 - ARISTA128T0: + ARISTA124T0: properties: - common bgp: - asn: 64002 + asn: 64124 peers: 65100: - - 10.0.1.22 - - fc00::22d + - 10.0.0.254 + - fc00::1fd interfaces: Loopback0: - ipv4: 100.1.0.140/32 - ipv6: 2064:100::8c/128 + ipv4: 100.1.0.128/32 + ipv6: 2064:100::80/128 Ethernet1: - ipv4: 10.0.1.23/31 - ipv6: fc00::22e/126 + ipv4: 10.0.0.255/31 + ipv6: fc00::1fe/126 bp_interfaces: ipv4: 10.10.246.129/24 ipv6: fc0a::81/64 - ARISTA129T0: + ARISTA125T0: properties: - common bgp: - asn: 64002 + asn: 64125 peers: 65100: - - 10.0.1.24 - - fc00::231 + - 10.0.1.0 + - fc00::201 interfaces: Loopback0: - ipv4: 100.1.0.141/32 - ipv6: 2064:100::8d/128 + ipv4: 100.1.0.129/32 + ipv6: 2064:100::81/128 Ethernet1: - ipv4: 10.0.1.25/31 - ipv6: fc00::232/126 + ipv4: 10.0.1.1/31 + ipv6: fc00::202/126 bp_interfaces: ipv4: 10.10.246.130/24 ipv6: fc0a::82/64 - ARISTA130T0: + ARISTA126T0: properties: - common bgp: - asn: 64002 + asn: 64126 peers: 65100: - - 10.0.1.26 - - fc00::235 + - 10.0.1.2 + - fc00::205 interfaces: Loopback0: - ipv4: 100.1.0.142/32 - ipv6: 2064:100::8e/128 + ipv4: 100.1.0.130/32 + ipv6: 2064:100::82/128 Ethernet1: - ipv4: 10.0.1.27/31 - ipv6: fc00::236/126 + ipv4: 10.0.1.3/31 + ipv6: fc00::206/126 bp_interfaces: ipv4: 10.10.246.131/24 ipv6: fc0a::83/64 - ARISTA131T0: + ARISTA127T0: properties: - common bgp: - asn: 64002 + asn: 64127 peers: 65100: - - 10.0.1.28 - - fc00::239 + - 10.0.1.4 + - fc00::209 interfaces: Loopback0: - ipv4: 100.1.0.143/32 - ipv6: 2064:100::8f/128 - Ethernet1: - ipv4: 10.0.1.29/31 - ipv6: fc00::23a/126 + ipv4: 100.1.0.131/32 + ipv6: 2064:100::83/128 + Ethernet1: + ipv4: 10.0.1.5/31 + ipv6: fc00::20a/126 bp_interfaces: ipv4: 10.10.246.132/24 ipv6: fc0a::84/64 - ARISTA132T0: + ARISTA128T0: properties: - common bgp: - asn: 64002 + asn: 64128 peers: 65100: - - 10.0.1.30 - - fc00::23d + - 10.0.1.6 + - fc00::20d interfaces: Loopback0: - ipv4: 100.1.0.144/32 - ipv6: 2064:100::90/128 + ipv4: 100.1.0.132/32 + ipv6: 2064:100::84/128 Ethernet1: - ipv4: 10.0.1.31/31 - ipv6: fc00::23e/126 + ipv4: 10.0.1.7/31 + ipv6: fc00::20e/126 bp_interfaces: ipv4: 10.10.246.133/24 ipv6: fc0a::85/64 - ARISTA133T0: + ARISTA129T0: properties: - common bgp: - asn: 64002 + asn: 64129 peers: 65100: - - 10.0.1.32 - - fc00::241 + - 10.0.1.8 + - fc00::211 interfaces: Loopback0: - ipv4: 100.1.0.145/32 - ipv6: 2064:100::91/128 + ipv4: 100.1.0.133/32 + ipv6: 2064:100::85/128 Ethernet1: - ipv4: 10.0.1.33/31 - ipv6: fc00::242/126 + ipv4: 10.0.1.9/31 + ipv6: fc00::212/126 bp_interfaces: ipv4: 10.10.246.134/24 ipv6: fc0a::86/64 - ARISTA134T0: + ARISTA130T0: properties: - common bgp: - asn: 64002 + asn: 64130 peers: 65100: - - 10.0.1.34 - - fc00::245 + - 10.0.1.10 + - fc00::215 interfaces: Loopback0: - ipv4: 100.1.0.146/32 - ipv6: 2064:100::92/128 + ipv4: 100.1.0.134/32 + ipv6: 2064:100::86/128 Ethernet1: - ipv4: 10.0.1.35/31 - ipv6: fc00::246/126 + ipv4: 10.0.1.11/31 + ipv6: fc00::216/126 bp_interfaces: ipv4: 10.10.246.135/24 ipv6: fc0a::87/64 - ARISTA135T0: + ARISTA131T0: properties: - common bgp: - asn: 64002 + asn: 64131 peers: 65100: - - 10.0.1.36 - - fc00::249 + - 10.0.1.12 + - fc00::219 interfaces: Loopback0: - ipv4: 100.1.0.147/32 - ipv6: 2064:100::93/128 + ipv4: 100.1.0.135/32 + ipv6: 2064:100::87/128 Ethernet1: - ipv4: 10.0.1.37/31 - ipv6: fc00::24a/126 + ipv4: 10.0.1.13/31 + ipv6: fc00::21a/126 bp_interfaces: ipv4: 10.10.246.136/24 ipv6: fc0a::88/64 - ARISTA136T0: + ARISTA132T0: properties: - common bgp: - asn: 64002 + asn: 64132 peers: 65100: - - 10.0.1.38 - - fc00::24d + - 10.0.1.14 + - fc00::21d interfaces: Loopback0: - ipv4: 100.1.0.148/32 - ipv6: 2064:100::94/128 + ipv4: 100.1.0.136/32 + ipv6: 2064:100::88/128 Ethernet1: - ipv4: 10.0.1.39/31 - ipv6: fc00::24e/126 + ipv4: 10.0.1.15/31 + ipv6: fc00::21e/126 bp_interfaces: ipv4: 10.10.246.137/24 ipv6: fc0a::89/64 - ARISTA137T0: + ARISTA133T0: properties: - common bgp: - asn: 64002 + asn: 64133 peers: 65100: - - 10.0.1.40 - - fc00::251 + - 10.0.1.16 + - fc00::221 interfaces: Loopback0: - ipv4: 100.1.0.149/32 - ipv6: 2064:100::95/128 + ipv4: 100.1.0.137/32 + ipv6: 2064:100::89/128 Ethernet1: - ipv4: 10.0.1.41/31 - ipv6: fc00::252/126 + ipv4: 10.0.1.17/31 + ipv6: fc00::222/126 bp_interfaces: ipv4: 10.10.246.138/24 ipv6: fc0a::8a/64 - ARISTA138T0: + ARISTA134T0: properties: - common bgp: - asn: 64002 + asn: 64134 peers: 65100: - - 10.0.1.42 - - fc00::255 + - 10.0.1.18 + - fc00::225 interfaces: Loopback0: - ipv4: 100.1.0.150/32 - ipv6: 2064:100::96/128 + ipv4: 100.1.0.138/32 + ipv6: 2064:100::8a/128 Ethernet1: - ipv4: 10.0.1.43/31 - ipv6: fc00::256/126 + ipv4: 10.0.1.19/31 + ipv6: fc00::226/126 bp_interfaces: ipv4: 10.10.246.139/24 ipv6: fc0a::8b/64 - ARISTA139T0: + ARISTA135T0: properties: - common bgp: - asn: 64002 + asn: 64135 peers: 65100: - - 10.0.1.44 - - fc00::259 + - 10.0.1.20 + - fc00::229 interfaces: Loopback0: - ipv4: 100.1.0.151/32 - ipv6: 2064:100::97/128 + ipv4: 100.1.0.139/32 + ipv6: 2064:100::8b/128 Ethernet1: - ipv4: 10.0.1.45/31 - ipv6: fc00::25a/126 + ipv4: 10.0.1.21/31 + ipv6: fc00::22a/126 bp_interfaces: ipv4: 10.10.246.140/24 ipv6: fc0a::8c/64 - ARISTA140T0: + ARISTA136T0: properties: - common bgp: - asn: 64002 + asn: 64136 peers: 65100: - - 10.0.1.46 - - fc00::25d + - 10.0.1.22 + - fc00::22d interfaces: Loopback0: - ipv4: 100.1.0.152/32 - ipv6: 2064:100::98/128 + ipv4: 100.1.0.140/32 + ipv6: 2064:100::8c/128 Ethernet1: - ipv4: 10.0.1.47/31 - ipv6: fc00::25e/126 + ipv4: 10.0.1.23/31 + ipv6: fc00::22e/126 bp_interfaces: ipv4: 10.10.246.141/24 ipv6: fc0a::8d/64 - ARISTA141T0: + ARISTA137T0: properties: - common bgp: - asn: 64002 + asn: 64137 peers: 65100: - - 10.0.1.48 - - fc00::261 + - 10.0.1.24 + - fc00::231 interfaces: Loopback0: - ipv4: 100.1.0.153/32 - ipv6: 2064:100::99/128 + ipv4: 100.1.0.141/32 + ipv6: 2064:100::8d/128 Ethernet1: - ipv4: 10.0.1.49/31 - ipv6: fc00::262/126 + ipv4: 10.0.1.25/31 + ipv6: fc00::232/126 bp_interfaces: ipv4: 10.10.246.142/24 ipv6: fc0a::8e/64 - ARISTA142T0: + ARISTA138T0: properties: - common bgp: - asn: 64002 + asn: 64138 peers: 65100: - - 10.0.1.50 - - fc00::265 + - 10.0.1.26 + - fc00::235 interfaces: Loopback0: - ipv4: 100.1.0.154/32 - ipv6: 2064:100::9a/128 + ipv4: 100.1.0.142/32 + ipv6: 2064:100::8e/128 Ethernet1: - ipv4: 10.0.1.51/31 - ipv6: fc00::266/126 + ipv4: 10.0.1.27/31 + ipv6: fc00::236/126 bp_interfaces: ipv4: 10.10.246.143/24 ipv6: fc0a::8f/64 - ARISTA143T0: + ARISTA139T0: properties: - common bgp: - asn: 64002 + asn: 64139 peers: 65100: - - 10.0.1.52 - - fc00::269 + - 10.0.1.28 + - fc00::239 interfaces: Loopback0: - ipv4: 100.1.0.155/32 - ipv6: 2064:100::9b/128 + ipv4: 100.1.0.143/32 + ipv6: 2064:100::8f/128 Ethernet1: - ipv4: 10.0.1.53/31 - ipv6: fc00::26a/126 + ipv4: 10.0.1.29/31 + ipv6: fc00::23a/126 bp_interfaces: ipv4: 10.10.246.144/24 ipv6: fc0a::90/64 - ARISTA144T0: + ARISTA140T0: properties: - common bgp: - asn: 64002 + asn: 64140 peers: 65100: - - 10.0.1.54 - - fc00::26d + - 10.0.1.30 + - fc00::23d interfaces: Loopback0: - ipv4: 100.1.0.156/32 - ipv6: 2064:100::9c/128 + ipv4: 100.1.0.144/32 + ipv6: 2064:100::90/128 Ethernet1: - ipv4: 10.0.1.55/31 - ipv6: fc00::26e/126 + ipv4: 10.0.1.31/31 + ipv6: fc00::23e/126 bp_interfaces: ipv4: 10.10.246.145/24 ipv6: fc0a::91/64 - ARISTA145T0: + ARISTA141T0: properties: - common bgp: - asn: 64002 + asn: 64141 peers: 65100: - - 10.0.1.56 - - fc00::271 + - 10.0.1.32 + - fc00::241 interfaces: Loopback0: - ipv4: 100.1.0.157/32 - ipv6: 2064:100::9d/128 + ipv4: 100.1.0.145/32 + ipv6: 2064:100::91/128 Ethernet1: - ipv4: 10.0.1.57/31 - ipv6: fc00::272/126 + ipv4: 10.0.1.33/31 + ipv6: fc00::242/126 bp_interfaces: ipv4: 10.10.246.146/24 ipv6: fc0a::92/64 - ARISTA146T0: + ARISTA142T0: properties: - common bgp: - asn: 64002 + asn: 64142 peers: 65100: - - 10.0.1.58 - - fc00::275 + - 10.0.1.34 + - fc00::245 interfaces: Loopback0: - ipv4: 100.1.0.158/32 - ipv6: 2064:100::9e/128 + ipv4: 100.1.0.146/32 + ipv6: 2064:100::92/128 Ethernet1: - ipv4: 10.0.1.59/31 - ipv6: fc00::276/126 + ipv4: 10.0.1.35/31 + ipv6: fc00::246/126 bp_interfaces: ipv4: 10.10.246.147/24 ipv6: fc0a::93/64 - ARISTA147T0: + ARISTA143T0: properties: - common bgp: - asn: 64002 + asn: 64143 peers: 65100: - - 10.0.1.60 - - fc00::279 + - 10.0.1.36 + - fc00::249 interfaces: Loopback0: - ipv4: 100.1.0.159/32 - ipv6: 2064:100::9f/128 + ipv4: 100.1.0.147/32 + ipv6: 2064:100::93/128 Ethernet1: - ipv4: 10.0.1.61/31 - ipv6: fc00::27a/126 + ipv4: 10.0.1.37/31 + ipv6: fc00::24a/126 bp_interfaces: ipv4: 10.10.246.148/24 ipv6: fc0a::94/64 - ARISTA148T0: + ARISTA144T0: properties: - common bgp: - asn: 64002 + asn: 64144 peers: 65100: - - 10.0.1.62 - - fc00::27d + - 10.0.1.38 + - fc00::24d interfaces: Loopback0: - ipv4: 100.1.0.160/32 - ipv6: 2064:100::a0/128 + ipv4: 100.1.0.148/32 + ipv6: 2064:100::94/128 Ethernet1: - ipv4: 10.0.1.63/31 - ipv6: fc00::27e/126 + ipv4: 10.0.1.39/31 + ipv6: fc00::24e/126 bp_interfaces: ipv4: 10.10.246.149/24 ipv6: fc0a::95/64 - ARISTA149T0: + ARISTA145T0: properties: - common bgp: - asn: 64002 + asn: 64145 peers: 65100: - - 10.0.1.64 - - fc00::281 + - 10.0.1.40 + - fc00::251 interfaces: Loopback0: - ipv4: 100.1.0.161/32 - ipv6: 2064:100::a1/128 + ipv4: 100.1.0.149/32 + ipv6: 2064:100::95/128 Ethernet1: - ipv4: 10.0.1.65/31 - ipv6: fc00::282/126 + ipv4: 10.0.1.41/31 + ipv6: fc00::252/126 bp_interfaces: ipv4: 10.10.246.150/24 ipv6: fc0a::96/64 - ARISTA150T0: + ARISTA146T0: properties: - common bgp: - asn: 64002 + asn: 64146 peers: 65100: - - 10.0.1.66 - - fc00::285 + - 10.0.1.42 + - fc00::255 interfaces: Loopback0: - ipv4: 100.1.0.162/32 - ipv6: 2064:100::a2/128 + ipv4: 100.1.0.150/32 + ipv6: 2064:100::96/128 Ethernet1: - ipv4: 10.0.1.67/31 - ipv6: fc00::286/126 + ipv4: 10.0.1.43/31 + ipv6: fc00::256/126 bp_interfaces: ipv4: 10.10.246.151/24 ipv6: fc0a::97/64 - ARISTA151T0: + ARISTA147T0: properties: - common bgp: - asn: 64002 + asn: 64147 peers: 65100: - - 10.0.1.68 - - fc00::289 + - 10.0.1.44 + - fc00::259 interfaces: Loopback0: - ipv4: 100.1.0.163/32 - ipv6: 2064:100::a3/128 + ipv4: 100.1.0.151/32 + ipv6: 2064:100::97/128 Ethernet1: - ipv4: 10.0.1.69/31 - ipv6: fc00::28a/126 + ipv4: 10.0.1.45/31 + ipv6: fc00::25a/126 bp_interfaces: ipv4: 10.10.246.152/24 ipv6: fc0a::98/64 - ARISTA152T0: + ARISTA148T0: properties: - common bgp: - asn: 64002 + asn: 64148 peers: 65100: - - 10.0.1.70 - - fc00::28d + - 10.0.1.46 + - fc00::25d interfaces: Loopback0: - ipv4: 100.1.0.164/32 - ipv6: 2064:100::a4/128 + ipv4: 100.1.0.152/32 + ipv6: 2064:100::98/128 Ethernet1: - ipv4: 10.0.1.71/31 - ipv6: fc00::28e/126 + ipv4: 10.0.1.47/31 + ipv6: fc00::25e/126 bp_interfaces: ipv4: 10.10.246.153/24 ipv6: fc0a::99/64 - ARISTA153T0: + ARISTA149T0: properties: - common bgp: - asn: 64002 + asn: 64149 peers: 65100: - - 10.0.1.72 - - fc00::291 + - 10.0.1.48 + - fc00::261 interfaces: Loopback0: - ipv4: 100.1.0.165/32 - ipv6: 2064:100::a5/128 + ipv4: 100.1.0.153/32 + ipv6: 2064:100::99/128 Ethernet1: - ipv4: 10.0.1.73/31 - ipv6: fc00::292/126 + ipv4: 10.0.1.49/31 + ipv6: fc00::262/126 bp_interfaces: ipv4: 10.10.246.154/24 ipv6: fc0a::9a/64 - ARISTA154T0: + ARISTA150T0: properties: - common bgp: - asn: 64002 + asn: 64150 peers: 65100: - - 10.0.1.74 - - fc00::295 + - 10.0.1.50 + - fc00::265 interfaces: Loopback0: - ipv4: 100.1.0.166/32 - ipv6: 2064:100::a6/128 + ipv4: 100.1.0.154/32 + ipv6: 2064:100::9a/128 Ethernet1: - ipv4: 10.0.1.75/31 - ipv6: fc00::296/126 + ipv4: 10.0.1.51/31 + ipv6: fc00::266/126 bp_interfaces: ipv4: 10.10.246.155/24 ipv6: fc0a::9b/64 - ARISTA155T0: + ARISTA151T0: properties: - common bgp: - asn: 64002 + asn: 64151 peers: 65100: - - 10.0.1.76 - - fc00::299 + - 10.0.1.52 + - fc00::269 interfaces: Loopback0: - ipv4: 100.1.0.167/32 - ipv6: 2064:100::a7/128 + ipv4: 100.1.0.155/32 + ipv6: 2064:100::9b/128 Ethernet1: - ipv4: 10.0.1.77/31 - ipv6: fc00::29a/126 + ipv4: 10.0.1.53/31 + ipv6: fc00::26a/126 bp_interfaces: ipv4: 10.10.246.156/24 ipv6: fc0a::9c/64 - ARISTA156T0: + ARISTA152T0: properties: - common bgp: - asn: 64002 + asn: 64152 peers: 65100: - - 10.0.1.78 - - fc00::29d + - 10.0.1.54 + - fc00::26d interfaces: Loopback0: - ipv4: 100.1.0.168/32 - ipv6: 2064:100::a8/128 + ipv4: 100.1.0.156/32 + ipv6: 2064:100::9c/128 Ethernet1: - ipv4: 10.0.1.79/31 - ipv6: fc00::29e/126 + ipv4: 10.0.1.55/31 + ipv6: fc00::26e/126 bp_interfaces: ipv4: 10.10.246.157/24 ipv6: fc0a::9d/64 - ARISTA157T0: + ARISTA153T0: properties: - common bgp: - asn: 64002 + asn: 64153 peers: 65100: - - 10.0.1.80 - - fc00::2a1 + - 10.0.1.56 + - fc00::271 interfaces: Loopback0: - ipv4: 100.1.0.169/32 - ipv6: 2064:100::a9/128 + ipv4: 100.1.0.157/32 + ipv6: 2064:100::9d/128 Ethernet1: - ipv4: 10.0.1.81/31 - ipv6: fc00::2a2/126 + ipv4: 10.0.1.57/31 + ipv6: fc00::272/126 bp_interfaces: ipv4: 10.10.246.158/24 ipv6: fc0a::9e/64 - ARISTA158T0: + ARISTA154T0: properties: - common bgp: - asn: 64002 + asn: 64154 peers: 65100: - - 10.0.1.82 - - fc00::2a5 + - 10.0.1.58 + - fc00::275 interfaces: Loopback0: - ipv4: 100.1.0.170/32 - ipv6: 2064:100::aa/128 + ipv4: 100.1.0.158/32 + ipv6: 2064:100::9e/128 Ethernet1: - ipv4: 10.0.1.83/31 - ipv6: fc00::2a6/126 + ipv4: 10.0.1.59/31 + ipv6: fc00::276/126 bp_interfaces: ipv4: 10.10.246.159/24 ipv6: fc0a::9f/64 - ARISTA159T0: + ARISTA155T0: properties: - common bgp: - asn: 64002 + asn: 64155 peers: 65100: - - 10.0.1.84 - - fc00::2a9 + - 10.0.1.60 + - fc00::279 interfaces: Loopback0: - ipv4: 100.1.0.171/32 - ipv6: 2064:100::ab/128 + ipv4: 100.1.0.159/32 + ipv6: 2064:100::9f/128 Ethernet1: - ipv4: 10.0.1.85/31 - ipv6: fc00::2aa/126 + ipv4: 10.0.1.61/31 + ipv6: fc00::27a/126 bp_interfaces: ipv4: 10.10.246.160/24 ipv6: fc0a::a0/64 - ARISTA160T0: + ARISTA156T0: properties: - common bgp: - asn: 64002 + asn: 64156 peers: 65100: - - 10.0.1.86 - - fc00::2ad + - 10.0.1.62 + - fc00::27d interfaces: Loopback0: - ipv4: 100.1.0.172/32 - ipv6: 2064:100::ac/128 + ipv4: 100.1.0.160/32 + ipv6: 2064:100::a0/128 Ethernet1: - ipv4: 10.0.1.87/31 - ipv6: fc00::2ae/126 + ipv4: 10.0.1.63/31 + ipv6: fc00::27e/126 bp_interfaces: ipv4: 10.10.246.161/24 ipv6: fc0a::a1/64 - ARISTA161T0: + ARISTA157T0: properties: - common bgp: - asn: 64002 + asn: 64157 peers: 65100: - - 10.0.1.88 - - fc00::2b1 + - 10.0.1.64 + - fc00::281 interfaces: Loopback0: - ipv4: 100.1.0.173/32 - ipv6: 2064:100::ad/128 + ipv4: 100.1.0.161/32 + ipv6: 2064:100::a1/128 Ethernet1: - ipv4: 10.0.1.89/31 - ipv6: fc00::2b2/126 + ipv4: 10.0.1.65/31 + ipv6: fc00::282/126 bp_interfaces: ipv4: 10.10.246.162/24 ipv6: fc0a::a2/64 - ARISTA162T0: + ARISTA158T0: properties: - common bgp: - asn: 64002 + asn: 64158 peers: 65100: - - 10.0.1.90 - - fc00::2b5 + - 10.0.1.66 + - fc00::285 interfaces: Loopback0: - ipv4: 100.1.0.174/32 - ipv6: 2064:100::ae/128 + ipv4: 100.1.0.162/32 + ipv6: 2064:100::a2/128 Ethernet1: - ipv4: 10.0.1.91/31 - ipv6: fc00::2b6/126 + ipv4: 10.0.1.67/31 + ipv6: fc00::286/126 bp_interfaces: ipv4: 10.10.246.163/24 ipv6: fc0a::a3/64 - ARISTA163T0: + ARISTA159T0: properties: - common bgp: - asn: 64002 + asn: 64159 peers: 65100: - - 10.0.1.92 - - fc00::2b9 + - 10.0.1.68 + - fc00::289 interfaces: Loopback0: - ipv4: 100.1.0.175/32 - ipv6: 2064:100::af/128 + ipv4: 100.1.0.163/32 + ipv6: 2064:100::a3/128 Ethernet1: - ipv4: 10.0.1.93/31 - ipv6: fc00::2ba/126 + ipv4: 10.0.1.69/31 + ipv6: fc00::28a/126 bp_interfaces: ipv4: 10.10.246.164/24 ipv6: fc0a::a4/64 - ARISTA164T0: + ARISTA160T0: properties: - common bgp: - asn: 64002 + asn: 64160 peers: 65100: - - 10.0.1.94 - - fc00::2bd + - 10.0.1.70 + - fc00::28d interfaces: Loopback0: - ipv4: 100.1.0.176/32 - ipv6: 2064:100::b0/128 + ipv4: 100.1.0.164/32 + ipv6: 2064:100::a4/128 Ethernet1: - ipv4: 10.0.1.95/31 - ipv6: fc00::2be/126 + ipv4: 10.0.1.71/31 + ipv6: fc00::28e/126 bp_interfaces: ipv4: 10.10.246.165/24 ipv6: fc0a::a5/64 - ARISTA165T2: + ARISTA05T2: properties: - common bgp: asn: 65200 peers: 65100: - - 10.0.1.96 - - fc00::2c1 + - 10.0.1.72 + - fc00::291 interfaces: Loopback0: - ipv4: 100.1.0.177/32 - ipv6: 2064:100::b1/128 + ipv4: 100.1.0.165/32 + ipv6: 2064:100::a5/128 Ethernet1: - ipv4: 10.0.1.97/31 - ipv6: fc00::2c2/126 + ipv4: 10.0.1.73/31 + ipv6: fc00::292/126 bp_interfaces: ipv4: 10.10.246.166/24 ipv6: fc0a::a6/64 - ARISTA166T2: + ARISTA06T2: properties: - common bgp: asn: 65200 peers: 65100: - - 10.0.1.98 - - fc00::2c5 + - 10.0.1.74 + - fc00::295 interfaces: Loopback0: - ipv4: 100.1.0.178/32 - ipv6: 2064:100::b2/128 + ipv4: 100.1.0.166/32 + ipv6: 2064:100::a6/128 Ethernet1: - ipv4: 10.0.1.99/31 - ipv6: fc00::2c6/126 + ipv4: 10.0.1.75/31 + ipv6: fc00::296/126 bp_interfaces: ipv4: 10.10.246.167/24 ipv6: fc0a::a7/64 - ARISTA167T0: + ARISTA161T0: properties: - common bgp: - asn: 64002 + asn: 64161 peers: 65100: - - 10.0.1.112 - - fc00::2e1 + - 10.0.1.76 + - fc00::299 interfaces: Loopback0: - ipv4: 100.1.0.185/32 - ipv6: 2064:100::b9/128 + ipv4: 100.1.0.167/32 + ipv6: 2064:100::a7/128 Ethernet1: - ipv4: 10.0.1.113/31 - ipv6: fc00::2e2/126 + ipv4: 10.0.1.77/31 + ipv6: fc00::29a/126 bp_interfaces: ipv4: 10.10.246.168/24 ipv6: fc0a::a8/64 - ARISTA168T0: + ARISTA162T0: properties: - common bgp: - asn: 64002 + asn: 64162 peers: 65100: - - 10.0.1.114 - - fc00::2e5 + - 10.0.1.78 + - fc00::29d interfaces: Loopback0: - ipv4: 100.1.0.186/32 - ipv6: 2064:100::ba/128 + ipv4: 100.1.0.168/32 + ipv6: 2064:100::a8/128 Ethernet1: - ipv4: 10.0.1.115/31 - ipv6: fc00::2e6/126 + ipv4: 10.0.1.79/31 + ipv6: fc00::29e/126 bp_interfaces: ipv4: 10.10.246.169/24 ipv6: fc0a::a9/64 - ARISTA169T0: + ARISTA163T0: properties: - common bgp: - asn: 64002 + asn: 64163 peers: 65100: - - 10.0.1.116 - - fc00::2e9 + - 10.0.1.80 + - fc00::2a1 interfaces: Loopback0: - ipv4: 100.1.0.187/32 - ipv6: 2064:100::bb/128 + ipv4: 100.1.0.169/32 + ipv6: 2064:100::a9/128 Ethernet1: - ipv4: 10.0.1.117/31 - ipv6: fc00::2ea/126 + ipv4: 10.0.1.81/31 + ipv6: fc00::2a2/126 bp_interfaces: ipv4: 10.10.246.170/24 ipv6: fc0a::aa/64 - ARISTA170T0: + ARISTA164T0: properties: - common bgp: - asn: 64002 + asn: 64164 peers: 65100: - - 10.0.1.118 - - fc00::2ed + - 10.0.1.82 + - fc00::2a5 interfaces: Loopback0: - ipv4: 100.1.0.188/32 - ipv6: 2064:100::bc/128 + ipv4: 100.1.0.170/32 + ipv6: 2064:100::aa/128 Ethernet1: - ipv4: 10.0.1.119/31 - ipv6: fc00::2ee/126 + ipv4: 10.0.1.83/31 + ipv6: fc00::2a6/126 bp_interfaces: ipv4: 10.10.246.171/24 ipv6: fc0a::ab/64 - ARISTA171T0: + ARISTA165T0: properties: - common bgp: - asn: 64002 + asn: 64165 peers: 65100: - - 10.0.1.120 - - fc00::2f1 + - 10.0.1.84 + - fc00::2a9 interfaces: Loopback0: - ipv4: 100.1.0.189/32 - ipv6: 2064:100::bd/128 + ipv4: 100.1.0.171/32 + ipv6: 2064:100::ab/128 Ethernet1: - ipv4: 10.0.1.121/31 - ipv6: fc00::2f2/126 + ipv4: 10.0.1.85/31 + ipv6: fc00::2aa/126 bp_interfaces: ipv4: 10.10.246.172/24 ipv6: fc0a::ac/64 - ARISTA172T0: + ARISTA166T0: properties: - common bgp: - asn: 64002 + asn: 64166 peers: 65100: - - 10.0.1.122 - - fc00::2f5 + - 10.0.1.86 + - fc00::2ad interfaces: Loopback0: - ipv4: 100.1.0.190/32 - ipv6: 2064:100::be/128 + ipv4: 100.1.0.172/32 + ipv6: 2064:100::ac/128 Ethernet1: - ipv4: 10.0.1.123/31 - ipv6: fc00::2f6/126 + ipv4: 10.0.1.87/31 + ipv6: fc00::2ae/126 bp_interfaces: ipv4: 10.10.246.173/24 ipv6: fc0a::ad/64 - ARISTA173T0: + ARISTA167T0: properties: - common bgp: - asn: 64002 + asn: 64167 peers: 65100: - - 10.0.1.124 - - fc00::2f9 + - 10.0.1.88 + - fc00::2b1 interfaces: Loopback0: - ipv4: 100.1.0.191/32 - ipv6: 2064:100::bf/128 + ipv4: 100.1.0.173/32 + ipv6: 2064:100::ad/128 Ethernet1: - ipv4: 10.0.1.125/31 - ipv6: fc00::2fa/126 + ipv4: 10.0.1.89/31 + ipv6: fc00::2b2/126 bp_interfaces: ipv4: 10.10.246.174/24 ipv6: fc0a::ae/64 - ARISTA174T0: + ARISTA168T0: properties: - common bgp: - asn: 64002 + asn: 64168 peers: 65100: - - 10.0.1.126 - - fc00::2fd + - 10.0.1.90 + - fc00::2b5 interfaces: Loopback0: - ipv4: 100.1.0.192/32 - ipv6: 2064:100::c0/128 + ipv4: 100.1.0.174/32 + ipv6: 2064:100::ae/128 Ethernet1: - ipv4: 10.0.1.127/31 - ipv6: fc00::2fe/126 + ipv4: 10.0.1.91/31 + ipv6: fc00::2b6/126 bp_interfaces: ipv4: 10.10.246.175/24 ipv6: fc0a::af/64 - ARISTA175T2: + ARISTA07T2: properties: - common bgp: asn: 65200 peers: 65100: - - 10.0.1.128 - - fc00::301 + - 10.0.1.92 + - fc00::2b9 interfaces: Loopback0: - ipv4: 100.1.0.193/32 - ipv6: 2064:100::c1/128 + ipv4: 100.1.0.175/32 + ipv6: 2064:100::af/128 Ethernet1: - ipv4: 10.0.1.129/31 - ipv6: fc00::302/126 + ipv4: 10.0.1.93/31 + ipv6: fc00::2ba/126 bp_interfaces: ipv4: 10.10.246.176/24 ipv6: fc0a::b0/64 - ARISTA176T2: + ARISTA08T2: properties: - common bgp: asn: 65200 peers: 65100: - - 10.0.1.130 - - fc00::305 + - 10.0.1.94 + - fc00::2bd interfaces: Loopback0: - ipv4: 100.1.0.194/32 - ipv6: 2064:100::c2/128 + ipv4: 100.1.0.176/32 + ipv6: 2064:100::b0/128 Ethernet1: - ipv4: 10.0.1.131/31 - ipv6: fc00::306/126 + ipv4: 10.0.1.95/31 + ipv6: fc00::2be/126 bp_interfaces: ipv4: 10.10.246.177/24 ipv6: fc0a::b1/64 - ARISTA177T0: + ARISTA169T0: properties: - common bgp: - asn: 64002 + asn: 64169 peers: 65100: - - 10.0.1.144 - - fc00::321 + - 10.0.1.96 + - fc00::2c1 interfaces: Loopback0: - ipv4: 100.1.0.201/32 - ipv6: 2064:100::c9/128 + ipv4: 100.1.0.177/32 + ipv6: 2064:100::b1/128 Ethernet1: - ipv4: 10.0.1.145/31 - ipv6: fc00::322/126 + ipv4: 10.0.1.97/31 + ipv6: fc00::2c2/126 bp_interfaces: ipv4: 10.10.246.178/24 ipv6: fc0a::b2/64 - ARISTA178T0: + ARISTA170T0: properties: - common bgp: - asn: 64002 + asn: 64170 peers: 65100: - - 10.0.1.146 - - fc00::325 + - 10.0.1.98 + - fc00::2c5 interfaces: Loopback0: - ipv4: 100.1.0.202/32 - ipv6: 2064:100::ca/128 + ipv4: 100.1.0.178/32 + ipv6: 2064:100::b2/128 Ethernet1: - ipv4: 10.0.1.147/31 - ipv6: fc00::326/126 + ipv4: 10.0.1.99/31 + ipv6: fc00::2c6/126 bp_interfaces: ipv4: 10.10.246.179/24 ipv6: fc0a::b3/64 - ARISTA179T0: + ARISTA171T0: properties: - common bgp: - asn: 64002 + asn: 64171 peers: 65100: - - 10.0.1.148 - - fc00::329 + - 10.0.1.100 + - fc00::2c9 interfaces: Loopback0: - ipv4: 100.1.0.203/32 - ipv6: 2064:100::cb/128 + ipv4: 100.1.0.179/32 + ipv6: 2064:100::b3/128 Ethernet1: - ipv4: 10.0.1.149/31 - ipv6: fc00::32a/126 + ipv4: 10.0.1.101/31 + ipv6: fc00::2ca/126 bp_interfaces: ipv4: 10.10.246.180/24 ipv6: fc0a::b4/64 - ARISTA180T0: + ARISTA172T0: properties: - common bgp: - asn: 64002 + asn: 64172 peers: 65100: - - 10.0.1.150 - - fc00::32d + - 10.0.1.102 + - fc00::2cd interfaces: Loopback0: - ipv4: 100.1.0.204/32 - ipv6: 2064:100::cc/128 + ipv4: 100.1.0.180/32 + ipv6: 2064:100::b4/128 Ethernet1: - ipv4: 10.0.1.151/31 - ipv6: fc00::32e/126 + ipv4: 10.0.1.103/31 + ipv6: fc00::2ce/126 bp_interfaces: ipv4: 10.10.246.181/24 ipv6: fc0a::b5/64 - ARISTA181T0: + ARISTA173T0: properties: - common bgp: - asn: 64002 + asn: 64173 peers: 65100: - - 10.0.1.152 - - fc00::331 + - 10.0.1.104 + - fc00::2d1 interfaces: Loopback0: - ipv4: 100.1.0.205/32 - ipv6: 2064:100::cd/128 + ipv4: 100.1.0.181/32 + ipv6: 2064:100::b5/128 Ethernet1: - ipv4: 10.0.1.153/31 - ipv6: fc00::332/126 + ipv4: 10.0.1.105/31 + ipv6: fc00::2d2/126 bp_interfaces: ipv4: 10.10.246.182/24 ipv6: fc0a::b6/64 - ARISTA182T0: + ARISTA174T0: properties: - common bgp: - asn: 64002 + asn: 64174 peers: 65100: - - 10.0.1.154 - - fc00::335 + - 10.0.1.106 + - fc00::2d5 interfaces: Loopback0: - ipv4: 100.1.0.206/32 - ipv6: 2064:100::ce/128 + ipv4: 100.1.0.182/32 + ipv6: 2064:100::b6/128 Ethernet1: - ipv4: 10.0.1.155/31 - ipv6: fc00::336/126 + ipv4: 10.0.1.107/31 + ipv6: fc00::2d6/126 bp_interfaces: ipv4: 10.10.246.183/24 ipv6: fc0a::b7/64 - ARISTA183T0: + ARISTA175T0: properties: - common bgp: - asn: 64002 + asn: 64175 peers: 65100: - - 10.0.1.156 - - fc00::339 + - 10.0.1.108 + - fc00::2d9 interfaces: Loopback0: - ipv4: 100.1.0.207/32 - ipv6: 2064:100::cf/128 + ipv4: 100.1.0.183/32 + ipv6: 2064:100::b7/128 Ethernet1: - ipv4: 10.0.1.157/31 - ipv6: fc00::33a/126 + ipv4: 10.0.1.109/31 + ipv6: fc00::2da/126 bp_interfaces: ipv4: 10.10.246.184/24 ipv6: fc0a::b8/64 - ARISTA184T0: + ARISTA176T0: properties: - common bgp: - asn: 64002 + asn: 64176 peers: 65100: - - 10.0.1.158 - - fc00::33d + - 10.0.1.110 + - fc00::2dd interfaces: Loopback0: - ipv4: 100.1.0.208/32 - ipv6: 2064:100::d0/128 + ipv4: 100.1.0.184/32 + ipv6: 2064:100::b8/128 Ethernet1: - ipv4: 10.0.1.159/31 - ipv6: fc00::33e/126 + ipv4: 10.0.1.111/31 + ipv6: fc00::2de/126 bp_interfaces: ipv4: 10.10.246.185/24 ipv6: fc0a::b9/64 - ARISTA185T0: + ARISTA177T0: properties: - common bgp: - asn: 64002 + asn: 64177 peers: 65100: - - 10.0.1.160 - - fc00::341 + - 10.0.1.112 + - fc00::2e1 interfaces: Loopback0: - ipv4: 100.1.0.209/32 - ipv6: 2064:100::d1/128 + ipv4: 100.1.0.185/32 + ipv6: 2064:100::b9/128 Ethernet1: - ipv4: 10.0.1.161/31 - ipv6: fc00::342/126 + ipv4: 10.0.1.113/31 + ipv6: fc00::2e2/126 bp_interfaces: ipv4: 10.10.246.186/24 ipv6: fc0a::ba/64 - ARISTA186T0: + ARISTA178T0: properties: - common bgp: - asn: 64002 + asn: 64178 peers: 65100: - - 10.0.1.162 - - fc00::345 + - 10.0.1.114 + - fc00::2e5 interfaces: Loopback0: - ipv4: 100.1.0.210/32 - ipv6: 2064:100::d2/128 + ipv4: 100.1.0.186/32 + ipv6: 2064:100::ba/128 Ethernet1: - ipv4: 10.0.1.163/31 - ipv6: fc00::346/126 + ipv4: 10.0.1.115/31 + ipv6: fc00::2e6/126 bp_interfaces: ipv4: 10.10.246.187/24 ipv6: fc0a::bb/64 - ARISTA187T0: + ARISTA179T0: properties: - common bgp: - asn: 64002 + asn: 64179 peers: 65100: - - 10.0.1.164 - - fc00::349 + - 10.0.1.116 + - fc00::2e9 interfaces: Loopback0: - ipv4: 100.1.0.211/32 - ipv6: 2064:100::d3/128 + ipv4: 100.1.0.187/32 + ipv6: 2064:100::bb/128 Ethernet1: - ipv4: 10.0.1.165/31 - ipv6: fc00::34a/126 + ipv4: 10.0.1.117/31 + ipv6: fc00::2ea/126 bp_interfaces: ipv4: 10.10.246.188/24 ipv6: fc0a::bc/64 - ARISTA188T0: + ARISTA180T0: properties: - common bgp: - asn: 64002 + asn: 64180 peers: 65100: - - 10.0.1.166 - - fc00::34d + - 10.0.1.118 + - fc00::2ed interfaces: Loopback0: - ipv4: 100.1.0.212/32 - ipv6: 2064:100::d4/128 + ipv4: 100.1.0.188/32 + ipv6: 2064:100::bc/128 Ethernet1: - ipv4: 10.0.1.167/31 - ipv6: fc00::34e/126 + ipv4: 10.0.1.119/31 + ipv6: fc00::2ee/126 bp_interfaces: ipv4: 10.10.246.189/24 ipv6: fc0a::bd/64 - ARISTA189T0: + ARISTA181T0: properties: - common bgp: - asn: 64002 + asn: 64181 peers: 65100: - - 10.0.1.168 - - fc00::351 + - 10.0.1.120 + - fc00::2f1 interfaces: Loopback0: - ipv4: 100.1.0.213/32 - ipv6: 2064:100::d5/128 + ipv4: 100.1.0.189/32 + ipv6: 2064:100::bd/128 Ethernet1: - ipv4: 10.0.1.169/31 - ipv6: fc00::352/126 + ipv4: 10.0.1.121/31 + ipv6: fc00::2f2/126 bp_interfaces: ipv4: 10.10.246.190/24 ipv6: fc0a::be/64 - ARISTA190T0: + ARISTA182T0: properties: - common bgp: - asn: 64002 + asn: 64182 peers: 65100: - - 10.0.1.170 - - fc00::355 + - 10.0.1.122 + - fc00::2f5 interfaces: Loopback0: - ipv4: 100.1.0.214/32 - ipv6: 2064:100::d6/128 + ipv4: 100.1.0.190/32 + ipv6: 2064:100::be/128 Ethernet1: - ipv4: 10.0.1.171/31 - ipv6: fc00::356/126 + ipv4: 10.0.1.123/31 + ipv6: fc00::2f6/126 bp_interfaces: ipv4: 10.10.246.191/24 ipv6: fc0a::bf/64 - ARISTA191T0: + ARISTA183T0: properties: - common bgp: - asn: 64002 + asn: 64183 peers: 65100: - - 10.0.1.172 - - fc00::359 + - 10.0.1.124 + - fc00::2f9 interfaces: Loopback0: - ipv4: 100.1.0.215/32 - ipv6: 2064:100::d7/128 + ipv4: 100.1.0.191/32 + ipv6: 2064:100::bf/128 Ethernet1: - ipv4: 10.0.1.173/31 - ipv6: fc00::35a/126 + ipv4: 10.0.1.125/31 + ipv6: fc00::2fa/126 bp_interfaces: ipv4: 10.10.246.192/24 ipv6: fc0a::c0/64 - ARISTA192T0: + ARISTA184T0: properties: - common bgp: - asn: 64002 + asn: 64184 peers: 65100: - - 10.0.1.174 - - fc00::35d + - 10.0.1.126 + - fc00::2fd interfaces: Loopback0: - ipv4: 100.1.0.216/32 - ipv6: 2064:100::d8/128 + ipv4: 100.1.0.192/32 + ipv6: 2064:100::c0/128 Ethernet1: - ipv4: 10.0.1.175/31 - ipv6: fc00::35e/126 + ipv4: 10.0.1.127/31 + ipv6: fc00::2fe/126 bp_interfaces: ipv4: 10.10.246.193/24 ipv6: fc0a::c1/64 - ARISTA193T0: + ARISTA185T0: properties: - common bgp: - asn: 64002 + asn: 64185 peers: 65100: - - 10.0.1.176 - - fc00::361 + - 10.0.1.128 + - fc00::301 interfaces: Loopback0: - ipv4: 100.1.0.217/32 - ipv6: 2064:100::d9/128 + ipv4: 100.1.0.193/32 + ipv6: 2064:100::c1/128 Ethernet1: - ipv4: 10.0.1.177/31 - ipv6: fc00::362/126 + ipv4: 10.0.1.129/31 + ipv6: fc00::302/126 bp_interfaces: ipv4: 10.10.246.194/24 ipv6: fc0a::c2/64 - ARISTA194T0: + ARISTA186T0: properties: - common bgp: - asn: 64002 + asn: 64186 peers: 65100: - - 10.0.1.178 - - fc00::365 + - 10.0.1.130 + - fc00::305 interfaces: Loopback0: - ipv4: 100.1.0.218/32 - ipv6: 2064:100::da/128 + ipv4: 100.1.0.194/32 + ipv6: 2064:100::c2/128 Ethernet1: - ipv4: 10.0.1.179/31 - ipv6: fc00::366/126 + ipv4: 10.0.1.131/31 + ipv6: fc00::306/126 bp_interfaces: ipv4: 10.10.246.195/24 ipv6: fc0a::c3/64 - ARISTA195T0: + ARISTA187T0: properties: - common bgp: - asn: 64002 + asn: 64187 peers: 65100: - - 10.0.1.180 - - fc00::369 + - 10.0.1.132 + - fc00::309 interfaces: Loopback0: - ipv4: 100.1.0.219/32 - ipv6: 2064:100::db/128 + ipv4: 100.1.0.195/32 + ipv6: 2064:100::c3/128 Ethernet1: - ipv4: 10.0.1.181/31 - ipv6: fc00::36a/126 + ipv4: 10.0.1.133/31 + ipv6: fc00::30a/126 bp_interfaces: ipv4: 10.10.246.196/24 ipv6: fc0a::c4/64 - ARISTA196T0: + ARISTA188T0: properties: - common bgp: - asn: 64002 + asn: 64188 peers: 65100: - - 10.0.1.182 - - fc00::36d + - 10.0.1.134 + - fc00::30d interfaces: Loopback0: - ipv4: 100.1.0.220/32 - ipv6: 2064:100::dc/128 + ipv4: 100.1.0.196/32 + ipv6: 2064:100::c4/128 Ethernet1: - ipv4: 10.0.1.183/31 - ipv6: fc00::36e/126 + ipv4: 10.0.1.135/31 + ipv6: fc00::30e/126 bp_interfaces: ipv4: 10.10.246.197/24 ipv6: fc0a::c5/64 - ARISTA197T0: + ARISTA189T0: properties: - common bgp: - asn: 64002 + asn: 64189 peers: 65100: - - 10.0.1.184 - - fc00::371 + - 10.0.1.136 + - fc00::311 interfaces: Loopback0: - ipv4: 100.1.0.221/32 - ipv6: 2064:100::dd/128 + ipv4: 100.1.0.197/32 + ipv6: 2064:100::c5/128 Ethernet1: - ipv4: 10.0.1.185/31 - ipv6: fc00::372/126 + ipv4: 10.0.1.137/31 + ipv6: fc00::312/126 bp_interfaces: ipv4: 10.10.246.198/24 ipv6: fc0a::c6/64 - ARISTA198T0: + ARISTA190T0: properties: - common bgp: - asn: 64002 + asn: 64190 peers: 65100: - - 10.0.1.186 - - fc00::375 + - 10.0.1.138 + - fc00::315 interfaces: Loopback0: - ipv4: 100.1.0.222/32 - ipv6: 2064:100::de/128 + ipv4: 100.1.0.198/32 + ipv6: 2064:100::c6/128 Ethernet1: - ipv4: 10.0.1.187/31 - ipv6: fc00::376/126 + ipv4: 10.0.1.139/31 + ipv6: fc00::316/126 bp_interfaces: ipv4: 10.10.246.199/24 ipv6: fc0a::c7/64 - ARISTA199T0: + ARISTA191T0: properties: - common bgp: - asn: 64002 + asn: 64191 peers: 65100: - - 10.0.1.188 - - fc00::379 + - 10.0.1.140 + - fc00::319 interfaces: Loopback0: - ipv4: 100.1.0.223/32 - ipv6: 2064:100::df/128 + ipv4: 100.1.0.199/32 + ipv6: 2064:100::c7/128 Ethernet1: - ipv4: 10.0.1.189/31 - ipv6: fc00::37a/126 + ipv4: 10.0.1.141/31 + ipv6: fc00::31a/126 bp_interfaces: ipv4: 10.10.246.200/24 ipv6: fc0a::c8/64 - ARISTA200T0: + ARISTA192T0: properties: - common bgp: - asn: 64002 + asn: 64192 peers: 65100: - - 10.0.1.190 - - fc00::37d + - 10.0.1.142 + - fc00::31d interfaces: Loopback0: - ipv4: 100.1.0.224/32 - ipv6: 2064:100::e0/128 + ipv4: 100.1.0.200/32 + ipv6: 2064:100::c8/128 Ethernet1: - ipv4: 10.0.1.191/31 - ipv6: fc00::37e/126 + ipv4: 10.0.1.143/31 + ipv6: fc00::31e/126 bp_interfaces: ipv4: 10.10.246.201/24 ipv6: fc0a::c9/64 - ARISTA201T0: + ARISTA193T0: properties: - common bgp: - asn: 64002 + asn: 64193 peers: 65100: - - 10.0.1.192 - - fc00::381 + - 10.0.1.144 + - fc00::321 interfaces: Loopback0: - ipv4: 100.1.0.225/32 - ipv6: 2064:100::e1/128 + ipv4: 100.1.0.201/32 + ipv6: 2064:100::c9/128 Ethernet1: - ipv4: 10.0.1.193/31 - ipv6: fc00::382/126 + ipv4: 10.0.1.145/31 + ipv6: fc00::322/126 bp_interfaces: ipv4: 10.10.246.202/24 ipv6: fc0a::ca/64 - ARISTA202T0: + ARISTA194T0: properties: - common bgp: - asn: 64002 + asn: 64194 peers: 65100: - - 10.0.1.194 - - fc00::385 + - 10.0.1.146 + - fc00::325 interfaces: Loopback0: - ipv4: 100.1.0.226/32 - ipv6: 2064:100::e2/128 + ipv4: 100.1.0.202/32 + ipv6: 2064:100::ca/128 Ethernet1: - ipv4: 10.0.1.195/31 - ipv6: fc00::386/126 + ipv4: 10.0.1.147/31 + ipv6: fc00::326/126 bp_interfaces: ipv4: 10.10.246.203/24 ipv6: fc0a::cb/64 - ARISTA203T0: + ARISTA195T0: properties: - common bgp: - asn: 64002 + asn: 64195 peers: 65100: - - 10.0.1.196 - - fc00::389 + - 10.0.1.148 + - fc00::329 interfaces: Loopback0: - ipv4: 100.1.0.227/32 - ipv6: 2064:100::e3/128 + ipv4: 100.1.0.203/32 + ipv6: 2064:100::cb/128 Ethernet1: - ipv4: 10.0.1.197/31 - ipv6: fc00::38a/126 + ipv4: 10.0.1.149/31 + ipv6: fc00::32a/126 bp_interfaces: ipv4: 10.10.246.204/24 ipv6: fc0a::cc/64 - ARISTA204T0: + ARISTA196T0: properties: - common bgp: - asn: 64002 + asn: 64196 peers: 65100: - - 10.0.1.198 - - fc00::38d + - 10.0.1.150 + - fc00::32d interfaces: Loopback0: - ipv4: 100.1.0.228/32 - ipv6: 2064:100::e4/128 + ipv4: 100.1.0.204/32 + ipv6: 2064:100::cc/128 Ethernet1: - ipv4: 10.0.1.199/31 - ipv6: fc00::38e/126 + ipv4: 10.0.1.151/31 + ipv6: fc00::32e/126 bp_interfaces: ipv4: 10.10.246.205/24 ipv6: fc0a::cd/64 - ARISTA205T0: + ARISTA197T0: properties: - common bgp: - asn: 64002 + asn: 64197 peers: 65100: - - 10.0.1.200 - - fc00::391 + - 10.0.1.152 + - fc00::331 interfaces: Loopback0: - ipv4: 100.1.0.229/32 - ipv6: 2064:100::e5/128 - Ethernet1: - ipv4: 10.0.1.201/31 - ipv6: fc00::392/126 + ipv4: 100.1.0.205/32 + ipv6: 2064:100::cd/128 + Ethernet1: + ipv4: 10.0.1.153/31 + ipv6: fc00::332/126 bp_interfaces: ipv4: 10.10.246.206/24 ipv6: fc0a::ce/64 - ARISTA206T0: + ARISTA198T0: properties: - common bgp: - asn: 64002 + asn: 64198 peers: 65100: - - 10.0.1.202 - - fc00::395 + - 10.0.1.154 + - fc00::335 interfaces: Loopback0: - ipv4: 100.1.0.230/32 - ipv6: 2064:100::e6/128 + ipv4: 100.1.0.206/32 + ipv6: 2064:100::ce/128 Ethernet1: - ipv4: 10.0.1.203/31 - ipv6: fc00::396/126 + ipv4: 10.0.1.155/31 + ipv6: fc00::336/126 bp_interfaces: ipv4: 10.10.246.207/24 ipv6: fc0a::cf/64 - ARISTA207T0: + ARISTA199T0: properties: - common bgp: - asn: 64002 + asn: 64199 peers: 65100: - - 10.0.1.204 - - fc00::399 + - 10.0.1.156 + - fc00::339 interfaces: Loopback0: - ipv4: 100.1.0.231/32 - ipv6: 2064:100::e7/128 + ipv4: 100.1.0.207/32 + ipv6: 2064:100::cf/128 Ethernet1: - ipv4: 10.0.1.205/31 - ipv6: fc00::39a/126 + ipv4: 10.0.1.157/31 + ipv6: fc00::33a/126 bp_interfaces: ipv4: 10.10.246.208/24 ipv6: fc0a::d0/64 - ARISTA208T0: + ARISTA200T0: properties: - common bgp: - asn: 64002 + asn: 64200 peers: 65100: - - 10.0.1.206 - - fc00::39d + - 10.0.1.158 + - fc00::33d interfaces: Loopback0: - ipv4: 100.1.0.232/32 - ipv6: 2064:100::e8/128 + ipv4: 100.1.0.208/32 + ipv6: 2064:100::d0/128 Ethernet1: - ipv4: 10.0.1.207/31 - ipv6: fc00::39e/126 + ipv4: 10.0.1.159/31 + ipv6: fc00::33e/126 bp_interfaces: ipv4: 10.10.246.209/24 ipv6: fc0a::d1/64 - ARISTA209T0: + ARISTA201T0: properties: - common bgp: - asn: 64002 + asn: 64201 peers: 65100: - - 10.0.1.208 - - fc00::3a1 + - 10.0.1.160 + - fc00::341 interfaces: Loopback0: - ipv4: 100.1.0.233/32 - ipv6: 2064:100::e9/128 + ipv4: 100.1.0.209/32 + ipv6: 2064:100::d1/128 Ethernet1: - ipv4: 10.0.1.209/31 - ipv6: fc00::3a2/126 + ipv4: 10.0.1.161/31 + ipv6: fc00::342/126 bp_interfaces: ipv4: 10.10.246.210/24 ipv6: fc0a::d2/64 - ARISTA210T0: + ARISTA202T0: properties: - common bgp: - asn: 64002 + asn: 64202 peers: 65100: - - 10.0.1.210 - - fc00::3a5 + - 10.0.1.162 + - fc00::345 interfaces: Loopback0: - ipv4: 100.1.0.234/32 - ipv6: 2064:100::ea/128 + ipv4: 100.1.0.210/32 + ipv6: 2064:100::d2/128 Ethernet1: - ipv4: 10.0.1.211/31 - ipv6: fc00::3a6/126 + ipv4: 10.0.1.163/31 + ipv6: fc00::346/126 bp_interfaces: ipv4: 10.10.246.211/24 ipv6: fc0a::d3/64 - ARISTA211T0: + ARISTA203T0: properties: - common bgp: - asn: 64002 + asn: 64203 peers: 65100: - - 10.0.1.212 - - fc00::3a9 + - 10.0.1.164 + - fc00::349 interfaces: Loopback0: - ipv4: 100.1.0.235/32 - ipv6: 2064:100::eb/128 + ipv4: 100.1.0.211/32 + ipv6: 2064:100::d3/128 Ethernet1: - ipv4: 10.0.1.213/31 - ipv6: fc00::3aa/126 + ipv4: 10.0.1.165/31 + ipv6: fc00::34a/126 bp_interfaces: ipv4: 10.10.246.212/24 ipv6: fc0a::d4/64 - ARISTA212T0: + ARISTA204T0: properties: - common bgp: - asn: 64002 + asn: 64204 peers: 65100: - - 10.0.1.214 - - fc00::3ad + - 10.0.1.166 + - fc00::34d interfaces: Loopback0: - ipv4: 100.1.0.236/32 - ipv6: 2064:100::ec/128 + ipv4: 100.1.0.212/32 + ipv6: 2064:100::d4/128 Ethernet1: - ipv4: 10.0.1.215/31 - ipv6: fc00::3ae/126 + ipv4: 10.0.1.167/31 + ipv6: fc00::34e/126 bp_interfaces: ipv4: 10.10.246.213/24 ipv6: fc0a::d5/64 - ARISTA213T0: + ARISTA205T0: properties: - common bgp: - asn: 64002 + asn: 64205 peers: 65100: - - 10.0.1.216 - - fc00::3b1 + - 10.0.1.168 + - fc00::351 interfaces: Loopback0: - ipv4: 100.1.0.237/32 - ipv6: 2064:100::ed/128 + ipv4: 100.1.0.213/32 + ipv6: 2064:100::d5/128 Ethernet1: - ipv4: 10.0.1.217/31 - ipv6: fc00::3b2/126 + ipv4: 10.0.1.169/31 + ipv6: fc00::352/126 bp_interfaces: ipv4: 10.10.246.214/24 ipv6: fc0a::d6/64 - ARISTA214T0: + ARISTA206T0: properties: - common bgp: - asn: 64002 + asn: 64206 peers: 65100: - - 10.0.1.218 - - fc00::3b5 + - 10.0.1.170 + - fc00::355 interfaces: Loopback0: - ipv4: 100.1.0.238/32 - ipv6: 2064:100::ee/128 + ipv4: 100.1.0.214/32 + ipv6: 2064:100::d6/128 Ethernet1: - ipv4: 10.0.1.219/31 - ipv6: fc00::3b6/126 + ipv4: 10.0.1.171/31 + ipv6: fc00::356/126 bp_interfaces: ipv4: 10.10.246.215/24 ipv6: fc0a::d7/64 - ARISTA215T0: + ARISTA207T0: properties: - common bgp: - asn: 64002 + asn: 64207 peers: 65100: - - 10.0.1.220 - - fc00::3b9 + - 10.0.1.172 + - fc00::359 interfaces: Loopback0: - ipv4: 100.1.0.239/32 - ipv6: 2064:100::ef/128 + ipv4: 100.1.0.215/32 + ipv6: 2064:100::d7/128 Ethernet1: - ipv4: 10.0.1.221/31 - ipv6: fc00::3ba/126 + ipv4: 10.0.1.173/31 + ipv6: fc00::35a/126 bp_interfaces: ipv4: 10.10.246.216/24 ipv6: fc0a::d8/64 - ARISTA216T0: + ARISTA208T0: properties: - common bgp: - asn: 64002 + asn: 64208 peers: 65100: - - 10.0.1.222 - - fc00::3bd + - 10.0.1.174 + - fc00::35d interfaces: Loopback0: - ipv4: 100.1.0.240/32 - ipv6: 2064:100::f0/128 + ipv4: 100.1.0.216/32 + ipv6: 2064:100::d8/128 Ethernet1: - ipv4: 10.0.1.223/31 - ipv6: fc00::3be/126 + ipv4: 10.0.1.175/31 + ipv6: fc00::35e/126 bp_interfaces: ipv4: 10.10.246.217/24 ipv6: fc0a::d9/64 - ARISTA217T0: + ARISTA209T0: properties: - common bgp: - asn: 64002 + asn: 64209 peers: 65100: - - 10.0.1.224 - - fc00::3c1 + - 10.0.1.176 + - fc00::361 interfaces: Loopback0: - ipv4: 100.1.0.241/32 - ipv6: 2064:100::f1/128 + ipv4: 100.1.0.217/32 + ipv6: 2064:100::d9/128 Ethernet1: - ipv4: 10.0.1.225/31 - ipv6: fc00::3c2/126 + ipv4: 10.0.1.177/31 + ipv6: fc00::362/126 bp_interfaces: ipv4: 10.10.246.218/24 ipv6: fc0a::da/64 - ARISTA218T0: + ARISTA210T0: properties: - common bgp: - asn: 64002 + asn: 64210 peers: 65100: - - 10.0.1.226 - - fc00::3c5 + - 10.0.1.178 + - fc00::365 interfaces: Loopback0: - ipv4: 100.1.0.242/32 - ipv6: 2064:100::f2/128 + ipv4: 100.1.0.218/32 + ipv6: 2064:100::da/128 Ethernet1: - ipv4: 10.0.1.227/31 - ipv6: fc00::3c6/126 + ipv4: 10.0.1.179/31 + ipv6: fc00::366/126 bp_interfaces: ipv4: 10.10.246.219/24 ipv6: fc0a::db/64 - ARISTA219T0: + ARISTA211T0: properties: - common bgp: - asn: 64002 + asn: 64211 peers: 65100: - - 10.0.1.228 - - fc00::3c9 + - 10.0.1.180 + - fc00::369 interfaces: Loopback0: - ipv4: 100.1.0.243/32 - ipv6: 2064:100::f3/128 + ipv4: 100.1.0.219/32 + ipv6: 2064:100::db/128 Ethernet1: - ipv4: 10.0.1.229/31 - ipv6: fc00::3ca/126 + ipv4: 10.0.1.181/31 + ipv6: fc00::36a/126 bp_interfaces: ipv4: 10.10.246.220/24 ipv6: fc0a::dc/64 - ARISTA220T0: + ARISTA212T0: properties: - common bgp: - asn: 64002 + asn: 64212 peers: 65100: - - 10.0.1.230 - - fc00::3cd + - 10.0.1.182 + - fc00::36d interfaces: Loopback0: - ipv4: 100.1.0.244/32 - ipv6: 2064:100::f4/128 + ipv4: 100.1.0.220/32 + ipv6: 2064:100::dc/128 Ethernet1: - ipv4: 10.0.1.231/31 - ipv6: fc00::3ce/126 + ipv4: 10.0.1.183/31 + ipv6: fc00::36e/126 bp_interfaces: ipv4: 10.10.246.221/24 ipv6: fc0a::dd/64 - ARISTA221T0: + ARISTA213T0: properties: - common bgp: - asn: 64002 + asn: 64213 peers: 65100: - - 10.0.1.232 - - fc00::3d1 + - 10.0.1.184 + - fc00::371 interfaces: Loopback0: - ipv4: 100.1.0.245/32 - ipv6: 2064:100::f5/128 + ipv4: 100.1.0.221/32 + ipv6: 2064:100::dd/128 Ethernet1: - ipv4: 10.0.1.233/31 - ipv6: fc00::3d2/126 + ipv4: 10.0.1.185/31 + ipv6: fc00::372/126 bp_interfaces: ipv4: 10.10.246.222/24 ipv6: fc0a::de/64 - ARISTA222T0: + ARISTA214T0: properties: - common bgp: - asn: 64002 + asn: 64214 peers: 65100: - - 10.0.1.234 - - fc00::3d5 + - 10.0.1.186 + - fc00::375 interfaces: Loopback0: - ipv4: 100.1.0.246/32 - ipv6: 2064:100::f6/128 + ipv4: 100.1.0.222/32 + ipv6: 2064:100::de/128 Ethernet1: - ipv4: 10.0.1.235/31 - ipv6: fc00::3d6/126 + ipv4: 10.0.1.187/31 + ipv6: fc00::376/126 bp_interfaces: ipv4: 10.10.246.223/24 ipv6: fc0a::df/64 - ARISTA223T0: + ARISTA215T0: properties: - common bgp: - asn: 64002 + asn: 64215 peers: 65100: - - 10.0.1.236 - - fc00::3d9 + - 10.0.1.188 + - fc00::379 interfaces: Loopback0: - ipv4: 100.1.0.247/32 - ipv6: 2064:100::f7/128 + ipv4: 100.1.0.223/32 + ipv6: 2064:100::df/128 Ethernet1: - ipv4: 10.0.1.237/31 - ipv6: fc00::3da/126 + ipv4: 10.0.1.189/31 + ipv6: fc00::37a/126 bp_interfaces: ipv4: 10.10.246.224/24 ipv6: fc0a::e0/64 - ARISTA224T0: + ARISTA216T0: properties: - common bgp: - asn: 64002 + asn: 64216 peers: 65100: - - 10.0.1.238 - - fc00::3dd + - 10.0.1.190 + - fc00::37d interfaces: Loopback0: - ipv4: 100.1.0.248/32 - ipv6: 2064:100::f8/128 + ipv4: 100.1.0.224/32 + ipv6: 2064:100::e0/128 Ethernet1: - ipv4: 10.0.1.239/31 - ipv6: fc00::3de/126 + ipv4: 10.0.1.191/31 + ipv6: fc00::37e/126 bp_interfaces: ipv4: 10.10.246.225/24 ipv6: fc0a::e1/64 - ARISTA225T0: + ARISTA217T0: properties: - common bgp: - asn: 64002 + asn: 64217 peers: 65100: - - 10.0.1.240 - - fc00::3e1 + - 10.0.1.192 + - fc00::381 interfaces: Loopback0: - ipv4: 100.1.0.249/32 - ipv6: 2064:100::f9/128 + ipv4: 100.1.0.225/32 + ipv6: 2064:100::e1/128 Ethernet1: - ipv4: 10.0.1.241/31 - ipv6: fc00::3e2/126 + ipv4: 10.0.1.193/31 + ipv6: fc00::382/126 bp_interfaces: ipv4: 10.10.246.226/24 ipv6: fc0a::e2/64 - ARISTA226T0: + ARISTA218T0: properties: - common bgp: - asn: 64002 + asn: 64218 peers: 65100: - - 10.0.1.242 - - fc00::3e5 + - 10.0.1.194 + - fc00::385 interfaces: Loopback0: - ipv4: 100.1.0.250/32 - ipv6: 2064:100::fa/128 + ipv4: 100.1.0.226/32 + ipv6: 2064:100::e2/128 Ethernet1: - ipv4: 10.0.1.243/31 - ipv6: fc00::3e6/126 + ipv4: 10.0.1.195/31 + ipv6: fc00::386/126 bp_interfaces: ipv4: 10.10.246.227/24 ipv6: fc0a::e3/64 - ARISTA227T0: + ARISTA219T0: properties: - common bgp: - asn: 64002 + asn: 64219 peers: 65100: - - 10.0.1.244 - - fc00::3e9 + - 10.0.1.196 + - fc00::389 interfaces: Loopback0: - ipv4: 100.1.0.251/32 - ipv6: 2064:100::fb/128 + ipv4: 100.1.0.227/32 + ipv6: 2064:100::e3/128 Ethernet1: - ipv4: 10.0.1.245/31 - ipv6: fc00::3ea/126 + ipv4: 10.0.1.197/31 + ipv6: fc00::38a/126 bp_interfaces: ipv4: 10.10.246.228/24 ipv6: fc0a::e4/64 - ARISTA228T0: + ARISTA220T0: properties: - common bgp: - asn: 64002 + asn: 64220 peers: 65100: - - 10.0.1.246 - - fc00::3ed + - 10.0.1.198 + - fc00::38d interfaces: Loopback0: - ipv4: 100.1.0.252/32 - ipv6: 2064:100::fc/128 + ipv4: 100.1.0.228/32 + ipv6: 2064:100::e4/128 Ethernet1: - ipv4: 10.0.1.247/31 - ipv6: fc00::3ee/126 + ipv4: 10.0.1.199/31 + ipv6: fc00::38e/126 bp_interfaces: ipv4: 10.10.246.229/24 ipv6: fc0a::e5/64 - ARISTA229T0: + ARISTA221T0: properties: - common bgp: - asn: 64002 + asn: 64221 peers: 65100: - - 10.0.1.248 - - fc00::3f1 + - 10.0.1.200 + - fc00::391 interfaces: Loopback0: - ipv4: 100.1.0.253/32 - ipv6: 2064:100::fd/128 + ipv4: 100.1.0.229/32 + ipv6: 2064:100::e5/128 Ethernet1: - ipv4: 10.0.1.249/31 - ipv6: fc00::3f2/126 + ipv4: 10.0.1.201/31 + ipv6: fc00::392/126 bp_interfaces: ipv4: 10.10.246.230/24 ipv6: fc0a::e6/64 - ARISTA230T0: + ARISTA222T0: properties: - common bgp: - asn: 64002 + asn: 64222 peers: 65100: - - 10.0.1.250 - - fc00::3f5 + - 10.0.1.202 + - fc00::395 interfaces: Loopback0: - ipv4: 100.1.0.254/32 - ipv6: 2064:100::fe/128 + ipv4: 100.1.0.230/32 + ipv6: 2064:100::e6/128 Ethernet1: - ipv4: 10.0.1.251/31 - ipv6: fc00::3f6/126 + ipv4: 10.0.1.203/31 + ipv6: fc00::396/126 bp_interfaces: ipv4: 10.10.246.231/24 ipv6: fc0a::e7/64 - ARISTA231T0: + ARISTA223T0: properties: - common bgp: - asn: 64002 + asn: 64223 peers: 65100: - - 10.0.1.252 - - fc00::3f9 + - 10.0.1.204 + - fc00::399 interfaces: Loopback0: - ipv4: 100.1.0.255/32 - ipv6: 2064:100::ff/128 + ipv4: 100.1.0.231/32 + ipv6: 2064:100::e7/128 Ethernet1: - ipv4: 10.0.1.253/31 - ipv6: fc00::3fa/126 + ipv4: 10.0.1.205/31 + ipv6: fc00::39a/126 bp_interfaces: ipv4: 10.10.246.232/24 ipv6: fc0a::e8/64 - ARISTA232T0: + ARISTA224T0: properties: - common bgp: - asn: 64002 + asn: 64224 peers: 65100: - - 10.0.1.254 - - fc00::3fd + - 10.0.1.206 + - fc00::39d interfaces: Loopback0: - ipv4: 100.1.1.0/32 - ipv6: 2064:100::100/128 + ipv4: 100.1.0.232/32 + ipv6: 2064:100::e8/128 Ethernet1: - ipv4: 10.0.1.255/31 - ipv6: fc00::3fe/126 + ipv4: 10.0.1.207/31 + ipv6: fc00::39e/126 bp_interfaces: ipv4: 10.10.246.233/24 ipv6: fc0a::e9/64 From 199637ff36902849719d119f6d3fd7c456f6e664 Mon Sep 17 00:00:00 2001 From: wumiao_nokia Date: Thu, 7 Nov 2024 20:05:12 -0500 Subject: [PATCH 112/221] Modify Small Partition Size to 300M from 100M (#15274) Description of PR It's found in some scaled setup the OC testing for test_logrotate_small_size could fail on fallocate 512K. {"changed": true, "cmd": "sudo fallocate -l 512.0K /var/log/syslog", "delta": "0:00:00.014333", "end": "2024-10-28 21:15:46.973853", "failed": true, "msg": "non-zero return code", "rc": 1, "start": "2024-10-28 21:15:46.959520", "stderr": "fallocate: fallocate failed: No space left on device", "stderr_lines": ["fallocate: fallocate failed: No space left on device"], "stdout": "", "stdout_lines": []} Our scaled setup could have 34K BGP routes and has more BGP neighbors. This test did config-reload after mounting new partition to /var/log. All new services restart and can fill the syslog and other logs and reach partition size. Added debug code to find after config reload the /var/log partition situation: udev 16G 0 16G 0% /dev tmpfs 3.2G 49M 3.1G 2% /run root-overlay 32G 6.7G 25G 22% / /dev/sda3 32G 6.7G 25G 22% /host /dev/loop2 89M 87M 0 100% /var/log tmpfs 16G 60K 16G 1% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup List all files under /var/log: /n total 4117 drwxr-xr-x 6 root root 1024 Oct 28 21:15 . drwxr-xr-x 1 root root 4096 Oct 25 21:11 .. -rw-r----- 1 root adm 0 Oct 28 21:15 auth.log -rw-r----- 1 root adm 47075 Oct 28 21:15 auth.log.1 -rw-r----- 1 root adm 0 Oct 28 21:15 cron.log drwxr-xr-x 2 root root 1024 Oct 28 21:15 frr -rw-r----- 1 root adm 0 Oct 28 21:15 gnmi.log -rw-r----- 1 root adm 1007 Oct 28 21:15 gnmi.log.1 drwx------ 2 root root 12288 Oct 28 21:10 lost+found -rw-r--r-- 1 root root 64 Oct 28 21:15 nokia-watchdog.log drwxrwxrwx 2 root root 1024 Oct 28 21:12 ntpsec drwxr-xr-x 2 root root 1024 Oct 28 21:15 swss -rw-r----- 1 root adm 0 Oct 28 21:15 syslog -rw-r----- 1 root adm 3185638 Oct 28 21:15 syslog.1 -rw-r----- 1 root adm 0 Oct 28 21:15 teamd.log -rw-r----- 1 root adm 955766 Oct 28 21:14 teamd.log.1 -rw-r----- 1 root adm 0 Oct 28 21:15 telemetry.log Solution is to make this partition to 300M during the test. This could make the test pass in scaled setup. Approach What is the motivation for this PR? test_logrotate_small_size test sometimes fails. How did you do it? How did you verify/test it? Verified with the change. We never hit the failure for test_logrotate_small_size. co-authorized by: jianquanye@microsoft.com --- tests/syslog/test_logrotate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/syslog/test_logrotate.py b/tests/syslog/test_logrotate.py index 3dfeabecb95..cabfaab71ab 100644 --- a/tests/syslog/test_logrotate.py +++ b/tests/syslog/test_logrotate.py @@ -15,7 +15,7 @@ ] LOG_FOLDER = '/var/log' -SMALL_VAR_LOG_PARTITION_SIZE = '100M' +SMALL_VAR_LOG_PARTITION_SIZE = '300M' FAKE_IP = '10.20.30.40' FAKE_MAC = 'aa:bb:cc:dd:11:22' From 9e468e72b35e8abc9a4edba559f9e2d198f2a1c1 Mon Sep 17 00:00:00 2001 From: Chenyang Wang <49756587+cyw233@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:23:55 +1100 Subject: [PATCH 113/221] chore: enable parallel run for more tests (#15449) Description of PR Enable parallel run for 10 more test modules. Disable parallel run for pfcwd/test_pfc_config.py because we are seeing file creation conflict when running it in parallel. Approach What is the motivation for this PR? We want to enable parallel run for more tests to further reduce the multi-DUT (e.g. T2) Nightly test running time. How did you do it? Add them to the test_parallel_modes.json file. How did you verify/test it? I ran these newly added test modules and can confirm that they can be run in parallel. co-authorized by: jianquanye@microsoft.com --- tests/test_parallel_modes.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_parallel_modes.json b/tests/test_parallel_modes.json index 5d72c23d63f..6d443f8c631 100644 --- a/tests/test_parallel_modes.json +++ b/tests/test_parallel_modes.json @@ -5,16 +5,25 @@ "bgp/test_bgp_session_flap.py": "FULL_PARALLEL", "container_checker/test_container_checker.py": "RP_FIRST", "crm/test_crm.py": "FULL_PARALLEL", + "iface_namingmode/test_iface_namingmode.py": "FULL_PARALLEL", "lldp/test_lldp.py": "FULL_PARALLEL", "memory_checker/test_memory_checker.py": "FULL_PARALLEL", "override_config_table/test_override_config_table_masic.py": "FULL_PARALLEL", "passw_hardening/test_passw_hardening.py": "FULL_PARALLEL", "pc/test_po_cleanup.py": "FULL_PARALLEL", - "pfcwd/test_pfc_config.py": "FULL_PARALLEL", + "platform_tests/api/test_chassis.py": "FULL_PARALLEL", + "platform_tests/api/test_module.py": "FULL_PARALLEL", "platform_tests/api/test_sfp.py": "FULL_PARALLEL", + "platform_tests/api/test_thermal.py": "FULL_PARALLEL", + "platform_tests/cli/test_show_chassis_module.py": "FULL_PARALLEL", + "platform_tests/link_flap/test_cont_link_flap.py": "FULL_PARALLEL", + "platform_tests/sfp/test_sfputil.py": "FULL_PARALLEL", + "platform_tests/test_memory_exhaustion.py": "RP_FIRST", "platform_tests/test_reboot.py": "RP_FIRST", "platform_tests/test_reload_config.py": "RP_FIRST", "platform_tests/test_sequential_restart.py": "FULL_PARALLEL", + "show_techsupport/test_techsupport.py": "FULL_PARALLEL", + "show_techsupport/test_techsupport_no_secret.py": "FULL_PARALLEL", "snmp/test_snmp_cpu.py": "FULL_PARALLEL", "snmp/test_snmp_interfaces.py": "FULL_PARALLEL", "snmp/test_snmp_link_local.py": "FULL_PARALLEL", From 3d5161488a754d1419324196b86a3841932b237d Mon Sep 17 00:00:00 2001 From: Chenyang Wang <49756587+cyw233@users.noreply.github.com> Date: Fri, 8 Nov 2024 13:46:46 +1100 Subject: [PATCH 114/221] refactor: optimize BFD test (#15370) Description of PR Optimize BFD tests to reduce the running time. Approach What is the motivation for this PR? The bfd/test_bfd_static_route.py and bfd/test_bfd_traffic.py are taking a very long time to finish. We can optimize them by multithreading and enabling safe reload and safe reboot. After the optimization, the running time of bfd/test_bfd_static_route.py will decrease by 1.5 to 2 hours, and the running time of bfd/test_bfd_traffic.py will decrease by 1 to 1.5 hours. How did you do it? Using multithreading and enabling safe reload and safe reboot to optimize the BFD tests. How did you verify/test it? I ran the updated code and can confirm that they can still run properly. Any platform specific information? T2 co-authorized by: jianquanye@microsoft.com --- tests/bfd/bfd_base.py | 177 +++- tests/bfd/bfd_helpers.py | 201 +--- tests/bfd/test_bfd_static_route.py | 1418 ++++++++-------------------- tests/bfd/test_bfd_traffic.py | 221 +++-- 4 files changed, 675 insertions(+), 1342 deletions(-) diff --git a/tests/bfd/bfd_base.py b/tests/bfd/bfd_base.py index 08b8a39b9ff..e801cbfa870 100644 --- a/tests/bfd/bfd_base.py +++ b/tests/bfd/bfd_base.py @@ -3,10 +3,10 @@ import pytest -from tests.bfd.bfd_helpers import modify_all_bfd_sessions, find_bfd_peers_with_given_state -from tests.common import config_reload -from tests.common.platform.processes_utils import wait_critical_processes -from tests.common.utilities import wait_until +from tests.bfd.bfd_helpers import prepare_bfd_state, selecting_route_to_delete, \ + extract_ip_addresses_for_backend_portchannels, get_dut_asic_static_routes, extract_backend_portchannels, \ + get_src_dst_asic_next_hops +from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor logger = logging.getLogger(__name__) @@ -25,55 +25,21 @@ def modify_bfd_sessions(self, duthosts): c. If expected state is "Up" and no. of down peers is 0, output is True d. If expected state is "Down" and no. of up peers is 0, output is True """ + duts = duthosts.frontend_nodes try: - duts = duthosts.frontend_nodes - for dut in duts: - modify_all_bfd_sessions(dut, "false") - for dut in duts: - # config reload - config_reload(dut) - wait_critical_processes(dut) - # Verification that all BFD sessions are deleted - for dut in duts: - asics = [ - asic.split("asic")[1] for asic in dut.get_asic_namespace_list() - ] - for asic in asics: - assert wait_until( - 600, - 10, - 0, - lambda: find_bfd_peers_with_given_state( - dut, asic, "No BFD sessions found" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for dut in duts: + executor.submit(prepare_bfd_state, dut, "false", "No BFD sessions found") yield finally: - duts = duthosts.frontend_nodes - for dut in duts: - modify_all_bfd_sessions(dut, "true") - for dut in duts: - config_reload(dut) - wait_critical_processes(dut) - # Verification that all BFD sessions are added - for dut in duts: - asics = [ - asic.split("asic")[1] for asic in dut.get_asic_namespace_list() - ] - for asic in asics: - assert wait_until( - 600, - 10, - 0, - lambda: find_bfd_peers_with_given_state( - dut, asic, "Up" - ), - ) - - @pytest.fixture(scope="class", name="select_src_dst_dut_and_asic", params=(["multi_dut"])) - def select_src_dst_dut_and_asic(self, duthosts, request, tbinfo): + with SafeThreadPoolExecutor(max_workers=8) as executor: + for dut in duts: + executor.submit(prepare_bfd_state, dut, "true", "Up") + + @pytest.fixture(scope="class", name="select_src_dst_dut_and_asic") + def select_src_dst_dut_and_asic(self, duthosts, tbinfo): if (len(duthosts.frontend_nodes)) < 2: pytest.skip("Don't have 2 frontend nodes - so can't run multi_dut tests") # Random selection of dut indices based on number of front end nodes @@ -131,6 +97,80 @@ def get_src_dst_asic_and_duts(self, duthosts, select_src_dst_dut_and_asic): rtn_dict.update(select_src_dst_dut_and_asic) yield rtn_dict + @pytest.fixture(scope="class", params=["ipv4", "ipv6"]) + def select_src_dst_dut_with_asic(self, request, get_src_dst_asic_and_duts): + logger.info( + "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" + ) + + version = request.param + logger.info("Version: %s", version) + + # Random selection of dut & asic. + src_asic = get_src_dst_asic_and_duts["src_asic"] + dst_asic = get_src_dst_asic_and_duts["dst_asic"] + src_dut = get_src_dst_asic_and_duts["src_dut"] + dst_dut = get_src_dst_asic_and_duts["dst_dut"] + + logger.info("Source Asic: %s", src_asic) + logger.info("Destination Asic: %s", dst_asic) + logger.info("Source dut: %s", src_dut) + logger.info("Destination dut: %s", dst_dut) + + request.config.src_asic = src_asic + request.config.dst_asic = dst_asic + request.config.src_dut = src_dut + request.config.dst_dut = dst_dut + + src_asic_routes = get_dut_asic_static_routes(version, src_dut) + dst_asic_routes = get_dut_asic_static_routes(version, dst_dut) + + # Extracting nexthops + dst_dut_nexthops = ( + extract_ip_addresses_for_backend_portchannels( + src_dut, src_asic, version + ) + ) + logger.info("Destination nexthops, {}".format(dst_dut_nexthops)) + assert len(dst_dut_nexthops) != 0, "Destination Nexthops are empty" + + src_dut_nexthops = ( + extract_ip_addresses_for_backend_portchannels( + dst_dut, dst_asic, version + ) + ) + logger.info("Source nexthops, {}".format(src_dut_nexthops)) + assert len(src_dut_nexthops) != 0, "Source Nexthops are empty" + + # Picking a static route to delete corresponding BFD session + src_prefix = selecting_route_to_delete( + src_asic_routes, src_dut_nexthops.values() + ) + logger.info("Source prefix: %s", src_prefix) + request.config.src_prefix = src_prefix + assert src_prefix is not None and src_prefix != "", "Source prefix not found" + + dst_prefix = selecting_route_to_delete( + dst_asic_routes, dst_dut_nexthops.values() + ) + logger.info("Destination prefix: %s", dst_prefix) + request.config.dst_prefix = dst_prefix + assert ( + dst_prefix is not None and dst_prefix != "" + ), "Destination prefix not found" + + yield { + "src_asic": src_asic, + "dst_asic": dst_asic, + "src_dut": src_dut, + "dst_dut": dst_dut, + "src_dut_nexthops": src_dut_nexthops, + "dst_dut_nexthops": dst_dut_nexthops, + "src_prefix": src_prefix, + "dst_prefix": dst_prefix, + "version": version, + } + @pytest.fixture(scope="class") def select_dut_and_src_dst_asic_index(self, duthosts): if not duthosts.frontend_nodes: @@ -179,3 +219,44 @@ def get_src_dst_asic(self, request, duthosts, select_dut_and_src_dst_asic_index) rtn_dict.update(select_dut_and_src_dst_asic_index) yield rtn_dict + + @pytest.fixture(scope="class", params=["ipv4", "ipv6"]) + def prepare_traffic_test_variables(self, get_src_dst_asic, request): + version = request.param + logger.info("Version: %s", version) + + dut = get_src_dst_asic["dut"] + src_asic = get_src_dst_asic["src_asic"] + src_asic_index = get_src_dst_asic["src_asic_index"] + dst_asic = get_src_dst_asic["dst_asic"] + dst_asic_index = get_src_dst_asic["dst_asic_index"] + logger.info( + "DUT: {}, src_asic_index: {}, dst_asic_index: {}".format(dut.hostname, src_asic_index, dst_asic_index) + ) + + backend_port_channels = extract_backend_portchannels(dut) + src_asic_next_hops, dst_asic_next_hops, src_prefix, dst_prefix = get_src_dst_asic_next_hops( + version, + dut, + src_asic, + dst_asic, + request, + backend_port_channels, + ) + + src_asic_router_mac = src_asic.get_router_mac() + + yield { + "dut": dut, + "src_asic": src_asic, + "src_asic_index": src_asic_index, + "dst_asic": dst_asic, + "dst_asic_index": dst_asic_index, + "src_asic_next_hops": src_asic_next_hops, + "dst_asic_next_hops": dst_asic_next_hops, + "src_prefix": src_prefix, + "dst_prefix": dst_prefix, + "src_asic_router_mac": src_asic_router_mac, + "backend_port_channels": backend_port_channels, + "version": version, + } diff --git a/tests/bfd/bfd_helpers.py b/tests/bfd/bfd_helpers.py index a867614baf0..1744545f38c 100644 --- a/tests/bfd/bfd_helpers.py +++ b/tests/bfd/bfd_helpers.py @@ -7,12 +7,57 @@ import pytest from ptf import testutils +from tests.common import config_reload from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor from tests.common.utilities import wait_until logger = logging.getLogger(__name__) +def prepare_bfd_state(dut, flag, expected_bfd_state): + modify_all_bfd_sessions(dut, flag) + config_reload(dut, safe_reload=True) + # Verification that all BFD sessions are deleted + asics = [asic.split("asic")[1] for asic in dut.get_asic_namespace_list()] + for asic in asics: + assert wait_until( + 600, + 10, + 0, + lambda: find_bfd_peers_with_given_state(dut, asic, expected_bfd_state), + ) + + +def verify_bfd_only(dut, nexthops, asic, expected_bfd_state): + logger.info("BFD verifications") + assert wait_until( + 300, + 10, + 0, + lambda: verify_bfd_state(dut, nexthops.values(), asic, expected_bfd_state), + ) + + +def create_and_verify_bfd_state(asic, prefix, dut, dut_nexthops): + logger.info("BFD addition on dut") + add_bfd(asic.asic_index, prefix, dut) + verify_bfd_only(dut, dut_nexthops, asic, "Up") + + +def verify_bfd_and_static_route(dut, dut_nexthops, asic, expected_bfd_state, request, prefix, + expected_prefix_state, version): + logger.info("BFD & Static route verifications") + verify_bfd_only(dut, dut_nexthops, asic, expected_bfd_state) + verify_static_route( + request, + asic, + prefix, + dut, + expected_prefix_state, + version, + ) + + def get_dut_asic_static_routes(version, dut): if version == "ipv4": static_route_command = "show ip route static" @@ -33,75 +78,6 @@ def get_dut_asic_static_routes(version, dut): return asic_static_routes -def select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version -): - logger.debug("Selecting source and destination DUTs with ASICs...") - # Random selection of dut & asic. - src_asic = get_src_dst_asic_and_duts["src_asic"] - dst_asic = get_src_dst_asic_and_duts["dst_asic"] - src_dut = get_src_dst_asic_and_duts["src_dut"] - dst_dut = get_src_dst_asic_and_duts["dst_dut"] - - logger.info("Source Asic: %s", src_asic) - logger.info("Destination Asic: %s", dst_asic) - logger.info("Source dut: %s", src_dut) - logger.info("Destination dut: %s", dst_dut) - - request.config.src_asic = src_asic - request.config.dst_asic = dst_asic - request.config.src_dut = src_dut - request.config.dst_dut = dst_dut - - src_asic_routes = get_dut_asic_static_routes(version, src_dut) - dst_asic_routes = get_dut_asic_static_routes(version, dst_dut) - - # Extracting nexthops - dst_dut_nexthops = ( - extract_ip_addresses_for_backend_portchannels( - src_dut, src_asic, version - ) - ) - logger.info("Destination nexthops, {}".format(dst_dut_nexthops)) - assert len(dst_dut_nexthops) != 0, "Destination Nexthops are empty" - - src_dut_nexthops = ( - extract_ip_addresses_for_backend_portchannels( - dst_dut, dst_asic, version - ) - ) - logger.info("Source nexthops, {}".format(src_dut_nexthops)) - assert len(src_dut_nexthops) != 0, "Source Nexthops are empty" - - # Picking a static route to delete correspinding BFD session - src_prefix = selecting_route_to_delete( - src_asic_routes, src_dut_nexthops.values() - ) - logger.info("Source prefix: %s", src_prefix) - request.config.src_prefix = src_prefix - assert src_prefix is not None and src_prefix != "", "Source prefix not found" - - dst_prefix = selecting_route_to_delete( - dst_asic_routes, dst_dut_nexthops.values() - ) - logger.info("Destination prefix: %s", dst_prefix) - request.config.dst_prefix = dst_prefix - assert ( - dst_prefix is not None and dst_prefix != "" - ), "Destination prefix not found" - - return ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) - - def verify_bfd_state(dut, dut_nexthops, dut_asic, expected_bfd_state): logger.info("Verifying BFD state on {} ".format(dut)) for nexthop in dut_nexthops: @@ -491,56 +467,6 @@ def ensure_interfaces_are_up(dut, asic, interfaces): toggle_interfaces_in_parallel(cmds, dut, asic, interfaces, "up") -def prepare_traffic_test_variables(get_src_dst_asic, request, version): - dut = get_src_dst_asic["dut"] - src_asic = get_src_dst_asic["src_asic"] - src_asic_index = get_src_dst_asic["src_asic_index"] - dst_asic = get_src_dst_asic["dst_asic"] - dst_asic_index = get_src_dst_asic["dst_asic_index"] - logger.info( - "DUT: {}, src_asic_index: {}, dst_asic_index: {}".format(dut.hostname, src_asic_index, dst_asic_index) - ) - - backend_port_channels = extract_backend_portchannels(dut) - src_asic_next_hops, dst_asic_next_hops, src_prefix, dst_prefix = get_src_dst_asic_next_hops( - version, - dut, - src_asic, - dst_asic, - request, - backend_port_channels, - ) - - add_bfd(src_asic_index, src_prefix, dut) - add_bfd(dst_asic_index, dst_prefix, dut) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state(dut, src_asic_next_hops.values(), src_asic, "Up"), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state(dut, dst_asic_next_hops.values(), dst_asic, "Up"), - ) - - src_asic_router_mac = src_asic.get_router_mac() - - return ( - dut, - src_asic, - src_asic_index, - dst_asic, - dst_asic_index, - src_asic_next_hops, - dst_asic_next_hops, - src_asic_router_mac, - backend_port_channels, - ) - - def clear_bfd_configs(dut, asic_index, prefix): logger.info("Clearing BFD configs on {}".format(dut)) command = ( @@ -794,27 +720,12 @@ def verify_given_bfd_state(asic_next_hops, port_channel, asic_index, dut, expect return current_state == expected_state -def wait_until_given_bfd_down( - src_asic_next_hops, - src_port_channel, - src_asic_index, - dst_asic_next_hops, - dst_port_channel, - dst_asic_index, - dut, -): - assert wait_until( - 180, - 10, - 0, - lambda: verify_given_bfd_state(src_asic_next_hops, dst_port_channel, src_asic_index, dut, "Down"), - ) - +def wait_until_given_bfd_down(next_hops, port_channel, asic_index, dut): assert wait_until( - 180, + 300, 10, 0, - lambda: verify_given_bfd_state(dst_asic_next_hops, src_port_channel, dst_asic_index, dut, "Down"), + lambda: verify_given_bfd_state(next_hops, port_channel, asic_index, dut, "Down"), ) @@ -859,19 +770,3 @@ def assert_traffic_switching( dst_asic_index, dut.hostname, ) - - -def wait_until_bfd_up(dut, src_asic_next_hops, src_asic, dst_asic_next_hops, dst_asic): - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state(dut, src_asic_next_hops.values(), src_asic, "Up"), - ) - - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state(dut, dst_asic_next_hops.values(), dst_asic, "Up"), - ) diff --git a/tests/bfd/test_bfd_static_route.py b/tests/bfd/test_bfd_static_route.py index 28c56228e0a..85e2e0bc607 100644 --- a/tests/bfd/test_bfd_static_route.py +++ b/tests/bfd/test_bfd_static_route.py @@ -4,12 +4,12 @@ import pytest from tests.bfd.bfd_base import BfdBase -from tests.bfd.bfd_helpers import verify_static_route, select_src_dst_dut_with_asic, check_bgp_status, \ - add_bfd, verify_bfd_state, delete_bfd, extract_backend_portchannels, batch_control_interface_state +from tests.bfd.bfd_helpers import check_bgp_status, add_bfd, delete_bfd, extract_backend_portchannels, \ + batch_control_interface_state, create_and_verify_bfd_state, verify_bfd_and_static_route, verify_bfd_only from tests.common.config_reload import config_reload +from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor from tests.common.platform.processes_utils import wait_critical_processes from tests.common.reboot import reboot -from tests.common.utilities import wait_until pytestmark = [ pytest.mark.topology("t2"), @@ -28,91 +28,39 @@ class TestBfdStaticRoute(BfdBase): 'diagnose': 200, } - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) - def test_bfd_with_lc_reboot( - self, - localhost, - duthost, - request, - tbinfo, - get_src_dst_asic_and_duts, - bfd_cleanup_db, - version, - ): + def test_bfd_with_lc_reboot(self, localhost, request, select_src_dst_dut_with_asic, bfd_cleanup_db): """ Author: Harsha Golla Email : harsgoll@cisco.com """ - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 300, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Savings the configs src_dut.shell("sudo config save -y") # Perform a cold reboot on source dut - reboot(src_dut, localhost) - - # Waiting for all processes on Source dut - wait_critical_processes(src_dut) + reboot(src_dut, localhost, safe_reboot=True) check_bgp_status(request) - # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "Up") logger.info("BFD deletion on source & destination dut") delete_bfd(src_asic.asic_index, src_prefix, src_dut) @@ -122,41 +70,16 @@ def test_bfd_with_lc_reboot( src_dut.shell("sudo config save -y") # Config reload of Source dut - reboot(src_dut, localhost) - - # Waiting for all processes on Source dut - wait_critical_processes(src_dut) + reboot(src_dut, localhost, safe_reboot=True) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "No BFD sessions found" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "No BFD sessions found") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) - def test_bfd_static_route_deletion( - self, - duthost, - request, - tbinfo, - get_src_dst_asic_and_duts, - bfd_cleanup_db, - version, - ): + def test_bfd_static_route_deletion(self, request, select_src_dst_dut_with_asic, bfd_cleanup_db): """ Author: Harsha Golla Email : harsgoll@cisco.com @@ -169,133 +92,64 @@ def test_bfd_static_route_deletion( 4. Delete BFD on Destination dut. 5. Verify that on Destination dut BFD gets cleaned up and static route will be added back. """ - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + version = select_src_dst_dut_with_asic["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) logger.info("BFD deletion on source dut") delete_bfd(src_asic.asic_index, src_prefix, src_dut) - - logger.info("BFD & Static route verifications") - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Down" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Removal", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for target, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "No BFD sessions found" if target == "src" else "Down", + request, + prefix, + "Route Addition" if target == "src" else "Route Removal", + version, + ) logger.info("BFD deletion on destination dut") delete_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - logger.info("BFD & Static route verifications") - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "No BFD sessions found" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Addition", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for target, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "No BFD sessions found", + request, + prefix, + "Route Addition", + version, + ) logger.info("BFD deletion did not influence static routes and test completed successfully") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_flap( self, - duthost, request, - duthosts, - tbinfo, - get_src_dst_asic_and_duts, + select_src_dst_dut_with_asic, bfd_cleanup_db, get_function_completeness_level, - version, ): """ Author: Harsha Golla @@ -311,45 +165,23 @@ def test_bfd_flap( 6. Verify that on destination dut BFD is up and static route is added back. 7. Repeat above steps 100 times. """ - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + version = select_src_dst_dut_with_asic["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) completeness_level = get_function_completeness_level if completeness_level is None: @@ -367,78 +199,36 @@ def test_bfd_flap( time.sleep(5) logger.info("BFD & Static route verifications") - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Down" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, - src_dut_nexthops.values(), - src_asic, - "No BFD sessions found", - ), - ) - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Removal", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for target, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "No BFD sessions found" if target == "src" else "Down", + request, + prefix, + "Route Addition" if target == "src" else "Route Removal", + version, + ) logger.info("BFD addition on source dut") add_bfd(src_asic.asic_index, src_prefix, src_dut) - logger.info("BFD & Static route verifications") - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Addition", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for target, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "Up", + request, + prefix, + "Route Addition", + version, + ) # Check if both iterations were successful and increment the counter successful_iterations += 1 @@ -455,18 +245,14 @@ def test_bfd_flap( logger.info("test_bfd_flap completed") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_with_rp_reboot( self, localhost, - duthost, request, duthosts, - tbinfo, - get_src_dst_asic_and_duts, enum_supervisor_dut_hostname, + select_src_dst_dut_with_asic, bfd_cleanup_db, - version, ): """ Author: Harsha Golla @@ -474,78 +260,40 @@ def test_bfd_with_rp_reboot( """ rp = duthosts[enum_supervisor_dut_hostname] - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Savings the configs src_dut.shell("sudo config save -y") dst_dut.shell("sudo config save -y") - # Perform a cold reboot on source dut - reboot(rp, localhost) + # Perform a cold reboot on RP + reboot(rp, localhost, safe_reboot=True) # Waiting for all processes on Source & destination dut - wait_critical_processes(src_dut) - wait_critical_processes(dst_dut) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, _, _, dut, _ in src_dst_context: + executor.submit(wait_critical_processes, dut) check_bgp_status(request) - # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "Up") logger.info("BFD deletion on source & destination dut") delete_bfd(src_asic.asic_index, src_prefix, src_dut) @@ -555,89 +303,44 @@ def test_bfd_with_rp_reboot( src_dut.shell("sudo config save -y") dst_dut.shell("sudo config save -y") - # Config reload of Source dut - reboot(rp, localhost) + # Perform a cold reboot on RP + reboot(rp, localhost, safe_reboot=True) # Waiting for all processes on Source & destination dut - wait_critical_processes(src_dut) - wait_critical_processes(dst_dut) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, _, _, dut, _ in src_dst_context: + executor.submit(wait_critical_processes, dut) check_bgp_status(request) - # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "No BFD sessions found" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "No BFD sessions found") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) - def test_bfd_remote_link_flap( - self, - duthost, - request, - tbinfo, - get_src_dst_asic_and_duts, - bfd_cleanup_db, - version, - ): + def test_bfd_remote_link_flap(self, request, select_src_dst_dut_with_asic, bfd_cleanup_db): """ Author: Harsha Golla Email : harsgoll@cisco.com """ request.config.interface_shutdown = True - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + version = select_src_dst_dut_with_asic["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Extract portchannel interfaces on dst list_of_portchannels_on_dst = src_dut_nexthops.keys() @@ -648,121 +351,56 @@ def test_bfd_remote_link_flap( batch_control_interface_state(dst_dut, dst_asic, list_of_portchannels_on_dst, "shutdown") # Verification of BFD session state on src dut - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Down" - ), - ) - - # Verify that corresponding static route has been removed on both duts - logger.info("BFD & Static route verifications") - verify_static_route( - request, + verify_bfd_and_static_route( + src_dut, + src_dut_nexthops, src_asic, + "Down", + request, src_prefix, - src_dut, "Route Removal", version, ) batch_control_interface_state(dst_dut, dst_asic, list_of_portchannels_on_dst, "startup") - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) - - # Verify that corresponding static route has been added on both duts - logger.info("BFD & Static route verifications") - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Addition", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) - - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) - def test_bfd_lc_asic_shutdown( - self, - duthost, - request, - tbinfo, - get_src_dst_asic_and_duts, - bfd_cleanup_db, - version, - ): + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "Up", + request, + prefix, + "Route Addition", + version, + ) + + def test_bfd_lc_asic_shutdown(self, request, select_src_dst_dut_with_asic, bfd_cleanup_db): """ Author: Harsha Golla Email : harsgoll@cisco.com """ request.config.interface_shutdown = True - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + version = select_src_dst_dut_with_asic["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Extract portchannel interfaces on src list_of_portchannels_on_src = dst_dut_nexthops.keys() @@ -772,138 +410,62 @@ def test_bfd_lc_asic_shutdown( # Shutdown PortChannels batch_control_interface_state(src_dut, src_asic, list_of_portchannels_on_src, "shutdown") - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Down" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Down" - ), - ) - - # Verify that corresponding static route has been removed on both duts - logger.info("BFD & Static route verifications") - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Removal", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Removal", - version, - ) + # Verify BFD and static routes + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "Down", + request, + prefix, + "Route Removal", + version, + ) batch_control_interface_state(src_dut, src_asic, list_of_portchannels_on_src, "startup") - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) - - # Verify that corresponding static route has been added on both duts - logger.info("BFD & Static route verifications") - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Addition", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) - - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) - def test_bfd_portchannel_member_flap( - self, - duthost, - request, - tbinfo, - get_src_dst_asic_and_duts, - bfd_cleanup_db, - version, - ): + # Verify BFD and static routes. + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "Up", + request, + prefix, + "Route Addition", + version, + ) + + def test_bfd_portchannel_member_flap(self, request, select_src_dst_dut_with_asic, bfd_cleanup_db): """ Author: Harsha Golla Email : harsgoll@cisco.com """ request.config.interface_shutdown = True - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + version = select_src_dst_dut_with_asic["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Extract portchannel interfaces on src list_of_portchannels_on_src = dst_dut_nexthops.keys() @@ -922,167 +484,73 @@ def test_bfd_portchannel_member_flap( request.config.selected_portchannel_members = port_channel_members_on_src batch_control_interface_state(src_dut, src_asic, port_channel_members_on_src, "shutdown") - # Verification of BFD session state. - assert wait_until( - 300, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Down" - ), - ) - assert wait_until( - 300, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Down" - ), - ) - - # Verify that corresponding static route has been removed on both duts - logger.info("BFD & Static route verifications") - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Removal", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Removal", - version, - ) + # Verify BFD and static routes + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "Down", + request, + prefix, + "Route Removal", + version, + ) # Bring up of PortChannel members batch_control_interface_state(src_dut, src_asic, port_channel_members_on_src, "startup") - # Verification of BFD session state. - assert wait_until( - 300, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) - - # Verify that corresponding static route has been added on both duts - logger.info("Static route verifications") - verify_static_route( - request, - dst_asic, - dst_prefix, - dst_dut, - "Route Addition", - version, - ) - verify_static_route( - request, - src_asic, - src_prefix, - src_dut, - "Route Addition", - version, - ) - - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) - def test_bfd_config_reload( - self, - duthost, - request, - tbinfo, - get_src_dst_asic_and_duts, - bfd_cleanup_db, - version, - ): + # Verify BFD and static routes + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit( + verify_bfd_and_static_route, + dut, + dut_nexthops, + asic, + "Up", + request, + prefix, + "Route Addition", + version, + ) + + def test_bfd_config_reload(self, request, select_src_dst_dut_with_asic, bfd_cleanup_db): """ Author: Harsha Golla Email : harsgoll@cisco.com """ - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Savings the configs src_dut.shell("sudo config save -y") # Config reload of Source dut - config_reload(src_dut) - - # Waiting for all processes on Source dut - wait_critical_processes(src_dut) + config_reload(src_dut, safe_reload=True) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "Up") logger.info("BFD deletion on source & destination dut") delete_bfd(src_asic.asic_index, src_prefix, src_dut) @@ -1092,43 +560,22 @@ def test_bfd_config_reload( src_dut.shell("sudo config save -y") # Config reload of Source dut - config_reload(src_dut) - - # Waiting for all processes on Source dut - wait_critical_processes(src_dut) + config_reload(src_dut, safe_reload=True) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "No BFD sessions found" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "No BFD sessions found") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_with_rp_config_reload( self, - localhost, - duthost, request, duthosts, - tbinfo, - get_src_dst_asic_and_duts, + select_src_dst_dut_with_asic, enum_supervisor_dut_hostname, bfd_cleanup_db, - version, ): """ Author: Harsha Golla @@ -1136,78 +583,41 @@ def test_bfd_with_rp_config_reload( """ rp = duthosts[enum_supervisor_dut_hostname] - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Savings the configs src_dut.shell("sudo config save -y") dst_dut.shell("sudo config save -y") - # Perform a cold reboot on source dut - config_reload(rp) + # Config reload of RP + config_reload(rp, safe_reload=True) # Waiting for all processes on Source & destination dut - wait_critical_processes(src_dut) - wait_critical_processes(dst_dut) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, _, _, dut, _ in src_dst_context: + executor.submit(wait_critical_processes, dut) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "Up") logger.info("BFD deletion on source & destination dut") delete_bfd(src_asic.asic_index, src_prefix, src_dut) @@ -1217,45 +627,28 @@ def test_bfd_with_rp_config_reload( src_dut.shell("sudo config save -y") dst_dut.shell("sudo config save -y") - # Config reload of Source dut - config_reload(rp) + # Config reload of RP + config_reload(rp, safe_reload=True) # Waiting for all processes on Source & destination dut - wait_critical_processes(src_dut) - wait_critical_processes(dst_dut) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, _, _, dut, _ in src_dst_context: + executor.submit(wait_critical_processes, dut) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "No BFD sessions found" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "No BFD sessions found") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_with_bad_fc_asic( self, - localhost, - duthost, request, duthosts, - tbinfo, - get_src_dst_asic_and_duts, + select_src_dst_dut_with_asic, enum_supervisor_dut_hostname, bfd_cleanup_db, - version, ): """ Author: Harsha Golla @@ -1263,47 +656,22 @@ def test_bfd_with_bad_fc_asic( """ rp = duthosts[enum_supervisor_dut_hostname] - # Selecting source, destination dut & prefix & BFD status verification for all nexthops - logger.info( - "Selecting Source dut, destination dut, source asic, destination asic, source prefix, destination prefix" - ) - ( - src_asic, - dst_asic, - src_dut, - dst_dut, - src_dut_nexthops, - dst_dut_nexthops, - src_prefix, - dst_prefix, - ) = select_src_dst_dut_with_asic( - request, get_src_dst_asic_and_duts, version - ) - - # Creation of BFD - logger.info("BFD addition on source dut") - add_bfd(src_asic.asic_index, src_prefix, src_dut) - - logger.info("BFD addition on destination dut") - add_bfd(dst_asic.asic_index, dst_prefix, dst_dut) - - # Verification of BFD session state. - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + src_asic = select_src_dst_dut_with_asic["src_asic"] + dst_asic = select_src_dst_dut_with_asic["dst_asic"] + src_dut = select_src_dst_dut_with_asic["src_dut"] + dst_dut = select_src_dst_dut_with_asic["dst_dut"] + src_dut_nexthops = select_src_dst_dut_with_asic["src_dut_nexthops"] + dst_dut_nexthops = select_src_dst_dut_with_asic["dst_dut_nexthops"] + src_prefix = select_src_dst_dut_with_asic["src_prefix"] + dst_prefix = select_src_dst_dut_with_asic["dst_prefix"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_dut, src_dut_nexthops), + ("dst", dst_asic, dst_prefix, dst_dut, dst_dut_nexthops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, dut, dut_nexthops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, dut_nexthops) # Savings the configs src_dut.shell("sudo config save -y") @@ -1316,53 +684,29 @@ def test_bfd_with_bad_fc_asic( asic_ids = [int(element.split("swss")[1]) for element in docker_output] # Shut down corresponding asic on supervisor to simulate bad asic - for asic_id in asic_ids: - rp.shell("systemctl stop swss@{}".format(asic_id)) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for asic_id in asic_ids: + executor.submit(rp.shell, "systemctl stop swss@{}".format(asic_id)) # Verify that BFD sessions are down - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Down" - ), - ) - assert wait_until( - 180, - 10, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Down" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "Down") # Config reload RP to bring up the swss containers - config_reload(rp) + config_reload(rp, safe_reload=True) # Waiting for all processes on Source & destination dut - wait_critical_processes(src_dut) - wait_critical_processes(dst_dut) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, _, _, dut, _ in src_dst_context: + executor.submit(wait_critical_processes, dut) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "Up" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "Up" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "Up") logger.info("BFD deletion on source dut") delete_bfd(src_asic.asic_index, src_prefix, src_dut) @@ -1373,28 +717,16 @@ def test_bfd_with_bad_fc_asic( dst_dut.shell("sudo config save -y") # Config reload RP - config_reload(rp) + config_reload(rp, safe_reload=True) # Waiting for all processes on Source & destination dut - wait_critical_processes(src_dut) - wait_critical_processes(dst_dut) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, _, _, dut, _ in src_dst_context: + executor.submit(wait_critical_processes, dut) check_bgp_status(request) # Verification of BFD session state. - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - dst_dut, dst_dut_nexthops.values(), dst_asic, "No BFD sessions found" - ), - ) - assert wait_until( - 300, - 20, - 0, - lambda: verify_bfd_state( - src_dut, src_dut_nexthops.values(), src_asic, "No BFD sessions found" - ), - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, dut, dut_nexthops in src_dst_context: + executor.submit(verify_bfd_only, dut, dut_nexthops, asic, "No BFD sessions found") diff --git a/tests/bfd/test_bfd_traffic.py b/tests/bfd/test_bfd_traffic.py index a49b09193ce..fd3aa77d614 100644 --- a/tests/bfd/test_bfd_traffic.py +++ b/tests/bfd/test_bfd_traffic.py @@ -4,8 +4,9 @@ from tests.bfd.bfd_base import BfdBase from tests.bfd.bfd_helpers import get_ptf_src_port, get_backend_interface_in_use_by_counter, \ - prepare_traffic_test_variables, get_random_bgp_neighbor_ip_of_asic, toggle_port_channel_or_member, \ - get_port_channel_by_member, wait_until_bfd_up, wait_until_given_bfd_down, assert_traffic_switching + get_random_bgp_neighbor_ip_of_asic, toggle_port_channel_or_member, get_port_channel_by_member, \ + wait_until_given_bfd_down, assert_traffic_switching, create_and_verify_bfd_state, verify_bfd_only +from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor pytestmark = [ pytest.mark.topology("t2"), @@ -18,27 +19,34 @@ class TestBfdTraffic(BfdBase): PACKET_COUNT = 10000 - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_traffic_remote_port_channel_shutdown( self, request, tbinfo, ptfadapter, - get_src_dst_asic, + prepare_traffic_test_variables, bfd_cleanup_db, - version, ): - ( - dut, - src_asic, - src_asic_index, - dst_asic, - dst_asic_index, - src_asic_next_hops, - dst_asic_next_hops, - src_asic_router_mac, - backend_port_channels, - ) = prepare_traffic_test_variables(get_src_dst_asic, request, version) + dut = prepare_traffic_test_variables["dut"] + src_asic = prepare_traffic_test_variables["src_asic"] + src_asic_index = prepare_traffic_test_variables["src_asic_index"] + dst_asic = prepare_traffic_test_variables["dst_asic"] + dst_asic_index = prepare_traffic_test_variables["dst_asic_index"] + src_asic_next_hops = prepare_traffic_test_variables["src_asic_next_hops"] + dst_asic_next_hops = prepare_traffic_test_variables["dst_asic_next_hops"] + src_prefix = prepare_traffic_test_variables["src_prefix"] + dst_prefix = prepare_traffic_test_variables["dst_prefix"] + src_asic_router_mac = prepare_traffic_test_variables["src_asic_router_mac"] + backend_port_channels = prepare_traffic_test_variables["backend_port_channels"] + version = prepare_traffic_test_variables["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_asic_next_hops), + ("dst", dst_asic, dst_prefix, dst_asic_next_hops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, next_hops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: @@ -78,15 +86,12 @@ def test_bfd_traffic_remote_port_channel_shutdown( src_bp_iface_before_shutdown, ) - wait_until_given_bfd_down( - src_asic_next_hops, - src_port_channel_before_shutdown, - src_asic_index, - dst_asic_next_hops, - dst_port_channel_before_shutdown, - dst_asic_index, - dut, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for next_hops, port_channel, asic_index in [ + (src_asic_next_hops, dst_port_channel_before_shutdown, src_asic_index), + (dst_asic_next_hops, src_port_channel_before_shutdown, dst_asic_index), + ]: + executor.submit(wait_until_given_bfd_down, next_hops, port_channel, asic_index, dut) src_bp_iface_after_shutdown, dst_bp_iface_after_shutdown = get_backend_interface_in_use_by_counter( dut, @@ -121,29 +126,38 @@ def test_bfd_traffic_remote_port_channel_shutdown( "startup", ) - wait_until_bfd_up(dut, src_asic_next_hops, src_asic, dst_asic_next_hops, dst_asic) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, next_hops in src_dst_context: + executor.submit(verify_bfd_only, dut, next_hops, asic, "Up") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_traffic_local_port_channel_shutdown( self, request, tbinfo, ptfadapter, - get_src_dst_asic, + prepare_traffic_test_variables, bfd_cleanup_db, - version, ): - ( - dut, - src_asic, - src_asic_index, - dst_asic, - dst_asic_index, - src_asic_next_hops, - dst_asic_next_hops, - src_asic_router_mac, - backend_port_channels, - ) = prepare_traffic_test_variables(get_src_dst_asic, request, version) + dut = prepare_traffic_test_variables["dut"] + src_asic = prepare_traffic_test_variables["src_asic"] + src_asic_index = prepare_traffic_test_variables["src_asic_index"] + dst_asic = prepare_traffic_test_variables["dst_asic"] + dst_asic_index = prepare_traffic_test_variables["dst_asic_index"] + src_asic_next_hops = prepare_traffic_test_variables["src_asic_next_hops"] + dst_asic_next_hops = prepare_traffic_test_variables["dst_asic_next_hops"] + src_prefix = prepare_traffic_test_variables["src_prefix"] + dst_prefix = prepare_traffic_test_variables["dst_prefix"] + src_asic_router_mac = prepare_traffic_test_variables["src_asic_router_mac"] + backend_port_channels = prepare_traffic_test_variables["backend_port_channels"] + version = prepare_traffic_test_variables["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_asic_next_hops), + ("dst", dst_asic, dst_prefix, dst_asic_next_hops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, next_hops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: @@ -183,15 +197,12 @@ def test_bfd_traffic_local_port_channel_shutdown( dst_bp_iface_before_shutdown, ) - wait_until_given_bfd_down( - src_asic_next_hops, - src_port_channel_before_shutdown, - src_asic_index, - dst_asic_next_hops, - dst_port_channel_before_shutdown, - dst_asic_index, - dut, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for next_hops, port_channel, asic_index in [ + (src_asic_next_hops, dst_port_channel_before_shutdown, src_asic_index), + (dst_asic_next_hops, src_port_channel_before_shutdown, dst_asic_index), + ]: + executor.submit(wait_until_given_bfd_down, next_hops, port_channel, asic_index, dut) src_bp_iface_after_shutdown, dst_bp_iface_after_shutdown = get_backend_interface_in_use_by_counter( dut, @@ -226,29 +237,38 @@ def test_bfd_traffic_local_port_channel_shutdown( "startup", ) - wait_until_bfd_up(dut, src_asic_next_hops, src_asic, dst_asic_next_hops, dst_asic) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, next_hops in src_dst_context: + executor.submit(verify_bfd_only, dut, next_hops, asic, "Up") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_traffic_remote_port_channel_member_shutdown( self, request, tbinfo, ptfadapter, - get_src_dst_asic, + prepare_traffic_test_variables, bfd_cleanup_db, - version, ): - ( - dut, - src_asic, - src_asic_index, - dst_asic, - dst_asic_index, - src_asic_next_hops, - dst_asic_next_hops, - src_asic_router_mac, - backend_port_channels, - ) = prepare_traffic_test_variables(get_src_dst_asic, request, version) + dut = prepare_traffic_test_variables["dut"] + src_asic = prepare_traffic_test_variables["src_asic"] + src_asic_index = prepare_traffic_test_variables["src_asic_index"] + dst_asic = prepare_traffic_test_variables["dst_asic"] + dst_asic_index = prepare_traffic_test_variables["dst_asic_index"] + src_asic_next_hops = prepare_traffic_test_variables["src_asic_next_hops"] + dst_asic_next_hops = prepare_traffic_test_variables["dst_asic_next_hops"] + src_prefix = prepare_traffic_test_variables["src_prefix"] + dst_prefix = prepare_traffic_test_variables["dst_prefix"] + src_asic_router_mac = prepare_traffic_test_variables["src_asic_router_mac"] + backend_port_channels = prepare_traffic_test_variables["backend_port_channels"] + version = prepare_traffic_test_variables["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_asic_next_hops), + ("dst", dst_asic, dst_prefix, dst_asic_next_hops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, next_hops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: @@ -288,15 +308,12 @@ def test_bfd_traffic_remote_port_channel_member_shutdown( if not src_port_channel_before_shutdown or not dst_port_channel_before_shutdown: pytest.fail("No port channel found with interface in use") - wait_until_given_bfd_down( - src_asic_next_hops, - src_port_channel_before_shutdown, - src_asic_index, - dst_asic_next_hops, - dst_port_channel_before_shutdown, - dst_asic_index, - dut, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for next_hops, port_channel, asic_index in [ + (src_asic_next_hops, dst_port_channel_before_shutdown, src_asic_index), + (dst_asic_next_hops, src_port_channel_before_shutdown, dst_asic_index), + ]: + executor.submit(wait_until_given_bfd_down, next_hops, port_channel, asic_index, dut) src_bp_iface_after_shutdown, dst_bp_iface_after_shutdown = get_backend_interface_in_use_by_counter( dut, @@ -331,29 +348,38 @@ def test_bfd_traffic_remote_port_channel_member_shutdown( "startup", ) - wait_until_bfd_up(dut, src_asic_next_hops, src_asic, dst_asic_next_hops, dst_asic) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, next_hops in src_dst_context: + executor.submit(verify_bfd_only, dut, next_hops, asic, "Up") - @pytest.mark.parametrize("version", ["ipv4", "ipv6"]) def test_bfd_traffic_local_port_channel_member_shutdown( self, request, tbinfo, ptfadapter, - get_src_dst_asic, + prepare_traffic_test_variables, bfd_cleanup_db, - version, ): - ( - dut, - src_asic, - src_asic_index, - dst_asic, - dst_asic_index, - src_asic_next_hops, - dst_asic_next_hops, - src_asic_router_mac, - backend_port_channels, - ) = prepare_traffic_test_variables(get_src_dst_asic, request, version) + dut = prepare_traffic_test_variables["dut"] + src_asic = prepare_traffic_test_variables["src_asic"] + src_asic_index = prepare_traffic_test_variables["src_asic_index"] + dst_asic = prepare_traffic_test_variables["dst_asic"] + dst_asic_index = prepare_traffic_test_variables["dst_asic_index"] + src_asic_next_hops = prepare_traffic_test_variables["src_asic_next_hops"] + dst_asic_next_hops = prepare_traffic_test_variables["dst_asic_next_hops"] + src_prefix = prepare_traffic_test_variables["src_prefix"] + dst_prefix = prepare_traffic_test_variables["dst_prefix"] + src_asic_router_mac = prepare_traffic_test_variables["src_asic_router_mac"] + backend_port_channels = prepare_traffic_test_variables["backend_port_channels"] + version = prepare_traffic_test_variables["version"] + src_dst_context = [ + ("src", src_asic, src_prefix, src_asic_next_hops), + ("dst", dst_asic, dst_prefix, dst_asic_next_hops), + ] + + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, prefix, next_hops in src_dst_context: + executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: @@ -393,15 +419,12 @@ def test_bfd_traffic_local_port_channel_member_shutdown( if not src_port_channel_before_shutdown or not dst_port_channel_before_shutdown: pytest.fail("No port channel found with interface in use") - wait_until_given_bfd_down( - src_asic_next_hops, - src_port_channel_before_shutdown, - src_asic_index, - dst_asic_next_hops, - dst_port_channel_before_shutdown, - dst_asic_index, - dut, - ) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for next_hops, port_channel, asic_index in [ + (src_asic_next_hops, dst_port_channel_before_shutdown, src_asic_index), + (dst_asic_next_hops, src_port_channel_before_shutdown, dst_asic_index), + ]: + executor.submit(wait_until_given_bfd_down, next_hops, port_channel, asic_index, dut) src_bp_iface_after_shutdown, dst_bp_iface_after_shutdown = get_backend_interface_in_use_by_counter( dut, @@ -436,4 +459,6 @@ def test_bfd_traffic_local_port_channel_member_shutdown( "startup", ) - wait_until_bfd_up(dut, src_asic_next_hops, src_asic, dst_asic_next_hops, dst_asic) + with SafeThreadPoolExecutor(max_workers=8) as executor: + for _, asic, _, next_hops in src_dst_context: + executor.submit(verify_bfd_only, dut, next_hops, asic, "Up") From f9d7b6f65001a13abc4a36397799a5c32d235e5c Mon Sep 17 00:00:00 2001 From: rbpittman Date: Thu, 7 Nov 2024 22:13:14 -0500 Subject: [PATCH 115/221] Cisco-8122 Increase buffer pool watermark test margin (#15450) * Increase pkt margin on buffer pool watermark test to 8. * Revise to be GR2 only. --- tests/qos/files/cisco/qos_param_generator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/qos/files/cisco/qos_param_generator.py b/tests/qos/files/cisco/qos_param_generator.py index 3f109ee69e5..b38a30d33c1 100644 --- a/tests/qos/files/cisco/qos_param_generator.py +++ b/tests/qos/files/cisco/qos_param_generator.py @@ -462,6 +462,8 @@ def __define_buffer_pool_watermark(self): "pkts_num_trig_pfc": self.lossless_drop_thr // self.buffer_size // packet_buffs, "cell_size": self.buffer_size, "packet_size": packet_size} + if self.dutAsic == "gr2": + lossless_params["pkts_num_margin"] = 8 self.write_params("wm_buf_pool_lossless", lossless_params) if self.should_autogen(["wm_buf_pool_lossy"]): lossy_params = {"dscp": self.dscp_queue0, @@ -472,6 +474,8 @@ def __define_buffer_pool_watermark(self): "pkts_num_fill_egr_min": 0, "cell_size": self.buffer_size, "packet_size": packet_size} + if self.dutAsic == "gr2": + lossy_params["pkts_num_margin"] = 8 self.write_params("wm_buf_pool_lossy", lossy_params) def __define_q_shared_watermark(self): From 3e54c34c934cb4d4bb5d8682ddacbc8a37d23ff9 Mon Sep 17 00:00:00 2001 From: nissampa <99767762+nissampa@users.noreply.github.com> Date: Thu, 7 Nov 2024 20:51:19 -0800 Subject: [PATCH 116/221] added fixtures as argument to all the test cases (#15153) * added fixtures as argument to all the test cases * added smartswitch topo * changed the scope for fixtures * added the is_smartswitch field in ansible/testbed.yaml * changed scope of the fixture * changed back to function scope to resolve mismatch * removed fixtures as parameter after autouse * removed is_smartswitch field from non-smartswitch configs * changed topo name to smartswitch-t1 and added symbolic links * added num_dpu_modules as fixtures * added correct marker * non-smartswitch runs fixes * non-smartswitch runs fixes * non-smartswitch runs fixes * resolved set of PR comments * resolved flake8 error * modified the skip reason * minor change --- .../eos/templates/smartswitch-t1-spine.j2 | 1 + .../roles/eos/templates/smartswitch-t1-tor.j2 | 1 + ansible/testbed.csv | 32 +- ansible/vars/topo_smartswitch-t1.yml | 669 ++++++++++++++++++ tests/smartswitch/common/device_utils_dpu.py | 31 +- .../platform_tests/test_reload_dpu.py | 14 +- .../platform_tests/test_show_platform_dpu.py | 18 +- 7 files changed, 715 insertions(+), 51 deletions(-) create mode 120000 ansible/roles/eos/templates/smartswitch-t1-spine.j2 create mode 120000 ansible/roles/eos/templates/smartswitch-t1-tor.j2 create mode 100644 ansible/vars/topo_smartswitch-t1.yml diff --git a/ansible/roles/eos/templates/smartswitch-t1-spine.j2 b/ansible/roles/eos/templates/smartswitch-t1-spine.j2 new file mode 120000 index 00000000000..1029da8a546 --- /dev/null +++ b/ansible/roles/eos/templates/smartswitch-t1-spine.j2 @@ -0,0 +1 @@ +t1-28-lag-spine.j2 \ No newline at end of file diff --git a/ansible/roles/eos/templates/smartswitch-t1-tor.j2 b/ansible/roles/eos/templates/smartswitch-t1-tor.j2 new file mode 120000 index 00000000000..7e09b9a1dce --- /dev/null +++ b/ansible/roles/eos/templates/smartswitch-t1-tor.j2 @@ -0,0 +1 @@ +t1-28-lag-tor.j2 \ No newline at end of file diff --git a/ansible/testbed.csv b/ansible/testbed.csv index 3892122bbbe..a91a8284a30 100644 --- a/ansible/testbed.csv +++ b/ansible/testbed.csv @@ -1,16 +1,16 @@ -# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_name,auto_recover,comment -ptf1-m,ptf1,ptf32,docker-ptf,ptf_ptf1,10.255.0.188/24,,server_1,,str-msn2700-01,lab,False,Test ptf Mellanox -ptf2-b,ptf2,ptf64,docker-ptf,ptf_ptf2,10.255.0.189/24,,server_1,,lab-s6100-01,lab,False,Test ptf Broadcom -vms-sn2700-t1,vms1-1,t1,docker-ptf,ptf_vms1-1,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests Mellanox SN2700 vms -vms-sn2700-t1-lag,vms1-2,t1-lag,docker-ptf,ptf_vms1-2,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests Mellanox SN2700 vms -vms-sn2700-t0,vms1-3,t0,docker-ptf,ptf_vms1-3,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests Mellanox SN2700 vms -vms-s6000-t0,vms2-1,t0,docker-ptf,ptf_vms2-1,10.255.0.179/24,,server_1,VM0100,lab-s6000-01,lab,True,Tests Dell S6000 vms -vms-a7260-t0,vms3-1,t0-116,docker-ptf,ptf_vms3-1,10.255.0.180/24,,server_1,VM0100,lab-a7260-01,lab,True,Tests Arista A7260 vms -vms-s6100-t0,vms4-1,t0-64,docker-ptf,ptf_vms4-1,10.255.0.181/24,,server_1,VM0100,lab-s6100-01,lab,True,Tests Dell S6100 vms -vms-s6100-t1,vms4-2,t1-64,docker-ptf,ptf_vms4-2,10.255.0.182/24,,server_1,VM0100,lab-s6100-01,lab,True,Tests Dell S6100 vms -vms-s6100-t1-lag,vms5-1,t1-64-lag,docker-ptf,ptf_vms5-1,10.255.0.183/24,,server_1,VM0100,lab-s6100-01,lab,True,ests Dell S6100 vms -vms-multi-dut,vms1-duts,ptf64,docker-ptf,ptf_vms1-duts,10.255.0.184/24,,server_1,VM0100,[dut-host1;dut-host2],lab,True,Example Multi DUTs testbed -vms-example-ixia-1,vms6-1,t0-64,docker-ptf-ixia,example-ixia-ptf-1,10.0.0.30/32,,server_6,VM0600,example-s6100-dut-1,lab,True,superman -ixanvl-vs-conf,anvl,ptf32,docker-ptf-anvl,ptf_anvl,10.250.0.100/24,,server_1,,vlab-01,lab,True,Test ptf ANVL SONIC VM -vms-snappi-sonic,vms6-1,ptf64,docker-ptf-snappi,snappi-sonic-ptf,10.251.0.232,,Server_6,,sonic-s6100-dut1,snappi-sonic,True,Batman -vms-snappi-sonic-multidut,vms6-1,ptf64,docker-ptf-snappi,snappi-sonic-ptf,10.251.0.232,,Server_6,,[sonic-s6100-dut1;sonic-s6100-dut2],snappi-sonic,True,Batman +# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_name,auto_recover,is_smartswitch,comment +ptf1-m,ptf1,ptf32,docker-ptf,ptf_ptf1,10.255.0.188/24,,server_1,,str-msn2700-01,lab,False,,Test ptf Mellanox +ptf2-b,ptf2,ptf64,docker-ptf,ptf_ptf2,10.255.0.189/24,,server_1,,lab-s6100-01,lab,False,,Test ptf Broadcom +vms-sn2700-t1,vms1-1,t1,docker-ptf,ptf_vms1-1,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,,Tests Mellanox SN2700 vms +vms-sn2700-t1-lag,vms1-2,t1-lag,docker-ptf,ptf_vms1-2,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,,Tests Mellanox SN2700 vms +vms-sn2700-t0,vms1-3,t0,docker-ptf,ptf_vms1-3,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,,Tests Mellanox SN2700 vms +vms-s6000-t0,vms2-1,t0,docker-ptf,ptf_vms2-1,10.255.0.179/24,,server_1,VM0100,lab-s6000-01,lab,True,,Tests Dell S6000 vms +vms-a7260-t0,vms3-1,t0-116,docker-ptf,ptf_vms3-1,10.255.0.180/24,,server_1,VM0100,lab-a7260-01,lab,True,,Tests Arista A7260 vms +vms-s6100-t0,vms4-1,t0-64,docker-ptf,ptf_vms4-1,10.255.0.181/24,,server_1,VM0100,lab-s6100-01,lab,True,,Tests Dell S6100 vms +vms-s6100-t1,vms4-2,t1-64,docker-ptf,ptf_vms4-2,10.255.0.182/24,,server_1,VM0100,lab-s6100-01,lab,True,,Tests Dell S6100 vms +vms-s6100-t1-lag,vms5-1,t1-64-lag,docker-ptf,ptf_vms5-1,10.255.0.183/24,,server_1,VM0100,lab-s6100-01,lab,True,,ests Dell S6100 vms +vms-multi-dut,vms1-duts,ptf64,docker-ptf,ptf_vms1-duts,10.255.0.184/24,,server_1,VM0100,[dut-host1;dut-host2],lab,True,,Example Multi DUTs testbed +vms-example-ixia-1,vms6-1,t0-64,docker-ptf-ixia,example-ixia-ptf-1,10.0.0.30/32,,server_6,VM0600,example-s6100-dut-1,lab,True,,superman +ixanvl-vs-conf,anvl,ptf32,docker-ptf-anvl,ptf_anvl,10.250.0.100/24,,server_1,,vlab-01,lab,True,,Test ptf ANVL SONIC VM +vms-snappi-sonic,vms6-1,ptf64,docker-ptf-snappi,snappi-sonic-ptf,10.251.0.232,,Server_6,,sonic-s6100-dut1,snappi-sonic,True,,Batman +vms-snappi-sonic-multidut,vms6-1,ptf64,docker-ptf-snappi,snappi-sonic-ptf,10.251.0.232,,Server_6,,[sonic-s6100-dut1;sonic-s6100-dut2],snappi-sonic,True,,Batman diff --git a/ansible/vars/topo_smartswitch-t1.yml b/ansible/vars/topo_smartswitch-t1.yml new file mode 100644 index 00000000000..c17de99876d --- /dev/null +++ b/ansible/vars/topo_smartswitch-t1.yml @@ -0,0 +1,669 @@ +topology: + VMs: + ARISTA01T2: + vlans: + - 0 + - 1 + vm_offset: 0 + ARISTA03T2: + vlans: + - 2 + - 3 + vm_offset: 1 + ARISTA05T2: + vlans: + - 4 + - 5 + vm_offset: 2 + ARISTA07T2: + vlans: + - 6 + - 7 + vm_offset: 3 + ARISTA01T0: + vlans: + - 8 + vm_offset: 4 + ARISTA02T0: + vlans: + - 9 + vm_offset: 5 + ARISTA03T0: + vlans: + - 10 + vm_offset: 6 + ARISTA04T0: + vlans: + - 11 + vm_offset: 7 + ARISTA05T0: + vlans: + - 12 + vm_offset: 8 + ARISTA06T0: + vlans: + - 13 + vm_offset: 9 + ARISTA07T0: + vlans: + - 14 + vm_offset: 10 + ARISTA08T0: + vlans: + - 15 + vm_offset: 11 + ARISTA09T0: + vlans: + - 16 + vm_offset: 12 + ARISTA10T0: + vlans: + - 17 + vm_offset: 13 + ARISTA11T0: + vlans: + - 18 + vm_offset: 14 + ARISTA12T0: + vlans: + - 19 + vm_offset: 15 + ARISTA13T0: + vlans: + - 20 + vm_offset: 16 + ARISTA14T0: + vlans: + - 21 + vm_offset: 17 + ARISTA15T0: + vlans: + - 22 + vm_offset: 18 + ARISTA16T0: + vlans: + - 23 + vm_offset: 19 + ARISTA17T0: + vlans: + - 24 + vm_offset: 20 + ARISTA18T0: + vlans: + - 25 + vm_offset: 21 + ARISTA19T0: + vlans: + - 26 + vm_offset: 22 + ARISTA20T0: + vlans: + - 27 + vm_offset: 23 + +configuration_properties: + common: + dut_asn: 65100 + dut_type: LeafRouter + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 20 + tor_subnet_number: 2 + max_tor_subnet_number: 20 + tor_subnet_size: 128 + spine: + swrole: spine + tor: + swrole: tor + +configuration: + ARISTA01T2: + properties: + - common + - spine + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.0 + - FC00::1 + interfaces: + Loopback0: + ipv4: 100.1.0.1/32 + ipv6: 2064:100::1/128 + Ethernet1: + lacp: 1 + Ethernet2: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.1/31 + ipv6: fc00::2/126 + bp_interface: + ipv4: 10.10.246.1/24 + ipv6: fc0a::2/64 + + ARISTA03T2: + properties: + - common + - spine + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.4 + - FC00::9 + interfaces: + Loopback0: + ipv4: 100.1.0.3/32 + ipv6: 2064:100::3/128 + Ethernet1: + lacp: 1 + Ethernet2: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.5/31 + ipv6: fc00::a/126 + bp_interface: + ipv4: 10.10.246.3/24 + ipv6: fc0a::6/64 + + ARISTA05T2: + properties: + - common + - spine + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.8 + - FC00::11 + interfaces: + Loopback0: + ipv4: 100.1.0.5/32 + ipv6: 2064:100::5/128 + Ethernet1: + lacp: 1 + Ethernet2: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.9/31 + ipv6: fc00::12/126 + bp_interface: + ipv4: 10.10.246.5/24 + ipv6: fc0a::a/64 + + ARISTA07T2: + properties: + - common + - spine + bgp: + asn: 65200 + peers: + 65100: + - 10.0.0.12 + - FC00::19 + interfaces: + Loopback0: + ipv4: 100.1.0.7/32 + ipv6: 2064:100::7/128 + Ethernet1: + lacp: 1 + Ethernet2: + lacp: 1 + Port-Channel1: + ipv4: 10.0.0.13/31 + ipv6: fc00::1a/126 + bp_interface: + ipv4: 10.10.246.7/24 + ipv6: fc0a::e/64 + + ARISTA01T0: + properties: + - common + - tor + tornum: 1 + bgp: + asn: 64001 + peers: + 65100: + - 10.0.0.32 + - FC00::41 + interfaces: + Loopback0: + ipv4: 100.1.0.17/32 + ipv6: 2064:100::11/128 + Ethernet1: + ipv4: 10.0.0.33/31 + ipv6: fc00::42/126 + bp_interface: + ipv4: 10.10.246.17/24 + ipv6: fc0a::22/64 + vips: + ipv4: + prefixes: + - 200.0.1.0/26 + asn: 64700 + + ARISTA02T0: + properties: + - common + - tor + tornum: 2 + bgp: + asn: 64002 + peers: + 65100: + - 10.0.0.34 + - FC00::45 + interfaces: + Loopback0: + ipv4: 100.1.0.18/32 + ipv6: 2064:100::12/128 + Ethernet1: + ipv4: 10.0.0.35/31 + ipv6: fc00::46/126 + bp_interface: + ipv4: 10.10.246.18/24 + ipv6: fc0a::25/64 + + ARISTA03T0: + properties: + - common + - tor + tornum: 3 + bgp: + asn: 64003 + peers: + 65100: + - 10.0.0.36 + - FC00::49 + interfaces: + Loopback0: + ipv4: 100.1.0.19/32 + ipv6: 2064:100::13/128 + Ethernet1: + ipv4: 10.0.0.37/31 + ipv6: fc00::4a/126 + bp_interface: + ipv4: 10.10.246.19/24 + ipv6: fc0a::26/64 + vips: + ipv4: + prefixes: + - 200.0.1.0/26 + asn: 64700 + + ARISTA04T0: + properties: + - common + - tor + tornum: 4 + bgp: + asn: 64004 + peers: + 65100: + - 10.0.0.38 + - FC00::4D + interfaces: + Loopback0: + ipv4: 100.1.0.20/32 + ipv6: 2064:100::14/128 + Ethernet1: + ipv4: 10.0.0.39/31 + ipv6: fc00::4e/126 + bp_interface: + ipv4: 10.10.246.20/24 + ipv6: fc0a::29/64 + + ARISTA05T0: + properties: + - common + - tor + tornum: 5 + bgp: + asn: 64005 + peers: + 65100: + - 10.0.0.40 + - FC00::51 + interfaces: + Loopback0: + ipv4: 100.1.0.21/32 + ipv6: 2064:100::15/128 + Ethernet1: + ipv4: 10.0.0.41/31 + ipv6: fc00::52/126 + bp_interface: + ipv4: 10.10.246.21/24 + ipv6: fc0a::2a/64 + + ARISTA06T0: + properties: + - common + - tor + tornum: 6 + bgp: + asn: 64006 + peers: + 65100: + - 10.0.0.42 + - FC00::55 + interfaces: + Loopback0: + ipv4: 100.1.0.22/32 + ipv6: 2064:100::16/128 + Ethernet1: + ipv4: 10.0.0.43/31 + ipv6: fc00::56/126 + bp_interface: + ipv4: 10.10.246.22/24 + ipv6: fc0a::2d/64 + + ARISTA07T0: + properties: + - common + - tor + tornum: 7 + bgp: + asn: 64007 + peers: + 65100: + - 10.0.0.44 + - FC00::59 + interfaces: + Loopback0: + ipv4: 100.1.0.23/32 + ipv6: 2064:100::17/128 + Ethernet1: + ipv4: 10.0.0.45/31 + ipv6: fc00::5a/126 + bp_interface: + ipv4: 10.10.246.23/24 + ipv6: fc0a::2e/64 + + ARISTA08T0: + properties: + - common + - tor + tornum: 8 + bgp: + asn: 64008 + peers: + 65100: + - 10.0.0.46 + - FC00::5D + interfaces: + Loopback0: + ipv4: 100.1.0.24/32 + ipv6: 2064:100::18/128 + Ethernet1: + ipv4: 10.0.0.47/31 + ipv6: fc00::5e/126 + bp_interface: + ipv4: 10.10.246.24/24 + ipv6: fc0a::31/64 + + ARISTA09T0: + properties: + - common + - tor + tornum: 9 + bgp: + asn: 64009 + peers: + 65100: + - 10.0.0.48 + - FC00::61 + interfaces: + Loopback0: + ipv4: 100.1.0.25/32 + ipv6: 2064:100::19/128 + Ethernet1: + ipv4: 10.0.0.49/31 + ipv6: fc00::62/126 + bp_interface: + ipv4: 10.10.246.25/24 + ipv6: fc0a::32/64 + + ARISTA10T0: + properties: + - common + - tor + tornum: 10 + bgp: + asn: 64010 + peers: + 65100: + - 10.0.0.50 + - FC00::65 + interfaces: + Loopback0: + ipv4: 100.1.0.26/32 + ipv6: 2064:100::1a/128 + Ethernet1: + ipv4: 10.0.0.51/31 + ipv6: fc00::66/126 + bp_interface: + ipv4: 10.10.246.26/24 + ipv6: fc0a::35/64 + + ARISTA11T0: + properties: + - common + - tor + tornum: 11 + bgp: + asn: 64011 + peers: + 65100: + - 10.0.0.52 + - FC00::69 + interfaces: + Loopback0: + ipv4: 100.1.0.27/32 + ipv6: 2064:100::1b/128 + Ethernet1: + ipv4: 10.0.0.53/31 + ipv6: fc00::6a/126 + bp_interface: + ipv4: 10.10.246.27/24 + ipv6: fc0a::36/64 + + ARISTA12T0: + properties: + - common + - tor + tornum: 12 + bgp: + asn: 64012 + peers: + 65100: + - 10.0.0.54 + - FC00::6D + interfaces: + Loopback0: + ipv4: 100.1.0.28/32 + ipv6: 2064:100::1c/128 + Ethernet1: + ipv4: 10.0.0.55/31 + ipv6: fc00::6e/126 + bp_interface: + ipv4: 10.10.246.28/24 + ipv6: fc0a::39/64 + + ARISTA13T0: + properties: + - common + - tor + tornum: 13 + bgp: + asn: 64013 + peers: + 65100: + - 10.0.0.56 + - FC00::71 + interfaces: + Loopback0: + ipv4: 100.1.0.29/32 + ipv6: 2064:100::1d/128 + Ethernet1: + ipv4: 10.0.0.57/31 + ipv6: fc00::72/126 + bp_interface: + ipv4: 10.10.246.29/24 + ipv6: fc0a::3a/64 + + ARISTA14T0: + properties: + - common + - tor + tornum: 14 + bgp: + asn: 64014 + peers: + 65100: + - 10.0.0.58 + - FC00::75 + interfaces: + Loopback0: + ipv4: 100.1.0.30/32 + ipv6: 2064:100::1e/128 + Ethernet1: + ipv4: 10.0.0.59/31 + ipv6: fc00::76/126 + bp_interface: + ipv4: 10.10.246.30/24 + ipv6: fc0a::3d/64 + + ARISTA15T0: + properties: + - common + - tor + tornum: 15 + bgp: + asn: 64015 + peers: + 65100: + - 10.0.0.60 + - FC00::79 + interfaces: + Loopback0: + ipv4: 100.1.0.31/32 + ipv6: 2064:100::1f/128 + Ethernet1: + ipv4: 10.0.0.61/31 + ipv6: fc00::7a/126 + bp_interface: + ipv4: 10.10.246.31/24 + ipv6: fc0a::3e/64 + + ARISTA16T0: + properties: + - common + - tor + tornum: 16 + bgp: + asn: 64016 + peers: + 65100: + - 10.0.0.62 + - FC00::7D + interfaces: + Loopback0: + ipv4: 100.1.0.32/32 + ipv6: 2064:100::20/128 + Ethernet1: + ipv4: 10.0.0.63/31 + ipv6: fc00::7e/126 + bp_interface: + ipv4: 10.10.246.32/24 + ipv6: fc0a::41/64 + + ARISTA17T0: + properties: + - common + - tor + tornum: 17 + bgp: + asn: 64017 + peers: + 65100: + - 10.0.0.64 + - FC00::81 + interfaces: + Loopback0: + ipv4: 100.1.0.33/32 + ipv6: 2064:100::21/128 + Ethernet1: + ipv4: 10.0.0.65/31 + ipv6: fc00::82/126 + bp_interface: + ipv4: 10.10.246.33/24 + ipv6: fc0a::42/64 + + ARISTA18T0: + properties: + - common + - tor + tornum: 18 + bgp: + asn: 64018 + peers: + 65100: + - 10.0.0.66 + - FC00::85 + interfaces: + Loopback0: + ipv4: 100.1.0.34/32 + ipv6: 2064:100::22/128 + Ethernet1: + ipv4: 10.0.0.67/31 + ipv6: fc00::86/126 + bp_interface: + ipv4: 10.10.246.34/24 + ipv6: fc0a::45/64 + + ARISTA19T0: + properties: + - common + - tor + tornum: 19 + bgp: + asn: 64019 + peers: + 65100: + - 10.0.0.68 + - FC00::89 + interfaces: + Loopback0: + ipv4: 100.1.0.35/32 + ipv6: 2064:100::23/128 + Ethernet1: + ipv4: 10.0.0.69/31 + ipv6: fc00::8a/126 + bp_interface: + ipv4: 10.10.246.35/24 + ipv6: fc0a::46/64 + + ARISTA20T0: + properties: + - common + - tor + tornum: 20 + bgp: + asn: 64020 + peers: + 65100: + - 10.0.0.70 + - FC00::8D + interfaces: + Loopback0: + ipv4: 100.1.0.36/32 + ipv6: 2064:100::24/128 + Ethernet1: + ipv4: 10.0.0.71/31 + ipv6: fc00::8e/126 + bp_interface: + ipv4: 10.10.246.36/24 + ipv6: fc0a::49/64 diff --git a/tests/smartswitch/common/device_utils_dpu.py b/tests/smartswitch/common/device_utils_dpu.py index 1367eff53f5..9b80882dd66 100644 --- a/tests/smartswitch/common/device_utils_dpu.py +++ b/tests/smartswitch/common/device_utils_dpu.py @@ -8,7 +8,6 @@ from tests.common.helpers.platform_api import chassis, module from tests.common.utilities import wait_until from tests.common.helpers.assertions import pytest_assert -from pkg_resources import parse_version @pytest.fixture(scope='function') @@ -23,10 +22,10 @@ def num_dpu_modules(platform_api_conn): return num_modules -@pytest.fixture(scope='function') +@pytest.fixture(scope='function', autouse=True) def check_smartswitch_and_dark_mode(duthosts, enum_rand_one_per_hwsku_hostname, - platform_api_conn): + platform_api_conn, num_dpu_modules): """ Checks whether given testbed is running 202405 image or below versions @@ -38,17 +37,17 @@ def check_smartswitch_and_dark_mode(duthosts, duthost = duthosts[enum_rand_one_per_hwsku_hostname] - if not duthost.facts["DPUS"] and \ - parse_version(duthost.os_version) <= parse_version("202405"): - pytest.skip("Test is not supported for this testbed and os version") + if "DPUS" not in duthost.facts: + pytest.skip("Test is not supported for this testbed") - darkmode = is_dark_mode_enabled(duthost, platform_api_conn) + darkmode = is_dark_mode_enabled(duthost, platform_api_conn, + num_dpu_modules) if darkmode: - dpu_power_on(duthost, platform_api_conn) + dpu_power_on(duthost, platform_api_conn, num_dpu_modules) -def is_dark_mode_enabled(duthost, platform_api_conn): +def is_dark_mode_enabled(duthost, platform_api_conn, num_dpu_modules): """ Checks the liveliness of DPU Returns: @@ -56,10 +55,9 @@ def is_dark_mode_enabled(duthost, platform_api_conn): else False """ - num_modules = num_dpu_modules(platform_api_conn) count_admin_down = 0 - for index in range(num_modules): + for index in range(num_dpu_modules): dpu = module.get_name(platform_api_conn, index) output_config_db = duthost.command( 'redis-cli -p 6379 -h 127.0.0.1 \ @@ -70,7 +68,7 @@ def is_dark_mode_enabled(duthost, platform_api_conn): if 'down' in output_config_db['stdout']: count_admin_down += 1 - if count_admin_down == num_modules: + if count_admin_down == num_dpu_modules: logging.info("Smartswitch is in dark mode") return True @@ -78,17 +76,16 @@ def is_dark_mode_enabled(duthost, platform_api_conn): return False -def dpu_power_on(duthost, platform_api_conn): +def dpu_power_on(duthost, platform_api_conn, num_dpu_modules): """ Executes power on all DPUs Returns: Returns True or False based on all DPUs powered on or not """ - num_modules = num_dpu_modules(platform_api_conn) ip_address_list = [] - for index in range(num_modules): + for index in range(num_dpu_modules): dpu = module.get_name(platform_api_conn, index) ip_address_list.append( module.get_midplane_ip(platform_api_conn, index)) @@ -129,7 +126,7 @@ def check_dpu_module_status(duthost, power_status, dpu_name): Returns True or False based on status of given DPU module """ - output_dpu_status = duthost.command( + output_dpu_status = duthost.shell( 'show chassis module status | grep %s' % (dpu_name)) if "Offline" in output_dpu_status["stdout"]: @@ -158,7 +155,7 @@ def check_dpu_reboot_cause(duthost, dpu_name): Returns True or False based on reboot cause of all DPU modules """ - output_reboot_cause = duthost.command( + output_reboot_cause = duthost.shell( 'show reboot-cause all | grep %s' % (dpu_name)) if 'Unknown' in output_reboot_cause["stdout"]: diff --git a/tests/smartswitch/platform_tests/test_reload_dpu.py b/tests/smartswitch/platform_tests/test_reload_dpu.py index 4c4d7b61d20..1e8e7518f33 100644 --- a/tests/smartswitch/platform_tests/test_reload_dpu.py +++ b/tests/smartswitch/platform_tests/test_reload_dpu.py @@ -17,18 +17,18 @@ from tests.platform_tests.api.conftest import * # noqa: F401,F403 pytestmark = [ - pytest.mark.topology('t1') + pytest.mark.topology('smartswitch') ] def test_dpu_ping_after_reboot(duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn, num_dpu_modules): + localhost, platform_api_conn, + num_dpu_modules): """ @summary: Verify output of `config chassis modules startup ` """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] ip_address_list = [] - num_modules = num_dpu_modules(platform_api_conn) logging.info("Starting switch reboot...") reboot(duthost, localhost, reboot_type=REBOOT_TYPE_COLD, @@ -39,7 +39,7 @@ def test_dpu_ping_after_reboot(duthosts, enum_rand_one_per_hwsku_hostname, "Not all ports that are admin up on are operationally up") logging.info("Interfaces are up") - for index in range(num_modules): + for index in range(num_dpu_modules): ip_address_list.append( module.get_midplane_ip(platform_api_conn, index)) dpu = module.get_name(platform_api_conn, index) @@ -52,16 +52,16 @@ def test_dpu_ping_after_reboot(duthosts, enum_rand_one_per_hwsku_hostname, def test_show_ping_int_after_reload(duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn, num_dpu_modules): + localhost, platform_api_conn, + num_dpu_modules): """ @summary: To Check Ping between NPU and DPU after configuration reload on NPU """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] - num_modules = num_dpu_modules(platform_api_conn) ip_address_list = [] - for index in range(num_modules): + for index in range(num_dpu_modules): ip_address_list.append( module.get_midplane_ip(platform_api_conn, index)) diff --git a/tests/smartswitch/platform_tests/test_show_platform_dpu.py b/tests/smartswitch/platform_tests/test_show_platform_dpu.py index 9c575a47880..5049975b67d 100644 --- a/tests/smartswitch/platform_tests/test_show_platform_dpu.py +++ b/tests/smartswitch/platform_tests/test_show_platform_dpu.py @@ -12,7 +12,7 @@ from tests.common.devices.sonic import * # noqa: 403 pytestmark = [ - pytest.mark.topology('t1') + pytest.mark.topology('smartswitch') ] @@ -44,9 +44,8 @@ def test_shutdown_power_up_dpu(duthosts, enum_rand_one_per_hwsku_hostname, @summary: Verify `shut down and power up DPU` """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] - num_modules = num_dpu_modules(platform_api_conn) - for index in range(num_modules): + for index in range(num_dpu_modules): dpu_name = module.get_name(platform_api_conn, index) duthosts.shell("config chassis modules shutdown %s" % (dpu_name)) pytest_assert(wait_until(180, 60, 0, @@ -54,7 +53,7 @@ def test_shutdown_power_up_dpu(duthosts, enum_rand_one_per_hwsku_hostname, duthost, "off", dpu_name), "DPU is not operationally down") - for index in range(num_modules): + for index in range(num_dpu_modules): dpu_name = module.get_name(platform_api_conn, index) duthosts.shell("config chassis modules startup %s" % (dpu_name)) pytest_assert(wait_until(180, 60, 0, @@ -69,9 +68,8 @@ def test_reboot_cause(duthosts, enum_rand_one_per_hwsku_hostname, @summary: Verify `Reboot Cause` """ duthost = duthosts[enum_rand_one_per_hwsku_hostname] - num_modules = num_dpu_modules(platform_api_conn) - for index in range(num_modules): + for index in range(num_dpu_modules): dpu_name = module.get_name(platform_api_conn, index) duthost.shell("config chassis \ module shutdown %s" % (dpu_name))["stdout_lines"] @@ -80,7 +78,7 @@ def test_reboot_cause(duthosts, enum_rand_one_per_hwsku_hostname, duthost, "off", dpu_name), "DPU is not operationally down") - for index in range(num_modules): + for index in range(num_dpu_modules): dpu_name = module.get_name(platform_api_conn, index) duthosts.shell("config chassis modules startup %s" % (dpu_name)) pytest_assert(wait_until(180, 60, 0, @@ -105,9 +103,7 @@ def test_pcie_link(duthosts, enum_rand_one_per_hwsku_hostname, 'PCIe Device Checking All Test ----------->>> PASSED', "PCIe Link is good'{}'".format(duthost.hostname)) - num_modules = num_dpu_modules(platform_api_conn) - - for index in range(num_modules): + for index in range(num_dpu_modules): dpu_name = module.get_name(platform_api_conn, index) duthosts.shell("config chassis modules shutdown %s" % (dpu_name)) pytest_assert(wait_until(180, 60, 0, @@ -120,7 +116,7 @@ def test_pcie_link(duthosts, enum_rand_one_per_hwsku_hostname, 'PCIe Device Checking All Test ----------->>> PASSED', "PCIe Link is good'{}'".format(duthost.hostname)) - for index in range(num_modules): + for index in range(num_dpu_modules): dpu_name = module.get_name(platform_api_conn, index) duthosts.shell("config chassis modules startup %s" % (dpu_name)) pytest_assert(wait_until(180, 60, 0, From e159098bfd3abc1028d1cdc4cf5342721ccc6096 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:12:57 +0800 Subject: [PATCH 117/221] Remove skip_traffic_test fixture in vxlan tests (#15459) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in vxlan tests How did you verify/test it? --- tests/vxlan/test_vxlan_bfd_tsa.py | 37 +++--- tests/vxlan/test_vxlan_decap.py | 6 +- tests/vxlan/test_vxlan_ecmp.py | 154 +++++++++------------- tests/vxlan/test_vxlan_ecmp_switchover.py | 41 +++--- 4 files changed, 100 insertions(+), 138 deletions(-) diff --git a/tests/vxlan/test_vxlan_bfd_tsa.py b/tests/vxlan/test_vxlan_bfd_tsa.py index 1538efd891f..b2a4ac12909 100644 --- a/tests/vxlan/test_vxlan_bfd_tsa.py +++ b/tests/vxlan/test_vxlan_bfd_tsa.py @@ -14,7 +14,6 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.ptf_runner import ptf_runner from tests.common.vxlan_ecmp_utils import Ecmp_Utils from tests.common.config_reload import config_system_checks_passed @@ -238,8 +237,7 @@ def dump_self_info_and_run_ptf(self, random_sport=False, random_src_ip=False, tolerance=None, - payload=None, - skip_traffic_test=False): # noqa F811 + payload=None): ''' Just a wrapper for dump_info_to_ptf to avoid entering 30 lines everytime. @@ -291,9 +289,6 @@ def dump_self_info_and_run_ptf(self, Logger.info( "dest->nh mapping:%s", self.vxlan_test_setup[encap_type]['dest_to_nh_map']) - if skip_traffic_test is True: - Logger.info("Skipping traffic test.") - return ptf_runner(self.vxlan_test_setup['ptfhost'], "ptftests", "vxlan_traffic.VxLAN_in_VxLAN" if payload == 'vxlan' @@ -411,7 +406,7 @@ def verfiy_bfd_down(self, ep_list): return False return True - def test_tsa_case1(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_tsa_case1(self, setUp, encap_type): ''' tc1: This test checks the basic TSA removal of BFD sessions. 1) Create Vnet route with 4 endpoints and BFD monitors. @@ -428,7 +423,7 @@ def test_tsa_case1(self, setUp, encap_type, skip_traffic_test): # noqa F811 dest, ep_list = self.create_vnet_route(encap_type) - self.dump_self_info_and_run_ptf("test1", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test1", encap_type, True, []) self.apply_tsa() pytest_assert(self.in_maintainence()) @@ -437,11 +432,11 @@ def test_tsa_case1(self, setUp, encap_type, skip_traffic_test): # noqa F811 self.apply_tsb() pytest_assert(not self.in_maintainence()) - self.dump_self_info_and_run_ptf("test1b", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test1b", encap_type, True, []) self.delete_vnet_route(encap_type, dest) - def test_tsa_case2(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_tsa_case2(self, setUp, encap_type): ''' tc2: This test checks the basic route application while in TSA. 1) apply TSA. @@ -464,11 +459,11 @@ def test_tsa_case2(self, setUp, encap_type, skip_traffic_test): # noqa F811 self.apply_tsb() pytest_assert(not self.in_maintainence()) - self.dump_self_info_and_run_ptf("test2", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True, []) self.delete_vnet_route(encap_type, dest) - def test_tsa_case3(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_tsa_case3(self, setUp, encap_type): ''' tc3: This test checks for lasting impact of TSA and TSB. 1) apply TSA. @@ -491,11 +486,11 @@ def test_tsa_case3(self, setUp, encap_type, skip_traffic_test): # noqa F811 dest, ep_list = self.create_vnet_route(encap_type) - self.dump_self_info_and_run_ptf("test3", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test3", encap_type, True, []) self.delete_vnet_route(encap_type, dest) - def test_tsa_case4(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_tsa_case4(self, setUp, encap_type): ''' tc4: This test checks basic Vnet route state retention during config reload. 1) Create Vnet route with 4 endpoints and BFD monitors. @@ -514,7 +509,7 @@ def test_tsa_case4(self, setUp, encap_type, skip_traffic_test): # noqa F811 duthost.shell("sudo config save -y", executable="/bin/bash", module_ignore_errors=True) - self.dump_self_info_and_run_ptf("test4", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test4", encap_type, True, []) duthost.shell("sudo config reload -y", executable="/bin/bash", module_ignore_errors=True) @@ -524,11 +519,11 @@ def test_tsa_case4(self, setUp, encap_type, skip_traffic_test): # noqa F811 ecmp_utils.configure_vxlan_switch(duthost, vxlan_port=4789, dutmac=self.vxlan_test_setup['dut_mac']) dest, ep_list = self.create_vnet_route(encap_type) - self.dump_self_info_and_run_ptf("test4b", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test4b", encap_type, True, []) self.delete_vnet_route(encap_type, dest) - def test_tsa_case5(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_tsa_case5(self, setUp, encap_type): ''' tc4: This test checks TSA state retention w.r.t BFD accross config reload. 1) Create Vnet route with 4 endpoints and BFD monitors. @@ -552,7 +547,7 @@ def test_tsa_case5(self, setUp, encap_type, skip_traffic_test): # noqa F811 duthost.shell("sudo config save -y", executable="/bin/bash", module_ignore_errors=True) - self.dump_self_info_and_run_ptf("test5", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test5", encap_type, True, []) self.apply_tsa() pytest_assert(self.in_maintainence()) @@ -569,11 +564,11 @@ def test_tsa_case5(self, setUp, encap_type, skip_traffic_test): # noqa F811 self.apply_tsb() pytest_assert(not self.in_maintainence()) - self.dump_self_info_and_run_ptf("test5b", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test5b", encap_type, True, []) self.delete_vnet_route(encap_type, dest) - def test_tsa_case6(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_tsa_case6(self, setUp, encap_type): ''' tc6: This test checks that the BFD doesnt come up while device is in TSA and remains down accross config reload. @@ -615,6 +610,6 @@ def test_tsa_case6(self, setUp, encap_type, skip_traffic_test): # noqa F811 self.apply_tsb() pytest_assert(not self.in_maintainence()) - self.dump_self_info_and_run_ptf("test6", encap_type, True, [], skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test6", encap_type, True, []) self.delete_vnet_route(encap_type, dest) diff --git a/tests/vxlan/test_vxlan_decap.py b/tests/vxlan/test_vxlan_decap.py index b6761ac25fd..5ba9d2c1237 100644 --- a/tests/vxlan/test_vxlan_decap.py +++ b/tests/vxlan/test_vxlan_decap.py @@ -14,7 +14,6 @@ from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 from tests.common.fixtures.ptfhost_utils import copy_arp_responder_py # noqa F401 from tests.common.fixtures.ptfhost_utils import remove_ip_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.ptf_runner import ptf_runner from tests.common.dualtor.mux_simulator_control import mux_server_url,\ toggle_all_simulator_ports_to_rand_selected_tor_m # noqa F401 @@ -185,7 +184,7 @@ def vxlan_status(setup, request, duthosts, rand_one_dut_hostname): def test_vxlan_decap(setup, vxlan_status, duthosts, rand_one_dut_hostname, tbinfo, - ptfhost, creds, toggle_all_simulator_ports_to_rand_selected_tor_m, skip_traffic_test): # noqa F811 + ptfhost, creds, toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 duthost = duthosts[rand_one_dut_hostname] sonic_admin_alt_password = duthost.host.options['variable_manager'].\ @@ -199,9 +198,6 @@ def test_vxlan_decap(setup, vxlan_status, duthosts, rand_one_dut_hostname, tbinf log_file = "/tmp/vxlan-decap.Vxlan.{}.{}.log".format( scenario, datetime.now().strftime('%Y-%m-%d-%H:%M:%S')) - if skip_traffic_test is True: - logger.info("Skip traffic test") - return ptf_runner(ptfhost, "ptftests", "vxlan-decap.Vxlan", diff --git a/tests/vxlan/test_vxlan_ecmp.py b/tests/vxlan/test_vxlan_ecmp.py index 028e856fa2f..a9a419065ac 100644 --- a/tests/vxlan/test_vxlan_ecmp.py +++ b/tests/vxlan/test_vxlan_ecmp.py @@ -60,7 +60,6 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.utilities import wait_until from tests.ptf_runner import ptf_runner from tests.common.vxlan_ecmp_utils import Ecmp_Utils @@ -394,8 +393,7 @@ def dump_self_info_and_run_ptf(self, random_sport=False, random_src_ip=False, tolerance=None, - payload=None, - skip_traffic_test=False): # noqa F811 + payload=None): ''' Just a wrapper for dump_info_to_ptf to avoid entering 30 lines everytime. @@ -450,9 +448,6 @@ def dump_self_info_and_run_ptf(self, Logger.info( "dest->nh mapping:%s", self.vxlan_test_setup[encap_type]['dest_to_nh_map']) - if skip_traffic_test is True: - Logger.info("Skipping traffic test.") - return ptf_runner(self.vxlan_test_setup['ptfhost'], "ptftests", "vxlan_traffic.VxLAN_in_VxLAN" if payload == 'vxlan' @@ -510,18 +505,16 @@ class Test_VxLAN_route_tests(Test_VxLAN): Common class for the basic route test cases. ''' - def test_vxlan_single_endpoint(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_single_endpoint(self, setUp, encap_type): ''' tc1:Create a tunnel route to a single endpoint a. Send packets to the route prefix dst. ''' self.vxlan_test_setup = setUp - self.dump_self_info_and_run_ptf("tc1", encap_type, True, skip_traffic_test=skip_traffic_test) - self.dump_self_info_and_run_ptf("tc1", encap_type, True, - payload="vxlan", skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc1", encap_type, True) + self.dump_self_info_and_run_ptf("tc1", encap_type, True, payload="vxlan") - def test_vxlan_modify_route_different_endpoint( - self, setUp, request, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_modify_route_different_endpoint(self, setUp, request, encap_type): ''' tc2: change the route to different endpoint. Packets are received only at endpoint b.") @@ -571,9 +564,9 @@ def test_vxlan_modify_route_different_endpoint( Logger.info( "Copy the new set of configs to the PTF and run the tests.") - self.dump_self_info_and_run_ptf("tc2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc2", encap_type, True) - def test_vxlan_remove_all_route(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_remove_all_route(self, setUp, encap_type): ''' tc3: remove the tunnel route. Send packets to the route prefix dst. packets should not @@ -588,7 +581,7 @@ def test_vxlan_remove_all_route(self, setUp, encap_type, skip_traffic_test): ecmp_utils.get_payload_version(encap_type), "DEL") Logger.info("Verify that the traffic is not coming back.") - self.dump_self_info_and_run_ptf("tc3", encap_type, False, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc3", encap_type, False) finally: Logger.info("Restore the routes in the DUT.") ecmp_utils.set_routes_in_dut( @@ -605,7 +598,7 @@ class Test_VxLAN_ecmp_create(Test_VxLAN): create testcases. ''' - def test_vxlan_configure_route1_ecmp_group_a(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_configure_route1_ecmp_group_a(self, setUp, encap_type): ''' tc4:create tunnel route 1 with two endpoints a = {a1, a2...}. send packets to the route 1's prefix dst. packets are received at either @@ -646,12 +639,12 @@ def test_vxlan_configure_route1_ecmp_group_a(self, setUp, encap_type, skip_traff Logger.info("Verify that the new config takes effect and run traffic.") - self.dump_self_info_and_run_ptf("tc4", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc4", encap_type, True) # Add vxlan payload testing as well. self.dump_self_info_and_run_ptf("tc4", encap_type, True, - payload="vxlan", skip_traffic_test=skip_traffic_test) + payload="vxlan") - def test_vxlan_remove_ecmp_route1(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_remove_ecmp_route1(self, setUp, encap_type): ''' Remove tunnel route 1. Send multiple packets (varying tuple) to the route 1's prefix dst. @@ -695,7 +688,7 @@ def test_vxlan_remove_ecmp_route1(self, setUp, encap_type, skip_traffic_test): ecmp_route1_end_point_list) Logger.info("Verify that the new config takes effect and run traffic.") - self.dump_self_info_and_run_ptf("tc5", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc5", encap_type, True) # Deleting Tunnel route 1 ecmp_utils.create_and_apply_config( @@ -710,13 +703,13 @@ def test_vxlan_remove_ecmp_route1(self, setUp, encap_type, skip_traffic_test): {ecmp_route1_new_dest: ecmp_route1_end_point_list} Logger.info("Verify that the new config takes effect and run traffic.") - self.dump_self_info_and_run_ptf("tc5", encap_type, False, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc5", encap_type, False) # Restoring dest_to_nh_map to old values self.vxlan_test_setup[encap_type]['dest_to_nh_map'][vnet] = copy.deepcopy(backup_dest) - self.dump_self_info_and_run_ptf("tc5", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc5", encap_type, True) - def test_vxlan_configure_route1_ecmp_group_b(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_configure_route1_ecmp_group_b(self, setUp, encap_type): ''' tc5: set tunnel route 2 to endpoint group a = {a1, a2}. send packets to route 2"s prefix dst. packets are received at either a1 @@ -725,7 +718,7 @@ def test_vxlan_configure_route1_ecmp_group_b(self, setUp, encap_type, skip_traff self.vxlan_test_setup = setUp self.setup_route2_ecmp_group_b(encap_type) Logger.info("Verify the configs work and traffic flows correctly.") - self.dump_self_info_and_run_ptf("tc5", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc5", encap_type, True) def setup_route2_ecmp_group_b(self, encap_type): ''' @@ -767,7 +760,7 @@ def setup_route2_ecmp_group_b(self, encap_type): self.vxlan_test_setup[encap_type]['tc5_dest'] = tc5_new_dest - def test_vxlan_configure_route2_ecmp_group_b(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_configure_route2_ecmp_group_b(self, setUp, encap_type): ''' tc6: set tunnel route 2 to endpoint group b = {b1, b2}. send packets to route 2"s prefix dst. packets are received at either @@ -809,13 +802,12 @@ def test_vxlan_configure_route2_ecmp_group_b(self, setUp, encap_type, skip_traff tc6_end_point_list) Logger.info("Verify that the traffic works.") - self.dump_self_info_and_run_ptf("tc6", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc6", encap_type, True) @pytest.mark.skipif( "config.option.bfd is False", reason="This test will be run only if '--bfd=True' is provided.") - def test_vxlan_bfd_health_state_change_a2down_a1up( - self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_bfd_health_state_change_a2down_a1up(self, setUp, encap_type): ''' Set BFD state for a1' to UP and a2' to Down. Send multiple packets (varying tuple) to the route 1's prefix dst. Packets are received @@ -863,12 +855,12 @@ def test_vxlan_bfd_health_state_change_a2down_a1up( end_point_list[1]) Logger.info("Verify that the new config takes effect and run traffic.") - self.dump_self_info_and_run_ptf("tc_a2down_a1up", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc_a2down_a1up", encap_type, True) @pytest.mark.skipif( "config.option.bfd is False", reason="This test will be run only if '--bfd=True' is provided.") - def test_vxlan_bfd_health_state_change_a1a2_down(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_bfd_health_state_change_a1a2_down(self, setUp, encap_type): ''' Set BFD state for a1' to Down and a2' to Down. Send multiple packets (varying tuple) to the route 1's prefix dst. Packets @@ -915,14 +907,13 @@ def test_vxlan_bfd_health_state_change_a1a2_down(self, setUp, encap_type, skip_t "a1a2_down", encap_type, True, - packet_count=4, - skip_traffic_test=skip_traffic_test) + packet_count=4) @pytest.mark.skipif( "config.option.bfd is False", reason="This test will be run only if '--bfd=True' is provided.") def test_vxlan_bfd_health_state_change_a2up_a1down( - self, setUp, encap_type, skip_traffic_test): # noqa F811 + self, setUp, encap_type): ''' Set BFD state for a2' to UP. Send packets to the route 1's prefix dst. Packets are received only at endpoint a2. Verify advertise @@ -970,9 +961,9 @@ def test_vxlan_bfd_health_state_change_a2up_a1down( end_point_list[0]) Logger.info("Verify that the new config takes effect and run traffic.") - self.dump_self_info_and_run_ptf("a2up_a1down", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("a2up_a1down", encap_type, True) - def test_vxlan_bfd_health_state_change_a1a2_up(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_bfd_health_state_change_a1a2_up(self, setUp, encap_type): ''' Set BFD state for a1' & a2' to UP. Send multiple packets (varying tuple) to the route 1's prefix dst. Packets are received at both @@ -1015,7 +1006,7 @@ def test_vxlan_bfd_health_state_change_a1a2_up(self, setUp, encap_type, skip_tra Logger.info("Verify that the new config takes effect and run traffic.") - self.dump_self_info_and_run_ptf("tc4", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc4", encap_type, True) # perform cleanup by removing all the routes added by this test class. # reset to add only the routes added in the setup phase. @@ -1206,7 +1197,7 @@ def setup_route2_shared_different_endpoints(self, encap_type): encap_type, tc9_new_nhs) - def test_vxlan_remove_route2(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_remove_route2(self, setUp, encap_type): ''' tc7:send packets to route 1's prefix dst. by removing route 2 from group a, no change expected to route 1. @@ -1252,7 +1243,7 @@ def test_vxlan_remove_route2(self, setUp, encap_type, skip_traffic_test): encap_type, tc7_end_point_list) Logger.info("Verify the setup works.") - self.dump_self_info_and_run_ptf("tc7", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc7", encap_type, True) Logger.info("End of setup.") Logger.info("Remove one of the routes.") @@ -1272,7 +1263,7 @@ def test_vxlan_remove_route2(self, setUp, encap_type, skip_traffic_test): "DEL") Logger.info("Verify the rest of the traffic still works.") - self.dump_self_info_and_run_ptf("tc7", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc7", encap_type, True) # perform cleanup by removing all the routes added by this test class. # reset to add only the routes added in the setup phase. @@ -1289,18 +1280,18 @@ def test_vxlan_remove_route2(self, setUp, encap_type, skip_traffic_test): ecmp_utils.get_payload_version(encap_type), "SET") - def test_vxlan_route2_single_nh(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_route2_single_nh(self, setUp, encap_type): ''' tc8: set tunnel route 2 to single endpoint b1. Send packets to route 2's prefix dst. ''' self.vxlan_test_setup = setUp self.setup_route2_single_endpoint(encap_type) - self.dump_self_info_and_run_ptf("tc8", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc8", encap_type, True) self.dump_self_info_and_run_ptf("tc8", encap_type, True, - payload="vxlan", skip_traffic_test=skip_traffic_test) + payload="vxlan") - def test_vxlan_route2_shared_nh(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_route2_shared_nh(self, setUp, encap_type): ''' tc9: set tunnel route 2 to shared endpoints a1 and b1. Send packets to route 2's @@ -1308,9 +1299,9 @@ def test_vxlan_route2_shared_nh(self, setUp, encap_type, skip_traffic_test): ''' self.vxlan_test_setup = setUp self.setup_route2_shared_endpoints(encap_type) - self.dump_self_info_and_run_ptf("tc9", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc9", encap_type, True) - def test_vxlan_route2_shared_different_nh(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_route2_shared_different_nh(self, setUp, encap_type): ''' tc9.2: set tunnel route 2 to 2 completely different shared(no-reuse) endpoints a1 and b1. send packets @@ -1318,9 +1309,9 @@ def test_vxlan_route2_shared_different_nh(self, setUp, encap_type, skip_traffic_ ''' self.vxlan_test_setup = setUp self.setup_route2_shared_different_endpoints(encap_type) - self.dump_self_info_and_run_ptf("tc9.2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc9.2", encap_type, True) - def test_vxlan_remove_ecmp_route2(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_remove_ecmp_route2(self, setUp, encap_type): ''' tc10: remove tunnel route 2. send packets to route 2's prefix dst. ''' @@ -1369,7 +1360,7 @@ def test_vxlan_remove_ecmp_route2(self, setUp, encap_type, skip_traffic_test): tc10_nhs Logger.info("The deleted route should fail to receive traffic.") - self.dump_self_info_and_run_ptf("tc10", encap_type, False, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc10", encap_type, False) # all others should be working. # Housekeeping: @@ -1380,7 +1371,7 @@ def test_vxlan_remove_ecmp_route2(self, setUp, encap_type, skip_traffic_test): del_needed = False Logger.info("Check the traffic is working in the other routes.") - self.dump_self_info_and_run_ptf("tc10", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc10", encap_type, True) except BaseException: self.vxlan_test_setup[encap_type]['dest_to_nh_map'][vnet] = full_map.copy() @@ -1399,7 +1390,7 @@ class Test_VxLAN_ecmp_random_hash(Test_VxLAN): Class for testing different tcp ports for payload. ''' - def test_vxlan_random_hash(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_random_hash(self, setUp, encap_type): ''' tc11: set tunnel route 3 to endpoint group c = {c1, c2, c3}. Ensure c1, c2, and c3 matches to underlay default route. @@ -1448,8 +1439,7 @@ def test_vxlan_random_hash(self, setUp, encap_type, skip_traffic_test): # no "tc11", encap_type, True, - packet_count=1000, - skip_traffic_test=skip_traffic_test) + packet_count=1000) @pytest.mark.skipif( @@ -1461,8 +1451,7 @@ class Test_VxLAN_underlay_ecmp(Test_VxLAN): Class for all test cases that modify the underlay default route. ''' @pytest.mark.parametrize("ecmp_path_count", [1, 2]) - def test_vxlan_modify_underlay_default( - self, setUp, minigraph_facts, encap_type, ecmp_path_count, skip_traffic_test): # noqa F811 + def test_vxlan_modify_underlay_default(self, setUp, minigraph_facts, encap_type, ecmp_path_count): ''' tc12: modify the underlay default route nexthop/s. send packets to route 3's prefix dst. @@ -1534,8 +1523,7 @@ def test_vxlan_modify_underlay_default( "tc12", encap_type, True, - packet_count=1000, - skip_traffic_test=skip_traffic_test) + packet_count=1000) Logger.info( "Reverse the action: bring up the selected_intfs" @@ -1582,8 +1570,7 @@ def test_vxlan_modify_underlay_default( "tc12", encap_type, True, - packet_count=1000, - skip_traffic_test=skip_traffic_test) + packet_count=1000) Logger.info("Recovery. Bring all up, and verify traffic works.") for intf in all_t2_intfs: @@ -1611,8 +1598,7 @@ def test_vxlan_modify_underlay_default( "tc12", encap_type, True, - packet_count=1000, - skip_traffic_test=skip_traffic_test) + packet_count=1000) except Exception: # If anything goes wrong in the try block, atleast bring the intf @@ -1640,8 +1626,7 @@ def test_vxlan_modify_underlay_default( def test_vxlan_remove_add_underlay_default(self, setUp, minigraph_facts, - encap_type, - skip_traffic_test): # noqa F811 + encap_type): ''' tc13: remove the underlay default route. tc14: add the underlay default route. @@ -1682,7 +1667,7 @@ def test_vxlan_remove_add_underlay_default(self, "BGP neighbors have not reached the required state after " "T2 intf are shutdown.") Logger.info("Verify that traffic is not flowing through.") - self.dump_self_info_and_run_ptf("tc13", encap_type, False, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc13", encap_type, False) # tc14: Re-add the underlay default route. Logger.info("Bring up the T2 interfaces.") @@ -1704,8 +1689,7 @@ def test_vxlan_remove_add_underlay_default(self, "tc14", encap_type, True, - packet_count=1000, - skip_traffic_test=skip_traffic_test) + packet_count=1000) except Exception: Logger.info( "If anything goes wrong in the try block," @@ -1724,7 +1708,7 @@ def test_vxlan_remove_add_underlay_default(self, " interfaces have been brought up.") raise - def test_underlay_specific_route(self, setUp, minigraph_facts, encap_type, skip_traffic_test): # noqa F811 + def test_underlay_specific_route(self, setUp, minigraph_facts, encap_type): ''' Create a more specific underlay route to c1. Verify c1 packets are received only on the c1's nexthop interface @@ -1795,8 +1779,7 @@ def test_underlay_specific_route(self, setUp, minigraph_facts, encap_type, skip_ self.dump_self_info_and_run_ptf( "underlay_specific_route", encap_type, - True, - skip_traffic_test=skip_traffic_test) + True) # Deletion of all static routes gateway = all_t2_neighbors[t2_neighbor][outer_layer_version].lower() for _, nexthops in list(endpoint_nhmap.items()): @@ -1844,14 +1827,12 @@ def test_underlay_specific_route(self, setUp, minigraph_facts, encap_type, skip_ self.dump_self_info_and_run_ptf( "underlay_specific_route", encap_type, - True, - skip_traffic_test=skip_traffic_test) + True) def test_underlay_portchannel_shutdown(self, setUp, minigraph_facts, - encap_type, - skip_traffic_test): # noqa F811 + encap_type): ''' Bring down one of the port-channels. Packets are equally recieved at c1, c2 or c3 @@ -1859,7 +1840,7 @@ def test_underlay_portchannel_shutdown(self, self.vxlan_test_setup = setUp # Verification of traffic before shutting down port channel - self.dump_self_info_and_run_ptf("tc12", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc12", encap_type, True) # Gathering all portchannels all_t2_portchannel_intfs = \ @@ -1894,7 +1875,7 @@ def test_underlay_portchannel_shutdown(self, self.vxlan_test_setup[encap_type]['t2_ports'], list(self.vxlan_test_setup['list_of_bfd_monitors'])) time.sleep(10) - self.dump_self_info_and_run_ptf("tc12", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc12", encap_type, True) for intf in all_t2_portchannel_members[selected_portchannel]: self.vxlan_test_setup['duthost'].shell( @@ -1906,7 +1887,7 @@ def test_underlay_portchannel_shutdown(self, self.vxlan_test_setup[encap_type]['t2_ports'], list(self.vxlan_test_setup['list_of_bfd_monitors'])) time.sleep(10) - self.dump_self_info_and_run_ptf("tc12", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("tc12", encap_type, True) except BaseException: for intf in all_t2_portchannel_members[selected_portchannel]: self.vxlan_test_setup['duthost'].shell( @@ -1936,8 +1917,7 @@ def verify_entropy( random_sport=False, random_dport=True, random_src_ip=False, - tolerance=None, - skip_traffic_test=False): # noqa F811 + tolerance=None): ''' Function to be reused by the entropy testcases. Sets up a couple of endpoints on the top of the existing ones, and performs the traffic @@ -1981,10 +1961,9 @@ def verify_entropy( random_dport=random_dport, random_src_ip=random_src_ip, packet_count=1000, - tolerance=tolerance, - skip_traffic_test=skip_traffic_test) + tolerance=tolerance) - def test_verify_entropy(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_verify_entropy(self, setUp, encap_type): ''' Verification of entropy - Create tunnel route 4 to endpoint group A. Send packets (fixed tuple) to route 4's prefix dst @@ -1995,10 +1974,9 @@ def test_verify_entropy(self, setUp, encap_type, skip_traffic_test): random_dport=True, random_sport=True, random_src_ip=True, - tolerance=0.75, # More tolerance since this varies entropy a lot. - skip_traffic_test=skip_traffic_test) + tolerance=0.75) # More tolerance since this varies entropy a lot. - def test_vxlan_random_dst_port(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_random_dst_port(self, setUp, encap_type): ''' Verification of entropy - Change the udp dst port of original packet to route 4's prefix dst @@ -2006,7 +1984,7 @@ def test_vxlan_random_dst_port(self, setUp, encap_type, skip_traffic_test): self.vxlan_test_setup = setUp self.verify_entropy(encap_type, tolerance=0.03) - def test_vxlan_random_src_port(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_random_src_port(self, setUp, encap_type): ''' Verification of entropy - Change the udp src port of original packet to route 4's prefix dst @@ -2016,10 +1994,9 @@ def test_vxlan_random_src_port(self, setUp, encap_type, skip_traffic_test): encap_type, random_dport=False, random_sport=True, - tolerance=0.03, - skip_traffic_test=skip_traffic_test) + tolerance=0.03) - def test_vxlan_varying_src_ip(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_varying_src_ip(self, setUp, encap_type): ''' Verification of entropy - Change the udp src ip of original packet to route 4's prefix dst @@ -2029,5 +2006,4 @@ def test_vxlan_varying_src_ip(self, setUp, encap_type, skip_traffic_test): encap_type, random_dport=False, random_src_ip=True, - tolerance=0.03, - skip_traffic_test=skip_traffic_test) + tolerance=0.03) diff --git a/tests/vxlan/test_vxlan_ecmp_switchover.py b/tests/vxlan/test_vxlan_ecmp_switchover.py index 200f9f3548d..32a13cadf83 100644 --- a/tests/vxlan/test_vxlan_ecmp_switchover.py +++ b/tests/vxlan/test_vxlan_ecmp_switchover.py @@ -11,7 +11,6 @@ import pytest from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.ptf_runner import ptf_runner from tests.common.vxlan_ecmp_utils import Ecmp_Utils @@ -222,8 +221,7 @@ def dump_self_info_and_run_ptf(self, random_sport=False, random_src_ip=False, tolerance=None, - payload=None, - skip_traffic_test=False): # noqa F811 + payload=None): ''' Just a wrapper for dump_info_to_ptf to avoid entering 30 lines everytime. @@ -276,9 +274,6 @@ def dump_self_info_and_run_ptf(self, Logger.info( "dest->nh mapping:%s", self.vxlan_test_setup[encap_type]['dest_to_nh_map']) - if skip_traffic_test is True: - Logger.info("Skipping traffic test.") - return ptf_runner(self.vxlan_test_setup['ptfhost'], "ptftests", "vxlan_traffic.VxLAN_in_VxLAN" if payload == 'vxlan' @@ -292,7 +287,7 @@ def dump_self_info_and_run_ptf(self, datetime.now().strftime('%Y-%m-%d-%H:%M:%S')), is_python3=True) - def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type): ''' tc1:create tunnel route 1 with two endpoints a = {a1, b1}. a1 is primary, b1 is secondary. 1) both a1,b1 are UP. @@ -369,7 +364,7 @@ def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type, skip_ ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)])) assert str(result['stdout']) == ecmp_utils.OVERLAY_DMAC - self.dump_self_info_and_run_ptf("test1", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test1", encap_type, True) # Single primary-secondary switchover. # Endpoint list = [A, A`], Primary[A] | Active NH=[A] | @@ -387,7 +382,7 @@ def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type, skip_ ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], tc1_end_point_list[0], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test1", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test1", encap_type, True) # Single primary recovery. # Endpoint list = [A, A`], Primary[A] | Active NH=[A`] | @@ -405,7 +400,7 @@ def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type, skip_ ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], tc1_end_point_list[0], "up") time.sleep(10) - self.dump_self_info_and_run_ptf("test1", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test1", encap_type, True) # Single primary backup Failure. # Endpoint list = [A, A`]. Primary[A]| Active NH=[A`] A is DOWN | @@ -427,7 +422,7 @@ def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type, skip_ tc1_end_point_list[0], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test1", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test1", encap_type, True) ecmp_utils.create_and_apply_priority_config( self.vxlan_test_setup['duthost'], vnet, @@ -447,7 +442,7 @@ def test_vxlan_priority_single_pri_sec_switchover(self, setUp, encap_type, skip_ [tc1_end_point_list[0]], "DEL") - def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_traffic_test): # noqa F811 + def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type): ''' tc2:create tunnel route 1 with 6 endpoints a = {A, B, A`, B`}. A,B are primary, A`,B` are secondary. @@ -545,7 +540,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t self.vxlan_test_setup['list_of_downed_endpoints'] = set(inactive_list) time.sleep(10) # ensure that the traffic is distributed to all 3 primary Endpoints. - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Single primary failure. # Endpoint list = [A, B, A`, B`], Primary = [A, B] | active NH = [A, B] | @@ -563,7 +558,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], primary_nhg[0], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. All primary failure. # Endpoint list = [A, B, A`, B`] Primary = [A, B] | A is Down. active NH = [B] | @@ -580,7 +575,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], primary_nhg[1], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Backup Failure. # Endpoint list = [A, B, A`, B`] Primary = [A, B] | @@ -599,7 +594,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], secondary_nhg[1], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Single primary recovery. # Endpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [A`] | @@ -617,7 +612,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], primary_nhg[0], "up") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Multiple primary & backup recovery. # Edpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [A] | @@ -639,7 +634,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t secondary_nhg[1], "up") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Multiple primary & backup all failure. # Edpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [A,B] | @@ -668,7 +663,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], secondary_nhg[1], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Multiple primary & backup recovery. # Edpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [] | @@ -698,7 +693,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t secondary_nhg[1], "up") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Multiple primary & backup all failure 2. # Edpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [A,B] | @@ -727,7 +722,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t ecmp_utils.HOST_MASK[ecmp_utils.get_payload_version(encap_type)], secondary_nhg[1], "down") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Multiple primary & backup recovery of secondary. # Edpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [] | @@ -749,7 +744,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t secondary_nhg[1], "up") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) # Multiple primary backups. Multiple primary & backup recovery of primary after secondary. # Edpoint list = [A, B, A`, B`] Primary = [A, B] | Active NH = [A`, B`] | @@ -771,7 +766,7 @@ def test_vxlan_priority_multi_pri_sec_switchover(self, setUp, encap_type, skip_t primary_nhg[1], "up") time.sleep(10) - self.dump_self_info_and_run_ptf("test2", encap_type, True, skip_traffic_test=skip_traffic_test) + self.dump_self_info_and_run_ptf("test2", encap_type, True) ecmp_utils.create_and_apply_priority_config( self.vxlan_test_setup['duthost'], vnet, From 757b86cad04c5cc063fd7676e247129447de9514 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:13:31 +0800 Subject: [PATCH 118/221] Remove skip_traffic_test fixture in vlan tests (#15458) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in vlan tests How did you verify/test it? --- tests/vlan/test_vlan_ping.py | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/tests/vlan/test_vlan_ping.py b/tests/vlan/test_vlan_ping.py index b2141646673..fd19021c88f 100644 --- a/tests/vlan/test_vlan_ping.py +++ b/tests/vlan/test_vlan_ping.py @@ -10,7 +10,6 @@ from tests.common.helpers.assertions import pytest_assert as py_assert from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor_m # noqa F401 from tests.common.dualtor.dual_tor_utils import lower_tor_host # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 logger = logging.getLogger(__name__) @@ -180,10 +179,7 @@ def vlan_ping_setup(duthosts, rand_one_dut_hostname, ptfhost, nbrhosts, tbinfo, def verify_icmp_packet(dut_mac, src_port, dst_port, ptfadapter, tbinfo, - vlan_mac=None, dtor_ul=False, dtor_dl=False, skip_traffic_test=False): # noqa F811 - if skip_traffic_test is True: - logger.info("Skipping traffic test") - return + vlan_mac=None, dtor_ul=False, dtor_dl=False): if dtor_ul is True: # use vlan int mac in case of dualtor UL test pkt pkt = testutils.simple_icmp_packet(eth_src=str(src_port['mac']), @@ -224,7 +220,7 @@ def verify_icmp_packet(dut_mac, src_port, dst_port, ptfadapter, tbinfo, def test_vlan_ping(vlan_ping_setup, duthosts, rand_one_dut_hostname, ptfadapter, tbinfo, - toggle_all_simulator_ports_to_rand_selected_tor_m, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 """ test for checking connectivity of statically added ipv4 and ipv6 arp entries """ @@ -252,16 +248,12 @@ def test_vlan_ping(vlan_ping_setup, duthosts, rand_one_dut_hostname, ptfadapter, for member in ptfhost_info: if 'dualtor' in tbinfo["topo"]["name"]: verify_icmp_packet(duthost.facts['router_mac'], ptfhost_info[member], - vmhost_info, ptfadapter, tbinfo, vlan_mac, dtor_ul=True, - skip_traffic_test=skip_traffic_test) + vmhost_info, ptfadapter, tbinfo, vlan_mac, dtor_ul=True) verify_icmp_packet(duthost.facts['router_mac'], vmhost_info, ptfhost_info[member], - ptfadapter, tbinfo, vlan_mac, dtor_dl=True, - skip_traffic_test=skip_traffic_test) + ptfadapter, tbinfo, vlan_mac, dtor_dl=True) else: - verify_icmp_packet(duthost.facts['router_mac'], ptfhost_info[member], vmhost_info, ptfadapter, tbinfo, - skip_traffic_test=skip_traffic_test) - verify_icmp_packet(duthost.facts['router_mac'], vmhost_info, ptfhost_info[member], ptfadapter, tbinfo, - skip_traffic_test=skip_traffic_test) + verify_icmp_packet(duthost.facts['router_mac'], ptfhost_info[member], vmhost_info, ptfadapter, tbinfo) + verify_icmp_packet(duthost.facts['router_mac'], vmhost_info, ptfhost_info[member], ptfadapter, tbinfo) # flushing and re-adding ipv6 static arp entry static_neighbor_entry(duthost, ptfhost_info, "del", "6") @@ -280,13 +272,9 @@ def test_vlan_ping(vlan_ping_setup, duthosts, rand_one_dut_hostname, ptfadapter, for member in ptfhost_info: if 'dualtor' in tbinfo["topo"]["name"]: verify_icmp_packet(duthost.facts['router_mac'], ptfhost_info[member], - vmhost_info, ptfadapter, tbinfo, vlan_mac, dtor_ul=True, - skip_traffic_test=skip_traffic_test) + vmhost_info, ptfadapter, tbinfo, vlan_mac, dtor_ul=True) verify_icmp_packet(duthost.facts['router_mac'], vmhost_info, ptfhost_info[member], - ptfadapter, tbinfo, vlan_mac, dtor_dl=True, - skip_traffic_test=skip_traffic_test) + ptfadapter, tbinfo, vlan_mac, dtor_dl=True) else: - verify_icmp_packet(duthost.facts['router_mac'], ptfhost_info[member], vmhost_info, ptfadapter, tbinfo, - skip_traffic_test=skip_traffic_test) - verify_icmp_packet(duthost.facts['router_mac'], vmhost_info, ptfhost_info[member], ptfadapter, tbinfo, - skip_traffic_test=skip_traffic_test) + verify_icmp_packet(duthost.facts['router_mac'], ptfhost_info[member], vmhost_info, ptfadapter, tbinfo) + verify_icmp_packet(duthost.facts['router_mac'], vmhost_info, ptfhost_info[member], ptfadapter, tbinfo) From ef01e7524743ad4108715db11fa4b7d7704c30a5 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:35:44 +0800 Subject: [PATCH 119/221] Remove skip_traffic_test fixture in span tests (#15456) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in span tests How did you verify/test it? --- tests/span/span_helpers.py | 4 +--- tests/span/test_port_mirroring.py | 27 ++++++++++----------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/tests/span/span_helpers.py b/tests/span/span_helpers.py index 28dc2f351b7..a85c2b8d309 100644 --- a/tests/span/span_helpers.py +++ b/tests/span/span_helpers.py @@ -5,7 +5,7 @@ import ptf.testutils as testutils -def send_and_verify_mirrored_packet(ptfadapter, src_port, monitor, skip_traffic_test=False): +def send_and_verify_mirrored_packet(ptfadapter, src_port, monitor): ''' Send packet from ptf and verify it on monitor port @@ -18,8 +18,6 @@ def send_and_verify_mirrored_packet(ptfadapter, src_port, monitor, skip_traffic_ pkt = testutils.simple_icmp_packet(eth_src=src_mac, eth_dst='ff:ff:ff:ff:ff:ff') - if skip_traffic_test is True: - return ptfadapter.dataplane.flush() testutils.send(ptfadapter, src_port, pkt) testutils.verify_packet(ptfadapter, pkt, monitor) diff --git a/tests/span/test_port_mirroring.py b/tests/span/test_port_mirroring.py index 646f699264a..145395b8e7f 100644 --- a/tests/span/test_port_mirroring.py +++ b/tests/span/test_port_mirroring.py @@ -5,7 +5,6 @@ import pytest from tests.common.fixtures.ptfhost_utils import change_mac_addresses # noqa F401 -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from span_helpers import send_and_verify_mirrored_packet pytestmark = [ @@ -13,7 +12,7 @@ ] -def test_mirroring_rx(ptfadapter, setup_session, skip_traffic_test): # noqa F811 +def test_mirroring_rx(ptfadapter, setup_session): ''' Test case #1 Verify ingress direction session @@ -27,11 +26,10 @@ def test_mirroring_rx(ptfadapter, setup_session, skip_traffic_test): # noqa F ''' send_and_verify_mirrored_packet(ptfadapter, setup_session['source1_index'], - setup_session['destination_index'], - skip_traffic_test=skip_traffic_test) + setup_session['destination_index']) -def test_mirroring_tx(ptfadapter, setup_session, skip_traffic_test): # noqa F811 +def test_mirroring_tx(ptfadapter, setup_session): ''' Test case #2 Verify egress direction session @@ -45,11 +43,10 @@ def test_mirroring_tx(ptfadapter, setup_session, skip_traffic_test): # noqa F ''' send_and_verify_mirrored_packet(ptfadapter, setup_session['source2_index'], - setup_session['destination_index'], - skip_traffic_test=skip_traffic_test) + setup_session['destination_index']) -def test_mirroring_both(ptfadapter, setup_session, skip_traffic_test): # noqa F811 +def test_mirroring_both(ptfadapter, setup_session): ''' Test case #3 Verify bidirectional session @@ -66,16 +63,14 @@ def test_mirroring_both(ptfadapter, setup_session, skip_traffic_test): # noqa ''' send_and_verify_mirrored_packet(ptfadapter, setup_session['source1_index'], - setup_session['destination_index'], - skip_traffic_test=skip_traffic_test) + setup_session['destination_index']) send_and_verify_mirrored_packet(ptfadapter, setup_session['source2_index'], - setup_session['destination_index'], - skip_traffic_test=skip_traffic_test) + setup_session['destination_index']) -def test_mirroring_multiple_source(ptfadapter, setup_session, skip_traffic_test): # noqa F811 +def test_mirroring_multiple_source(ptfadapter, setup_session): ''' Test case #4 Verify ingress direction session with multiple source ports @@ -92,10 +87,8 @@ def test_mirroring_multiple_source(ptfadapter, setup_session, skip_traffic_test) ''' send_and_verify_mirrored_packet(ptfadapter, setup_session['source1_index'], - setup_session['destination_index'], - skip_traffic_test=skip_traffic_test) + setup_session['destination_index']) send_and_verify_mirrored_packet(ptfadapter, setup_session['source2_index'], - setup_session['destination_index'], - skip_traffic_test=skip_traffic_test) + setup_session['destination_index']) From 0e320fe12c0a4b920404987890692b8a3646d926 Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Fri, 8 Nov 2024 20:40:27 +1100 Subject: [PATCH 120/221] feat: fix pfc_storm flaky (#15418) Description of PR Summary: Fixes # (issue) 301125860 Approach What is the motivation for this PR? pfc_gen_t2 is written and using python3 library format. In some switches the default python is not linked to python3 and still refers to python2.7 which leads to unexpected result. How did you do it? Explicitly specify to use python3 co-authorized by: jianquanye@microsoft.com --- tests/common/templates/pfc_storm_sonic_t2.j2 | 4 ++-- tests/common/templates/pfc_storm_stop_sonic_t2.j2 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/common/templates/pfc_storm_sonic_t2.j2 b/tests/common/templates/pfc_storm_sonic_t2.j2 index fb6945ee2dc..7881a510804 100644 --- a/tests/common/templates/pfc_storm_sonic_t2.j2 +++ b/tests/common/templates/pfc_storm_sonic_t2.j2 @@ -1,6 +1,6 @@ cd {{pfc_gen_dir}} {% if (pfc_asym is defined) and (pfc_asym == True) %} -nohup sh -c "{% if pfc_storm_defer_time is defined %}sleep {{pfc_storm_defer_time}} &&{% endif %} sudo nice --20 python {{pfc_gen_file}} -p {{pfc_queue_index}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}}" > /dev/null 2>&1 & +nohup sh -c "{% if pfc_storm_defer_time is defined %}sleep {{pfc_storm_defer_time}} &&{% endif %} sudo nice --20 python3 {{pfc_gen_file}} -p {{pfc_queue_index}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}}" > /dev/null 2>&1 & {% else %} -nohup sh -c "{% if pfc_storm_defer_time is defined %}sleep {{pfc_storm_defer_time}} &&{% endif %} sudo nice --20 python {{pfc_gen_file}} -p {{(1).__lshift__(pfc_queue_index)}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}} -r {{ansible_eth0_ipv4_addr}}" > /dev/null 2>&1 & +nohup sh -c "{% if pfc_storm_defer_time is defined %}sleep {{pfc_storm_defer_time}} &&{% endif %} sudo nice --20 python3 {{pfc_gen_file}} -p {{(1).__lshift__(pfc_queue_index)}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}} -r {{ansible_eth0_ipv4_addr}}" > /dev/null 2>&1 & {% endif %} diff --git a/tests/common/templates/pfc_storm_stop_sonic_t2.j2 b/tests/common/templates/pfc_storm_stop_sonic_t2.j2 index 1f29691ca5f..597417abb6b 100755 --- a/tests/common/templates/pfc_storm_stop_sonic_t2.j2 +++ b/tests/common/templates/pfc_storm_stop_sonic_t2.j2 @@ -1,6 +1,6 @@ cd {{pfc_gen_dir}} {% if (pfc_asym is defined) and (pfc_asym == True) %} -nohup sh -c "{% if pfc_storm_stop_defer_time is defined %}sleep {{pfc_storm_stop_defer_time}} &&{% endif %} sudo pkill -f 'python {{pfc_gen_file}} -p {{pfc_queue_index}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}}'" > /dev/null 2>&1 & +nohup sh -c "{% if pfc_storm_stop_defer_time is defined %}sleep {{pfc_storm_stop_defer_time}} &&{% endif %} sudo pkill -f 'python3 {{pfc_gen_file}} -p {{pfc_queue_index}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}}'" > /dev/null 2>&1 & {% else %} -nohup sh -c "{% if pfc_storm_stop_defer_time is defined %}sleep {{pfc_storm_stop_defer_time}} &&{% endif %} sudo pkill -f 'python {{pfc_gen_file}} -p {{(1).__lshift__(pfc_queue_index)}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}} -r {{ansible_eth0_ipv4_addr}}'" > /dev/null 2>&1 & +nohup sh -c "{% if pfc_storm_stop_defer_time is defined %}sleep {{pfc_storm_stop_defer_time}} &&{% endif %} sudo pkill -f 'python3 {{pfc_gen_file}} -p {{(1).__lshift__(pfc_queue_index)}} -t 65535 -s {{pfc_send_period}} -n {{pfc_frames_number}} -i {{pfc_fanout_interface}} -r {{ansible_eth0_ipv4_addr}}'" > /dev/null 2>&1 & {% endif %} From 8901c4b06d0c10f06099a00da62dd8b509ebc430 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Fri, 8 Nov 2024 01:44:01 -0800 Subject: [PATCH 121/221] [T2:multidut]: Change reboot to reboot-fixture in pfcwd_basic. (#15445) Description of PR Summary: As per PR:15099, change test_multidut_pfcwd_basic_with_snappi.py and test_multidut_pfc_pause_lossy_with_snappi.py to use the new fixtures. Approach What is the motivation for this PR? Fix for: "ARP not resolved issue" in reboot cases in pause_lossy, and pfcwd_basic. How did you do it? Moved the reboot logic to the fixture, and calling the fixture in the tests. Removed the repeated code in all tests. How did you verify/test it? Ran it on my T2 TB: ------------------------------------------------------------------------------------------------------------------- live log sessionfinish ------------------------------------------------------------------------------------------------------------------- 06:40:51 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ================================================================================================================== short test summary info =================================================================================================================== PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|0] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|1] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|2] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|5] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|6] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|0] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|1] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|2] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|5] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|6] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_multi_lossy_prio[multidut_port_info0] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_multi_lossy_prio[multidut_port_info1] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info0-cold-yy39top-lc4|0] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info0-cold-yy39top-lc4|1] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info0-cold-yy39top-lc4|2] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info0-cold-yy39top-lc4|5] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info0-cold-yy39top-lc4|6] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info1-cold-yy39top-lc4|0] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info1-cold-yy39top-lc4|1] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info1-cold-yy39top-lc4|2] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info1-cold-yy39top-lc4|5] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio_reboot[multidut_port_info1-cold-yy39top-lc4|6] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_multi_lossy_prio_reboot[multidut_port_info0-cold] PASSED snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_multi_lossy_prio_reboot[multidut_port_info1-cold] SKIPPED [10] snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py:135: Reboot type warm is not supported on cisco-8000 switches SKIPPED [10] snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py:135: Reboot type fast is not supported on cisco-8000 switches SKIPPED [2] snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py:195: Reboot type warm is not supported on cisco-8000 switches SKIPPED [2] snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py:195: Reboot type fast is not supported on cisco-8000 switches ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|0] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|5] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info0-yy39top-lc4|6] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|1] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|2] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_single_lossy_prio[multidut_port_info1-yy39top-lc4|5] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_multi_lossy_prio[multidut_port_info0] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ERROR snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py::test_pfc_pause_multi_lossy_prio[multidut_port_info1] - Failed: Processes "['analyze_logs--']" failed with exit code "1" ============================================================================================ 24 passed, 24 skipped, 28 warnings, 8 errors in 20375.01s (5:39:35) ============================================================================================= sonic@ixia-sonic-mgmt-whitebox:/data/tests$ co-authorized by: jianquanye@microsoft.com --- ...st_multidut_pfc_pause_lossy_with_snappi.py | 195 +++--------- .../test_multidut_pfcwd_basic_with_snappi.py | 299 ++++-------------- 2 files changed, 100 insertions(+), 394 deletions(-) diff --git a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py index 0158317a951..8a03b72ac0e 100644 --- a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py +++ b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py @@ -9,30 +9,34 @@ get_snappi_ports # noqa: F401 from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, all_prio_list, lossless_prio_list,\ lossy_prio_list # noqa F401 -from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED +from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED # noqa: F401 from tests.snappi_tests.multidut.pfc.files.multidut_helper import run_pfc_test -from tests.common.reboot import reboot -from tests.common.utilities import wait_until import logging from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.files.helper import skip_warm_reboot +from tests.snappi_tests.files.helper import reboot_duts, setup_ports_and_dut, multidut_port_info # noqa: F401 logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) +@pytest.fixture(autouse=True) +def number_of_tx_rx_ports(): + yield (1, 1) + + def test_pfc_pause_single_lossy_prio(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 fanout_graph_facts_multidut, # noqa: F811 duthosts, enum_dut_lossy_prio, - prio_dscp_map, # noqa: F811 - lossy_prio_list, # noqa: F811 - all_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info): # noqa: F811 + prio_dscp_map, # noqa: F811 + lossy_prio_list, # noqa: F811 + all_prio_list, # noqa: F811 + lossless_prio_list, # noqa: F811 + get_snappi_ports, # noqa: F811 + tbinfo, # noqa: F811 + setup_ports_and_dut # noqa: F811 + ): """ Test if PFC will impact a single lossy priority in multidut setup @@ -51,31 +55,7 @@ def test_pfc_pause_single_lossy_prio(snappi_api, # noqa: F811 Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut _, lossy_prio = enum_dut_lossy_prio.split('|') lossy_prio = int(lossy_prio) @@ -99,10 +79,8 @@ def test_pfc_pause_single_lossy_prio(snappi_api, # noqa: F811 prio_dscp_map=prio_dscp_map, test_traffic_pause=False, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfc_pause_multi_lossy_prio(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 fanout_graph_facts_multidut, # noqa: F811 @@ -112,14 +90,14 @@ def test_pfc_pause_multi_lossy_prio(snappi_api, # noqa: F811 lossless_prio_list, # noqa: F811 get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - multidut_port_info): # noqa: F811 + setup_ports_and_dut): # noqa: F811 """ Test if PFC will impact multiple lossy priorities in multidut setup Args: snappi_api (pytest fixture): SNAPPI session conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph + fanout_graph_facts_multidut (pytest fixture): fanout graph duthosts (pytest fixture): list of DUTs prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). lossless_prio_list (pytest fixture): list of all the lossless priorities @@ -129,31 +107,7 @@ def test_pfc_pause_multi_lossy_prio(snappi_api, # noqa: F811 Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut pause_prio_list = lossy_prio_list test_prio_list = lossy_prio_list @@ -174,35 +128,33 @@ def test_pfc_pause_multi_lossy_prio(snappi_api, # noqa: F811 prio_dscp_map=prio_dscp_map, test_traffic_pause=False, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) @pytest.mark.disable_loganalyzer -@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfc_pause_single_lossy_prio_reboot(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 fanout_graph_facts_multidut, # noqa: F811 duthosts, localhost, - enum_dut_lossy_prio_with_completeness_level, - prio_dscp_map, # noqa: F811 - lossy_prio_list, # noqa: F811 - all_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 + enum_dut_lossy_prio, + prio_dscp_map, # noqa: F811 + lossy_prio_list, # noqa: F811 + all_prio_list, # noqa: F811 + lossless_prio_list, # noqa: F811 + get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - reboot_type, - multidut_port_info): + setup_ports_and_dut, # noqa: F811 + reboot_duts): # noqa: F811 """ Test if PFC will impact a single lossy priority after various kinds of reboots in multidut setup Args: snappi_api (pytest fixture): SNAPPI session conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph + fanout_graph_facts_multidut (pytest fixture): fanout graph duthosts (pytest fixture): list of DUTs localhost (pytest fixture): localhost handle - enum_dut_lossy_prio_with_completeness_level (str): lossy priority to test, e.g., 's6100-1|2' + enum_dut_lossy_prio (str): name of lossy priority to test, e.g., 's6100-1|2' prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). lossy_prio_list (pytest fixture): list of all the lossy priorities all_prio_list (pytest fixture): list of all the priorities @@ -212,48 +164,15 @@ def test_pfc_pause_single_lossy_prio_reboot(snappi_api, # noqa: F811 Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - - skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) - skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) - - _, lossy_prio = enum_dut_lossy_prio_with_completeness_level.split('|') + _, lossy_prio = enum_dut_lossy_prio.split('|') lossy_prio = int(lossy_prio) pause_prio_list = [lossy_prio] test_prio_list = [lossy_prio] bg_prio_list = [p for p in all_prio_list] bg_prio_list.remove(lossy_prio) - for duthost in set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]): - logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) - reboot(duthost, localhost, reboot_type=reboot_type, safe_reboot=True) - logger.info("Wait until the system is stable") - wait_until(180, 20, 0, duthost.critical_services_fully_started) - snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports @@ -269,24 +188,21 @@ def test_pfc_pause_single_lossy_prio_reboot(snappi_api, # noqa: F811 prio_dscp_map=prio_dscp_map, test_traffic_pause=False, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) @pytest.mark.disable_loganalyzer -@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfc_pause_multi_lossy_prio_reboot(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 fanout_graph_facts_multidut, # noqa: F811 duthosts, localhost, - prio_dscp_map, # noqa: F811 - lossy_prio_list, # noqa: F811 - lossless_prio_list, # noqa: F811 + prio_dscp_map, # noqa: F811 + lossy_prio_list, # noqa: F811 + lossless_prio_list, # noqa: F811 get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - reboot_type, - multidut_port_info): + tbinfo, # noqa: F811 + setup_ports_and_dut, # noqa: F811 + reboot_duts): # noqa: F811 """ Test if PFC will impact multiple lossy priorities after various kinds of reboots @@ -294,7 +210,7 @@ def test_pfc_pause_multi_lossy_prio_reboot(snappi_api, # noqa: F811 snappi_api (pytest fixture): SNAPPI session snappi_testbed_config (pytest fixture): testbed configuration information conn_graph_facts (pytest fixture): connection graph - fanout_graph_facts (pytest fixture): fanout graph + fanout_graph_facts_multidut (pytest fixture): fanout graph localhost (pytest fixture): localhost handle duthosts (pytest fixture): list of DUTs prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). @@ -306,44 +222,12 @@ def test_pfc_pause_multi_lossy_prio_reboot(snappi_api, # noqa: F811 Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) - skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut pause_prio_list = lossy_prio_list test_prio_list = lossy_prio_list bg_prio_list = lossless_prio_list - for duthost in set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]): - logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) - reboot(duthost, localhost, reboot_type=reboot_type, safe_reboot=True) - logger.info("Wait until the system is stable") - wait_until(180, 20, 0, duthost.critical_services_fully_started) - snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports @@ -359,4 +243,3 @@ def test_pfc_pause_multi_lossy_prio_reboot(snappi_api, # noqa: F811 prio_dscp_map=prio_dscp_map, test_traffic_pause=False, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) diff --git a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py index 01b5a64a899..126a5fe14dd 100644 --- a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py +++ b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py @@ -11,28 +11,36 @@ get_snappi_ports_multi_dut, is_snappi_multidut, \ snappi_api, snappi_dut_base_config, get_snappi_ports, get_snappi_ports_for_rdma, cleanup_config # noqa: F401 from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, lossless_prio_list # noqa F401 -from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED +from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED # noqa: F401 from tests.common.reboot import reboot # noqa: F401 from tests.common.utilities import wait_until # noqa: F401 from tests.snappi_tests.multidut.pfcwd.files.pfcwd_multidut_basic_helper import run_pfcwd_basic_test from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.files.helper import skip_warm_reboot, skip_pfcwd_test # noqa: F401 +from tests.snappi_tests.files.helper import skip_pfcwd_test, reboot_duts, \ + setup_ports_and_dut, multidut_port_info # noqa: F401 logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] +WAIT_TIME = 600 +INTERVAL = 40 + + +@pytest.fixture(autouse=True) +def number_of_tx_rx_ports(): + yield (1, 1) + @pytest.mark.parametrize("trigger_pfcwd", [True, False]) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfcwd_basic_single_lossless_prio(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 fanout_graph_facts_multidut, # noqa: F811 duthosts, lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info, - prio_dscp_map, # noqa F811 - trigger_pfcwd): + tbinfo, # noqa: F811 + prio_dscp_map, # noqa F811 + setup_ports_and_dut, # noqa: F811 + trigger_pfcwd, # noqa: F811 + ): """ Run PFC watchdog basic test on a single lossless priority @@ -47,33 +55,7 @@ def test_pfcwd_basic_single_lossless_prio(snappi_api, # noqa: Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - skip_pfcwd_test(duthost=snappi_ports[0]['duthost'], trigger_pfcwd=trigger_pfcwd) - skip_pfcwd_test(duthost=snappi_ports[1]['duthost'], trigger_pfcwd=trigger_pfcwd) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut lossless_prio = random.sample(lossless_prio_list, 1) lossless_prio = int(lossless_prio[0]) @@ -92,20 +74,16 @@ def test_pfcwd_basic_single_lossless_prio(snappi_api, # noqa: trigger_pfcwd=trigger_pfcwd, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) - @pytest.mark.parametrize("trigger_pfcwd", [True, False]) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfcwd_basic_multi_lossless_prio(snappi_api, # noqa F811 conn_graph_facts, # noqa F811 fanout_graph_facts_multidut, # noqa F811 duthosts, lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - multidut_port_info, prio_dscp_map, # noqa F811 + setup_ports_and_dut, # noqa: F811 trigger_pfcwd): """ Run PFC watchdog basic test on multiple lossless priorities @@ -122,31 +100,7 @@ def test_pfcwd_basic_multi_lossless_prio(snappi_api, # noqa F811 Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports @@ -162,25 +116,21 @@ def test_pfcwd_basic_multi_lossless_prio(snappi_api, # noqa F811 trigger_pfcwd=trigger_pfcwd, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) - @pytest.mark.disable_loganalyzer -@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) @pytest.mark.parametrize("trigger_pfcwd", [True, False]) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # noqa F811 conn_graph_facts, # noqa F811 fanout_graph_facts_multidut, # noqa F811 localhost, duthosts, - enum_dut_lossless_prio_with_completeness_level, # noqa: F811 - get_snappi_ports, # noqa: F811 + lossless_prio_list, # noqa: F811 tbinfo, # noqa: F811 - multidut_port_info, - prio_dscp_map, # noqa F811 - reboot_type, - trigger_pfcwd): + prio_dscp_map, # noqa: F811 + setup_ports_and_dut, # noqa: F811 + reboot_duts, # noqa: F811 + trigger_pfcwd # noqa: F811 + ): """ Verify PFC watchdog basic test works on a single lossless priority after various types of reboot @@ -190,7 +140,6 @@ def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # no fanout_graph_facts_multidut (pytest fixture): fanout graph localhost (pytest fixture): localhost handle duthosts (pytest fixture): list of DUTs - enum_dut_lossless_prio_with_completeness_level (str): lossless priority to test, e.g., 's6100-1|3' prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority) reboot_type (str): reboot type to be issued on the DUT trigger_pfcwd (bool): if PFC watchdog is expected to be triggered @@ -199,46 +148,13 @@ def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # no N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) - skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) - - _, lossless_prio = enum_dut_lossless_prio_with_completeness_level.split('|') - lossless_prio = int(lossless_prio) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut + + lossless_prio = random.sample(lossless_prio_list, 1) + lossless_prio = int(lossless_prio[0]) snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports - for duthost in set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]): - logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) - reboot(duthost, localhost, reboot_type=reboot_type, safe_reboot=True) - logger.info("Wait until the system is stable") - pytest_assert(wait_until(300, 20, 0, duthost.critical_services_fully_started), - "Not all critical services are fully started") - run_pfcwd_basic_test(api=snappi_api, testbed_config=testbed_config, port_config_list=port_config_list, @@ -250,24 +166,19 @@ def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # no trigger_pfcwd=trigger_pfcwd, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) - @pytest.mark.disable_loganalyzer -@pytest.mark.parametrize('reboot_type', ['warm', 'cold', 'fast']) @pytest.mark.parametrize("trigger_pfcwd", [True, False]) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfcwd_basic_multi_lossless_prio_reboot(snappi_api, # noqa F811 conn_graph_facts, # noqa F811 fanout_graph_facts_multidut, # noqa F811 localhost, duthosts, - lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 - tbinfo, # noqa: F811 - multidut_port_info, - prio_dscp_map, # noqa F811 - reboot_type, + lossless_prio_list, # noqa: F811 + tbinfo, # noqa: F811 + prio_dscp_map, # noqa F811 + setup_ports_and_dut, # noqa: F811 + reboot_duts, # noqa: F811 trigger_pfcwd): """ Verify PFC watchdog basic test works on multiple lossless priorities after various kinds of reboots @@ -286,41 +197,7 @@ def test_pfcwd_basic_multi_lossless_prio_reboot(snappi_api, # no Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) - - skip_warm_reboot(snappi_ports[0]['duthost'], reboot_type) - skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) - - for duthost in set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]): - logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, duthost.hostname)) - reboot(duthost, localhost, reboot_type=reboot_type, safe_reboot=True) - logger.info("Wait until the system is stable") - pytest_assert(wait_until(300, 20, 0, duthost.critical_services_fully_started), - "Not all critical services are fully started") + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports @@ -336,24 +213,20 @@ def test_pfcwd_basic_multi_lossless_prio_reboot(snappi_api, # no trigger_pfcwd=trigger_pfcwd, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) - @pytest.mark.disable_loganalyzer @pytest.mark.parametrize('restart_service', ['swss']) @pytest.mark.parametrize("trigger_pfcwd", [True, False]) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, # noqa F811 conn_graph_facts, # noqa F811 fanout_graph_facts_multidut, # noqa F811 duthosts, lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - multidut_port_info, - prio_dscp_map, # noqa F811 + prio_dscp_map, # noqa: F811 restart_service, - trigger_pfcwd): + trigger_pfcwd, + setup_ports_and_dut): # noqa: F811 """ Verify PFC watchdog basic test works on a single lossless priority after various service restarts @@ -369,31 +242,7 @@ def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut lossless_prio = random.sample(lossless_prio_list, 1) lossless_prio = int(lossless_prio[0]) @@ -406,24 +255,27 @@ def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, ports_dict[k] = list(set(ports_dict[k])) logger.info('Port dictionary:{}'.format(ports_dict)) - for duthost in [snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]: + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): + # Record current state of critical services. + duthost.critical_services_fully_started() + asic_list = ports_dict[duthost.hostname] - for asic in asic_list: - asic_id = re.match(r"(asic)(\d+)", asic).group(2) - proc = 'swss@' + asic_id - logger.info("Issuing a restart of service {} on the dut {}".format(proc, duthost.hostname)) - duthost.command("sudo systemctl reset-failed {}".format(proc)) - duthost.command("sudo systemctl restart {}".format(proc)) - logger.info("Wait until the system is stable") - pytest_assert(wait_until(300, 20, 0, duthost.critical_services_fully_started), - "Not all critical services are fully started") + asic = random.sample(asic_list, 1)[0] + asic_id = re.match(r"(asic)(\d+)", asic).group(2) + proc = 'swss@' + asic_id + logger.info("Issuing a restart of service {} on the dut {}".format(proc, duthost.hostname)) + duthost.command("sudo systemctl reset-failed {}".format(proc)) + duthost.command("sudo systemctl restart {}".format(proc)) + logger.info("Wait until the system is stable") + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), + "Not all critical services are fully started") else: - for duthost in [snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]: + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): logger.info("Issuing a restart of service {} on the dut {}".format(restart_service, duthost.hostname)) duthost.command("systemctl reset-failed {}".format(restart_service)) duthost.command("systemctl restart {}".format(restart_service)) logger.info("Wait until the system is stable") - pytest_assert(wait_until(300, 20, 0, duthost.critical_services_fully_started), + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), "Not all critical services are fully started") snappi_extra_params = SnappiTestParams() @@ -440,23 +292,19 @@ def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, trigger_pfcwd=trigger_pfcwd, snappi_extra_params=snappi_extra_params) - cleanup_config(duthosts, snappi_ports) - @pytest.mark.disable_loganalyzer @pytest.mark.parametrize('restart_service', ['swss']) @pytest.mark.parametrize("trigger_pfcwd", [True, False]) -@pytest.mark.parametrize("multidut_port_info", MULTIDUT_PORT_INFO[MULTIDUT_TESTBED]) def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, # noqa F811 conn_graph_facts, # noqa F811 fanout_graph_facts_multidut, # noqa F811 duthosts, lossless_prio_list, # noqa: F811 - get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - multidut_port_info, prio_dscp_map, # noqa F811 restart_service, + setup_ports_and_dut, # noqa: F811 trigger_pfcwd): """ Verify PFC watchdog basic test works on multiple lossless priorities after various service restarts @@ -474,31 +322,8 @@ def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, Returns: N/A """ - for testbed_subtype, rdma_ports in multidut_port_info.items(): - tx_port_count = 1 - rx_port_count = 1 - snappi_port_list = get_snappi_ports - pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count, - "Need Minimum of 2 ports defined in ansible/files/*links.csv file") - - pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - - pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count, - 'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \ - testbed {}, subtype {} in variables.py'. - format(MULTIDUT_TESTBED, testbed_subtype)) - logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - if is_snappi_multidut(duthosts): - snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports, - tx_port_count, rx_port_count, MULTIDUT_TESTBED) - else: - snappi_ports = get_snappi_ports - testbed_config, port_config_list, snappi_ports = snappi_dut_base_config(duthosts, - snappi_ports, - snappi_api) + + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut if (snappi_ports[0]['duthost'].is_multi_asic): ports_dict = defaultdict(list) @@ -509,7 +334,7 @@ def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, ports_dict[k] = list(set(ports_dict[k])) logger.info('Port dictionary:{}'.format(ports_dict)) - for duthost in [snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]: + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): asic_list = ports_dict[duthost.hostname] for asic in asic_list: asic_id = re.match(r"(asic)(\d+)", asic).group(2) @@ -518,15 +343,15 @@ def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, duthost.command("sudo systemctl reset-failed {}".format(proc)) duthost.command("sudo systemctl restart {}".format(proc)) logger.info("Wait until the system is stable") - pytest_assert(wait_until(300, 20, 0, duthost.critical_services_fully_started), + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), "Not all critical services are fully started") else: - for duthost in [snappi_ports[0]['duthost'], snappi_ports[1]['duthost']]: + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): logger.info("Issuing a restart of service {} on the dut {}".format(restart_service, duthost.hostname)) duthost.command("systemctl reset-failed {}".format(restart_service)) duthost.command("systemctl restart {}".format(restart_service)) logger.info("Wait until the system is stable") - pytest_assert(wait_until(300, 20, 0, duthost.critical_services_fully_started), + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), "Not all critical services are fully started") snappi_extra_params = SnappiTestParams() @@ -541,5 +366,3 @@ def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, prio_dscp_map=prio_dscp_map, trigger_pfcwd=trigger_pfcwd, snappi_extra_params=snappi_extra_params) - - cleanup_config(duthosts, snappi_ports) From ed98bddc49faa9f6b3fa9ad3bde5d2d11f612b45 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:16:47 +0800 Subject: [PATCH 122/221] Skip dualtor check_nexthops_single_downlink on VS platform (#15470) Approach What is the motivation for this PR? In PR test, check_nexthops_single_downlink have chance to take more than 1 hour because it needs to run several rounds of traffic test, each round would take more than 20 mins, it would easily cause PR test timeout How did you do it? Skip earlier in check_nexthops_single_downlink for VS platform, needn't go deep into traffic test Co-authored-by: xwjiang2021 <96218837+xwjiang2021@users.noreply.github.com> --- tests/common/dualtor/dual_tor_utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/common/dualtor/dual_tor_utils.py b/tests/common/dualtor/dual_tor_utils.py index ee76923be5d..27b4819d447 100644 --- a/tests/common/dualtor/dual_tor_utils.py +++ b/tests/common/dualtor/dual_tor_utils.py @@ -1184,6 +1184,10 @@ def check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_add ptf_t1_intf = random.choice(get_t1_ptf_ports(rand_selected_dut, tbinfo)) port_packet_count = dict() + + if asic_type == "vs": + logging.info("Skipping validation on VS platform") + return packets_to_send = generate_hashed_packet_to_server(ptfadapter, rand_selected_dut, HASH_KEYS, dst_server_addr, expect_packet_num) @@ -1197,10 +1201,6 @@ def check_nexthops_single_downlink(rand_selected_dut, ptfadapter, dst_server_add for ptf_idx, pkt_count in ptf_port_count.items(): port_packet_count[ptf_idx] = port_packet_count.get(ptf_idx, 0) + pkt_count - if asic_type == "vs": - logging.info("Skipping validation on VS platform") - return - logging.info("Received packets in ports: {}".format(str(port_packet_count))) for downlink_int in expected_downlink_ports: # packets should be either 0 or expect_packet_num: From 151b07c9b9c5c6743a0ce04e16b5d4fc9f0b1a61 Mon Sep 17 00:00:00 2001 From: jingwenxie Date: Fri, 8 Nov 2024 20:01:12 +0800 Subject: [PATCH 123/221] [GCU] Extend timeout to 10min (#15434) What is the motivation for this PR? update timeout introduced in #14881 How did you do it? increase How did you verify/test it? E2E --- tests/common/gu_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/gu_utils.py b/tests/common/gu_utils.py index 3bf7da0d5bf..cb5b0f96a37 100644 --- a/tests/common/gu_utils.py +++ b/tests/common/gu_utils.py @@ -14,7 +14,7 @@ DEFAULT_CHECKPOINT_NAME = "test" GCU_FIELD_OPERATION_CONF_FILE = "gcu_field_operation_validators.conf.json" GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" -GCUTIMEOUT = 240 +GCUTIMEOUT = 600 BASE_DIR = os.path.dirname(os.path.realpath(__file__)) FILES_DIR = os.path.join(BASE_DIR, "files") From 0a4e40b04a1ff41cbc5f8ef63199e68734ff0d81 Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Mon, 11 Nov 2024 13:42:49 +1100 Subject: [PATCH 124/221] feat: add support for clearing counter for ingress (#15469) Description of PR Summary: Fixes # (issue) Az 30112879 Approach What is the motivation for this PR? Ingress port does not get cleared before running the test. This change will make sure both ingress and egress are cleared Signed-off-by: Austin Pham --- tests/common/snappi_tests/multi_dut_params.py | 2 ++ tests/common/snappi_tests/traffic_generation.py | 7 ++++--- .../lossless_response_to_external_pause_storms_helper.py | 8 ++++++++ ...lossless_response_to_throttling_pause_storms_helper.py | 8 ++++++++ .../multidut/pfc/files/m2o_fluctuating_lossless_helper.py | 8 ++++++++ .../pfc/files/m2o_oversubscribe_lossless_helper.py | 7 +++++++ .../pfc/files/m2o_oversubscribe_lossless_lossy_helper.py | 8 ++++++++ .../multidut/pfc/files/m2o_oversubscribe_lossy_helper.py | 8 ++++++++ 8 files changed, 53 insertions(+), 3 deletions(-) diff --git a/tests/common/snappi_tests/multi_dut_params.py b/tests/common/snappi_tests/multi_dut_params.py index b8e5ba4d332..20f7bd5b90d 100644 --- a/tests/common/snappi_tests/multi_dut_params.py +++ b/tests/common/snappi_tests/multi_dut_params.py @@ -16,3 +16,5 @@ def __init__(self): self.duthost1 = None self.duthost2 = None self.multi_dut_ports = None + self.ingress_duthosts = [] + self.egress_duthosts = [] diff --git a/tests/common/snappi_tests/traffic_generation.py b/tests/common/snappi_tests/traffic_generation.py index 5acf21c90fd..005f53c0a00 100644 --- a/tests/common/snappi_tests/traffic_generation.py +++ b/tests/common/snappi_tests/traffic_generation.py @@ -344,9 +344,10 @@ def run_traffic(duthost, cs.state = cs.START api.set_capture_state(cs) - clear_dut_interface_counters(duthost) - - clear_dut_que_counters(duthost) + for host in set([*snappi_extra_params.multi_dut_params.ingress_duthosts, + *snappi_extra_params.multi_dut_params.egress_duthosts, duthost]): + clear_dut_interface_counters(host) + clear_dut_que_counters(host) logger.info("Starting transmit on all flows ...") ts = api.transmit_state() diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py index 88ec47e38b9..56fc66aabf5 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py @@ -74,11 +74,19 @@ def run_lossless_response_to_external_pause_storms_test(api, rx_port = snappi_extra_params.multi_dut_params.multi_dut_ports[0] rx_port_id_list = [rx_port["port_id"]] egress_duthost = rx_port['duthost'] + + # Append the egress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.egress_duthosts.append(egress_duthost) + dut_asics_to_be_configured.add((egress_duthost, rx_port['asic_value'])) tx_port = [snappi_extra_params.multi_dut_params.multi_dut_ports[1], snappi_extra_params.multi_dut_params.multi_dut_ports[2]] ingress_duthost = tx_port[0]['duthost'] + + # Append the ingress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.ingress_duthosts.append(ingress_duthost) + tx_port_id_list = [tx_port[0]["port_id"], tx_port[1]["port_id"]] # add ingress DUT into the set dut_asics_to_be_configured.add((tx_port[0]['duthost'], tx_port[0]['asic_value'])) diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py index a07222e5bcd..216a22ece41 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py @@ -80,11 +80,19 @@ def run_lossless_response_to_throttling_pause_storms_test(api, rx_port = snappi_extra_params.multi_dut_params.multi_dut_ports[0] rx_port_id_list = [rx_port["port_id"]] egress_duthost = rx_port['duthost'] + + # Append the egress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.egress_duthosts.append(egress_duthost) + dut_asics_to_be_configured.add((egress_duthost, rx_port['asic_value'])) tx_port = [snappi_extra_params.multi_dut_params.multi_dut_ports[1], snappi_extra_params.multi_dut_params.multi_dut_ports[2]] ingress_duthost = tx_port[0]['duthost'] + + # Append the ingress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.ingress_duthosts.append(ingress_duthost) + tx_port_id_list = [tx_port[0]["port_id"], tx_port[1]["port_id"]] # add ingress DUT into the set dut_asics_to_be_configured.add((tx_port[0]['duthost'], tx_port[0]['asic_value'])) diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py index 2561831ec24..ad1a5bb7f81 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py @@ -67,11 +67,19 @@ def run_m2o_fluctuating_lossless_test(api, rx_port = snappi_extra_params.multi_dut_params.multi_dut_ports[0] rx_port_id_list = [rx_port["port_id"]] egress_duthost = rx_port['duthost'] + + # Append the egress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.egress_duthosts.append(egress_duthost) + dut_asics_to_be_configured.add((egress_duthost, rx_port['asic_value'])) tx_port = [snappi_extra_params.multi_dut_params.multi_dut_ports[1], snappi_extra_params.multi_dut_params.multi_dut_ports[2]] ingress_duthost = tx_port[0]['duthost'] + + # Append the ingress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.ingress_duthosts.append(ingress_duthost) + tx_port_id_list = [tx_port[0]["port_id"], tx_port[1]["port_id"]] # add ingress DUT into the set dut_asics_to_be_configured.add((tx_port[0]['duthost'], tx_port[0]['asic_value'])) diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py index 948a370ba49..550f94a0236 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py @@ -71,9 +71,16 @@ def run_m2o_oversubscribe_lossless_test(api, egress_duthost = rx_port['duthost'] dut_asics_to_be_configured.add((egress_duthost, rx_port['asic_value'])) + # Append the egress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.egress_duthosts.append(egress_duthost) + tx_port = [snappi_extra_params.multi_dut_params.multi_dut_ports[1], snappi_extra_params.multi_dut_params.multi_dut_ports[2]] ingress_duthost = tx_port[0]['duthost'] + + # Append the ingress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.ingress_duthosts.append(ingress_duthost) + tx_port_id_list = [tx_port[0]["port_id"], tx_port[1]["port_id"]] # add ingress DUT into the set dut_asics_to_be_configured.add((tx_port[0]['duthost'], tx_port[0]['asic_value'])) diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py index 5d8f740044f..8efd129cff3 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py @@ -74,11 +74,19 @@ def run_pfc_m2o_oversubscribe_lossless_lossy_test(api, rx_port = snappi_extra_params.multi_dut_params.multi_dut_ports[0] rx_port_id_list = [rx_port["port_id"]] egress_duthost = rx_port['duthost'] + + # Append the egress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.egress_duthosts.append(egress_duthost) + dut_asics_to_be_configured.add((egress_duthost, rx_port['asic_value'])) tx_port = [snappi_extra_params.multi_dut_params.multi_dut_ports[1], snappi_extra_params.multi_dut_params.multi_dut_ports[2]] ingress_duthost = tx_port[0]['duthost'] + + # Append the ingress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.ingress_duthosts.append(ingress_duthost) + tx_port_id_list = [tx_port[0]["port_id"], tx_port[1]["port_id"]] # add ingress DUT into the set dut_asics_to_be_configured.add((tx_port[0]['duthost'], tx_port[0]['asic_value'])) diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py index 261ab507f75..ac5defb9bdf 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py @@ -73,11 +73,19 @@ def run_pfc_m2o_oversubscribe_lossy_test(api, rx_port = snappi_extra_params.multi_dut_params.multi_dut_ports[0] rx_port_id_list = [rx_port["port_id"]] egress_duthost = rx_port['duthost'] + + # Append the egress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.egress_duthosts.append(egress_duthost) + dut_asics_to_be_configured.add((egress_duthost, rx_port['asic_value'])) tx_port = [snappi_extra_params.multi_dut_params.multi_dut_ports[1], snappi_extra_params.multi_dut_params.multi_dut_ports[2]] ingress_duthost = tx_port[0]['duthost'] + + # Append the ingress here for run_traffic to clear its counters + snappi_extra_params.multi_dut_params.ingress_duthosts.append(ingress_duthost) + tx_port_id_list = [tx_port[0]["port_id"], tx_port[1]["port_id"]] # add ingress DUT into the set dut_asics_to_be_configured.add((tx_port[0]['duthost'], tx_port[0]['asic_value'])) From 91ea307b26ff2a4f94db2b114de7cd78360416ff Mon Sep 17 00:00:00 2001 From: wenyiz2021 <91497961+wenyiz2021@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:33:23 -0800 Subject: [PATCH 125/221] [multi-asic fix] fix new change in test_route_perf.py to support multi-asic (#15452) Description of PR Summary: Fixes # (issue) for multi-asic devices, when asic is broadcom, using "bcmcmd" needs to specify asic id. --- .azure-pipelines/pr_test_scripts.yaml | 1 + tests/route/test_route_perf.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/pr_test_scripts.yaml b/.azure-pipelines/pr_test_scripts.yaml index af74bf44aa0..290ce1d9a7d 100644 --- a/.azure-pipelines/pr_test_scripts.yaml +++ b/.azure-pipelines/pr_test_scripts.yaml @@ -428,6 +428,7 @@ multi-asic-t1-lag: - bgp/test_bgp_bbr.py - bgp/test_bgp_fact.py - bgp/test_bgp_update_timer.py + - route/test_route_perf.py - snmp/test_snmp_default_route.py - snmp/test_snmp_link_local.py - snmp/test_snmp_loopback.py diff --git a/tests/route/test_route_perf.py b/tests/route/test_route_perf.py index 2a7fccd3167..3488792e9d8 100644 --- a/tests/route/test_route_perf.py +++ b/tests/route/test_route_perf.py @@ -55,15 +55,18 @@ def get_route_scale_per_role(tbinfo, ip_version): @pytest.fixture -def check_config(duthosts, enum_rand_one_per_hwsku_frontend_hostname, tbinfo): +def check_config(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_rand_one_frontend_asic_index, tbinfo): if tbinfo["topo"]["type"] in ["m0", "mx"]: return duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] asic = duthost.facts["asic_type"] + asic_id = enum_rand_one_frontend_asic_index if (asic == "broadcom"): - alpm_enable = duthost.command('bcmcmd "conf show l3_alpm_enable"')["stdout_lines"][2].strip() + broadcom_cmd = "bcmcmd -n " + str(asic_id) if duthost.is_multi_asic else "bcmcmd" + alpm_cmd = "{} {}".format(broadcom_cmd, "conf show l3_alpm_enable") + alpm_enable = duthost.command(alpm_cmd)["stdout_lines"][2].strip() logger.info("Checking config: {}".format(alpm_enable)) pytest_assert(alpm_enable == "l3_alpm_enable=2", "l3_alpm_enable is not set for route scaling") From 55ff70e99ef07e33f82df13896abb874da4db46c Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:40:44 -0800 Subject: [PATCH 126/221] Address test gap to verify portchannel member packet forwarding w.r.t SAI_LAG_MEMBER_ATTR_EGRESS/INGRESS enable/disable state (#15191) Verifies: Added new test case to validate LAG MEMBER SAI attribute SAI_LAG_MEMBER_ATTR_EGRESS and SAI_LAG_MEMBER_ATTR_INGRESS value of enable/disable On disable: 1. Control packets to/from should not be processed (BGP down) 2. Data packets from/to CPU not be processed (ping to IP interface should faild) 3. Data packets across portchannel not to be processed (ping to another peer ip should fail) On enable: Reverse of all the above 3 scenarios, --- tests/common/devices/sonic.py | 30 +++- tests/common/devices/sonic_asic.py | 26 +++- tests/pc/test_lag_member_forwarding.py | 181 +++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 tests/pc/test_lag_member_forwarding.py diff --git a/tests/common/devices/sonic.py b/tests/common/devices/sonic.py index 83a6d52ed31..b19ee0fb873 100644 --- a/tests/common/devices/sonic.py +++ b/tests/common/devices/sonic.py @@ -2229,12 +2229,38 @@ def ping_v4(self, ipv4, count=1, ns_arg=""): netns_arg = "sudo ip netns exec {} ".format(ns_arg) try: - self.shell("{}ping -q -c{} {} > /dev/null".format( + rc = self.shell("{}ping -q -c{} {} > /dev/null".format( netns_arg, count, ipv4 )) except RunAnsibleModuleFail: return False - return True + return not rc['failed'] + + def ping_v6(self, ipv6, count=1, ns_arg=""): + """ + Returns 'True' if ping to IP address works, else 'False' + Args: + IPv6 address + + Returns: + True or False + """ + try: + socket.inet_pton(socket.AF_INET6, ipv6) + except socket.error: + raise Exception("Invalid IPv6 address {}".format(ipv6)) + + netns_arg = "" + if ns_arg is not DEFAULT_NAMESPACE: + netns_arg = "sudo ip netns exec {} ".format(ns_arg) + + try: + rc = self.shell("{}ping -6 -q -c{} {} > /dev/null".format( + netns_arg, count, ipv6 + )) + except RunAnsibleModuleFail: + return False + return not rc['failed'] def is_backend_portchannel(self, port_channel, mg_facts): ports = mg_facts["minigraph_portchannels"].get(port_channel) diff --git a/tests/common/devices/sonic_asic.py b/tests/common/devices/sonic_asic.py index 7f8ff9c1190..89e1b33f8b7 100644 --- a/tests/common/devices/sonic_asic.py +++ b/tests/common/devices/sonic_asic.py @@ -267,12 +267,34 @@ def ping_v4(self, ipv4, count=1): raise Exception("Invalid IPv4 address {}".format(ipv4)) try: - self.sonichost.shell("{}ping -q -c{} {} > /dev/null".format( + rc = self.sonichost.shell("{}ping -q -c{} {} > /dev/null".format( self.ns_arg, count, ipv4 )) except RunAnsibleModuleFail: return False - return True + return not rc['failed'] + + def ping_v6(self, ipv6, count=1): + """ + Returns 'True' if ping to IP address works, else 'False' + Args: + IPv6 address + + Returns: + True or False + """ + try: + socket.inet_pton(socket.AF_INET6, ipv6) + except socket.error: + raise Exception("Invalid IPv6 address {}".format(ipv6)) + + try: + rc = self.sonichost.shell("{}ping -6 -q -c{} {} > /dev/null".format( + self.ns_arg, count, ipv6 + )) + except RunAnsibleModuleFail: + return False + return not rc['failed'] def is_backend_portchannel(self, port_channel): mg_facts = self.sonichost.minigraph_facts(host=self.sonichost.hostname)['ansible_facts'] diff --git a/tests/pc/test_lag_member_forwarding.py b/tests/pc/test_lag_member_forwarding.py new file mode 100644 index 00000000000..d6dea34e233 --- /dev/null +++ b/tests/pc/test_lag_member_forwarding.py @@ -0,0 +1,181 @@ +import ipaddr as ipaddress +import json +import pytest +import time +from tests.common import config_reload +from ptf.mask import Mask +import ptf.packet as scapy +import ptf.testutils as testutils +from tests.common.helpers.assertions import pytest_assert + +pytestmark = [ + pytest.mark.topology('any') +] + + +def build_pkt(dest_mac, ip_addr, ttl): + pkt = testutils.simple_tcp_packet( + eth_dst=dest_mac, + eth_src="00:11:22:33:44:55", + pktlen=100, + ip_src="19.0.0.100", + ip_dst=ip_addr, + ip_ttl=ttl, + tcp_dport=200, + tcp_sport=100 + ) + exp_packet = Mask(pkt) + exp_packet.set_do_not_care_scapy(scapy.Ether, "dst") + exp_packet.set_do_not_care_scapy(scapy.Ether, "src") + + exp_packet.set_do_not_care_scapy(scapy.IP, "version") + exp_packet.set_do_not_care_scapy(scapy.IP, "ihl") + exp_packet.set_do_not_care_scapy(scapy.IP, "tos") + exp_packet.set_do_not_care_scapy(scapy.IP, "len") + exp_packet.set_do_not_care_scapy(scapy.IP, "flags") + exp_packet.set_do_not_care_scapy(scapy.IP, "id") + exp_packet.set_do_not_care_scapy(scapy.IP, "frag") + exp_packet.set_do_not_care_scapy(scapy.IP, "ttl") + exp_packet.set_do_not_care_scapy(scapy.IP, "chksum") + exp_packet.set_do_not_care_scapy(scapy.IP, "options") + + exp_packet.set_do_not_care_scapy(scapy.TCP, "seq") + exp_packet.set_do_not_care_scapy(scapy.TCP, "ack") + exp_packet.set_do_not_care_scapy(scapy.TCP, "reserved") + exp_packet.set_do_not_care_scapy(scapy.TCP, "dataofs") + exp_packet.set_do_not_care_scapy(scapy.TCP, "window") + exp_packet.set_do_not_care_scapy(scapy.TCP, "chksum") + exp_packet.set_do_not_care_scapy(scapy.TCP, "urgptr") + + exp_packet.set_ignore_extra_bytes() + return pkt, exp_packet + + +def test_lag_member_forwarding_packets(duthosts, enum_rand_one_per_hwsku_frontend_hostname, tbinfo, ptfadapter): + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + mg_facts = duthost.get_extended_minigraph_facts(tbinfo) + lag_facts = duthost.lag_facts(host=duthost.hostname)['ansible_facts']['lag_facts'] + if not len(lag_facts['lags'].keys()): + pytest.skip("No Lag found in this topology") + portchannel_name = list(lag_facts['lags'].keys())[0] + portchannel_dest_name = None + recv_port = [] + if len(lag_facts['lags'].keys()) > 1: + portchannel_dest_name = list(lag_facts['lags'].keys())[1] + portchannel_dest_members = list(lag_facts['lags'][portchannel_dest_name]['po_stats']['ports'].keys()) + assert len(portchannel_dest_members) > 0 + for member in portchannel_dest_members: + recv_port.append(mg_facts['minigraph_ptf_indices'][member]) + + portchannel_members = list(lag_facts['lags'][portchannel_name]['po_stats']['ports'].keys()) + assert len(portchannel_members) > 0 + asic_name = lag_facts['names'][portchannel_name] + dest_asic_name = lag_facts['names'][portchannel_dest_name] + asic_idx = duthost.get_asic_id_from_namespace(asic_name) + asichost = duthost.asic_instance_from_namespace(asic_name) + dest_asichost = duthost.asic_instance_from_namespace(dest_asic_name) + + config_facts = asichost.config_facts(host=duthost.hostname, source="running")['ansible_facts'] + dest_config_facts = dest_asichost.config_facts(host=duthost.hostname, source="running")['ansible_facts'] + send_port = mg_facts['minigraph_ptf_indices'][portchannel_members[0]] + holdtime = 0 + + peer_device_ip_set = set() + peer_device_dest_ip = None + + # Find test (1st) port channel and fetch it's BGP neighbors + # ipv4 and ipv6 ip address to verify case of ping to neighbor + for peer_device_ip, peer_device_bgp_data in config_facts['BGP_NEIGHBOR'].items(): + if peer_device_bgp_data["name"] == config_facts['DEVICE_NEIGHBOR'][portchannel_members[0]]['name']: + peer_device_ip_set.add(peer_device_ip) + # holdtime to wait for BGP session to go down when lag member is marked as disable state. + if not holdtime: + holdtime = duthost.get_bgp_neighbor_info(peer_device_ip, asic_idx)["bgpTimerHoldTimeMsecs"] + # Find test (2nd) port channel and fetch it's BGP neighbors + # ipv4 and ipv6 ip address to verify data forwarding across port-channel + elif (portchannel_dest_name and not peer_device_dest_ip + and peer_device_bgp_data["name"] == + dest_config_facts['DEVICE_NEIGHBOR'][portchannel_dest_members[0]]['name'] and + ipaddress.IPNetwork(peer_device_ip).version == 4): + peer_device_dest_ip = peer_device_ip + + # we should have v4 and v6 peer neighbors + assert len(peer_device_ip_set) == 2 + assert holdtime > 0 + + bgp_fact_info = asichost.bgp_facts() + + for ip in peer_device_ip_set: + assert bgp_fact_info['ansible_facts']['bgp_neighbors'][ip]['state'] == 'established' + + for ip in peer_device_ip_set: + if ipaddress.IPNetwork(ip).version == 4: + rc = asichost.ping_v4(ip) + else: + rc = asichost.ping_v6(ip) + assert rc + + rtr_mac = asichost.get_router_mac() + ip_ttl = 121 + ip_route = peer_device_dest_ip + + def built_and_send_tcp_ip_packet(expected): + pkt, exp_pkt = build_pkt(rtr_mac, ip_route, ip_ttl) + testutils.send(ptfadapter, send_port, pkt, 10) + if expected: + (_, recv_pkt) = testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, + ports=recv_port) + assert recv_pkt + # Make sure routing is done + pytest_assert(scapy.Ether(recv_pkt).ttl == (ip_ttl - 1), "Routed Packet TTL not decremented") + else: + testutils.verify_no_packet_any(test=ptfadapter, pkt=exp_pkt, + ports=recv_port) + + if peer_device_dest_ip: + ptfadapter.dataplane.flush() + built_and_send_tcp_ip_packet(True) + + lag_member_file_dir = duthost.shell('mktemp')['stdout'] + lag_member_config = [] + for portchannel_member_name in portchannel_members: + lag_member_config.append({ + "LAG_MEMBER_TABLE:{}:{}".format(portchannel_name, portchannel_member_name): { + "status": "disabled" + }, + "OP": "SET" + }) + try: + # Copy json file to DUT + duthost.copy(content=json.dumps(lag_member_config, indent=4), dest=lag_member_file_dir, verbose=False) + json_set = "/dev/stdin < {}".format(lag_member_file_dir) + result = duthost.docker_exec_swssconfig(json_set, "swss", asic_idx) + if result["rc"] != 0: + pytest.fail( + "Failed to apply lag member configuration file: {}".format(result["stderr"]) + ) + + # Make sure data forwarding starts to fail + if peer_device_dest_ip: + ptfadapter.dataplane.flush() + built_and_send_tcp_ip_packet(False) + + # make sure ping should fail + for ip in peer_device_ip_set: + if ipaddress.IPNetwork(ip).version == 4: + rc = asichost.ping_v4(ip) + else: + rc = asichost.ping_v6(ip) + + if rc: + pytest.fail("Ping is still working on lag disable member for neighbor {}", ip) + + time.sleep(holdtime/1000) + # Make sure BGP goes down + bgp_fact_info = asichost.bgp_facts() + for ip in peer_device_ip_set: + if bgp_fact_info['ansible_facts']['bgp_neighbors'][ip]['state'] == 'established': + pytest.fail("BGP is still enable on lag disable member for neighbor {}", ip) + finally: + duthost.shell('rm -f {}'.format(lag_member_file_dir)) + config_reload(duthost, config_source='config_db') From 47b734a0919acac7cb1645306a34c8a0cdc0fd2c Mon Sep 17 00:00:00 2001 From: ryanzhu706 Date: Mon, 11 Nov 2024 16:51:49 -0800 Subject: [PATCH 127/221] Add missed import fixture (#15369) What is the motivation for this PR? test_advanced_reboot test failed due to fixture 'advanceboot_neighbor_restore' not found How did you do it? Add missed fixture "advanceboot_neighbor_restore" --- tests/platform_tests/test_advanced_reboot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/platform_tests/test_advanced_reboot.py b/tests/platform_tests/test_advanced_reboot.py index d036f275156..52246c4405a 100644 --- a/tests/platform_tests/test_advanced_reboot.py +++ b/tests/platform_tests/test_advanced_reboot.py @@ -8,7 +8,7 @@ from tests.common.fixtures.advanced_reboot import get_advanced_reboot # noqa F401 from tests.platform_tests.verify_dut_health import add_fail_step_to_reboot # noqa F401 from tests.common.platform.warmboot_sad_cases import get_sad_case_list, SAD_CASE_LIST -from tests.common.platform.device_utils import advanceboot_loganalyzer, verify_dut_health # noqa F401 +from tests.common.platform.device_utils import advanceboot_loganalyzer, verify_dut_health, advanceboot_neighbor_restore # noqa F401 from tests.common.fixtures.ptfhost_utils import run_icmp_responder, run_garp_service # noqa F401 from tests.common.dualtor.dual_tor_utils import mux_cable_server_ip, show_muxcable_status From 1f9072790ea9f1fd7a93d4f166a64ca17ed6dd9a Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:05:52 -0800 Subject: [PATCH 128/221] Adding minor misc fixes for pfcwd scripts. (#15286) Description of PR This PR addresses the following issues: The dut-counter check on pfcwd scripts is using a wrong logic, it attempts to read the incoming drops and incoming packets and compares. Unfortunately, the packets are not being dropped in ingress, but they are dropped in egress. So this PR changes the logic to read the outgoing port's drops, and incoming ports' total packets. The flow-completion-check in the common code is for 20 seconds. But some of the traffic streams is configured for 26 seconds, so we need to check for atleast 26 seconds. So I have increased the time to 30 seconds. Along with the above, the pfcwd_basic script is updated to use the common code as implemented in the PR:15099. Summary: Pls see above. Approach What is the motivation for this PR? Fixing some of the issues that we came across during the testing. move the repeated code to the common code. How did you do it? Updated the counter reading mechanism. Updated the max_attempts for flow-completion to 30 seconds. Updated the pfcwd_basic to use the new lib code from Move the common code from testcases to the fixtures. #15099. How did you verify/test it? Ran it on my TB: Any platform specific information? Changes were tested on cisco-8000 only. The one fail below is not related to this change. My run result: =========================================================================================================================== PASSES =========================================================================================================================== ______________________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio[multidut_port_info0-True] _______________________________________________________________________________________________ ______________________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio[multidut_port_info1-True] _______________________________________________________________________________________________ ______________________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio[multidut_port_info1-False] ______________________________________________________________________________________________ ----------------------------------------------------------------------------- generated xml file: /run_logs/ixia/fixturize-reboot/2024-10-30-21-43-12/tr_2024-10-30-21-43-12.xml ----------------------------------------------------------------------------- INFO:root:Can not get Allure report URL. Please check logs ------------------------------------------------------------------------------------------------------------------- live log sessionfinish ------------------------------------------------------------------------------------------------------------------- 21:54:15 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ================================================================================================================== short test summary info =================================================================================================================== PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio[multidut_port_info0-True] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio[multidut_port_info1-True] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio[multidut_port_info1-False] FAILED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio[multidut_port_info0-False] - Failed: Loss rate of Data Flow 1 (0.17994320225890004) should be in [0, 0] ==================================================================================================== 1 failed, 3 passed, 7 warnings in 660.78s (0:11:00) ===================================================================================================== sonic@ixia-sonic-mgmt-whitebox:/data/tests$ co-authrized by: jianquanye@microsoft.com --- tests/common/snappi_tests/common_helpers.py | 2 +- ...esponse_to_external_pause_storms_helper.py | 14 ++++----- ...ponse_to_throttling_pause_storms_helper.py | 14 ++++----- .../files/m2o_fluctuating_lossless_helper.py | 16 +++++----- .../m2o_oversubscribe_lossless_helper.py | 14 ++++----- ...m2o_oversubscribe_lossless_lossy_helper.py | 17 +++++------ .../files/m2o_oversubscribe_lossy_helper.py | 15 +++++----- .../pfcwd_multidut_burst_storm_helper.py | 2 +- .../test_multidut_pfcwd_basic_with_snappi.py | 29 ++++++++----------- 9 files changed, 54 insertions(+), 69 deletions(-) diff --git a/tests/common/snappi_tests/common_helpers.py b/tests/common/snappi_tests/common_helpers.py index d7f79642b4a..5521b6c2c97 100644 --- a/tests/common/snappi_tests/common_helpers.py +++ b/tests/common/snappi_tests/common_helpers.py @@ -1134,9 +1134,9 @@ def get_interface_stats(duthost, port): """ # Initializing nested dictionary i_stats i_stats = defaultdict(dict) - i_stats[duthost.hostname][port] = {} n_out = parse_portstat(duthost.command('portstat -i {}'.format(port))['stdout_lines'])[port] + i_stats[duthost.hostname][port] = n_out # rx_err, rx_ovr and rx_drp are counted in single counter rx_fail # tx_err, tx_ovr and tx_drp are counted in single counter tx_fail rx_err = ['rx_err', 'rx_ovr', 'rx_drp'] diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py index 56fc66aabf5..fb139f3f255 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py @@ -137,15 +137,13 @@ def run_lossless_response_to_external_pause_storms_test(api, exp_dur_sec=DATA_FLOW_DURATION_SEC + DATA_FLOW_DELAY_SEC, snappi_extra_params=snappi_extra_params) - tx_port1 = tx_port[0]['peer_port'] - tx_port2 = tx_port[1]['peer_port'] + dut_tx_port = rx_port['peer_port'] + dut_rx_port1 = tx_port[0]['peer_port'] + dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_fail'] - pkt_drop2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_fail'] - rx_pkts_1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_pkts'] - rx_pkts_2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_pkts'] - # Calculate the total packet drop - pkt_drop = pkt_drop1 + pkt_drop2 + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] + rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets total_rx_pkts = rx_pkts_1 + rx_pkts_2 # Calculate the drop percentage diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py index 216a22ece41..b177fd58282 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py @@ -144,15 +144,13 @@ def run_lossless_response_to_throttling_pause_storms_test(api, exp_dur_sec=DATA_FLOW_DURATION_SEC + DATA_FLOW_DELAY_SEC, snappi_extra_params=snappi_extra_params) - tx_port1 = tx_port[0]['peer_port'] - tx_port2 = tx_port[1]['peer_port'] + dut_tx_port = rx_port['peer_port'] + dut_rx_port1 = tx_port[0]['peer_port'] + dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_fail'] - pkt_drop2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_fail'] - rx_pkts_1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_pkts'] - rx_pkts_2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_pkts'] - # Calculate the total packet drop - pkt_drop = pkt_drop1 + pkt_drop2 + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] + rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets total_rx_pkts = rx_pkts_1 + rx_pkts_2 # Calculate the drop percentage diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py index ad1a5bb7f81..5da4ec7d6bf 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py @@ -1,5 +1,6 @@ import logging # noqa: F401 import random +from math import ceil from tests.common.helpers.assertions import pytest_assert, pytest_require # noqa: F401 from tests.common.fixtures.conn_graph_facts import conn_graph_facts, fanout_graph_facts # noqa: F401 from tests.common.snappi_tests.snappi_helpers import get_dut_port_id # noqa: F401 @@ -10,7 +11,6 @@ from tests.common.snappi_tests.traffic_generation import run_traffic, \ setup_base_traffic_config # noqa: F401 from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict -from math import ceil logger = logging.getLogger(__name__) PAUSE_FLOW_NAME = 'Pause Storm' @@ -126,15 +126,13 @@ def run_m2o_fluctuating_lossless_test(api, exp_dur_sec=DATA_FLOW_DURATION_SEC + DATA_FLOW_DELAY_SEC, snappi_extra_params=snappi_extra_params) - tx_port1 = tx_port[0]['peer_port'] - tx_port2 = tx_port[1]['peer_port'] + dut_tx_port = rx_port['peer_port'] + dut_rx_port1 = tx_port[0]['peer_port'] + dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_fail'] - pkt_drop2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_fail'] - rx_pkts_1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_pkts'] - rx_pkts_2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_pkts'] - # Calculate the total packet drop - pkt_drop = pkt_drop1 + pkt_drop2 + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] + rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets total_rx_pkts = rx_pkts_1 + rx_pkts_2 # Calculate the drop percentage diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py index 550f94a0236..3f34d6a341b 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py @@ -129,15 +129,13 @@ def run_m2o_oversubscribe_lossless_test(api, exp_dur_sec=DATA_FLOW_DURATION_SEC + DATA_FLOW_DELAY_SEC, snappi_extra_params=snappi_extra_params) - tx_port1 = tx_port[0]['peer_port'] - tx_port2 = tx_port[1]['peer_port'] + dut_tx_port = rx_port['peer_port'] + dut_rx_port1 = tx_port[0]['peer_port'] + dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_fail'] - pkt_drop2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_fail'] - rx_pkts_1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_pkts'] - rx_pkts_2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_pkts'] - # Calculate the total packet drop - pkt_drop = pkt_drop1 + pkt_drop2 + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] + rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets total_rx_pkts = rx_pkts_1 + rx_pkts_2 # Calculate the drop percentage diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py index 8efd129cff3..302ea6b852a 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py @@ -10,12 +10,13 @@ from tests.common.fixtures.conn_graph_facts import conn_graph_facts, fanout_graph_facts # noqa: F401 from tests.common.snappi_tests.snappi_helpers import get_dut_port_id # noqa: F401 from tests.common.snappi_tests.common_helpers import pfc_class_enable_vector, \ - stop_pfcwd, disable_packet_aging, sec_to_nanosec, get_interface_stats # noqa: F401 + stop_pfcwd, disable_packet_aging, sec_to_nanosec, get_interface_stats # noqa: F401 from tests.common.snappi_tests.port import select_ports # noqa: F401 from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import run_traffic, \ setup_base_traffic_config # noqa: F401 from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.portstat_utilities import parse_portstat # noqa: F401 logger = logging.getLogger(__name__) @@ -133,15 +134,13 @@ def run_pfc_m2o_oversubscribe_lossless_lossy_test(api, exp_dur_sec=DATA_FLOW_DURATION_SEC + DATA_FLOW_DELAY_SEC, snappi_extra_params=snappi_extra_params) - tx_port1 = tx_port[0]['peer_port'] - tx_port2 = tx_port[1]['peer_port'] + dut_rx_port1 = tx_port[0]['peer_port'] + dut_rx_port2 = tx_port[1]['peer_port'] + dut_tx_port = rx_port['peer_port'] # Fetch relevant statistics - pkt_drop1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_fail'] - pkt_drop2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_fail'] - rx_pkts_1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_pkts'] - rx_pkts_2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_pkts'] - # Calculate the total packet drop - pkt_drop = pkt_drop1 + pkt_drop2 + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] + rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets total_rx_pkts = rx_pkts_1 + rx_pkts_2 # Calculate the drop percentage diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py index ac5defb9bdf..9bacdc7ade5 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py @@ -135,14 +135,13 @@ def run_pfc_m2o_oversubscribe_lossy_test(api, exp_dur_sec=DATA_FLOW_DURATION_SEC + DATA_FLOW_DELAY_SEC, snappi_extra_params=snappi_extra_params) - tx_port1 = tx_port[0]['peer_port'] - tx_port2 = tx_port[1]['peer_port'] - pkt_drop1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_fail'] - pkt_drop2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_fail'] - rx_pkts_1 = get_interface_stats(ingress_duthost, tx_port1)[ingress_duthost.hostname][tx_port1]['rx_pkts'] - rx_pkts_2 = get_interface_stats(ingress_duthost, tx_port2)[ingress_duthost.hostname][tx_port2]['rx_pkts'] - # Calculate the total packet drop - pkt_drop = pkt_drop1 + pkt_drop2 + dut_tx_port = rx_port['peer_port'] + dut_rx_port1 = tx_port[0]['peer_port'] + dut_rx_port2 = tx_port[1]['peer_port'] + + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] + rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets total_rx_pkts = rx_pkts_1 + rx_pkts_2 # Calculate the drop percentage diff --git a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py index 9b8b02e9257..daa2048a2af 100644 --- a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py +++ b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py @@ -285,7 +285,7 @@ def __run_traffic(api, config, all_flow_names, exp_dur_sec): time.sleep(exp_dur_sec) attempts = 0 - max_attempts = 20 + max_attempts = 30 while attempts < max_attempts: request = api.metrics_request() diff --git a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py index 126a5fe14dd..daf00e18751 100644 --- a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py +++ b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py @@ -11,13 +11,12 @@ get_snappi_ports_multi_dut, is_snappi_multidut, \ snappi_api, snappi_dut_base_config, get_snappi_ports, get_snappi_ports_for_rdma, cleanup_config # noqa: F401 from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, lossless_prio_list # noqa F401 -from tests.snappi_tests.variables import MULTIDUT_PORT_INFO, MULTIDUT_TESTBED # noqa: F401 from tests.common.reboot import reboot # noqa: F401 from tests.common.utilities import wait_until # noqa: F401 from tests.snappi_tests.multidut.pfcwd.files.pfcwd_multidut_basic_helper import run_pfcwd_basic_test from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.snappi_tests.files.helper import skip_pfcwd_test, reboot_duts, \ - setup_ports_and_dut, multidut_port_info # noqa: F401 + setup_ports_and_dut # noqa: F401 logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] @@ -124,13 +123,12 @@ def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # no fanout_graph_facts_multidut, # noqa F811 localhost, duthosts, - lossless_prio_list, # noqa: F811 - tbinfo, # noqa: F811 - prio_dscp_map, # noqa: F811 - setup_ports_and_dut, # noqa: F811 + enum_dut_lossless_prio_with_completeness_level, # noqa: F811 + get_snappi_ports, # noqa: F811 + prio_dscp_map, # noqa F811 + setup_ports_and_dut, # noqa: F811 reboot_duts, # noqa: F811 - trigger_pfcwd # noqa: F811 - ): + trigger_pfcwd): """ Verify PFC watchdog basic test works on a single lossless priority after various types of reboot @@ -141,7 +139,6 @@ def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # no localhost (pytest fixture): localhost handle duthosts (pytest fixture): list of DUTs prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority) - reboot_type (str): reboot type to be issued on the DUT trigger_pfcwd (bool): if PFC watchdog is expected to be triggered Returns: @@ -150,8 +147,8 @@ def test_pfcwd_basic_single_lossless_prio_reboot(snappi_api, # no testbed_config, port_config_list, snappi_ports = setup_ports_and_dut - lossless_prio = random.sample(lossless_prio_list, 1) - lossless_prio = int(lossless_prio[0]) + _, lossless_prio = enum_dut_lossless_prio_with_completeness_level.split('|') + lossless_prio = int(lossless_prio) snappi_extra_params = SnappiTestParams() snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports @@ -174,11 +171,10 @@ def test_pfcwd_basic_multi_lossless_prio_reboot(snappi_api, # no fanout_graph_facts_multidut, # noqa F811 localhost, duthosts, - lossless_prio_list, # noqa: F811 - tbinfo, # noqa: F811 - prio_dscp_map, # noqa F811 - setup_ports_and_dut, # noqa: F811 - reboot_duts, # noqa: F811 + enum_dut_lossless_prio_with_completeness_level, # noqa: F811 + tbinfo, # noqa: F811 + prio_dscp_map, # noqa F811 + reboot_duts, # noqa: F811 trigger_pfcwd): """ Verify PFC watchdog basic test works on multiple lossless priorities after various kinds of reboots @@ -191,7 +187,6 @@ def test_pfcwd_basic_multi_lossless_prio_reboot(snappi_api, # no duthosts (pytest fixture): list of DUTs lossless_prio_list (pytest fixture): list of all the lossless priorities prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority) - reboot_type (str): reboot type to be issued on the DUT trigger_pfcwd (bool): if PFC watchdog is expected to be triggered Returns: From f7a4584d8811abe9d1eed16d01c98d88d1a72277 Mon Sep 17 00:00:00 2001 From: Rajendra Kumar Thirumurthi Date: Mon, 11 Nov 2024 17:38:07 -0800 Subject: [PATCH 129/221] Skipping test_dip_sip for Cisco 8122 platforms (#15479) --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index d91c871a263..a4737b99dc2 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1103,8 +1103,10 @@ ip/test_mgmt_ipv6_only.py: ####################################### ipfwd/test_dip_sip.py: skip: - reason: "Unsupported topology." + reason: "Unsupported topology or unsupported in specific Cisco platforms." + conditions_logical_operator: or conditions: + - "platform in ['x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" - "topo_type not in ['t0', 't1', 't2', 'm0', 'mx']" ipfwd/test_dir_bcast.py: From 979b9a2c1ee40c25c55ad1451c0c9be310f11fd2 Mon Sep 17 00:00:00 2001 From: zitingguo-ms Date: Mon, 11 Nov 2024 18:55:35 -0800 Subject: [PATCH 130/221] Add a new case to check if config exist (#15080) Description of PR Summary: Fixes # (issue) There has been an issue that missing exit in the FRR template that caused nht config is missed in the FRR config when vrf is configurated. After fixing the issue in sonic-net/sonic-buildimage#19587, add a new case to verify the 'ip nht resolve-via-default' should be present in FRR config whether vrf is configurated. --- tests/bgp/test_bgpmon.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/bgp/test_bgpmon.py b/tests/bgp/test_bgpmon.py index a2b413252ed..8954753d9b8 100644 --- a/tests/bgp/test_bgpmon.py +++ b/tests/bgp/test_bgpmon.py @@ -109,6 +109,17 @@ def build_syn_pkt(local_addr, peer_addr): return exp_packet +def test_resolve_via_default_exist(duthost): + """ + Test to verify if 'ip nht resolve-via-default' and 'ipv6 nht resolve-via-default' are present in global FRR config. + """ + frr_global_config = duthost.shell("vtysh -c 'show running-config'")['stdout'] + pytest_assert("ip nht resolve-via-default" in frr_global_config, + "ip nht resolve-via-default not present in global FRR config") + pytest_assert("ipv6 nht resolve-via-default" in frr_global_config, + "ipv6 nht resolve-via-default not present in global FRR config") + + def test_bgpmon(dut_with_default_route, localhost, enum_rand_one_frontend_asic_index, common_setup_teardown, set_timeout_for_bgpmon, ptfadapter, ptfhost): """ From 953710b13f8245c4750425bc8d9b2fa909f528d3 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:35:30 +0800 Subject: [PATCH 131/221] Remove skip_traffic_test fixture in sub_port_interfaces tests (#15457) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in sub_port_interfaces tests How did you verify/test it? --- .../sub_port_interfaces/sub_ports_helpers.py | 21 +++++++++++-------- .../test_sub_port_interfaces.py | 21 +++++++------------ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/tests/sub_port_interfaces/sub_ports_helpers.py b/tests/sub_port_interfaces/sub_ports_helpers.py index f92730b54b4..f509b6a8abc 100644 --- a/tests/sub_port_interfaces/sub_ports_helpers.py +++ b/tests/sub_port_interfaces/sub_ports_helpers.py @@ -86,7 +86,7 @@ def create_packet(eth_dst, eth_src, ip_dst, ip_src, vlan_vid, tr_type, ttl, dl_v def generate_and_verify_traffic(duthost, ptfadapter, src_port, dst_port, ptfhost=None, ip_src='', ip_dst='', pkt_action=None, type_of_traffic='ICMP', ttl=64, pktlen=100, ip_tunnel=None, - skip_traffic_test=False, **kwargs): + **kwargs): """ Send packet from PTF to DUT and verify that DUT sends/doesn't packet to PTF. @@ -105,9 +105,6 @@ def generate_and_verify_traffic(duthost, ptfadapter, src_port, dst_port, ptfhost pktlen: packet length ip_tunnel: Tunnel IP address of DUT """ - if skip_traffic_test is True: - logger.info("Skipping traffic test") - return type_of_traffic = [type_of_traffic] if not isinstance(type_of_traffic, list) else type_of_traffic for tr_type in type_of_traffic: @@ -150,6 +147,7 @@ def generate_and_verify_tcp_udp_traffic(duthost, ptfadapter, src_port, dst_port, src_dl_vlan_enable = False dst_dl_vlan_enable = False router_mac = duthost.facts['router_mac'] + asic_type = duthost.facts['asic_type'] src_port_number = int(get_port_number(src_port)) dst_port_number = int(get_port_number(dst_port)) src_mac = ptfadapter.dataplane.get_mac(0, src_port_number).decode() @@ -198,7 +196,8 @@ def generate_and_verify_tcp_udp_traffic(duthost, ptfadapter, src_port, dst_port, pkt_in_buffer = pkt_filter.filter_pkt_in_buffer() - pytest_assert(pkt_in_buffer is True, "Expected packet not available:\n{}".format(pkt_in_buffer)) + if asic_type != 'vs': + pytest_assert(pkt_in_buffer is True, "Expected packet not available:\n{}".format(pkt_in_buffer)) def generate_and_verify_icmp_traffic(duthost, ptfadapter, src_port, dst_port, ip_src, ip_dst, pkt_action, tr_type, @@ -288,6 +287,7 @@ def generate_and_verify_decap_traffic(duthost, ptfadapter, src_port, dst_port, i ip_tunnel: Tunnel IP address of DUT """ router_mac = duthost.facts['router_mac'] + asic_type = duthost.facts['asic_type'] src_port_number = int(get_port_number(src_port)) dst_port_number = int(get_port_number(dst_port)) @@ -327,7 +327,8 @@ def generate_and_verify_decap_traffic(duthost, ptfadapter, src_port, dst_port, i pkt_in_buffer = pkt_filter.filter_pkt_in_buffer() - pytest_assert(pkt_in_buffer is True, "Expected packet not available:\n{}".format(pkt_in_buffer)) + if asic_type != 'vs': + pytest_assert(pkt_in_buffer is True, "Expected packet not available:\n{}".format(pkt_in_buffer)) def generate_and_verify_balancing_traffic(duthost, ptfhost, ptfadapter, src_port, dst_port, ip_src, ip_dst, @@ -347,6 +348,7 @@ def generate_and_verify_balancing_traffic(duthost, ptfhost, ptfadapter, src_port ttl: Time to live """ router_mac = duthost.facts['router_mac'] + asic_type = duthost.facts['asic_type'] src_port_number = int(get_port_number(src_port)) src_mac = ptfadapter.dataplane.get_mac(0, src_port_number) ip_src = '10.0.0.1' @@ -403,9 +405,10 @@ def generate_and_verify_balancing_traffic(duthost, ptfhost, ptfadapter, src_port pkt_in_buffer = pkt_filter.filter_pkt_in_buffer() - pytest_assert(pkt_in_buffer is True, "Expected packet not available:\n{}".format(pkt_in_buffer)) - pytest_assert(check_balancing(pkt_filter.matched_index), - "Balancing error:\n{}".format(pkt_filter.matched_index)) + if asic_type != 'vs': + pytest_assert(pkt_in_buffer is True, "Expected packet not available:\n{}".format(pkt_in_buffer)) + pytest_assert(check_balancing(pkt_filter.matched_index), + "Balancing error:\n{}".format(pkt_filter.matched_index)) def shutdown_port(duthost, interface): diff --git a/tests/sub_port_interfaces/test_sub_port_interfaces.py b/tests/sub_port_interfaces/test_sub_port_interfaces.py index c3bba0e73d5..bde70b883f9 100644 --- a/tests/sub_port_interfaces/test_sub_port_interfaces.py +++ b/tests/sub_port_interfaces/test_sub_port_interfaces.py @@ -15,7 +15,6 @@ from sub_ports_helpers import check_sub_port from sub_ports_helpers import remove_sub_port from sub_ports_helpers import create_sub_port_on_dut -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 pytestmark = [ pytest.mark.topology('t0', 't1') @@ -347,7 +346,7 @@ def test_routing_between_sub_ports_and_port(self, request, type_of_traffic, duth pktlen=pktlen) def test_tunneling_between_sub_ports(self, duthost, ptfadapter, apply_tunnel_table_to_dut, - apply_route_config, skip_traffic_test): # noqa F811 + apply_route_config): """ Validates that packets are routed between sub-ports. @@ -380,11 +379,10 @@ def test_tunneling_between_sub_ports(self, duthost, ptfadapter, apply_tunnel_tab ip_tunnel=sub_ports[src_port]['ip'], pkt_action='fwd', type_of_traffic='decap', - ttl=63, - skip_traffic_test=skip_traffic_test) + ttl=63) def test_balancing_sub_ports(self, duthost, ptfhost, ptfadapter, - apply_balancing_config, skip_traffic_test): # noqa F811 + apply_balancing_config): """ Validates load-balancing when sub-port is part of ECMP Test steps: @@ -417,13 +415,12 @@ def test_balancing_sub_ports(self, duthost, ptfhost, ptfadapter, dst_port=dst_ports, ip_dst=ip_dst, type_of_traffic='balancing', - ttl=63, - skip_traffic_test=skip_traffic_test) + ttl=63) class TestSubPortsNegative(object): def test_packet_routed_with_invalid_vlan(self, duthost, ptfadapter, apply_config_on_the_dut, - apply_config_on_the_ptf, skip_traffic_test): # noqa F811 + apply_config_on_the_ptf): """ Validates that packet aren't routed if sub-ports have invalid VLAN ID. @@ -447,13 +444,12 @@ def test_packet_routed_with_invalid_vlan(self, duthost, ptfadapter, apply_config ip_src=value['neighbor_ip'], dst_port=sub_port, ip_dst=value['ip'], - pkt_action='drop', - skip_traffic_test=skip_traffic_test) + pkt_action='drop') class TestSubPortStress(object): def test_max_numbers_of_sub_ports(self, duthost, ptfadapter, apply_config_on_the_dut, - apply_config_on_the_ptf, skip_traffic_test): # noqa F811 + apply_config_on_the_ptf): """ Validates that 256 sub-ports can be created per port or LAG @@ -486,5 +482,4 @@ def test_max_numbers_of_sub_ports(self, duthost, ptfadapter, apply_config_on_the ip_src=value['neighbor_ip'], dst_port=sub_port, ip_dst=value['ip'], - pkt_action='fwd', - skip_traffic_test=skip_traffic_test) + pkt_action='fwd') From 1bff8b830142ba2c1673641e3b1dc60cfea7cf8e Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:35:45 +0800 Subject: [PATCH 132/221] Remove skip_traffic_test fixture in ip tests (#15455) What is the motivation for this PR? Currently we are using conditional mark to add marker, then use pytest hook to redirect testutils.verify function to a function always return True to skip traffic test. With this change, the skip_traffic_test fixture is no longer needed in test cases, streamlining the test code and improving clarity. How did you do it? Remove skip_traffic_test fixture in ip tests How did you verify/test it? --- tests/ip/test_ip_packet.py | 50 ++++++++++++++++++++++------------- tests/ipfwd/test_dir_bcast.py | 6 ++--- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/tests/ip/test_ip_packet.py b/tests/ip/test_ip_packet.py index ac0ad5ef303..9d12aa3ee79 100644 --- a/tests/ip/test_ip_packet.py +++ b/tests/ip/test_ip_packet.py @@ -12,7 +12,6 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.portstat_utilities import parse_column_positions from tests.common.portstat_utilities import parse_portstat -from tests.common.fixtures.ptfhost_utils import skip_traffic_test # noqa F401 from tests.common.helpers.dut_utils import is_mellanox_fanout @@ -195,12 +194,13 @@ def common_param(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, tbin .format(prefix, selected_peer_ip_ifaces_pairs[1][0]), ptf_port_idx_namespace)) def test_forward_ip_packet_with_0x0000_chksum(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a ip packet with checksum 0x0000(compute from scratch) # WHEN send the packet to DUT # THEN DUT should forward it as normal ip packet duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, ptf_indices, ingress_router_mac) = common_param pkt = testutils.simple_ip_packet( @@ -251,7 +251,8 @@ def test_forward_ip_packet_with_0x0000_chksum(self, duthosts, enum_rand_one_per_ tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -266,12 +267,13 @@ def test_forward_ip_packet_with_0x0000_chksum(self, duthosts, enum_rand_one_per_ .format(tx_ok, match_cnt)) def test_forward_ip_packet_with_0xffff_chksum_tolerant(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a ip packet with checksum 0x0000(compute from scratch) # WHEN manually set checksum as 0xffff and send the packet to DUT # THEN DUT should tolerant packet with 0xffff, forward it as normal packet duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, ptf_indices, ingress_router_mac) = common_param pkt = testutils.simple_ip_packet( @@ -322,7 +324,8 @@ def test_forward_ip_packet_with_0xffff_chksum_tolerant(self, duthosts, enum_rand tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -338,13 +341,14 @@ def test_forward_ip_packet_with_0xffff_chksum_tolerant(self, duthosts, enum_rand def test_forward_ip_packet_with_0xffff_chksum_drop(self, duthosts, localhost, enum_rand_one_per_hwsku_frontend_hostname, ptfadapter, - common_param, tbinfo, skip_traffic_test): # noqa F811 + common_param, tbinfo): # GIVEN a ip packet with checksum 0x0000(compute from scratch) # WHEN manually set checksum as 0xffff and send the packet to DUT # THEN DUT should drop packet with 0xffff and add drop count duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] if is_mellanox_fanout(duthost, localhost): pytest.skip("Not supported at Mellanox fanout") (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, @@ -404,7 +408,8 @@ def test_forward_ip_packet_with_0xffff_chksum_drop(self, duthosts, localhost, logger.info("Setting PKT_NUM_ZERO for t2 max topology with 0.2 tolerance") self.PKT_NUM_ZERO = self.PKT_NUM * 0.2 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -419,7 +424,7 @@ def test_forward_ip_packet_with_0xffff_chksum_drop(self, duthosts, localhost, .format(match_cnt)) def test_forward_ip_packet_recomputed_0xffff_chksum(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a ip packet, after forwarded(ttl-1) by DUT, # it's checksum will be 0xffff after wrongly incrementally recomputed # ref to https://datatracker.ietf.org/doc/html/rfc1624 @@ -428,6 +433,7 @@ def test_forward_ip_packet_recomputed_0xffff_chksum(self, duthosts, enum_rand_on # THEN DUT recompute new checksum correctly and forward packet as expected. duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, ptf_indices, ingress_router_mac) = common_param pkt = testutils.simple_ip_packet( @@ -477,7 +483,8 @@ def test_forward_ip_packet_recomputed_0xffff_chksum(self, duthosts, enum_rand_on tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -492,12 +499,13 @@ def test_forward_ip_packet_recomputed_0xffff_chksum(self, duthosts, enum_rand_on .format(tx_ok, match_cnt)) def test_forward_ip_packet_recomputed_0x0000_chksum(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a ip packet, after forwarded(ttl-1) by DUT, it's checksum will be 0x0000 after recompute from scratch # WHEN send the packet to DUT # THEN DUT recompute new checksum as 0x0000 and forward packet as expected. duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, ptf_indices, ingress_router_mac) = common_param pkt = testutils.simple_ip_packet( @@ -547,7 +555,8 @@ def test_forward_ip_packet_recomputed_0x0000_chksum(self, duthosts, enum_rand_on tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -562,11 +571,12 @@ def test_forward_ip_packet_recomputed_0x0000_chksum(self, duthosts, enum_rand_on .format(tx_ok, match_cnt)) def test_forward_normal_ip_packet(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a random normal ip packet # WHEN send the packet to DUT # THEN DUT should forward it as normal ip packet, nothing change but ttl-1 duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, ptf_indices, ingress_router_mac) = common_param pkt = testutils.simple_ip_packet( @@ -610,7 +620,8 @@ def test_forward_normal_ip_packet(self, duthosts, enum_rand_one_per_hwsku_fronte tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -625,11 +636,12 @@ def test_forward_normal_ip_packet(self, duthosts, enum_rand_one_per_hwsku_fronte .format(tx_ok, match_cnt)) def test_drop_ip_packet_with_wrong_0xffff_chksum(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a random normal ip packet, and manually modify checksum to 0xffff # WHEN send the packet to DUT # THEN DUT should drop it and add drop count duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, ptf_indices, ingress_router_mac) = common_param pkt = testutils.simple_ip_packet( @@ -665,8 +677,8 @@ def test_drop_ip_packet_with_wrong_0xffff_chksum(self, duthosts, enum_rand_one_p tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - asic_type = duthost.facts['asic_type'] - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) @@ -678,11 +690,12 @@ def test_drop_ip_packet_with_wrong_0xffff_chksum(self, duthosts, enum_rand_one_p "Dropped {} packets in tx, not in expected range".format(tx_err)) def test_drop_l3_ip_packet_non_dut_mac(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - ptfadapter, common_param, skip_traffic_test): # noqa F811 + ptfadapter, common_param): # GIVEN a random normal ip packet, and random dest mac address # WHEN send the packet to DUT with dst_mac != ingress_router_mac to a layer 3 interface # THEN DUT should drop it and add drop count duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + asic_type = duthost.facts["asic_type"] (peer_ip_ifaces_pair, rif_rx_ifaces, rif_support, ptf_port_idx, pc_ports_map, _, ingress_router_mac) = common_param @@ -721,7 +734,8 @@ def test_drop_l3_ip_packet_non_dut_mac(self, duthosts, enum_rand_one_per_hwsku_f tx_drp = TestIPPacket.sum_ifaces_counts(portstat_out, out_ifaces, "tx_drp") tx_rif_err = TestIPPacket.sum_ifaces_counts(rif_counter_out, out_rif_ifaces, "tx_err") if rif_support else 0 - if skip_traffic_test is True: + if asic_type == "vs": + logger.info("Skipping packet count check on VS platform") return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) diff --git a/tests/ipfwd/test_dir_bcast.py b/tests/ipfwd/test_dir_bcast.py index 0e07ce18111..1c462271bb5 100644 --- a/tests/ipfwd/test_dir_bcast.py +++ b/tests/ipfwd/test_dir_bcast.py @@ -2,7 +2,7 @@ import json import logging -from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory, skip_traffic_test # noqa F401 +from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 from tests.ptf_runner import ptf_runner from datetime import datetime from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports_to_rand_selected_tor_m # noqa F401 @@ -65,7 +65,7 @@ def ptf_test_port_map(duthost, ptfhost, mg_facts, testbed_type, tbinfo): def test_dir_bcast(duthosts, rand_one_dut_hostname, ptfhost, tbinfo, - toggle_all_simulator_ports_to_rand_selected_tor_m, skip_traffic_test): # noqa F811 + toggle_all_simulator_ports_to_rand_selected_tor_m): # noqa F811 duthost = duthosts[rand_one_dut_hostname] testbed_type = tbinfo['topo']['name'] @@ -81,8 +81,6 @@ def test_dir_bcast(duthosts, rand_one_dut_hostname, ptfhost, tbinfo, 'ptf_test_port_map': PTF_TEST_PORT_MAP } log_file = "/tmp/dir_bcast.BcastTest.{}.log".format(datetime.now().strftime("%Y-%m-%d-%H:%M:%S")) - if skip_traffic_test is True: - return ptf_runner( ptfhost, 'ptftests', From 9b81013c3bbcfa9d680ff36be813882a6d3fa5ca Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:31:35 +0800 Subject: [PATCH 133/221] [CI] Enhance elastictest template and test_plan.py, fix az token issue (#15497) * enhance elastictest template, use bash script instead of azcli task, improve and fix azlogin and get token when requesting APIs * Directly specify the value of MGMT_BRANCH as master. Because dynamic assignment does not take effect immediately for the conditional statement of pipeline yaml, the expected value of MGMT_BRANCH cannot be obtained, and the locally updated testplan.py cannot be used. Signed-off-by: Chun'ang Li --- .../run-test-elastictest-template.yml | 343 ++++++++---------- .azure-pipelines/test_plan.py | 334 ++++++++--------- azure-pipelines.yml | 20 +- 3 files changed, 331 insertions(+), 366 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 595a6cb3136..882ab9ce6b9 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -1,3 +1,10 @@ +# Description: +# - This template manages the entire life cycle of the Elastictest test plan in test pipelines. +# +# Important!!!: +# - This template is referenced in multiple pipelines. +# - Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. + parameters: - name: TOPOLOGY type: string @@ -184,206 +191,176 @@ steps: fi displayName: "Install azure-cli" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - - pip install PyYAML - - rm -f new_test_plan_id.txt - - python ./.azure-pipelines/test_plan.py create \ - -t ${{ parameters.TOPOLOGY }} \ - -o new_test_plan_id.txt \ - --min-worker ${{ parameters.MIN_WORKER }} \ - --max-worker ${{ parameters.MAX_WORKER }} \ - --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ - --test-set ${{ parameters.TEST_SET }} \ - --kvm-build-id $(KVM_BUILD_ID) \ - --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ - --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ - --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ - --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ - --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ - --image_url ${{ parameters.IMAGE_URL }} \ - --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ - --hwsku ${{ parameters.HWSKU }} \ - --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ - --platform ${{ parameters.PLATFORM }} \ - --testbed-name "${{ parameters.TESTBED_NAME }}" \ - --scripts "${{ parameters.SCRIPTS }}" \ - --features "${{ parameters.FEATURES }}" \ - --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ - --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ - --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ - --affinity='${{ parameters.AFFINITY }}' \ - --build-reason ${{ parameters.BUILD_REASON }} \ - --repo-name ${{ parameters.REPO_NAME }} \ - --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ - --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ - --retry-times ${{ parameters.RETRY_TIMES }} \ - --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ - --requester "${{ parameters.REQUESTER }}" \ - --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ - --test-plan-num ${{ parameters.TEST_PLAN_NUM }} - - TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo "Created test plan $TEST_PLAN_ID" - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - done - TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") - TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} - echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" + - script: | + set -e + + pip install PyYAML + + rm -f new_test_plan_id.txt + + python ./.azure-pipelines/test_plan.py create \ + -t ${{ parameters.TOPOLOGY }} \ + -o new_test_plan_id.txt \ + --min-worker ${{ parameters.MIN_WORKER }} \ + --max-worker ${{ parameters.MAX_WORKER }} \ + --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ + --test-set ${{ parameters.TEST_SET }} \ + --kvm-build-id $(KVM_BUILD_ID) \ + --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ + --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ + --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ + --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ + --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ + --image_url ${{ parameters.IMAGE_URL }} \ + --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ + --hwsku ${{ parameters.HWSKU }} \ + --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ + --platform ${{ parameters.PLATFORM }} \ + --testbed-name "${{ parameters.TESTBED_NAME }}" \ + --scripts "${{ parameters.SCRIPTS }}" \ + --features "${{ parameters.FEATURES }}" \ + --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ + --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ + --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ + --affinity='${{ parameters.AFFINITY }}' \ + --build-reason ${{ parameters.BUILD_REASON }} \ + --repo-name ${{ parameters.REPO_NAME }} \ + --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ + --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --retry-times ${{ parameters.RETRY_TIMES }} \ + --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ + --requester "${{ parameters.REQUESTER }}" \ + --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ + --test-plan-num ${{ parameters.TEST_PLAN_NUM }} + + TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo "Created test plan $TEST_PLAN_ID" + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + done + TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") + TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} + echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" displayName: "Trigger test" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Lock testbed" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" - echo "[test_plan.py] poll LOCK_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Lock testbed" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" + echo "[test_plan.py] poll LOCK_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Lock testbed" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Prepare testbed" - echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" - echo "[test_plan.py] poll PREPARE_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Prepare testbed" + echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" + echo "[test_plan.py] poll PREPARE_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Prepare testbed" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -o - echo "Run test" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" - echo "[test_plan.py] poll EXECUTING status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - script: | + set -o + echo "Run test" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" + echo "[test_plan.py] poll EXECUTING status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Run test" timeoutInMinutes: ${{ parameters.MAX_RUN_TEST_MINUTES }} - ${{ if eq(parameters.DUMP_KVM_IF_FAIL, 'True') }}: - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - echo "KVM dump" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" - echo "##[group][test_plan.py] poll KVMDUMP status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP - done + - script: | + set -e + echo "KVM dump" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" + echo "##[group][test_plan.py] poll KVMDUMP status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP + done condition: succeededOrFailed() displayName: "KVM dump" - - task: AzureCLI@2 - inputs: - azureSubscription: "SONiC-Automation" - scriptType: 'bash' - scriptLocation: 'inlineScript' - inlineScript: | - set -e - echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID - done + - script: | + set -e + echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID + done condition: always() displayName: "Finalize running test plan" diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index f4b07bb2d18..1cc48fdbd31 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -1,3 +1,12 @@ +""" +Description: +- This script provides access to Elastictest test plan API, including creating, canceling, and polling status. + +Important!!!: +- This script is downloaded in multiple pipelines. +- Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. +""" + from __future__ import print_function, division import argparse @@ -8,7 +17,7 @@ import subprocess import copy import time -from datetime import datetime, timedelta +from datetime import datetime, timezone import requests import yaml @@ -22,8 +31,7 @@ INTERNAL_SONIC_MGMT_REPO = "https://dev.azure.com/mssonic/internal/_git/sonic-mgmt-int" PR_TEST_SCRIPTS_FILE = "pr_test_scripts.yaml" SPECIFIC_PARAM_KEYWORD = "specific_param" -TOLERATE_HTTP_EXCEPTION_TIMES = 20 -TOKEN_EXPIRE_HOURS = 1 +MAX_POLL_RETRY_TIMES = 10 MAX_GET_TOKEN_RETRY_TIMES = 3 TEST_PLAN_STATUS_UNSUCCESSFUL_FINISHED = ["FAILED", "CANCELLED"] TEST_PLAN_STEP_STATUS_UNFINISHED = ["EXECUTING", None] @@ -83,13 +91,15 @@ def __init__(self, status): def get_status(self): return self.status.value - def print_logs(self, test_plan_id, resp_data, start_time): + def print_logs(self, test_plan_id, resp_data, expected_status, start_time): status = resp_data.get("status", None) current_status = test_plan_status_factory(status).get_status() if current_status == self.get_status(): - print("Test plan id: {}, status: {}, elapsed: {:.0f} seconds" - .format(test_plan_id, resp_data.get("status", None), time.time() - start_time)) + print( + f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " + f"expected_status: {expected_status}, elapsed: {time.time() - start_time:.0f} seconds" + ) class InitStatus(AbstractStatus): @@ -111,10 +121,12 @@ class ExecutingStatus(AbstractStatus): def __init__(self): super(ExecutingStatus, self).__init__(TestPlanStatus.EXECUTING) - def print_logs(self, test_plan_id, resp_data, start_time): - print("Test plan id: {}, status: {}, progress: {:.2f}%, elapsed: {:.0f} seconds" - .format(test_plan_id, resp_data.get("status", None), - resp_data.get("progress", 0) * 100, time.time() - start_time)) + def print_logs(self, test_plan_id, resp_data, expected_status, start_time): + print( + f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " + f"expected_status: {expected_status}, progress: {resp_data.get('progress', 0) * 100:.2f}%, " + f"elapsed: {time.time() - start_time:.0f} seconds" + ) class KvmDumpStatus(AbstractStatus): @@ -150,74 +162,81 @@ def parse_list_from_str(s): if single_str.strip()] +def run_cmd(cmd): + process = subprocess.Popen( + cmd.split(), + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + return_code = process.returncode + + if return_code != 0: + raise Exception(f'Command {cmd} execution failed, rc={return_code}, error={stderr}') + return stdout, stderr, return_code + + class TestPlanManager(object): - def __init__(self, scheduler_url, community_url, frontend_url, client_id=None): + def __init__(self, scheduler_url, frontend_url, client_id, managed_identity_id): self.scheduler_url = scheduler_url - self.community_url = community_url self.frontend_url = frontend_url self.client_id = client_id - self.with_auth = False - self._token = None - self._token_expires_on = None - if self.client_id: - self.with_auth = True - self.get_token() - - def cmd(self, cmds): - process = subprocess.Popen( - cmds, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - stdout, stderr = process.communicate() - return_code = process.returncode - - return stdout, stderr, return_code - - def az_run(self, cmd): - stdout, stderr, retcode = self.cmd(cmd.split()) - if retcode != 0: - raise Exception(f'Command {cmd} execution failed, rc={retcode}, error={stderr}') - return stdout, stderr, retcode + self.managed_identity_id = managed_identity_id def get_token(self): - token_is_valid = \ - self._token_expires_on is not None and \ - (self._token_expires_on - datetime.now()) > timedelta(hours=TOKEN_EXPIRE_HOURS) + # 1. Run az login with re-try + az_login_cmd = f"az login --identity --username {self.managed_identity_id}" + az_login_attempts = 0 + while az_login_attempts < MAX_GET_TOKEN_RETRY_TIMES: + try: + stdout, _, _ = run_cmd(az_login_cmd) + print(f"Az login successfully. Login time: {datetime.now(timezone.utc)}") + break + except Exception as exception: + az_login_attempts += 1 + print( + f"Failed to az login with exception: {repr(exception)}. " + f"Retry {MAX_GET_TOKEN_RETRY_TIMES - az_login_attempts} times to login." + ) - if self._token is not None and token_is_valid: - return self._token + # If az login failed, return with exception + if az_login_attempts >= MAX_GET_TOKEN_RETRY_TIMES: + raise Exception(f"Failed to az login after {MAX_GET_TOKEN_RETRY_TIMES} attempts.") - cmd = 'az account get-access-token --resource {}'.format(self.client_id) - attempt = 0 - while attempt < MAX_GET_TOKEN_RETRY_TIMES: + # 2. Get access token with re-try + get_token_cmd = f"az account get-access-token --resource {self.client_id}" + get_token_attempts = 0 + while get_token_attempts < MAX_GET_TOKEN_RETRY_TIMES: try: - stdout, _, _ = self.az_run(cmd) + stdout, _, _ = run_cmd(get_token_cmd) token = json.loads(stdout.decode("utf-8")) - self._token = token.get("accessToken", None) - if not self._token: - raise Exception("Parse token from stdout failed") + access_token = token.get("accessToken", None) + if not access_token: + raise Exception("Parse token from stdout failed, accessToken is None.") # Parse token expires time from string token_expires_on = token.get("expiresOn", "") - self._token_expires_on = datetime.strptime(token_expires_on, "%Y-%m-%d %H:%M:%S.%f") - print("Get token successfully.") - return self._token + if token_expires_on: + print(f"Get token successfully. Token will expire on {token_expires_on}.") + + return access_token except Exception as exception: - attempt += 1 - print("Failed to get token with exception: {}".format(repr(exception))) + get_token_attempts += 1 + print(f"Failed to get token with exception: {repr(exception)}.") - raise Exception("Failed to get token after {} attempts".format(MAX_GET_TOKEN_RETRY_TIMES)) + # If az get token failed, return with exception + if get_token_attempts >= MAX_GET_TOKEN_RETRY_TIMES: + raise Exception(f"Failed to get token after {MAX_GET_TOKEN_RETRY_TIMES} attempts") def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params="", kvm_build_id="", min_worker=None, max_worker=None, pr_id="unknown", output=None, common_extra_params="", **kwargs): - tp_url = "{}/test_plan".format(self.scheduler_url) + tp_url = f"{self.scheduler_url}/test_plan" testbed_name = parse_list_from_str(kwargs.get("testbed_name", None)) image_url = kwargs.get("image_url", None) hwsku = kwargs.get("hwsku", None) @@ -229,8 +248,10 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) - print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, - repo_name, pr_id, build_id)) + print( + f"Creating test plan, topology: {topology}, name: {test_plan_name}, " + f"build info:{repo_name} {pr_id} {build_id}" + ) print("Test scripts to be covered in this test plan:") print(json.dumps(scripts, indent=4)) @@ -320,10 +341,9 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "extra_params": {}, "priority": 10 } - print('Creating test plan with payload:\n{}'.format(json.dumps(payload, indent=4))) + print(f"Creating test plan with payload:\n{json.dumps(payload, indent=4)}") headers = { - "Authorization": "Bearer {}".format(self.get_token()), - "scheduler-site": "PRTest", + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } raw_resp = {} @@ -331,17 +351,16 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params raw_resp = requests.post(tp_url, headers=headers, data=json.dumps(payload), timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" - .format(tp_url, str(raw_resp), str(exception))) + raise Exception(f"HTTP execute failure, url: {tp_url}, raw_resp: {raw_resp}, exception: {str(exception)}") if not resp["data"]: - raise Exception("Pre deploy action failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Create test plan failed with error: {resp['errmsg']}") if not resp["success"]: - raise Exception("Create test plan failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Create test plan failed with error: {resp['errmsg']}") - print("Result of creating test plan: {}".format(str(resp["data"]))) + print(f"Result of creating test plan: {str(resp['data'])}") if output: - print("Store new test plan id to file {}".format(output)) + print(f"Store new test plan id to file {output}") with open(output, "a") as f: f.write(str(resp["data"]) + "\n") @@ -349,15 +368,14 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params def cancel(self, test_plan_id): - tp_url = "{}/test_plan/{}".format(self.scheduler_url, test_plan_id) - cancel_url = "{}/cancel".format(tp_url) + tp_url = f"{self.scheduler_url}/test_plan/{test_plan_id}" + cancel_url = f"{tp_url}/cancel" - print("Cancelling test plan at {}".format(cancel_url)) + print(f"Cancelling test plan at {cancel_url}") payload = json.dumps({}) headers = { - "Authorization": "Bearer {}".format(self.get_token()), - "scheduler-site": "PRTest", + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } @@ -366,73 +384,57 @@ def cancel(self, test_plan_id): raw_resp = requests.post(cancel_url, headers=headers, data=payload, timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" - .format(cancel_url, str(raw_resp), str(exception))) + raise Exception(f"HTTP execute failure, url: {cancel_url}, raw_resp: {str(raw_resp)}, " + f"exception: {str(exception)}") if not resp["success"]: - raise Exception("Cancel test plan failed with error: {}".format(resp["errmsg"])) + raise Exception(f"Cancel test plan failed with error: {resp['errmsg']}") - print("Result of cancelling test plan at {}:".format(tp_url)) + print(f"Result of cancelling test plan at {tp_url}:") print(str(resp["data"])) def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expected_result=None): - print("Polling progress and status of test plan at {}/scheduler/testplan/{}" - .format(self.frontend_url, test_plan_id)) - print("Polling interval: {} seconds".format(interval)) + print(f"Polling progress and status of test plan at {self.frontend_url}/scheduler/testplan/{test_plan_id}") + print(f"Polling interval: {interval} seconds") - poll_url = "{}/test_plan/{}/get_test_plan_status".format(self.scheduler_url, test_plan_id) - poll_url_no_auth = "{}/get_test_plan_status/{}".format(self.community_url, test_plan_id) + poll_url = f"{self.scheduler_url}/test_plan/{test_plan_id}/get_test_plan_status" + # In current polling task, initialize headers one time to avoid frequent token accessing + # For some tasks running over 24h, then token may expire, need a fresh headers = { + "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } start_time = time.time() - http_exception_times = 0 - http_exception_times_no_auth = 0 - failed_poll_auth_url = False + poll_retry_times = 0 while timeout < 0 or (time.time() - start_time) < timeout: resp = None - # To make the transition smoother, first try to access the original API - if not failed_poll_auth_url: - try: - if self.with_auth: - headers["Authorization"] = "Bearer {}".format(self.get_token()) - resp = requests.get(poll_url, headers=headers, timeout=10).json() - except Exception as exception: - print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url, resp, - str(exception))) - http_exception_times = http_exception_times + 1 - if http_exception_times >= TOLERATE_HTTP_EXCEPTION_TIMES: - failed_poll_auth_url = True - else: - time.sleep(interval) - continue - - # If failed on poll auth url(most likely token has expired), try with no-auth url - else: - print("Polling test plan status failed with auth url, try with no-auth url.") - try: - resp = requests.get(poll_url_no_auth, headers={"Content-Type": "application/json"}, - timeout=10).json() - except Exception as e: - print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, - repr(e))) - http_exception_times_no_auth = http_exception_times_no_auth + 1 - if http_exception_times_no_auth >= TOLERATE_HTTP_EXCEPTION_TIMES: - raise Exception( - "HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, - repr(e))) - else: - time.sleep(interval) - continue + try: + resp = requests.get(poll_url, headers=headers, timeout=10).json() - if not resp: - raise Exception("Poll test plan status failed with request error, no response!") + if not resp: + raise Exception("Poll test plan status failed with request error, no response!") - if not resp["success"]: - raise Exception("Query test plan at {} failed with error: {}".format(poll_url, resp["errmsg"])) + if not resp["success"]: + raise Exception(f"Get test plan status failed with error: {resp['errmsg']}") + + resp_data = resp.get("data", None) + if not resp_data: + raise Exception("No valid data in response.") + + except Exception as exception: + print(f"Failed to get valid response, url: {poll_url}, raw_resp: {resp}, exception: {str(exception)}") - resp_data = resp.get("data", None) - if not resp_data: - raise Exception("No valid data in response: {}".format(str(resp))) + # Refresh headers token to address token expiration issue + headers = { + "Authorization": f"Bearer {self.get_token()}", + "Content-Type": "application/json" + } + + poll_retry_times = poll_retry_times + 1 + if poll_retry_times >= MAX_POLL_RETRY_TIMES: + raise Exception("Poll test plan status failed, exceeded the maximum number of retries.") + else: + time.sleep(interval) + continue current_tp_status = resp_data.get("status", None) current_tp_result = resp_data.get("result", None) @@ -441,11 +443,10 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte current_status = test_plan_status_factory(current_tp_status) expected_status = test_plan_status_factory(expected_state) - print("current test plan status: {}, expected status: {}".format(current_tp_status, expected_state)) + current_status.print_logs(test_plan_id, resp_data, expected_state, start_time) - if expected_status.get_status() == current_status.get_status(): - current_status.print_logs(test_plan_id, resp_data, start_time) - elif expected_status.get_status() < current_status.get_status(): + # If test plan has finished current step, its now status will behind the expected status + if expected_status.get_status() < current_status.get_status(): steps = None step_status = None runtime = resp_data.get("runtime", None) @@ -460,7 +461,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print test summary test_summary = resp_data.get("runtime", {}).get("test_summary", None) if test_summary: - print("Test summary:\n{}".format(json.dumps(test_summary, indent=4))) + print(f"Test summary:\n{json.dumps(test_summary, indent=4)}") """ In below scenarios, need to return false to pipeline. @@ -477,38 +478,34 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print error type and message err_code = resp_data.get("runtime", {}).get("err_code", None) if err_code: - print("Error type: {}".format(err_code)) + print(f"Error type: {err_code}") err_msg = resp_data.get("runtime", {}).get("message", None) if err_msg: - print("Error message: {}".format(err_msg)) + print(f"Error message: {err_msg}") - raise Exception("Test plan id: {}, status: {}, result: {}, Elapsed {:.0f} seconds. " - "Check {}/scheduler/testplan/{} for test plan status" - .format(test_plan_id, step_status, current_tp_result, time.time() - start_time, - self.frontend_url, - test_plan_id)) + raise Exception( + f"Test plan id: {test_plan_id}, status: {step_status}, " + f"result: {current_tp_result}, Elapsed {time.time() - start_time:.0f} seconds. " + f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" + ) if expected_result: if current_tp_result != expected_result: - raise Exception("Test plan id: {}, status: {}, result: {} not match expected result: {}, " - "Elapsed {:.0f} seconds. " - "Check {}/scheduler/testplan/{} for test plan status" - .format(test_plan_id, step_status, current_tp_result, - expected_result, time.time() - start_time, - self.frontend_url, - test_plan_id)) - - print("Current step status is {}".format(step_status)) + raise Exception( + f"Test plan id: {test_plan_id}, status: {step_status}, " + f"result: {current_tp_result} not match expected result: {expected_result}, " + f"Elapsed {time.time() - start_time:.0f} seconds. " + f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" + ) + + print(f"Current step status is {step_status}.") return - else: - print("Current test plan state is {}, waiting for the expected state {}".format(current_tp_status, - expected_state)) time.sleep(interval) else: raise PollTimeoutException( - "Max polling time reached, test plan at {} is not successfully finished or cancelled".format(poll_url) + f"Max polling time reached, test plan at {poll_url} is not successfully finished or cancelled" ) @@ -930,30 +927,28 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # https://github.com/microsoft/azure-pipelines-tasks/issues/10331 args.test_plan_id = args.test_plan_id.replace("'", "") - print("Test plan utils parameters: {}".format(args)) - auth_env = ["CLIENT_ID"] - required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL"] + print(f"Test plan utils parameters: {args}") - if args.action in ["create", "cancel"]: - required_env.extend(auth_env) + required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL", "CLIENT_ID", "SONIC_AUTOMATION_UMI"] env = { - "elastictest_scheduler_backend_url": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), - "elastictest_community_url": os.environ.get("ELASTICTEST_COMMUNITY_URL"), - "client_id": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), - "frontend_url": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), + "ELASTICTEST_SCHEDULER_BACKEND_URL": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), + "CLIENT_ID": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), + "FRONTEND_URL": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), + "SONIC_AUTOMATION_UMI": os.environ.get("SONIC_AUTOMATION_UMI"), } env_missing = [k.upper() for k, v in env.items() if k.upper() in required_env and not v] if env_missing: - print("Missing required environment variables: {}".format(env_missing)) + print(f"Missing required environment variables: {env_missing}.") sys.exit(1) try: tp = TestPlanManager( - env["elastictest_scheduler_backend_url"], - env["elastictest_community_url"], - env["frontend_url"], - env["client_id"]) + env["ELASTICTEST_SCHEDULER_BACKEND_URL"], + env["FRONTEND_URL"], + env["CLIENT_ID"], + env["SONIC_AUTOMATION_UMI"] + ) if args.action == "create": pr_id = os.environ.get("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") or os.environ.get( @@ -964,14 +959,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte job_name = os.environ.get("SYSTEM_JOBDISPLAYNAME") repo_name = args.repo_name if args.repo_name else os.environ.get("BUILD_REPOSITORY_NAME") - test_plan_prefix = "{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}" \ - .format( - repo=repo, - reason=reason, - pr_id=pr_id, - build_id=build_id, - job_name=job_name - ).replace(' ', '_') + test_plan_prefix = f"{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}".replace(' ', '_') scripts = args.scripts specific_param = json.loads(args.specific_param) @@ -989,7 +977,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte for num in range(args.test_plan_num): test_plan_name = copy.copy(test_plan_prefix) if args.test_plan_num > 1: - test_plan_name = "{}_{}".format(test_plan_name, num + 1) + test_plan_name = f"{test_plan_name}_{num + 1}" tp.create( args.topology, @@ -1033,8 +1021,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte tp.cancel(args.test_plan_id) sys.exit(0) except PollTimeoutException as e: - print("Polling test plan failed with exception: {}".format(repr(e))) + print(f"Polling test plan failed with exception: {repr(e)}") sys.exit(2) except Exception as e: - print("Operation failed with exception: {}".format(repr(e))) + print(f"Operation failed with exception: {repr(e)}") sys.exit(3) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1256f817404..d268873c065 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -71,7 +71,7 @@ stages: MIN_WORKER: $(T0_INSTANCE_NUM) MAX_WORKER: $(T0_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: t0_2vlans_elastictest displayName: "kvmtest-t0-2vlans by Elastictest" @@ -87,7 +87,7 @@ stages: MAX_WORKER: $(T0_2VLANS_INSTANCE_NUM) DEPLOY_MG_EXTRA_PARAMS: "-e vlan_config=two_vlan_a" KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: t1_lag_elastictest displayName: "kvmtest-t1-lag by Elastictest" @@ -101,7 +101,7 @@ stages: MIN_WORKER: $(T1_LAG_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: dualtor_elastictest displayName: "kvmtest-dualtor-t0 by Elastictest" @@ -116,7 +116,7 @@ stages: MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) COMMON_EXTRA_PARAMS: "--disable_loganalyzer " KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: multi_asic_elastictest displayName: "kvmtest-multi-asic-t1-lag by Elastictest" @@ -132,7 +132,7 @@ stages: MAX_WORKER: $(MULTI_ASIC_INSTANCE_NUM) NUM_ASIC: 4 KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: sonic_t0_elastictest displayName: "kvmtest-t0-sonic by Elastictest" @@ -149,7 +149,7 @@ stages: COMMON_EXTRA_PARAMS: "--neighbor_type=sonic " VM_TYPE: vsonic KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: dpu_elastictest displayName: "kvmtest-dpu by Elastictest" @@ -163,7 +163,7 @@ stages: MIN_WORKER: $(T0_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: onboarding_elastictest_t0 displayName: "onboarding t0 testcases by Elastictest - optional" @@ -179,7 +179,7 @@ stages: MIN_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" TEST_SET: onboarding_t0 - job: onboarding_elastictest_t1 @@ -196,7 +196,7 @@ stages: MIN_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" TEST_SET: onboarding_t1 # - job: onboarding_elastictest_dualtor @@ -213,7 +213,7 @@ stages: # MIN_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # KVM_IMAGE_BRANCH: $(BUILD_BRANCH) -# MGMT_BRANCH: $(BUILD_BRANCH) +# MGMT_BRANCH: "master" # TEST_SET: onboarding_dualtor # - job: wan_elastictest From 1690f53aaa547c52c7ec868e6d7e682724b4c329 Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:00:01 +0800 Subject: [PATCH 134/221] =?UTF-8?q?Revert=20"[CI]=20Enhance=20elastictest?= =?UTF-8?q?=20template=20and=20test=5Fplan.py,=20fix=20az=20token=20issu?= =?UTF-8?q?=E2=80=A6"=20(#15502)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9b81013c3bbcfa9d680ff36be813882a6d3fa5ca. --- .../run-test-elastictest-template.yml | 343 ++++++++++-------- .azure-pipelines/test_plan.py | 334 +++++++++-------- azure-pipelines.yml | 20 +- 3 files changed, 366 insertions(+), 331 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 882ab9ce6b9..595a6cb3136 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -1,10 +1,3 @@ -# Description: -# - This template manages the entire life cycle of the Elastictest test plan in test pipelines. -# -# Important!!!: -# - This template is referenced in multiple pipelines. -# - Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. - parameters: - name: TOPOLOGY type: string @@ -191,176 +184,206 @@ steps: fi displayName: "Install azure-cli" - - script: | - set -e - - pip install PyYAML - - rm -f new_test_plan_id.txt - - python ./.azure-pipelines/test_plan.py create \ - -t ${{ parameters.TOPOLOGY }} \ - -o new_test_plan_id.txt \ - --min-worker ${{ parameters.MIN_WORKER }} \ - --max-worker ${{ parameters.MAX_WORKER }} \ - --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ - --test-set ${{ parameters.TEST_SET }} \ - --kvm-build-id $(KVM_BUILD_ID) \ - --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ - --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ - --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ - --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ - --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ - --image_url ${{ parameters.IMAGE_URL }} \ - --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ - --hwsku ${{ parameters.HWSKU }} \ - --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ - --platform ${{ parameters.PLATFORM }} \ - --testbed-name "${{ parameters.TESTBED_NAME }}" \ - --scripts "${{ parameters.SCRIPTS }}" \ - --features "${{ parameters.FEATURES }}" \ - --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ - --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ - --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ - --affinity='${{ parameters.AFFINITY }}' \ - --build-reason ${{ parameters.BUILD_REASON }} \ - --repo-name ${{ parameters.REPO_NAME }} \ - --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ - --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ - --retry-times ${{ parameters.RETRY_TIMES }} \ - --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ - --requester "${{ parameters.REQUESTER }}" \ - --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ - --test-plan-num ${{ parameters.TEST_PLAN_NUM }} - - TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo "Created test plan $TEST_PLAN_ID" - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - done - TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") - TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} - echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + + pip install PyYAML + + rm -f new_test_plan_id.txt + + python ./.azure-pipelines/test_plan.py create \ + -t ${{ parameters.TOPOLOGY }} \ + -o new_test_plan_id.txt \ + --min-worker ${{ parameters.MIN_WORKER }} \ + --max-worker ${{ parameters.MAX_WORKER }} \ + --lock-wait-timeout-seconds ${{ parameters.LOCK_WAIT_TIMEOUT_SECONDS }} \ + --test-set ${{ parameters.TEST_SET }} \ + --kvm-build-id $(KVM_BUILD_ID) \ + --kvm-image-branch "${{ parameters.KVM_IMAGE_BRANCH }}" \ + --deploy-mg-extra-params="${{ parameters.DEPLOY_MG_EXTRA_PARAMS }}" \ + --common-extra-params="${{ parameters.COMMON_EXTRA_PARAMS }}" \ + --vm-type ${{ parameters.VM_TYPE }} --num-asic ${{ parameters.NUM_ASIC }} \ + --ptf_image_tag ${{ parameters.PTF_IMAGE_TAG }} \ + --image_url ${{ parameters.IMAGE_URL }} \ + --upgrade-image-param="${{ parameters.UPGRADE_IMAGE_PARAM }}" \ + --hwsku ${{ parameters.HWSKU }} \ + --test-plan-type ${{ parameters.TEST_PLAN_TYPE }} \ + --platform ${{ parameters.PLATFORM }} \ + --testbed-name "${{ parameters.TESTBED_NAME }}" \ + --scripts "${{ parameters.SCRIPTS }}" \ + --features "${{ parameters.FEATURES }}" \ + --scripts-exclude "${{ parameters.SCRIPTS_EXCLUDE }}" \ + --features-exclude "${{ parameters.FEATURES_EXCLUDE }}" \ + --specific-param='${{ parameters.SPECIFIC_PARAM }}' \ + --affinity='${{ parameters.AFFINITY }}' \ + --build-reason ${{ parameters.BUILD_REASON }} \ + --repo-name ${{ parameters.REPO_NAME }} \ + --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ + --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --retry-times ${{ parameters.RETRY_TIMES }} \ + --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ + --requester "${{ parameters.REQUESTER }}" \ + --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ + --test-plan-num ${{ parameters.TEST_PLAN_NUM }} + + TEST_PLAN_ID_LIST=( $(cat new_test_plan_id.txt) ) + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo "Created test plan $TEST_PLAN_ID" + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + done + TEST_PLAN_ID_LIST_STRING=$(printf "%s," "${TEST_PLAN_ID_LIST[@]}") + TEST_PLAN_ID_LIST_STRING=${TEST_PLAN_ID_LIST_STRING%,} + echo "##vso[task.setvariable variable=TEST_PLAN_ID_LIST_STRING]$TEST_PLAN_ID_LIST_STRING" displayName: "Trigger test" - - script: | - set -o - echo "Lock testbed" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" - echo "[test_plan.py] poll LOCK_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Lock testbed" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "LOCK_TESTBED" finish, it changes into "PREPARE_TESTBED" + echo "[test_plan.py] poll LOCK_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state LOCK_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Lock testbed" - - script: | - set -o - echo "Prepare testbed" - echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" - echo "[test_plan.py] poll PREPARE_TESTBED status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Prepare testbed" + echo "Preparing the testbed(add-topo, deploy-mg) may take 15-30 minutes. Before the testbed is ready, the progress of the test plan keeps displayed as 0, please be patient" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "PREPARE_TESTBED" finish, it changes into "EXECUTING" + echo "[test_plan.py] poll PREPARE_TESTBED status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state PREPARE_TESTBED + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ "$failure_count" -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Prepare testbed" - - script: | - set -o - echo "Run test" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - failure_count=0 - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" - echo "[test_plan.py] poll EXECUTING status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} - RET=$? - if [ $RET -ne 0 ]; then - ((failure_count++)) - fi - done - - if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then - echo "All testplan failed, cancel following steps" - exit 3 - fi + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -o + echo "Run test" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + failure_count=0 + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "EXECUTING" finish, it changes into "KVMDUMP", "FAILED", "CANCELLED" or "FINISHED" + echo "[test_plan.py] poll EXECUTING status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state EXECUTING --expected-result ${{ parameters.EXPECTED_RESULT }} + RET=$? + if [ $RET -ne 0 ]; then + ((failure_count++)) + fi + done + + if [ $failure_count -eq ${#TEST_PLAN_ID_LIST[@]} ]; then + echo "All testplan failed, cancel following steps" + exit 3 + fi displayName: "Run test" timeoutInMinutes: ${{ parameters.MAX_RUN_TEST_MINUTES }} - ${{ if eq(parameters.DUMP_KVM_IF_FAIL, 'True') }}: - - script: | - set -e - echo "KVM dump" - - echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - echo -e -n "\033[33mPlease visit Elastictest page \033[0m" - echo -n "$(ELASTICTEST_FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " - echo -e "\033[33mfor detailed test plan progress \033[0m" - # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" - echo "##[group][test_plan.py] poll KVMDUMP status" - python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP - done + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + echo "KVM dump" + + echo -e "\033[33mSONiC PR system-level test is powered by SONiC Elastictest, for any issue, please send email to sonicelastictest@microsoft.com \033[0m" + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + echo -e -n "\033[33mPlease visit Elastictest page \033[0m" + echo -n "$(FRONTEND_URL)/scheduler/testplan/$TEST_PLAN_ID " + echo -e "\033[33mfor detailed test plan progress \033[0m" + # When "KVMDUMP" finish, it changes into "FAILED", "CANCELLED" or "FINISHED" + echo "##[group][test_plan.py] poll KVMDUMP status" + python ./.azure-pipelines/test_plan.py poll -i $TEST_PLAN_ID --expected-state KVMDUMP + done condition: succeededOrFailed() displayName: "KVM dump" - - script: | - set -e - echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." - IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" - for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" - do - python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID - done + - task: AzureCLI@2 + inputs: + azureSubscription: "SONiC-Automation" + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + set -e + echo "Try to cancel test plan $TEST_PLAN_ID, cancelling finished test plan has no effect." + IFS=',' read -ra TEST_PLAN_ID_LIST <<< "$TEST_PLAN_ID_LIST_STRING" + for TEST_PLAN_ID in "${TEST_PLAN_ID_LIST[@]}" + do + python ./.azure-pipelines/test_plan.py cancel -i $TEST_PLAN_ID + done condition: always() displayName: "Finalize running test plan" diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index 1cc48fdbd31..f4b07bb2d18 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -1,12 +1,3 @@ -""" -Description: -- This script provides access to Elastictest test plan API, including creating, canceling, and polling status. - -Important!!!: -- This script is downloaded in multiple pipelines. -- Any updates to this file must be tested on all dependent pipelines to ensure compatibility and prevent disruptions. -""" - from __future__ import print_function, division import argparse @@ -17,7 +8,7 @@ import subprocess import copy import time -from datetime import datetime, timezone +from datetime import datetime, timedelta import requests import yaml @@ -31,7 +22,8 @@ INTERNAL_SONIC_MGMT_REPO = "https://dev.azure.com/mssonic/internal/_git/sonic-mgmt-int" PR_TEST_SCRIPTS_FILE = "pr_test_scripts.yaml" SPECIFIC_PARAM_KEYWORD = "specific_param" -MAX_POLL_RETRY_TIMES = 10 +TOLERATE_HTTP_EXCEPTION_TIMES = 20 +TOKEN_EXPIRE_HOURS = 1 MAX_GET_TOKEN_RETRY_TIMES = 3 TEST_PLAN_STATUS_UNSUCCESSFUL_FINISHED = ["FAILED", "CANCELLED"] TEST_PLAN_STEP_STATUS_UNFINISHED = ["EXECUTING", None] @@ -91,15 +83,13 @@ def __init__(self, status): def get_status(self): return self.status.value - def print_logs(self, test_plan_id, resp_data, expected_status, start_time): + def print_logs(self, test_plan_id, resp_data, start_time): status = resp_data.get("status", None) current_status = test_plan_status_factory(status).get_status() if current_status == self.get_status(): - print( - f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " - f"expected_status: {expected_status}, elapsed: {time.time() - start_time:.0f} seconds" - ) + print("Test plan id: {}, status: {}, elapsed: {:.0f} seconds" + .format(test_plan_id, resp_data.get("status", None), time.time() - start_time)) class InitStatus(AbstractStatus): @@ -121,12 +111,10 @@ class ExecutingStatus(AbstractStatus): def __init__(self): super(ExecutingStatus, self).__init__(TestPlanStatus.EXECUTING) - def print_logs(self, test_plan_id, resp_data, expected_status, start_time): - print( - f"Test plan id: {test_plan_id}, status: {resp_data.get('status', None)}, " - f"expected_status: {expected_status}, progress: {resp_data.get('progress', 0) * 100:.2f}%, " - f"elapsed: {time.time() - start_time:.0f} seconds" - ) + def print_logs(self, test_plan_id, resp_data, start_time): + print("Test plan id: {}, status: {}, progress: {:.2f}%, elapsed: {:.0f} seconds" + .format(test_plan_id, resp_data.get("status", None), + resp_data.get("progress", 0) * 100, time.time() - start_time)) class KvmDumpStatus(AbstractStatus): @@ -162,81 +150,74 @@ def parse_list_from_str(s): if single_str.strip()] -def run_cmd(cmd): - process = subprocess.Popen( - cmd.split(), - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - stdout, stderr = process.communicate() - return_code = process.returncode - - if return_code != 0: - raise Exception(f'Command {cmd} execution failed, rc={return_code}, error={stderr}') - return stdout, stderr, return_code - - class TestPlanManager(object): - def __init__(self, scheduler_url, frontend_url, client_id, managed_identity_id): + def __init__(self, scheduler_url, community_url, frontend_url, client_id=None): self.scheduler_url = scheduler_url + self.community_url = community_url self.frontend_url = frontend_url self.client_id = client_id - self.managed_identity_id = managed_identity_id + self.with_auth = False + self._token = None + self._token_expires_on = None + if self.client_id: + self.with_auth = True + self.get_token() + + def cmd(self, cmds): + process = subprocess.Popen( + cmds, + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + return_code = process.returncode + + return stdout, stderr, return_code + + def az_run(self, cmd): + stdout, stderr, retcode = self.cmd(cmd.split()) + if retcode != 0: + raise Exception(f'Command {cmd} execution failed, rc={retcode}, error={stderr}') + return stdout, stderr, retcode def get_token(self): - # 1. Run az login with re-try - az_login_cmd = f"az login --identity --username {self.managed_identity_id}" - az_login_attempts = 0 - while az_login_attempts < MAX_GET_TOKEN_RETRY_TIMES: - try: - stdout, _, _ = run_cmd(az_login_cmd) - print(f"Az login successfully. Login time: {datetime.now(timezone.utc)}") - break - except Exception as exception: - az_login_attempts += 1 - print( - f"Failed to az login with exception: {repr(exception)}. " - f"Retry {MAX_GET_TOKEN_RETRY_TIMES - az_login_attempts} times to login." - ) + token_is_valid = \ + self._token_expires_on is not None and \ + (self._token_expires_on - datetime.now()) > timedelta(hours=TOKEN_EXPIRE_HOURS) - # If az login failed, return with exception - if az_login_attempts >= MAX_GET_TOKEN_RETRY_TIMES: - raise Exception(f"Failed to az login after {MAX_GET_TOKEN_RETRY_TIMES} attempts.") + if self._token is not None and token_is_valid: + return self._token - # 2. Get access token with re-try - get_token_cmd = f"az account get-access-token --resource {self.client_id}" - get_token_attempts = 0 - while get_token_attempts < MAX_GET_TOKEN_RETRY_TIMES: + cmd = 'az account get-access-token --resource {}'.format(self.client_id) + attempt = 0 + while attempt < MAX_GET_TOKEN_RETRY_TIMES: try: - stdout, _, _ = run_cmd(get_token_cmd) + stdout, _, _ = self.az_run(cmd) token = json.loads(stdout.decode("utf-8")) - access_token = token.get("accessToken", None) - if not access_token: - raise Exception("Parse token from stdout failed, accessToken is None.") + self._token = token.get("accessToken", None) + if not self._token: + raise Exception("Parse token from stdout failed") # Parse token expires time from string token_expires_on = token.get("expiresOn", "") - if token_expires_on: - print(f"Get token successfully. Token will expire on {token_expires_on}.") - - return access_token + self._token_expires_on = datetime.strptime(token_expires_on, "%Y-%m-%d %H:%M:%S.%f") + print("Get token successfully.") + return self._token except Exception as exception: - get_token_attempts += 1 - print(f"Failed to get token with exception: {repr(exception)}.") + attempt += 1 + print("Failed to get token with exception: {}".format(repr(exception))) - # If az get token failed, return with exception - if get_token_attempts >= MAX_GET_TOKEN_RETRY_TIMES: - raise Exception(f"Failed to get token after {MAX_GET_TOKEN_RETRY_TIMES} attempts") + raise Exception("Failed to get token after {} attempts".format(MAX_GET_TOKEN_RETRY_TIMES)) def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params="", kvm_build_id="", min_worker=None, max_worker=None, pr_id="unknown", output=None, common_extra_params="", **kwargs): - tp_url = f"{self.scheduler_url}/test_plan" + tp_url = "{}/test_plan".format(self.scheduler_url) testbed_name = parse_list_from_str(kwargs.get("testbed_name", None)) image_url = kwargs.get("image_url", None) hwsku = kwargs.get("hwsku", None) @@ -248,10 +229,8 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) - print( - f"Creating test plan, topology: {topology}, name: {test_plan_name}, " - f"build info:{repo_name} {pr_id} {build_id}" - ) + print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, + repo_name, pr_id, build_id)) print("Test scripts to be covered in this test plan:") print(json.dumps(scripts, indent=4)) @@ -341,9 +320,10 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "extra_params": {}, "priority": 10 } - print(f"Creating test plan with payload:\n{json.dumps(payload, indent=4)}") + print('Creating test plan with payload:\n{}'.format(json.dumps(payload, indent=4))) headers = { - "Authorization": f"Bearer {self.get_token()}", + "Authorization": "Bearer {}".format(self.get_token()), + "scheduler-site": "PRTest", "Content-Type": "application/json" } raw_resp = {} @@ -351,16 +331,17 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params raw_resp = requests.post(tp_url, headers=headers, data=json.dumps(payload), timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception(f"HTTP execute failure, url: {tp_url}, raw_resp: {raw_resp}, exception: {str(exception)}") + raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" + .format(tp_url, str(raw_resp), str(exception))) if not resp["data"]: - raise Exception(f"Create test plan failed with error: {resp['errmsg']}") + raise Exception("Pre deploy action failed with error: {}".format(resp["errmsg"])) if not resp["success"]: - raise Exception(f"Create test plan failed with error: {resp['errmsg']}") + raise Exception("Create test plan failed with error: {}".format(resp["errmsg"])) - print(f"Result of creating test plan: {str(resp['data'])}") + print("Result of creating test plan: {}".format(str(resp["data"]))) if output: - print(f"Store new test plan id to file {output}") + print("Store new test plan id to file {}".format(output)) with open(output, "a") as f: f.write(str(resp["data"]) + "\n") @@ -368,14 +349,15 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params def cancel(self, test_plan_id): - tp_url = f"{self.scheduler_url}/test_plan/{test_plan_id}" - cancel_url = f"{tp_url}/cancel" + tp_url = "{}/test_plan/{}".format(self.scheduler_url, test_plan_id) + cancel_url = "{}/cancel".format(tp_url) - print(f"Cancelling test plan at {cancel_url}") + print("Cancelling test plan at {}".format(cancel_url)) payload = json.dumps({}) headers = { - "Authorization": f"Bearer {self.get_token()}", + "Authorization": "Bearer {}".format(self.get_token()), + "scheduler-site": "PRTest", "Content-Type": "application/json" } @@ -384,57 +366,73 @@ def cancel(self, test_plan_id): raw_resp = requests.post(cancel_url, headers=headers, data=payload, timeout=10) resp = raw_resp.json() except Exception as exception: - raise Exception(f"HTTP execute failure, url: {cancel_url}, raw_resp: {str(raw_resp)}, " - f"exception: {str(exception)}") + raise Exception("HTTP execute failure, url: {}, raw_resp: {}, exception: {}" + .format(cancel_url, str(raw_resp), str(exception))) if not resp["success"]: - raise Exception(f"Cancel test plan failed with error: {resp['errmsg']}") + raise Exception("Cancel test plan failed with error: {}".format(resp["errmsg"])) - print(f"Result of cancelling test plan at {tp_url}:") + print("Result of cancelling test plan at {}:".format(tp_url)) print(str(resp["data"])) def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expected_result=None): - print(f"Polling progress and status of test plan at {self.frontend_url}/scheduler/testplan/{test_plan_id}") - print(f"Polling interval: {interval} seconds") + print("Polling progress and status of test plan at {}/scheduler/testplan/{}" + .format(self.frontend_url, test_plan_id)) + print("Polling interval: {} seconds".format(interval)) - poll_url = f"{self.scheduler_url}/test_plan/{test_plan_id}/get_test_plan_status" - # In current polling task, initialize headers one time to avoid frequent token accessing - # For some tasks running over 24h, then token may expire, need a fresh + poll_url = "{}/test_plan/{}/get_test_plan_status".format(self.scheduler_url, test_plan_id) + poll_url_no_auth = "{}/get_test_plan_status/{}".format(self.community_url, test_plan_id) headers = { - "Authorization": f"Bearer {self.get_token()}", "Content-Type": "application/json" } start_time = time.time() - poll_retry_times = 0 + http_exception_times = 0 + http_exception_times_no_auth = 0 + failed_poll_auth_url = False while timeout < 0 or (time.time() - start_time) < timeout: resp = None - try: - resp = requests.get(poll_url, headers=headers, timeout=10).json() - - if not resp: - raise Exception("Poll test plan status failed with request error, no response!") - - if not resp["success"]: - raise Exception(f"Get test plan status failed with error: {resp['errmsg']}") + # To make the transition smoother, first try to access the original API + if not failed_poll_auth_url: + try: + if self.with_auth: + headers["Authorization"] = "Bearer {}".format(self.get_token()) + resp = requests.get(poll_url, headers=headers, timeout=10).json() + except Exception as exception: + print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url, resp, + str(exception))) + http_exception_times = http_exception_times + 1 + if http_exception_times >= TOLERATE_HTTP_EXCEPTION_TIMES: + failed_poll_auth_url = True + else: + time.sleep(interval) + continue + + # If failed on poll auth url(most likely token has expired), try with no-auth url + else: + print("Polling test plan status failed with auth url, try with no-auth url.") + try: + resp = requests.get(poll_url_no_auth, headers={"Content-Type": "application/json"}, + timeout=10).json() + except Exception as e: + print("HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, + repr(e))) + http_exception_times_no_auth = http_exception_times_no_auth + 1 + if http_exception_times_no_auth >= TOLERATE_HTTP_EXCEPTION_TIMES: + raise Exception( + "HTTP execute failure, url: {}, raw_resp: {}, exception: {}".format(poll_url_no_auth, resp, + repr(e))) + else: + time.sleep(interval) + continue - resp_data = resp.get("data", None) - if not resp_data: - raise Exception("No valid data in response.") + if not resp: + raise Exception("Poll test plan status failed with request error, no response!") - except Exception as exception: - print(f"Failed to get valid response, url: {poll_url}, raw_resp: {resp}, exception: {str(exception)}") + if not resp["success"]: + raise Exception("Query test plan at {} failed with error: {}".format(poll_url, resp["errmsg"])) - # Refresh headers token to address token expiration issue - headers = { - "Authorization": f"Bearer {self.get_token()}", - "Content-Type": "application/json" - } - - poll_retry_times = poll_retry_times + 1 - if poll_retry_times >= MAX_POLL_RETRY_TIMES: - raise Exception("Poll test plan status failed, exceeded the maximum number of retries.") - else: - time.sleep(interval) - continue + resp_data = resp.get("data", None) + if not resp_data: + raise Exception("No valid data in response: {}".format(str(resp))) current_tp_status = resp_data.get("status", None) current_tp_result = resp_data.get("result", None) @@ -443,10 +441,11 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte current_status = test_plan_status_factory(current_tp_status) expected_status = test_plan_status_factory(expected_state) - current_status.print_logs(test_plan_id, resp_data, expected_state, start_time) + print("current test plan status: {}, expected status: {}".format(current_tp_status, expected_state)) - # If test plan has finished current step, its now status will behind the expected status - if expected_status.get_status() < current_status.get_status(): + if expected_status.get_status() == current_status.get_status(): + current_status.print_logs(test_plan_id, resp_data, start_time) + elif expected_status.get_status() < current_status.get_status(): steps = None step_status = None runtime = resp_data.get("runtime", None) @@ -461,7 +460,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print test summary test_summary = resp_data.get("runtime", {}).get("test_summary", None) if test_summary: - print(f"Test summary:\n{json.dumps(test_summary, indent=4)}") + print("Test summary:\n{}".format(json.dumps(test_summary, indent=4))) """ In below scenarios, need to return false to pipeline. @@ -478,34 +477,38 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # Print error type and message err_code = resp_data.get("runtime", {}).get("err_code", None) if err_code: - print(f"Error type: {err_code}") + print("Error type: {}".format(err_code)) err_msg = resp_data.get("runtime", {}).get("message", None) if err_msg: - print(f"Error message: {err_msg}") + print("Error message: {}".format(err_msg)) - raise Exception( - f"Test plan id: {test_plan_id}, status: {step_status}, " - f"result: {current_tp_result}, Elapsed {time.time() - start_time:.0f} seconds. " - f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" - ) + raise Exception("Test plan id: {}, status: {}, result: {}, Elapsed {:.0f} seconds. " + "Check {}/scheduler/testplan/{} for test plan status" + .format(test_plan_id, step_status, current_tp_result, time.time() - start_time, + self.frontend_url, + test_plan_id)) if expected_result: if current_tp_result != expected_result: - raise Exception( - f"Test plan id: {test_plan_id}, status: {step_status}, " - f"result: {current_tp_result} not match expected result: {expected_result}, " - f"Elapsed {time.time() - start_time:.0f} seconds. " - f"Check {self.frontend_url}/scheduler/testplan/{test_plan_id} for test plan status" - ) - - print(f"Current step status is {step_status}.") + raise Exception("Test plan id: {}, status: {}, result: {} not match expected result: {}, " + "Elapsed {:.0f} seconds. " + "Check {}/scheduler/testplan/{} for test plan status" + .format(test_plan_id, step_status, current_tp_result, + expected_result, time.time() - start_time, + self.frontend_url, + test_plan_id)) + + print("Current step status is {}".format(step_status)) return + else: + print("Current test plan state is {}, waiting for the expected state {}".format(current_tp_status, + expected_state)) time.sleep(interval) else: raise PollTimeoutException( - f"Max polling time reached, test plan at {poll_url} is not successfully finished or cancelled" + "Max polling time reached, test plan at {} is not successfully finished or cancelled".format(poll_url) ) @@ -927,28 +930,30 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte # https://github.com/microsoft/azure-pipelines-tasks/issues/10331 args.test_plan_id = args.test_plan_id.replace("'", "") - print(f"Test plan utils parameters: {args}") + print("Test plan utils parameters: {}".format(args)) + auth_env = ["CLIENT_ID"] + required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL"] - required_env = ["ELASTICTEST_SCHEDULER_BACKEND_URL", "CLIENT_ID", "SONIC_AUTOMATION_UMI"] + if args.action in ["create", "cancel"]: + required_env.extend(auth_env) env = { - "ELASTICTEST_SCHEDULER_BACKEND_URL": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), - "CLIENT_ID": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), - "FRONTEND_URL": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), - "SONIC_AUTOMATION_UMI": os.environ.get("SONIC_AUTOMATION_UMI"), + "elastictest_scheduler_backend_url": os.environ.get("ELASTICTEST_SCHEDULER_BACKEND_URL"), + "elastictest_community_url": os.environ.get("ELASTICTEST_COMMUNITY_URL"), + "client_id": os.environ.get("ELASTICTEST_MSAL_CLIENT_ID"), + "frontend_url": os.environ.get("ELASTICTEST_FRONTEND_URL", "https://elastictest.org"), } env_missing = [k.upper() for k, v in env.items() if k.upper() in required_env and not v] if env_missing: - print(f"Missing required environment variables: {env_missing}.") + print("Missing required environment variables: {}".format(env_missing)) sys.exit(1) try: tp = TestPlanManager( - env["ELASTICTEST_SCHEDULER_BACKEND_URL"], - env["FRONTEND_URL"], - env["CLIENT_ID"], - env["SONIC_AUTOMATION_UMI"] - ) + env["elastictest_scheduler_backend_url"], + env["elastictest_community_url"], + env["frontend_url"], + env["client_id"]) if args.action == "create": pr_id = os.environ.get("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER") or os.environ.get( @@ -959,7 +964,14 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte job_name = os.environ.get("SYSTEM_JOBDISPLAYNAME") repo_name = args.repo_name if args.repo_name else os.environ.get("BUILD_REPOSITORY_NAME") - test_plan_prefix = f"{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}".replace(' ', '_') + test_plan_prefix = "{repo}_{reason}_PR_{pr_id}_BUILD_{build_id}_JOB_{job_name}" \ + .format( + repo=repo, + reason=reason, + pr_id=pr_id, + build_id=build_id, + job_name=job_name + ).replace(' ', '_') scripts = args.scripts specific_param = json.loads(args.specific_param) @@ -977,7 +989,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte for num in range(args.test_plan_num): test_plan_name = copy.copy(test_plan_prefix) if args.test_plan_num > 1: - test_plan_name = f"{test_plan_name}_{num + 1}" + test_plan_name = "{}_{}".format(test_plan_name, num + 1) tp.create( args.topology, @@ -1021,8 +1033,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte tp.cancel(args.test_plan_id) sys.exit(0) except PollTimeoutException as e: - print(f"Polling test plan failed with exception: {repr(e)}") + print("Polling test plan failed with exception: {}".format(repr(e))) sys.exit(2) except Exception as e: - print(f"Operation failed with exception: {repr(e)}") + print("Operation failed with exception: {}".format(repr(e))) sys.exit(3) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d268873c065..1256f817404 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -71,7 +71,7 @@ stages: MIN_WORKER: $(T0_INSTANCE_NUM) MAX_WORKER: $(T0_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: t0_2vlans_elastictest displayName: "kvmtest-t0-2vlans by Elastictest" @@ -87,7 +87,7 @@ stages: MAX_WORKER: $(T0_2VLANS_INSTANCE_NUM) DEPLOY_MG_EXTRA_PARAMS: "-e vlan_config=two_vlan_a" KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: t1_lag_elastictest displayName: "kvmtest-t1-lag by Elastictest" @@ -101,7 +101,7 @@ stages: MIN_WORKER: $(T1_LAG_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: dualtor_elastictest displayName: "kvmtest-dualtor-t0 by Elastictest" @@ -116,7 +116,7 @@ stages: MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) COMMON_EXTRA_PARAMS: "--disable_loganalyzer " KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: multi_asic_elastictest displayName: "kvmtest-multi-asic-t1-lag by Elastictest" @@ -132,7 +132,7 @@ stages: MAX_WORKER: $(MULTI_ASIC_INSTANCE_NUM) NUM_ASIC: 4 KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: sonic_t0_elastictest displayName: "kvmtest-t0-sonic by Elastictest" @@ -149,7 +149,7 @@ stages: COMMON_EXTRA_PARAMS: "--neighbor_type=sonic " VM_TYPE: vsonic KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: dpu_elastictest displayName: "kvmtest-dpu by Elastictest" @@ -163,7 +163,7 @@ stages: MIN_WORKER: $(T0_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) - job: onboarding_elastictest_t0 displayName: "onboarding t0 testcases by Elastictest - optional" @@ -179,7 +179,7 @@ stages: MIN_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) TEST_SET: onboarding_t0 - job: onboarding_elastictest_t1 @@ -196,7 +196,7 @@ stages: MIN_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: "master" + MGMT_BRANCH: $(BUILD_BRANCH) TEST_SET: onboarding_t1 # - job: onboarding_elastictest_dualtor @@ -213,7 +213,7 @@ stages: # MIN_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # KVM_IMAGE_BRANCH: $(BUILD_BRANCH) -# MGMT_BRANCH: "master" +# MGMT_BRANCH: $(BUILD_BRANCH) # TEST_SET: onboarding_dualtor # - job: wan_elastictest From 3b2d216615e37ddcd5efbce747bc812b2cac698a Mon Sep 17 00:00:00 2001 From: Yawen Date: Tue, 12 Nov 2024 20:04:06 +1100 Subject: [PATCH 135/221] add Cisco-8122-O128 (#15384) --- ansible/module_utils/port_utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ansible/module_utils/port_utils.py b/ansible/module_utils/port_utils.py index 8df35ca1d8c..8f195d1fe2b 100644 --- a/ansible/module_utils/port_utils.py +++ b/ansible/module_utils/port_utils.py @@ -358,6 +358,10 @@ def get_port_alias_to_name_map(hwsku, asic_name=None): elif hwsku in ["Cisco-8122-O64"]: for i in range(0, 64): port_alias_to_name_map["etp%d" % i] = "Ethernet%d" % (i * 8) + elif hwsku in ["Cisco-8122-O128"]: + for i in range(0, 64): + port_alias_to_name_map["etp%da" % i] = "Ethernet%d" % (i * 4 * 2) + port_alias_to_name_map["etp%db" % i] = "Ethernet%d" % ((i * 4 * 2) + 4) elif hwsku in ["Cisco-8800-LC-48H-C48"]: for i in range(0, 48, 1): port_alias_to_name_map["Ethernet%d" % i] = "Ethernet%d" % (i * 4) From e734df6049d5b060c4c022c31c588669372cfd1b Mon Sep 17 00:00:00 2001 From: Charudatta Chitale Date: Tue, 12 Nov 2024 01:04:29 -0800 Subject: [PATCH 136/221] skipping test_route_flow_counter.py on Cisco 8122 platforms (#15017) * skip route_flow_counter TCs on 8122 platforms * correcting conditional mark sort for test_route_flow_counter.py --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index a4737b99dc2..baa5e89f28f 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1633,6 +1633,12 @@ route/test_route_flap.py: - "https://github.com/sonic-net/sonic-mgmt/issues/11324 and 'dualtor-64' in topo_name" - "'standalone' in topo_name" +route/test_route_flow_counter.py: + skip: + reason: "Test not supported for cisco-8122 platform" + conditions: + - "platform in ['x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" + route/test_route_perf.py: skip: reason: "Does not apply to standalone topos." From ffcb7aa4781459cca599bb61b42df045e2d24b37 Mon Sep 17 00:00:00 2001 From: dypet Date: Tue, 12 Nov 2024 02:04:58 -0700 Subject: [PATCH 137/221] Use COUNTER_MARGIN in PFCXonTest check. (#15305) --- tests/saitests/py3/sai_qos_tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index 2d649a4221e..9ec46133975 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -2710,7 +2710,8 @@ def runTest(self): # & may give inconsistent test results # Adding COUNTER_MARGIN to provide room to 2 pkt incase, extra traffic received for cntr in ingress_counters: - if platform_asic and platform_asic == "broadcom-dnx": + if (platform_asic and + platform_asic in ["broadcom-dnx", "cisco-8000"]): qos_test_assert( self, recv_counters[cntr] <= recv_counters_base[cntr] + COUNTER_MARGIN, 'unexpectedly ingress drop on recv port (counter: {}), at step {} {}'.format( From 2adfb21d4526a3398b4b7974f208a168e87a81cc Mon Sep 17 00:00:00 2001 From: Xincun Li <147451452+xincunli-sonic@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:58:13 -0800 Subject: [PATCH 138/221] Fix replace ingress_lossless_pool (#15332) * Fix replace ingress_lossless_pool * Add log * Fix log message. --- tests/common/gu_utils.py | 2 +- .../test_incremental_qos.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/common/gu_utils.py b/tests/common/gu_utils.py index cb5b0f96a37..e62ece315cf 100644 --- a/tests/common/gu_utils.py +++ b/tests/common/gu_utils.py @@ -107,7 +107,7 @@ def expect_res_success(duthost, output, expected_content_list, unexpected_conten def expect_op_failure(output): """Expected failure from apply-patch output """ - logger.info("return code {}".format(output['rc'])) + logger.info("Return code: {}, error: {}".format(output['rc'], output['stderr'])) pytest_assert( output['rc'], "The command should fail with non zero return code" diff --git a/tests/generic_config_updater/test_incremental_qos.py b/tests/generic_config_updater/test_incremental_qos.py index 7282f251b6f..7856320fe53 100644 --- a/tests/generic_config_updater/test_incremental_qos.py +++ b/tests/generic_config_updater/test_incremental_qos.py @@ -240,12 +240,17 @@ def test_incremental_qos_config_updates(duthost, tbinfo, ensure_dut_readiness, c try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) if op == "replace" and not field_value: + logger.info("{} expects failure when configdb_field: {} does not have value.".format(op, configdb_field)) expect_op_failure(output) - - if is_valid_platform_and_version(duthost, "BUFFER_POOL", "Shared/headroom pool size changes", op, field_value): - expect_op_success(duthost, output) - ensure_application_of_updated_config(duthost, configdb_field, value) else: - expect_op_failure(output) + if is_valid_platform_and_version(duthost, + "BUFFER_POOL", + "Shared/headroom pool size changes", + op, + field_value): + expect_op_success(duthost, output) + ensure_application_of_updated_config(duthost, configdb_field, value) + else: + expect_op_failure(output) finally: delete_tmpfile(duthost, tmpfile) From dbd6ac8b47d99da52e74bea809ec249d5718cd40 Mon Sep 17 00:00:00 2001 From: Riff Date: Tue, 12 Nov 2024 15:09:51 -0800 Subject: [PATCH 139/221] Update SSH session gen to generate tmuxinator configurations (#15483) * Update ssh session gen. * Minor fix. --- ansible/devutil/device_inventory.py | 124 ++++++++++++++++- ansible/devutil/ssh_session_repo.py | 206 ++++++++++++++++++++-------- ansible/devutil/testbed.py | 75 ++++++++++ ansible/ssh_session_gen.py | 164 ++++++++++++---------- 4 files changed, 437 insertions(+), 132 deletions(-) mode change 100644 => 100755 ansible/ssh_session_gen.py diff --git a/ansible/devutil/device_inventory.py b/ansible/devutil/device_inventory.py index c890e86830f..78d26f34fce 100644 --- a/ansible/devutil/device_inventory.py +++ b/ansible/devutil/device_inventory.py @@ -1,3 +1,4 @@ +import copy import os import csv import glob @@ -22,7 +23,7 @@ def __init__( self.device_type = device_type self.protocol = protocol self.os = os - self.console_device = None + self.physical_hostname = None self.console_port = 0 @staticmethod @@ -50,6 +51,107 @@ def is_ssh_supported(self) -> bool: return True +class DeviceLinkInfo: + """Device link information.""" + + def __init__( + self, + start_device: str, + start_port: str, + end_device: str, + end_port: str, + bandwidth: int, + vlan_ranges: List[range], + vlan_mode: str, + auto_neg: str + ): + self.start_device = start_device + self.start_port = start_port + self.end_device = end_device + self.end_port = end_port + self.bandwidth = bandwidth + self.vlan_ranges = vlan_ranges + self.vlan_mode = vlan_mode + self.auto_neg = auto_neg + + @staticmethod + def from_csv_row(row: List[str]) -> "DeviceLinkInfo": + vlan_list = row[5] if row[5] else "" + vlan_ranges_str = vlan_list.split(",") if vlan_list != "" else [] + vlan_ranges = [] + for vlan_range_str in vlan_ranges_str: + vlan_range = vlan_range_str.split("-") + if len(vlan_range) == 1: + vlan_ranges.append(range(int(vlan_range[0]), int(vlan_range[0]) + 1)) + elif len(vlan_range) == 2: + vlan_ranges.append(range(int(vlan_range[0]), int(vlan_range[1]) + 1)) + else: + raise ValueError(f"Invalid vlan range: {vlan_range_str}") + + return DeviceLinkInfo( + start_device=row[0], + start_port=row[1], + end_device=row[2], + end_port=row[3], + bandwidth=int(row[4]), + vlan_ranges=vlan_ranges, + vlan_mode=row[6], + auto_neg=row[7] if len(row) > 7 else "" + ) + + def create_reverse_link(self) -> "DeviceLinkInfo": + return DeviceLinkInfo( + start_device=self.end_device, + start_port=self.end_port, + end_device=self.start_device, + end_port=self.start_port, + bandwidth=self.bandwidth, + vlan_ranges=self.vlan_ranges, + vlan_mode=self.vlan_mode, + auto_neg=self.auto_neg + ) + + +class DeviceLinkMap: + """Device link map.""" + + @staticmethod + def from_csv_file(file_path: str) -> "DeviceLinkMap": + links = DeviceLinkMap() + with open(file_path, newline="") as file: + reader = csv.reader(file) + + # Skip the header line + next(reader) + + for row in reader: + if row: + device_link = DeviceLinkInfo.from_csv_row(row) + links.add_link(device_link) + + return links + + def __init__(self): + self.links: Dict[str, Dict[str, DeviceLinkInfo]] = {} + + def add_link(self, link: DeviceLinkInfo): + if link.start_device not in self.links: + self.links[link.start_device] = {} + self.links[link.start_device][link.start_port] = link + + reverse_link = link.create_reverse_link() + if reverse_link.start_device not in self.links: + self.links[reverse_link.start_device] = {} + self.links[reverse_link.start_device][reverse_link.start_port] = reverse_link + + def get_links(self, device: str) -> Optional[Dict[str, DeviceLinkInfo]]: + return self.links.get(device) + + def get_link(self, device: str, port: str) -> Optional[DeviceLinkInfo]: + links = self.get_links(device) + return links.get(port) if links else None + + class DeviceInventory(object): """Device inventory from csv files.""" @@ -59,15 +161,22 @@ def __init__( self.inv_name = inv_name self.device_file_name = device_file_name self.devices = devices + self.links = DeviceLinkMap() @staticmethod def from_device_files(device_file_pattern: str) -> "List[DeviceInventory]": inv: List[DeviceInventory] = [] for file_path in glob.glob(device_file_pattern): device_inventory = DeviceInventory.from_device_file(file_path) + console_links_file_path = file_path.replace("_devices", "_console_links") if os.path.exists(console_links_file_path): device_inventory.load_console_links_info(console_links_file_path) + + device_links_file_path = file_path.replace("_devices", "_links") + if os.path.exists(device_links_file_path): + device_inventory.load_device_link_map(device_links_file_path) + inv.append(device_inventory) return inv @@ -116,8 +225,17 @@ def load_console_links_info(self, file_path: str): if not device_info: print(f"Unknown device hostname {device_hostname}, skipping") continue - device_info.console_device = console_device_info - device_info.console_port = console_port + + device_console_device = copy.deepcopy(console_device_info) + device_console_device.hostname = f"{device_hostname}-console" + device_console_device.device_type = "Console" # Make it different from ConsoleServer + device_console_device.physical_hostname = console_hostname + device_console_device.console_port = console_port + self.devices[device_console_device.hostname] = device_console_device + + def load_device_link_map(self, file_path: str): + print(f"Loading device links inventory: {file_path}") + self.links = DeviceLinkMap.from_csv_file(file_path) def get_device(self, hostname: str) -> Optional[DeviceInfo]: return self.devices.get(hostname) diff --git a/ansible/devutil/ssh_session_repo.py b/ansible/devutil/ssh_session_repo.py index 8324c660c3c..3daf5382b54 100644 --- a/ansible/devutil/ssh_session_repo.py +++ b/ansible/devutil/ssh_session_repo.py @@ -5,15 +5,28 @@ """ import os +from typing import Dict, List, Optional import sshconf from Crypto.Hash import SHA256 from Crypto.Cipher import AES +from devutil.device_inventory import DeviceInfo +import jinja2 + + +class DeviceSSHInfo(object): + """SSH info for devices.""" + + def __init__(self, ip: Optional[str], ipv6: Optional[str], user: Optional[str], password: Optional[str]): + self.ip = ip + self.ipv6 = ipv6 + self.user = user + self.password = password class SshSessionRepoGenerator(object): """Base class for ssh session repo generator.""" - def __init__(self, target, template_file): + def __init__(self, target: str, template_file: str): """Store all parameters as attributes. Args: @@ -23,7 +36,7 @@ def __init__(self, target, template_file): self.target = target self.template = self._load_template(template_file) - def _load_template(self, template_file): + def _load_template(self, template_file: str): """Load SSH session template file. Args: @@ -34,17 +47,11 @@ def _load_template(self, template_file): """ raise NotImplementedError - def generate(self, session_path, ssh_ip, ssh_ipv6, ssh_user, ssh_pass, - console_ssh_ip, console_ssh_port, console_ssh_user, console_ssh_pass): + def generate(self, repo_type: str, inv_name: str, testbed_name: str, + device: DeviceInfo, device_name: str, ssh_info: DeviceSSHInfo): """Generate SSH session for a node. This is a virtual method that should be implemented by child class. - - Args: - session_path(str): SSH session path. - ssh_ip (str): SSH IP address. - ssh_user (str): SSH username. - ssh_pass (str): SSH password. """ raise NotImplementedError @@ -53,7 +60,31 @@ def finish(self): This is a virtual method that should be implemented by child class. """ - raise NotImplementedError + pass + + def _get_device_type_short_name(self, device: DeviceInfo) -> str: + """Get the short name of the device type. + + Args: + device_type (str): Device type. + + Returns: + str: Short name of the device type. + """ + device_type = "dut" + + if device.device_type == "PTF": + device_type = "ptf" + elif "Root" in device.device_type: + device_type = "root" + elif "Fanout" in device.device_type: + device_type = "fan" + elif "Console" in device.device_type: + device_type = "console" + elif "Server" in device.device_type: + device_type = "server" + + return device_type class SecureCRTSshSessionRepoGenerator(SshSessionRepoGenerator): @@ -103,22 +134,23 @@ def _load_template(self, template_file): return template - def generate(self, session_path, ssh_ip, ssh_ipv6, ssh_user, ssh_pass, - console_ssh_ip, console_ssh_port, console_ssh_user, console_ssh_pass): + def generate(self, repo_type: str, inv_name: str, testbed_name: str, + device: DeviceInfo, ssh_info: DeviceSSHInfo): """Generate SSH session for a testbed node.""" + device_name = f"{self._get_device_type_short_name(device)}-{device.hostname}" + session_file_matrix = [ - (session_path, ssh_ip, ssh_user, ssh_pass), - (session_path + "-v6", ssh_ipv6, ssh_user, ssh_pass), - (session_path + "-console", console_ssh_ip, f"{console_ssh_user}:{console_ssh_port}", console_ssh_pass), + (device_name, ssh_info.ip, ssh_info), + (device_name + "-v6", ssh_info.ipv6, ssh_info), ] - for (session_name, ip, user, password) in session_file_matrix: - if not ip or not user: + for (device_name, ip, ssh_info) in session_file_matrix: + if not ip or not ssh_info.user: continue # In SecureCRT, every SSH session is stored in a ini file separately, # hence we add .ini extension to the session path in order to generate individual SSH session file. - ssh_session_file_path = os.path.join(self.target, session_name + ".ini") + ssh_session_file_path = os.path.join(self.target, repo_type, inv_name, testbed_name, device_name + ".ini") # Recursively create SSH session file directory ssh_session_folder = os.path.dirname(ssh_session_file_path) @@ -126,7 +158,7 @@ def generate(self, session_path, ssh_ip, ssh_ipv6, ssh_user, ssh_pass, # Generate SSH session file ssh_session_file_content = self._generate_ssh_session_file_content( - session_name, ip, user, password + device_name, ip, ssh_info ) with open(ssh_session_file_path, "w") as ssh_session_file: ssh_session_file.write(ssh_session_file_content) @@ -135,10 +167,10 @@ def generate(self, session_path, ssh_ip, ssh_ipv6, ssh_user, ssh_pass, ssh_session_folder_data = SecureCRTRepoFolderData.from_folder( ssh_session_folder, create_if_not_exist=True ) - ssh_session_folder_data.add_session(session_name) + ssh_session_folder_data.add_session(device_name) ssh_session_folder_data.save() - def _create_ssh_session_folder(self, ssh_session_file_dir): + def _create_ssh_session_folder(self, ssh_session_file_dir: str): """Recursively create SSH session file directory level by level if it does not exist, and init the folder with a folder data ini file. @@ -164,7 +196,7 @@ def _create_ssh_session_folder(self, ssh_session_file_dir): parent_folder_data.save() def _generate_ssh_session_file_content( - self, session_name, ssh_ip, ssh_user, ssh_pass + self, session_name: str, ssh_ip: str, ssh_info: DeviceSSHInfo ): """Generate SSH session file content: @@ -177,17 +209,13 @@ def _generate_ssh_session_file_content( Returns: str: SSH session file content. """ - encrypted_pass = "02:" + self.crypto.encrypt(ssh_pass) + encrypted_pass = "02:" + self.crypto.encrypt(ssh_info.password) return ( - self.template.replace("%USERNAME%", ssh_user) + self.template.replace("%USERNAME%", ssh_info.user) .replace("%HOST%", ssh_ip) .replace("%PASSWORD%", encrypted_pass) ) - def finish(self): - """Finish SSH session generation.""" - pass - class SecureCRTRepoFolderData(object): """This class represents the __FolderData__.ini file in SecureCRT SSH session repository.""" @@ -247,7 +275,7 @@ def _parse_ini_file(self): elif line.startswith('S:"Is Expanded"='): self.is_expanded = bool(int(line.split("=")[1].strip())) - def add_folder(self, folder): + def add_folder(self, folder: str): """Add a folder to the folder list. Args: @@ -255,7 +283,7 @@ def add_folder(self, folder): """ self.folder_list.add(folder) - def add_session(self, session): + def add_session(self, session: str): """Add a session to the session list. Args: @@ -263,7 +291,7 @@ def add_session(self, session): """ self.session_list.add(session) - def set_is_expanded(self, is_expanded): + def set_is_expanded(self, is_expanded: bool): """Set is_expanded. Args: @@ -337,7 +365,7 @@ class SshConfigSshSessionRepoGenerator(SshSessionRepoGenerator): It derives from SshSessionRepoGenerator and implements the generate method. """ - def __init__(self, target, ssh_config_params, console_ssh_config_params): + def __init__(self, target: str, ssh_config_params: Dict[str, str], console_ssh_config_params: Dict[str, str]): super().__init__(target, "") # Load SSH config file from target file path @@ -348,8 +376,8 @@ def __init__(self, target, ssh_config_params, console_ssh_config_params): self.ssh_config = sshconf.read_ssh_config(self.target) # Add SSH config parameters - self.ssh_config_params = ssh_config_params - self.console_ssh_config_params = console_ssh_config_params + self.ssh_config_params = ssh_config_params if ssh_config_params is not None else {} + self.console_ssh_config_params = console_ssh_config_params if console_ssh_config_params is not None else {} def _load_template(self, template_file): """Load SSH session template file. @@ -358,43 +386,113 @@ def _load_template(self, template_file): """ pass - def generate(self, session_path, ssh_ip, ssh_ipv6, ssh_user, ssh_pass, - console_ssh_ip, console_ssh_port, console_ssh_user, console_ssh_pass): + def generate(self, repo_type: str, inv_name: str, testbed_name: str, + device: DeviceInfo, ssh_info: DeviceSSHInfo): """Generate SSH session for a testbed node.""" - ssh_session_name = os.path.basename(session_path) + ssh_session_name = device.hostname current_hosts = self.ssh_config.hosts() ssh_config = {} - if ssh_user: - ssh_config["User"] = ssh_user + if ssh_info.user: + ssh_config["User"] = ssh_info.user # Add new host config - if ssh_ip: + if ssh_info.ip: session_name = ssh_session_name - ssh_config["Hostname"] = ssh_ip + ssh_config["Hostname"] = ssh_info.ip if session_name in current_hosts: self.ssh_config.set(session_name, **ssh_config, **self.ssh_config_params) else: self.ssh_config.add(session_name, **ssh_config, **self.ssh_config_params) - if ssh_ipv6: + + if ssh_info.ipv6: session_name = ssh_session_name + "-v6" - ssh_config["Hostname"] = ssh_ipv6 + ssh_config["Hostname"] = ssh_info.ipv6 if session_name in current_hosts: self.ssh_config.set(session_name, **ssh_config, **self.ssh_config_params) else: self.ssh_config.add(session_name, **ssh_config, **self.ssh_config_params) - if console_ssh_ip: - session_name = ssh_session_name + "-console" - ssh_config["User"] = f"{console_ssh_user}:{console_ssh_port}" - ssh_config["Hostname"] = console_ssh_ip - if session_name in current_hosts: - self.ssh_config.set(session_name, **ssh_config, **self.ssh_config_params, - **self.console_ssh_config_params) - else: - self.ssh_config.add(session_name, **ssh_config, **self.ssh_config_params, - **self.console_ssh_config_params) def finish(self): """Finish SSH session generation.""" # Write SSH config to target file path self.ssh_config.write(self.target) + + +class SshConfigTmuxinatorSessionRepoGenerator(SshSessionRepoGenerator): + """Tmuxinator session repo generator for tmuxinator configs. + + It derives from SshSessionRepoGenerator and implements the generate method. + """ + + def __init__(self, target: str, ssh_config_params: Dict[str, str], console_ssh_config_params: Dict[str, str]): + super().__init__(target, "") + + self.testbeds = {} + + # Create target folder + self.target = os.path.expanduser(self.target) + os.makedirs(self.target, exist_ok=True) + + # Add SSH config parameters + self.ssh_config_params = "".join([f" -o {k}={v}" for k, v in ssh_config_params.items()] + if ssh_config_params is not None else []) + + self.console_ssh_config_params = "".join([f" -o {k}={v}" for k, v in console_ssh_config_params.items()] + if console_ssh_config_params is not None else []) + + def _load_template(self, template_file): + """Load SSH session template file. + + This function will pass since tmuxinator config does not need a template file. + """ + + template = """ +name: {{ testbed_name }} +root: . +enable_pane_titles: true + +windows: +{%- for device_type, panes in config.items() %} + - {{ device_type }}: + layout: main-vertical + panes: + {%- for title, command in panes.items() %} + - {{ title }}: + - {{ command }} + {%- endfor %} +{%- endfor %} +""" + return jinja2.Template(template) + + def generate(self, repo_type: str, inv_name: str, testbed_name: str, + device: DeviceInfo, ssh_info: DeviceSSHInfo): + config = self.testbeds.setdefault(testbed_name, {}) + self._generate_tmuxinator_config_for_device(config, device, ssh_info.ip, ssh_info) + + def _generate_tmuxinator_config_for_device(self, config: Dict[str, List[str]], device: DeviceInfo, + ssh_ip: str, ssh_info: DeviceSSHInfo): + device_type = self._get_device_type_short_name(device) + ssh_pass = f"sshpass -p {ssh_info.password} " if ssh_info.password else "" + ssh_common_params = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" + + if device.device_type == "Console": + command = f"{ssh_pass}ssh {ssh_common_params}{self.console_ssh_config_params} -l {ssh_info.user} {ssh_ip}" + else: + command = f"{ssh_pass}ssh {ssh_common_params}{self.ssh_config_params} {ssh_info.user}@{ssh_ip}" + + panes = config.setdefault(device_type, {}) + panes[device.hostname] = command + + def finish(self): + for testbed_name, config in self.testbeds.items(): + self._generate_tmuxinator_session_file(testbed_name, config) + + def _generate_tmuxinator_session_file(self, testbed_name: str, config: Dict[str, List[str]]): + tmux_config_file_path = os.path.join(self.target, testbed_name + ".yml") + + config_file_content = self.template.render(testbed_name=testbed_name, + config=config) + + with open(tmux_config_file_path, "w") as f: + f.write(config_file_content) diff --git a/ansible/devutil/testbed.py b/ansible/devutil/testbed.py index 58892335494..209431d77d2 100644 --- a/ansible/devutil/testbed.py +++ b/ansible/devutil/testbed.py @@ -2,6 +2,7 @@ Utility classes for loading and managing testbed data. """ +import itertools import os import re import yaml @@ -71,6 +72,11 @@ def __init__(self, raw_dict: Any, device_inventories: List[DeviceInventory]): protocol="ssh", ) + self.console_nodes = {} + self.fanout_nodes = {} + self.root_fanout_nodes = {} + self.server_nodes = {} + # Loop through each DUT in the testbed and find the device info self.dut_nodes = {} for dut in raw_dict["dut"]: @@ -78,6 +84,7 @@ def __init__(self, raw_dict: Any, device_inventories: List[DeviceInventory]): device = inv.get_device(dut) if device is not None: self.dut_nodes[dut] = device + self.link_dut_related_devices(inv, device) break else: print(f"Error: Failed to find device info for DUT {dut}") @@ -86,3 +93,71 @@ def __init__(self, raw_dict: Any, device_inventories: List[DeviceInventory]): # so we need to use "unknown" as inv_name instead. if not hasattr(self, "inv_name"): self.inv_name = "unknown" + + def link_dut_related_devices(self, inv: DeviceInventory, dut: DeviceInfo) -> None: + """Link all devices that is relavent to the given DUT.""" + links = inv.links.get_links(dut.hostname) + if links is None: + return None + + # Get all DUT VLANs + dut_vlan_list = [] + for link in links.values(): + dut_vlan_list.extend(link.vlan_ranges) + dut_vlans = list(itertools.chain(*dut_vlan_list)) + + # Use the VLANs to find all connected nodes + linked_devices = [] + visited_devices = {dut.hostname: True} + pending_devices = [dut] + while len(pending_devices) > 0: + device_name = pending_devices.pop(0).hostname + + # Enumerate all links of the device and find the ones with VLANs used by the DUT + device_links = inv.links.get_links(device_name) + for link in device_links.values(): + link_has_vlan = False + for dut_vlan in dut_vlans: + for link_vlan_range in link.vlan_ranges: + if dut_vlan in link_vlan_range: + link_has_vlan = True + break + if link_has_vlan: + break + + # The link has VLANs used by the DUTs + if link_has_vlan: + if link.end_device in visited_devices: + continue + visited_devices[link.end_device] = True + + peer_device = inv.get_device(link.end_device) + if peer_device is None: + raise ValueError(f"Link to device is defined by failed to find device info: {link.end_device}") + + # Count the peer device as linked and add it to the pending list + linked_devices.append(peer_device) + pending_devices.append(peer_device) + + # print(f"Linked devices for DUT {dut.hostname}:") + for linked_device in linked_devices: + if "Root" in linked_device.device_type: + self.root_fanout_nodes[linked_device.hostname] = linked_device + # print(f" RootFanout: {linked_device.hostname}") + elif "Fanout" in linked_device.device_type: + self.fanout_nodes[linked_device.hostname] = linked_device + # print(f" Fanout: {linked_device.hostname}") + elif linked_device.device_type == "Server": + self.server_nodes[linked_device.hostname] = linked_device + # print(f" Server: {linked_device.hostname}") + elif "Dev" in linked_device.device_type: + print(f"ERROR: Conflicting VLAN ID is found between 2 DUTs: {dut.hostname} and " + f"{linked_device.hostname}! Please fix the testbed config.") + else: + raise ValueError(f"Unknown device type: {linked_device.device_type} " + f"(DUT: {dut.hostname}, Linked: {linked_device.hostname})") + + dut_console_node_name = f"{dut.hostname}-console" + dut_console_node = inv.get_device(dut_console_node_name) + if dut_console_node is not None: + self.console_nodes[dut_console_node.hostname] = dut_console_node diff --git a/ansible/ssh_session_gen.py b/ansible/ssh_session_gen.py old mode 100644 new mode 100755 index 88e0a846d9d..8768c57d3de --- a/ansible/ssh_session_gen.py +++ b/ansible/ssh_session_gen.py @@ -1,17 +1,21 @@ +#!/usr/bin/env python3 + """ Script used to generate SSH session files for console access to devices. """ import argparse -import os +import itertools import re -from typing import Dict, List, Optional, Tuple +from typing import Dict, List, Optional from devutil.device_inventory import DeviceInfo, DeviceInventory from devutil.testbed import TestBed from devutil.inv_helpers import HostManager from devutil.ssh_session_repo import ( + DeviceSSHInfo, SecureCRTSshSessionRepoGenerator, SshConfigSshSessionRepoGenerator, + SshConfigTmuxinatorSessionRepoGenerator, SshSessionRepoGenerator, ) @@ -57,12 +61,13 @@ def __init__( "FanoutLeaf": {"user": leaf_fanout_user, "pass": leaf_fanout_pass}, "FanoutLeafSonic": {"user": leaf_fanout_user, "pass": leaf_fanout_pass}, "FanoutRoot": {"user": root_fanout_user, "pass": root_fanout_pass}, + "Console": {"user": console_server_user, "pass": console_server_pass}, "ConsoleServer": {"user": console_server_user, "pass": console_server_pass}, "MgmtTsToRRouter": {"user": console_server_user, "pass": console_server_pass}, "PTF": {"user": ptf_user, "pass": ptf_pass}, } - def get_ssh_cred(self, device: DeviceInfo) -> Tuple[str, str, str, str]: + def get_ssh_cred(self, device: DeviceInfo) -> DeviceSSHInfo: """ Get SSH info for a testbed node. @@ -85,9 +90,10 @@ def get_ssh_cred(self, device: DeviceInfo) -> Tuple[str, str, str, str]: else "" ) - if not ssh_ip or not ssh_user or not ssh_pass or not ssh_ipv6: + if not ssh_ip or not ssh_user or not ssh_pass or ("Console" not in device.device_type and not ssh_ipv6): try: - host_vars = self.ansible_hosts.get_host_vars(device.hostname) + device_hostname = device.hostname if device.physical_hostname is None else device.physical_hostname + host_vars = self.ansible_hosts.get_host_vars(device_hostname) ssh_ip = host_vars["ansible_host"] if not ssh_ip else ssh_ip ssh_ipv6 = host_vars["ansible_hostv6"] if not ssh_ipv6 and "ansible_hostv6" in host_vars else ssh_ipv6 @@ -97,15 +103,20 @@ def get_ssh_cred(self, device: DeviceInfo) -> Tuple[str, str, str, str]: ) except Exception as e: print( - f"Error: Failed to get SSH credential for device {device.hostname} ({device.device_type}): {str(e)}" + f"Error: Failed to get SSH credential for device {device_hostname} ({device.device_type}): {str(e)}" ) - ssh_ip = "" if ssh_ip is None else ssh_ip - ssh_ipv6 = "" if ssh_ipv6 is None else ssh_ipv6 - ssh_user = "" if ssh_user is None else ssh_user - ssh_pass = "" if ssh_pass is None else ssh_pass + ssh_info = DeviceSSHInfo( + ip="" if ssh_ip is None else ssh_ip, + ipv6="" if ssh_ipv6 is None else ssh_ipv6, + user="" if ssh_user is None else ssh_user, + password="" if ssh_pass is None else ssh_pass + ) + + if device.console_port > 0: + ssh_info.user = f"{ssh_info.user}:{device.console_port}" - return ssh_ip, ssh_ipv6, ssh_user, ssh_pass + return ssh_info class DeviceSshSessionRepoGenerator(object): @@ -115,47 +126,40 @@ def __init__( self.repo_generator = repo_generator self.ssh_info_solver = ssh_info_solver - def generate_ssh_session_for_device(self, device: DeviceInfo, session_path: str): + def generate_ssh_session_for_device(self, + device: DeviceInfo, + repo_type: str, + inv_name: str, + testbed_name: str): + """Generate SSH session for a device. Args: device (DeviceInfo): Represents a device. - session_path (str): Path to store the SSH session file. + repo_type (str): Repository type. + inv_name (str): Inventory name. + testbed_name (str): Testbed name. """ if not device.is_ssh_supported(): return - ssh_ip, ssh_ipv6, ssh_user, ssh_pass = self.ssh_info_solver.get_ssh_cred(device) - if not ssh_ip and not ssh_ipv6: + ssh_info = self.ssh_info_solver.get_ssh_cred(device) + if not ssh_info.ip and not ssh_info.ipv6: print( f"WARNING: Management IP is not specified for testbed node, skipped: {device.hostname}" ) return - if device.console_device: - console_ssh_ip, _, console_ssh_user, console_ssh_pass = self.ssh_info_solver.get_ssh_cred( - device.console_device) - console_ssh_port = device.console_port - else: - console_ssh_ip, console_ssh_user, console_ssh_pass, console_ssh_port = None, None, None, 0 - - if not ssh_user: - print( - "WARNING: SSH credential is missing for device: {}".format( - device.hostname - ) - ) + if not ssh_info.user: + print(f"WARNING: SSH credential is missing for device: {device.hostname}") + # print(f"Generating SSH session for device: {device.hostname}") self.repo_generator.generate( - session_path, - ssh_ip, - ssh_ipv6, - ssh_user, - ssh_pass, - console_ssh_ip, - console_ssh_port, - console_ssh_user, - console_ssh_pass + repo_type, + inv_name, + testbed_name, + device, + ssh_info, ) @@ -195,7 +199,15 @@ def _generate_ssh_sessions_for_testbed(self, testbed: TestBed): Args: testbed (object): Represents a testbed setup. """ - devices = [testbed.ptf_node] + list(testbed.dut_nodes.values()) + devices = itertools.chain( + testbed.dut_nodes.values(), + [testbed.ptf_node], + testbed.fanout_nodes.values(), + testbed.root_fanout_nodes.values(), + testbed.console_nodes.values(), + testbed.server_nodes.values() + ) + for device in devices: self._generate_ssh_session_for_testbed_node(testbed, device) @@ -213,16 +225,7 @@ def _generate_ssh_session_for_testbed_node( testbed_node_type (str): Type of the testbed node. It can be "ptf" or "dut". testbed_node (object): Represents a connectable node in the testbed. """ - device_type = "dut" if device.device_type != "PTF" else "ptf" - - session_path = os.path.join( - "testbeds", - testbed.inv_name, - testbed.conf_name, - device_type + "-" + device.hostname, - ) - - self.generate_ssh_session_for_device(device, session_path) + self.generate_ssh_session_for_device(device, "testbeds", testbed.inv_name, testbed.conf_name) device_type_pattern = re.compile(r"(? Date: Tue, 12 Nov 2024 18:30:20 -0500 Subject: [PATCH 140/221] [TACACS] Add --no-pager to tacacs utils (#15491) Summary: Add --no-pager to journalctl to display all logs at once, allowing grep to search through the output even when there are many logs. --- tests/tacacs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tacacs/utils.py b/tests/tacacs/utils.py index b3424cc04b3..3d398102826 100644 --- a/tests/tacacs/utils.py +++ b/tests/tacacs/utils.py @@ -66,7 +66,7 @@ def log_exist(ptfhost, sed_command): def get_auditd_config_reload_timestamp(duthost): - res = duthost.shell("sudo journalctl -u auditd --boot | grep 'audisp-tacplus re-initializing configuration'") + res = duthost.shell("sudo journalctl -u auditd --boot --no-pager | grep 'audisp-tacplus re-initializing configuration'") # noqa E501 logger.info("aaa config file timestamp {}".format(res["stdout_lines"])) if len(res["stdout_lines"]) == 0: From d21e103a6c61625563b0109d8d7f18b1b61c50d7 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:51:34 -0800 Subject: [PATCH 141/221] Fix the parameters for AllPortQueueWaterMark Testcase. (#15482) The testcase test_qos_sai.py::TestQosSai::testQosSaiQWatermarkAllPorts is failing due to much narrower margins in the lossy queue counter case. So this PR attempts to increase the margin, and also handle a case where the required qos.yml key is not present in the TC's params, but in the params for port-speed structure itself. --- tests/qos/files/qos_params.gb.yaml | 6 +++--- tests/qos/test_qos_sai.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/qos/files/qos_params.gb.yaml b/tests/qos/files/qos_params.gb.yaml index 0a098ddee99..4d83f6054d2 100644 --- a/tests/qos/files/qos_params.gb.yaml +++ b/tests/qos/files/qos_params.gb.yaml @@ -414,7 +414,7 @@ qos_params: wm_q_wm_all_ports: ecn: 1 pkt_count: 3000 - pkts_num_margin: 1024 + pkts_num_margin: 3072 cell_size: 384 xon_1: dscp: 3 @@ -538,7 +538,7 @@ qos_params: wm_q_wm_all_ports: ecn: 1 pkt_count: 3000 - pkts_num_margin: 1024 + pkts_num_margin: 3072 cell_size: 384 packet_size: 1350 xon_1: @@ -729,7 +729,7 @@ qos_params: wm_q_wm_all_ports: ecn: 1 pkt_count: 855 - pkts_num_margin: 1024 + pkts_num_margin: 3072 cell_size: 6144 packet_size: 6144 400000_120000m: diff --git a/tests/qos/test_qos_sai.py b/tests/qos/test_qos_sai.py index 270799e8f02..03ee7986cec 100644 --- a/tests/qos/test_qos_sai.py +++ b/tests/qos/test_qos_sai.py @@ -2178,7 +2178,9 @@ def testQosSaiQWatermarkAllPorts( "src_port_id": src_port_id, "src_port_ip": src_port_ip, "src_port_vlan": dutConfig["testPorts"]["src_port_vlan"], - "pkts_num_leak_out": qosConfig[queueProfile]["pkts_num_leak_out"], + "pkts_num_leak_out": qosConfig[queueProfile]["pkts_num_leak_out"] + if ("pkts_num_leak_out" in qosConfig[queueProfile]) else + qosConfig["pkts_num_leak_out"], "pkt_count": qosConfig[queueProfile]["pkt_count"], "cell_size": qosConfig[queueProfile]["cell_size"], "hwsku": dutTestParams['hwsku'], From 633fe601dfd1f6999acc0c863997ad4a684a873c Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:54:24 +0800 Subject: [PATCH 142/221] Move some stable test to PR test set and add test to skip PR test set (#15500) What is the motivation for this PR? Some dataplane test scripts have been added to PR test and put into optional onboarding job to test case performance, I calculated the success rate of test scripts in recent 3 days, I think I can move high success rate test scripts to t0/t1 job now How did you do it? Move test from onboarding job to t0/t1 job Add pfc_asym test to skip PR test set since it's only supported on barefoot platform Add snappi test to skip PR test set Add some ecmp platform specific test to skip PR test set How did you verify/test it? Co-authored-by: xwjiang2021 <96218837+xwjiang2021@users.noreply.github.com> --- .azure-pipelines/pr_test_scripts.yaml | 14 ++++++-------- .azure-pipelines/pr_test_skip_scripts.yaml | 7 +++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.azure-pipelines/pr_test_scripts.yaml b/.azure-pipelines/pr_test_scripts.yaml index 290ce1d9a7d..cd44402cf13 100644 --- a/.azure-pipelines/pr_test_scripts.yaml +++ b/.azure-pipelines/pr_test_scripts.yaml @@ -220,6 +220,10 @@ t0: - telemetry/test_telemetry.py - platform_tests/test_cont_warm_reboot.py - snmp/test_snmp_link_local.py + - arp/test_arp_update.py + - decap/test_subnet_decap.py + - fdb/test_fdb_mac_learning.py + - ip/test_mgmt_ipv6_only.py t0-2vlans: - dhcp_relay/test_dhcp_relay.py @@ -423,6 +427,8 @@ t1-lag: - generic_config_updater/test_cacl.py - telemetry/test_telemetry.py - snmp/test_snmp_link_local.py + - mpls/test_mpls.py + - vxlan/test_vxlan_route_advertisement.py multi-asic-t1-lag: - bgp/test_bgp_bbr.py @@ -464,17 +470,9 @@ onboarding_t0: - lldp/test_lldp_syncd.py # Flaky, we will triage and fix it later, move to onboarding to unblock pr check - dhcp_relay/test_dhcp_relay_stress.py - - arp/test_arp_update.py - - decap/test_subnet_decap.py - - fdb/test_fdb_mac_learning.py - - ip/test_mgmt_ipv6_only.py - onboarding_t1: - lldp/test_lldp_syncd.py - - mpls/test_mpls.py - - vxlan/test_vxlan_route_advertisement.py - specific_param: t0-sonic: diff --git a/.azure-pipelines/pr_test_skip_scripts.yaml b/.azure-pipelines/pr_test_skip_scripts.yaml index f233f470736..4b5dd6b943c 100644 --- a/.azure-pipelines/pr_test_skip_scripts.yaml +++ b/.azure-pipelines/pr_test_skip_scripts.yaml @@ -7,6 +7,10 @@ t0: - dualtor_io/test_normal_op.py # This script would toggle PDU, which is not supported on KVM - dualtor_io/test_tor_failure.py + # This script only supported on Broadcom + - ecmp/test_ecmp_sai_value.py + # This script only supported on Mellanox + - ecmp/test_fgnhg.py # This script only supported on Mellanox - generic_config_updater/test_pfcwd_interval.py # There is no k8s in inventory file @@ -22,6 +26,8 @@ t0: - ospf/test_ospf.py - ospf/test_ospf_bfd.py # Test is not supported on vs testbed + - pfc_asym/test_pfc_asym.py + # Test is not supported on vs testbed - platform_tests/test_intf_fec.py # Platform api needs the module `sonic_platform`, which is not included in vs # So skip these scripts @@ -251,6 +257,7 @@ tgen: - snappi_tests/pfc/test_pfc_pause_unset_bit_enable_vector.py - snappi_tests/pfc/test_pfc_pause_zero_mac.py - snappi_tests/pfc/test_valid_pfc_frame_with_snappi.py + - snappi_tests/pfc/test_valid_src_mac_pfc_frame.py - snappi_tests/pfcwd/test_pfcwd_a2a_with_snappi.py - snappi_tests/pfcwd/test_pfcwd_basic_with_snappi.py - snappi_tests/pfcwd/test_pfcwd_burst_storm_with_snappi.py From 265843cafcbc95aefd784a7a1077f9c18bac4166 Mon Sep 17 00:00:00 2001 From: longhuan-cisco <84595962+longhuan-cisco@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:06:57 -0800 Subject: [PATCH 143/221] Add extra logic in test_sfputil to make sure modules are restored (#13108) * Add extra logic in test_sfputil to make sure modules are restored * Fix flake8 E125 * Use config dom enable/disable * flake8 fix * Use context manager and remove unnecessary sleep * Handle breakout case propperly and increase wait_time * Add skip for lpmode handling and fix for breakout * Restore dom_polling to origional * Add comments * Add lpmode on/off seq, remove lpmode restore logic and avoid starting admin-down ports * Fix typo for lpmode on/off --- tests/platform_tests/sfp/test_sfputil.py | 365 ++++++++++++++++++++--- 1 file changed, 321 insertions(+), 44 deletions(-) diff --git a/tests/platform_tests/sfp/test_sfputil.py b/tests/platform_tests/sfp/test_sfputil.py index 472394df318..f088a360b8f 100644 --- a/tests/platform_tests/sfp/test_sfputil.py +++ b/tests/platform_tests/sfp/test_sfputil.py @@ -7,7 +7,7 @@ import logging import time import copy - +from natsort import natsorted import pytest from .util import parse_eeprom @@ -15,12 +15,27 @@ from .util import get_dev_conn from tests.common.utilities import skip_release, wait_until from tests.common.fixtures.duthost_utils import shutdown_ebgp # noqa F401 +from tests.common.port_toggle import default_port_toggle_wait_time +from tests.common.platform.interface_utils import get_physical_port_indices cmd_sfp_presence = "sudo sfputil show presence" cmd_sfp_eeprom = "sudo sfputil show eeprom" cmd_sfp_reset = "sudo sfputil reset" cmd_sfp_show_lpmode = "sudo sfputil show lpmode" cmd_sfp_set_lpmode = "sudo sfputil lpmode" +cmd_config_intf_dom = "config interface {} transceiver dom {} {}" +cmd_config_intf_action = "config interface {} {} {}" +cmd_intf_startup = "startup" +cmd_intf_shutdown = "shutdown" +cmd_dom_disable = "disable" +cmd_dom_enable = "enable" +db_cmd_dom_polling = "sonic-db-cli {} CONFIG_DB {} 'PORT|{}' 'dom_polling' {}" +DOM_DISABLED = "disabled" +DOM_ENABLED = "enabled" +DOM_POLLING_CONFIG_VALUES = [DOM_DISABLED, DOM_ENABLED] + +I2C_WAIT_TIME_AFTER_SFP_RESET = 5 # in seconds +WAIT_TIME_AFTER_LPMODE_SET = 3 # in seconds logger = logging.getLogger(__name__) @@ -30,6 +45,167 @@ ] +class LogicalInterfaceDisabler: + """ + Disable the given logical interface and restore afterwards. + """ + def __init__(self, duthost, enum_frontend_asic_index, logical_intf, phy_intf, + is_admin_up, skip_dom_polling_handle=False): + self.duthost = duthost + self.logical_intf = logical_intf + self.phy_intf = phy_intf + self.skip_dom_polling_handle = skip_dom_polling_handle + self.wait_after_dom_config = 5 + + self.namespace_cmd_opt = get_namespace_cmd_option(duthost, + enum_frontend_asic_index) + self.cmd_down = cmd_config_intf_action.format(self.namespace_cmd_opt, + cmd_intf_shutdown, logical_intf) + self.cmd_up = cmd_config_intf_action.format(self.namespace_cmd_opt, + cmd_intf_startup, logical_intf) + self.cmd_disable_dom = cmd_config_intf_dom.format(self.namespace_cmd_opt, + logical_intf, cmd_dom_disable) + self.cmd_enable_dom = cmd_config_intf_dom.format(self.namespace_cmd_opt, + logical_intf, cmd_dom_enable) + self.cmd_sfp_presence = "{} -p {}".format(cmd_sfp_presence, logical_intf) + self.db_cmd_dom_polling_clear = db_cmd_dom_polling.format(self.namespace_cmd_opt, + "HDEL", + logical_intf, + "") + self.db_cmd_dom_polling_get = db_cmd_dom_polling.format(self.namespace_cmd_opt, + "HGET", + logical_intf, + "") + self.orig_dom_polling_value = None + self.is_admin_up = is_admin_up + + def disable(self): + """ + Disable a logical interface by doing below: + * Disable DOM polling + * Shutdown port + """ + if not self.skip_dom_polling_handle: + orig_dom_get_result = self.duthost.command(self.db_cmd_dom_polling_get) + if orig_dom_get_result["stdout"] in DOM_POLLING_CONFIG_VALUES: + self.orig_dom_polling_value = orig_dom_get_result["stdout"] + logging.info("Disable DOM polling to avoid race condition during sfp reset" + " for {}".format(self.logical_intf)) + disable_dom_result = self.duthost.command(self.cmd_disable_dom) + assert disable_dom_result["rc"] == 0, \ + "Disable DOM polling failed for {}".format(self.logical_intf) + time.sleep(self.wait_after_dom_config) + + if not self.is_admin_up: + logging.info("Skip shutdown {} as it's already admin down pre-test".format(self.logical_intf)) + return + # It's needed to shutdown ports before reset and startup ports after reset, + # to get config/state machine/etc replayed, so that the modules can be fully + # restored. + logging.info("Shutdown {} before sfp reset".format(self.logical_intf)) + shutdown_result = self.duthost.command(self.cmd_down) + assert shutdown_result["rc"] == 0, "Shutdown {} failed".format(self.logical_intf) + assert check_interface_status(self.duthost, [self.logical_intf], expect_up=False) + + def restore(self): + """ + Restore a logical interface from disabled state by doing below: + * Startup port + * Enable DOM polling + """ + if self.is_admin_up: + logging.info("Startup {} after sfp reset to restore module".format(self.logical_intf)) + startup_result = self.duthost.command(self.cmd_up) + assert startup_result["rc"] == 0, "Startup {} failed".format(self.logical_intf) + assert check_interface_status(self.duthost, [self.logical_intf], expect_up=True) + else: + logging.info("Skip startup {} after sfp reset as it's admin down pre-test".format(self.logical_intf)) + + if not self.skip_dom_polling_handle: + logging.info("Restore DOM polling to {} after sfp reset for {}".format(self.orig_dom_polling_value, + self.logical_intf)) + if not self.orig_dom_polling_value: + restore_dom_result = self.duthost.command(self.db_cmd_dom_polling_clear) + else: + restore_dom_result = self.duthost.command(db_cmd_dom_polling.format(self.namespace_cmd_opt, + "HSET", + self.logical_intf, + self.orig_dom_polling_value)) + assert restore_dom_result["rc"] == 0, "Restore DOM polling failed for {}".format(self.logical_intf) + + +class DisablePhysicalInterface: + """ + Context manager to disable the given physical interface (as wells as its + logical interfaces if needed) and restore afterwards. + + Disable/enable port includes: + * Disable/enable DOM polling + * Shutdown/startup port + """ + def __init__(self, duthost, enum_frontend_asic_index, phy_intf, logical_intfs_dict): + self.duthost = duthost + self.phy_intf = phy_intf + self.original_lpmode_state = None + self.wait_after_dom_config = 1 + self.logical_intf_disablers = \ + [LogicalInterfaceDisabler(duthost, + enum_frontend_asic_index, + logical_intf, + phy_intf, + is_admin_up, + skip_dom_polling_handle=(i != 0)) + for i, (logical_intf, is_admin_up) in enumerate(logical_intfs_dict.items())] + + def __enter__(self): + """ + Disable a physical port by doing below: + * Disable DOM polling + * Shutdown port + """ + for logical_intf_disabler in self.logical_intf_disablers: + logical_intf_disabler.disable() + + def __exit__(self, exc_type, exc_val, exc_tb): + """ + Restore a physical port from disabled state by doing below: + * Startup port + * Enable DOM polling + """ + for logical_intf_disabler in self.logical_intf_disablers: + logical_intf_disabler.restore() + + +def get_transceiver_info(duthost, enum_frontend_asic_index, logical_intf): + namespace_cmd_opt = get_namespace_cmd_option(duthost, enum_frontend_asic_index) + cmd = "sonic-db-cli {} STATE_DB HGETALL 'TRANSCEIVER_INFO|{}'".format(namespace_cmd_opt, logical_intf) + xcvr_info_output = duthost.command(cmd)["stdout"] + return xcvr_info_output + + +def is_cmis_module(duthost, enum_frontend_asic_index, logical_intf): + return "cmis_rev" in get_transceiver_info(duthost, enum_frontend_asic_index, logical_intf) + + +def is_power_class_1_module(duthost, enum_frontend_asic_index, logical_intf): + return "Power Class 1" in get_transceiver_info(duthost, enum_frontend_asic_index, logical_intf) + + +def set_lpmode(duthost, logical_intf, lpmode): + """ + Set the low power mode of the given interface. + + Args: + duthost: DUT host object + logical_intf: Logical interface to set lpmode + lpmode: Low power mode to set, 'on' or 'off' + """ + cmd = "{} {} {}".format(cmd_sfp_set_lpmode, lpmode, logical_intf) + lpmode_set_result = duthost.command(cmd) + assert lpmode_set_result["rc"] == 0, "'{}' failed".format(cmd) + time.sleep(WAIT_TIME_AFTER_LPMODE_SET) + + def check_interfaces_up(duthost, namespace, up_ports): logging.info("Checking interface status") intf_facts = duthost.interface_facts(namespace=namespace, up_ports=up_ports)["ansible_facts"] @@ -40,6 +216,100 @@ def check_interfaces_up(duthost, namespace, up_ports): return False +def get_namespace_cmd_option(duthost, asic_index): + """Get the namespace option used in the command""" + namespace = duthost.get_namespace_from_asic_id(asic_index) + return "-n {}".format(namespace) if namespace else "" + + +def get_down_ports(duthost, ports): + """Check and return the down ports among the given ports.""" + return duthost.show_interface(command="status", up_ports=ports)["ansible_facts"][ + "ansible_interface_link_down_ports"] + + +def is_interface_status_expected(duthost, ports, expect_up=True): + """Check if the given ports are up or down as expected.""" + if expect_up: + return len(get_down_ports(duthost, ports)) == 0 + else: + return len(get_down_ports(duthost, ports)) == len(ports) + + +def check_interface_status(duthost, ports, expect_up=True, wait_time=None): + """ + Check if the given ports are up or down as expected. + + Args: + duthost: DUT host object + ports: List of ports to check + expect_up: True if the ports are expected to be up, False if down + wait_time: Time to wait for the ports to come up or down + """ + expect_status_str = "up" if expect_up else "down" + err_msg = "" + + if wait_time is None: + port_down_wait_time, port_up_wait_time = \ + default_port_toggle_wait_time(duthost, len(ports)) + if expect_up: + wait_time = port_up_wait_time + else: + wait_time = port_down_wait_time + + logging.info("Wait for ports to come {}: {}".format(expect_status_str, ports)) + is_ok = wait_until(wait_time, 1, 0, + is_interface_status_expected, + duthost, ports, expect_up) + + if not is_ok: + down_ports = get_down_ports(duthost, ports) + if expect_up: + problematic_ports = down_ports + else: + problematic_ports = set(ports) - down_ports + + err_msg = "Some ports did not come {} as expected: {}".format( + expect_status_str, str(problematic_ports)) + return is_ok, err_msg + + +def get_phy_intfs_to_test_per_asic(duthost, + conn_graph_facts, + enum_frontend_asic_index, + xcvr_skip_list): + """ + Get the interfaces to test for given asic, excluding the skipped ones. + + return: + dict of all physical interfaces to test (key: physical port number, + value: dict of logical interfaces under this physical port whose value + is True if the interface is admin-up) + """ + _, dev_conn = get_dev_conn(duthost, + conn_graph_facts, + enum_frontend_asic_index) + physical_port_idx_map = get_physical_port_indices(duthost, logical_intfs=dev_conn) + phy_intfs_to_test_per_asic = {} + + pre_test_intf_status_dict = duthost.show_interface(command="status")["ansible_facts"]["int_status"] + for logical_intf in dev_conn: + # Skip the interfaces in the skip list + if logical_intf in xcvr_skip_list[ans_host.hostname]: + continue + physical_port_idx = physical_port_idx_map[logical_intf] + phy_intfs_to_test_per_asic.setdefault(physical_port_idx, {})[logical_intf] = \ + pre_test_intf_status_dict.get(logical_intf, {}).get("admin_state", "down") == "up" + # sort physical interfaces + for phy_intf, logical_intfs_dict in sorted(phy_intfs_to_test_per_asic.items()): + # sort logical interfaces within the same physical interface + phy_intfs_to_test_per_asic[phy_intf] = {lintf: logical_intfs_dict[lintf] + for lintf in natsorted(logical_intfs_dict)} + logging.info("Interfaces to test for asic {}: {}".format(enum_frontend_asic_index, + phy_intfs_to_test_per_asic)) + return phy_intfs_to_test_per_asic + + def test_check_sfputil_presence(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, conn_graph_facts, xcvr_skip_list): """ @@ -122,54 +392,61 @@ def test_check_sfputil_eeprom(duthosts, enum_rand_one_per_hwsku_frontend_hostnam def test_check_sfputil_reset(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, conn_graph_facts, - tbinfo, xcvr_skip_list, shutdown_ebgp, stop_xcvrd): # noqa F811 + tbinfo, xcvr_skip_list, shutdown_ebgp): # noqa F811 """ - @summary: Check SFP presence using 'sfputil show presence' + @summary: Check SFP reset using 'sfputil reset' """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] global ans_host ans_host = duthost - portmap, dev_conn = get_dev_conn(duthost, conn_graph_facts, enum_frontend_asic_index) - tested_physical_ports = set() - for intf in dev_conn: - if intf not in xcvr_skip_list[duthost.hostname]: - phy_intf = portmap[intf][0] - if phy_intf in tested_physical_ports: - logging.info( - "skip tested SFPs {} to avoid repeating operating physical interface {}".format(intf, phy_intf)) - continue - tested_physical_ports.add(phy_intf) - logging.info("resetting {} physical interface {}".format(intf, phy_intf)) - reset_result = duthost.command("{} {}".format(cmd_sfp_reset, intf)) - assert reset_result["rc"] == 0, "'{} {}' failed".format(cmd_sfp_reset, intf) - time.sleep(5) - sleep_time = 60 - if duthost.shell("show interfaces transceiver eeprom | grep 400ZR", module_ignore_errors=True)['rc'] == 0: - sleep_time = 90 - - logging.info("Wait some time for SFP to fully recover after reset") - time.sleep(sleep_time) - - logging.info("Check sfp presence again after reset") - sfp_presence = duthost.command(cmd_sfp_presence, module_ignore_errors=True) - - # For vs testbed, we will get expected Error code `ERROR_CHASSIS_LOAD = 2` here. - if duthost.facts["asic_type"] == "vs" and sfp_presence['rc'] == 2: - pass - else: - assert sfp_presence['rc'] == 0, "Run command '{}' failed".format(cmd_sfp_presence) - - parsed_presence = parse_output(sfp_presence["stdout_lines"][2:]) - for intf in dev_conn: - if intf not in xcvr_skip_list[duthost.hostname]: - assert intf in parsed_presence, "Interface is not in output of '{}'".format(cmd_sfp_presence) - assert parsed_presence[intf] == "Present", "Interface presence is not 'Present'" - - logging.info("Check interface status") - mg_facts = duthost.get_extended_minigraph_facts(tbinfo) - intf_facts = duthost.interface_facts(up_ports=mg_facts["minigraph_ports"])["ansible_facts"] - assert len(intf_facts["ansible_interface_link_down_ports"]) == 0, \ - "Some interfaces are down: {}".format(intf_facts["ansible_interface_link_down_ports"]) + phy_intfs_to_test_per_asic = get_phy_intfs_to_test_per_asic(duthost, + conn_graph_facts, + enum_frontend_asic_index, + xcvr_skip_list) + for phy_intf, logical_intfs_dict in phy_intfs_to_test_per_asic.items(): + # Only reset the first logical interface, since sfputil command acts on this physical port entirely. + logical_intf = list(logical_intfs_dict.keys())[0] + with DisablePhysicalInterface(duthost, enum_frontend_asic_index, phy_intf, logical_intfs_dict): + cmd_sfp_presence_per_intf = cmd_sfp_presence + " -p {}".format(logical_intf) + + cmd_sfp_reset_intf = "{} {}".format(cmd_sfp_reset, logical_intf) + logging.info("resetting {} physical interface {}".format(logical_intf, phy_intf)) + reset_result = duthost.command(cmd_sfp_reset_intf) + assert reset_result["rc"] == 0, "'{}' failed".format(cmd_sfp_reset_intf) + time.sleep(I2C_WAIT_TIME_AFTER_SFP_RESET) + + if not is_cmis_module(duthost, enum_frontend_asic_index, logical_intf) and \ + not is_power_class_1_module(duthost, enum_frontend_asic_index, logical_intf): + # On platforms where LowPwrRequestHW=DEASSERTED, module will not get reset to low power. + logging.info("Force {} (physical interface {}) to go through the sequence of lpmode on/off".format( + logical_intf, phy_intf)) + set_lpmode(duthost, logical_intf, "on") + time.sleep(WAIT_TIME_AFTER_LPMODE_SET) + set_lpmode(duthost, logical_intf, "off") + time.sleep(WAIT_TIME_AFTER_LPMODE_SET) + + logging.info("Check sfp presence again after reset") + sfp_presence = duthost.command(cmd_sfp_presence_per_intf, module_ignore_errors=True) + + # For vs testbed, we will get expected Error code `ERROR_CHASSIS_LOAD = 2` here. + if duthost.facts["asic_type"] == "vs" and sfp_presence['rc'] == 2: + pass + else: + assert sfp_presence['rc'] == 0, \ + "Run command '{}' failed".format(cmd_sfp_presence_per_intf) + + parsed_presence = parse_output(sfp_presence["stdout_lines"][2:]) + assert logical_intf in parsed_presence, \ + "Interface is not in output of '{}'".format(cmd_sfp_presence_per_intf) + assert parsed_presence[logical_intf] == "Present", \ + "Interface presence is not 'Present' for {}".format(logical_intf) + + # Check interface status for all interfaces in the end just in case + assert check_interface_status(duthost, + [logical_intf + for logical_intfs_dict in phy_intfs_to_test_per_asic.values() + for logical_intf, is_admin_up in logical_intfs_dict.items() if is_admin_up], + expect_up=True) def test_check_sfputil_low_power_mode(duthosts, enum_rand_one_per_hwsku_frontend_hostname, From b27f64f43ffe39819903bc555fa91bc3e098681d Mon Sep 17 00:00:00 2001 From: Dayou Liu <113053330+dayouliu1@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:32:41 -0800 Subject: [PATCH 144/221] fix sample_golden_config_db.j2 portchannel undefined (#15311) Add portchannel check to sample_golden_config_db.j2 to resolve errors for topos (specifically mx) that do not have portchannels for golden_config_infra/test_config_reload_with_rendered_golden_config.py when running `sonic-cfggen -d -t /tmp/golden_config_db.j2 > /etc/sonic/golden_config_db.json` --- .../templates/sample_golden_config_db.j2 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/golden_config_infra/templates/sample_golden_config_db.j2 b/tests/golden_config_infra/templates/sample_golden_config_db.j2 index 07a119dd2e5..634711e4225 100644 --- a/tests/golden_config_infra/templates/sample_golden_config_db.j2 +++ b/tests/golden_config_infra/templates/sample_golden_config_db.j2 @@ -1,7 +1,9 @@ {% set portchannels= [] %} -{% for pc, value in PORTCHANNEL.items() %} - {% set _ = portchannels.append(pc) %} -{% endfor %} +{% if PORTCHANNEL is defined %} + {% for pc, value in PORTCHANNEL.items() %} + {% set _ = portchannels.append(pc) %} + {% endfor %} +{% endif %} { "NEW_FEATURE": { From 8f3e42ab1a56eb49f92636c5a843ce34228f42f5 Mon Sep 17 00:00:00 2001 From: Chris <156943338+ccroy-arista@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:34:32 -0800 Subject: [PATCH 145/221] Fix asic identification (#15297) * sonic-mgmt: improve asic identification Device ASIC identification is achieved by whole line matches from the output of lspci, which is excessive and subject to fail due to unforeseeable changes in such output. This change reduces the string matching to specific unique differentiators in the output from lspci, while also future-proofing against similar changes in the lspci that could foreseeably occur. * sonic-mgmt: add th4/th5 asic identification Add token matches for identifying the TH4 and TH5 ASICs from the output of lspci. * sonic-mgmt: fix pre-commit issue Fix pre-commit error introduced within the prior two commits. --- tests/common/devices/sonic.py | 37 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/tests/common/devices/sonic.py b/tests/common/devices/sonic.py index b19ee0fb873..c4947d736c8 100644 --- a/tests/common/devices/sonic.py +++ b/tests/common/devices/sonic.py @@ -32,6 +32,7 @@ "orchagent": "swss", "syncd": "syncd" } +UNKNOWN_ASIC = "unknown" class SonicHost(AnsibleHostBase): @@ -1759,28 +1760,34 @@ def run_redis_cli_cmd(self, redis_cmd): cmd = "/usr/bin/redis-cli {}".format(redis_cmd) return self.command(cmd, verbose=False) + def _try_get_brcm_asic_name(self, output): + search_sets = { + "td2": {"b85", "BCM5685"}, + "td3": {"b87", "BCM5687"}, + "th": {"b96", "BCM5696"}, + "th2": {"b97", "BCM5697"}, + "th3": {"b98", "BCM5698"}, + "th4": {"b99", "BCM5699"}, + "th5": {"f90", "BCM7890"}, + } + for asic in search_sets.keys(): + for search_term in search_sets[asic]: + if search_term in output: + return asic + return UNKNOWN_ASIC + def get_asic_name(self): - asic = "unknown" + asic = UNKNOWN_ASIC output = self.shell("lspci", module_ignore_errors=True)["stdout"] - if ("Broadcom Limited Device b960" in output or - "Broadcom Limited Broadcom BCM56960" in output): - asic = "th" - elif "Device b971" in output: - asic = "th2" - elif ("Broadcom Limited Device b850" in output or - "Broadcom Limited Broadcom BCM56850" in output or - "Broadcom Inc. and subsidiaries Broadcom BCM56850" in output): - asic = "td2" - elif ("Broadcom Limited Device b870" in output or - "Broadcom Inc. and subsidiaries Device b870" in output): - asic = "td3" - elif "Broadcom Limited Device b980" in output: - asic = "th3" + if "Broadcom" in output: + asic = self._try_get_brcm_asic_name(output) elif "Cisco Systems Inc Device a001" in output: asic = "gb" elif "Mellanox Technologies" in output: asic = "spc" + logger.info("asic: {}".format(asic)) + return asic def is_nvidia_platform(self): From 9ff03875c6801b6996e1bb04a226ab22a5c54a1b Mon Sep 17 00:00:00 2001 From: Zhijian Li Date: Tue, 12 Nov 2024 21:19:15 -0800 Subject: [PATCH 146/221] [M0-2VLAN] Update test_vlan_ping for m0-2vlan topo (#15503) What is the motivation for this PR? Update test_vlan_ping for m0-2vlan topo. How did you do it? Use topo_type instead of topo_name. How did you verify/test it? Verified on Nokia-7215 M0-2VLAN testbed. --- tests/vlan/test_vlan_ping.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/vlan/test_vlan_ping.py b/tests/vlan/test_vlan_ping.py index fd19021c88f..3b02d493852 100644 --- a/tests/vlan/test_vlan_ping.py +++ b/tests/vlan/test_vlan_ping.py @@ -60,15 +60,15 @@ def vlan_ping_setup(duthosts, rand_one_dut_hostname, ptfhost, nbrhosts, tbinfo, vm_host_info = {} vm_name, vm_info = None, None - topo_name = tbinfo["topo"]["name"] + topo_type = tbinfo["topo"]["type"] for nbr_name, nbr_info in list(nbrhosts.items()): - if topo_name != "m0" or (topo_name == "m0" and "M1" in nbr_name): + if topo_type != "m0" or (topo_type == "m0" and "M1" in nbr_name): vm_name = nbr_name vm_info = nbr_info break py_assert(vm_name is not None, "Can't get neighbor vm") - if topo_name == "mx": + if topo_type == "mx": vm_ip_with_prefix = six.ensure_text(vm_info['conf']['interfaces']['Ethernet1']['ipv4']) output = vm_info['host'].command("ip addr show dev eth1") else: @@ -104,7 +104,7 @@ def vlan_ping_setup(duthosts, rand_one_dut_hostname, ptfhost, nbrhosts, tbinfo, # Get the bgp neighbor connected to the selected VM if a_bgp_nbr['name'] == vm_name and a_bgp_nbr['addr'] == str(vm_host_info['ipv4']): # Find the interface that connects to the selected VM - if topo_name == "mx": + if topo_type == "mx": for intf in mg_facts['minigraph_interfaces']: if intf['peer_addr'] == str(vm_host_info['ipv4']): vm_host_info['port_index_list'] = [mg_facts['minigraph_ptf_indices'][intf['attachto']]] From 48b6c08b7545ca5fd0ce89c19bc5be0b1eea6ea8 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:31:36 +0800 Subject: [PATCH 147/221] Skip traffic test in route perf test for multi-asic (#15515) What is the motivation for this PR? Currently, route/test_route_perf.py does not support traffic tests on multi-asic KVM testbeds and has a high failure rate How did you do it? Skipping traffic test in route perf test for multi-asic KVM platform How did you verify/test it? --- .../tests_mark_conditions_skip_traffic_test.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml index c9e35f27883..18371c03db6 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml @@ -279,6 +279,16 @@ ipfwd/test_dir_bcast.py: conditions: - "asic_type in ['vs']" +####################################### +##### route ##### +####################################### +route/test_route_perf.py: + skip_traffic_test: + reason: "Skip traffic test for KVM testbed" + conditions: + - "asic_type in ['vs']" + - "is_multi_asic==True" + ####################################### ##### span ##### ####################################### From b24321ea3066843067565cfd36dedcae38076310 Mon Sep 17 00:00:00 2001 From: Kevin Wang <65380078+kevinskwang@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:53:33 +0800 Subject: [PATCH 148/221] Increase the sleep time after change the interface status (#15517) Signed-off-by: Kevin Wang --- tests/fdb/test_fdb_mac_learning.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fdb/test_fdb_mac_learning.py b/tests/fdb/test_fdb_mac_learning.py index e8f192243b4..c11590f5ced 100644 --- a/tests/fdb/test_fdb_mac_learning.py +++ b/tests/fdb/test_fdb_mac_learning.py @@ -200,7 +200,7 @@ def testFdbMacLearning(self, ptfadapter, duthosts, rand_one_dut_hostname, ptfhos # unshut 1 port and populate fdb for that port. make sure fdb entry is populated in mac table duthost = duthosts[rand_one_dut_hostname] duthost.shell("sudo config interface startup {}".format(target_ports_to_ptf_mapping[0][0])) - time.sleep(10) + time.sleep(30) self.dynamic_fdb_oper(duthost, tbinfo, ptfhost, [target_ports_to_ptf_mapping[0]]) pytest_assert(wait_until(300, 2, 1, fdb_table_has_dummy_mac_for_interface, duthost, target_ports_to_ptf_mapping[0][0], self.DUMMY_MAC_PREFIX), "After starting {}" @@ -210,7 +210,7 @@ def testFdbMacLearning(self, ptfadapter, duthosts, rand_one_dut_hostname, ptfhos # unshut 3 more ports and populate fdb for those ports duthost.shell("sudo config interface startup {}-{}".format(target_ports_to_ptf_mapping[1][0], target_ports_to_ptf_mapping[3][0][8:])) - time.sleep(10) + time.sleep(30) self.dynamic_fdb_oper(duthost, tbinfo, ptfhost, target_ports_to_ptf_mapping[1:]) for i in range(1, len(target_ports_to_ptf_mapping)): pytest_assert(wait_until(300, 2, 1, fdb_table_has_dummy_mac_for_interface, duthost, @@ -221,7 +221,7 @@ def testFdbMacLearning(self, ptfadapter, duthosts, rand_one_dut_hostname, ptfhos # shutdown last 3 ports and make sure corresponding entries are gone from MAC address table for i in range(1, len(target_ports_to_ptf_mapping)): duthost.shell("sudo config interface shutdown {}".format(target_ports_to_ptf_mapping[i][0])) - time.sleep(10) + time.sleep(30) for i in range(1, len(target_ports_to_ptf_mapping)): pytest_assert(not (fdb_table_has_dummy_mac_for_interface(duthost, target_ports_to_ptf_mapping[i][0])), "mac entry present when interface {} is down" From f3d2014a06e4114dc74182fefc01bba18413a6c6 Mon Sep 17 00:00:00 2001 From: veronica-arista <117375955+veronica-arista@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:30:39 -0800 Subject: [PATCH 149/221] Fix intermittent issue on reboot in test_lldp_syncd (#15331) At the start of test_lldp_syncd.py::test_lldp_entry_table_after_reboot the test polls and checks that LLDP_ENTRY_TABLE keys match show lldp table output. The eth0 port is added last so sometimes the entry keys will have it but the lldp table output will not. From debugging, this is the case since the end of the previous test (I put a check on the keys vs lldp table output and observed the missing eth0 at the end of test_lldp_syncd.py::test_lldp_entry_table_after_lldp_restart) Added a wait_until at the start of test_lldp_entry_table_after_reboot to wait until the LLDP_ENTRY_TABLE keys match show lldp table output before the tests starts to reboot. --- tests/lldp/test_lldp_syncd.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/lldp/test_lldp_syncd.py b/tests/lldp/test_lldp_syncd.py index 361188f0dc1..75d1e03b090 100644 --- a/tests/lldp/test_lldp_syncd.py +++ b/tests/lldp/test_lldp_syncd.py @@ -90,6 +90,13 @@ def get_show_lldp_table_output(duthost): return interface_list +def check_lldp_table_keys(duthost, db_instance): + # Check if LLDP_ENTRY_TABLE keys match show lldp table output + lldp_entry_keys = get_lldp_entry_keys(db_instance) + show_lldp_table_int_list = get_show_lldp_table_output(duthost) + return sorted(lldp_entry_keys) == sorted(show_lldp_table_int_list) + + def assert_lldp_interfaces( lldp_entry_keys, show_lldp_table_int_list, lldpctl_interface ): @@ -322,6 +329,12 @@ def test_lldp_entry_table_after_reboot( localhost, duthosts, enum_rand_one_per_hwsku_frontend_hostname, db_instance ): duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + + # Verify LLDP_ENTRY_TABLE keys match show lldp table output at the start of test + keys_match = wait_until(30, 5, 0, check_lldp_table_keys, duthost, db_instance) + if not keys_match: + assert keys_match, "LLDP_ENTRY_TABLE keys do not match 'show lldp table' output" + # reboot logging.info("Run cold reboot on DUT") reboot( From e3e1c66a37d61bf90e0ddba0e5415cade6ca7bf1 Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:29:16 +0800 Subject: [PATCH 150/221] Add dualtor stanalone and swithover faulty ycable test to PR test (#15519) What is the motivation for this PR? Elastictest performs well in distribute running PR test in multiple KVMs, which support us to add more test scripts to PR checker. But some traffic test using ptfadapter can't be tested on KVM platform, we need to skip traffic test if needed How did you do it? Add dualtor stanalone and swithover faulty ycable test to PR test How did you verify/test it? --- .azure-pipelines/pr_test_scripts.yaml | 2 ++ tests/common/dualtor/tunnel_traffic_utils.py | 11 +++++------ tests/dualtor/test_switchover_faulty_ycable.py | 12 ++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.azure-pipelines/pr_test_scripts.yaml b/.azure-pipelines/pr_test_scripts.yaml index cd44402cf13..b48fd5685b5 100644 --- a/.azure-pipelines/pr_test_scripts.yaml +++ b/.azure-pipelines/pr_test_scripts.yaml @@ -245,7 +245,9 @@ dualtor: - arp/test_arp_dualtor.py - arp/test_arp_extended.py - dualtor/test_ipinip.py + - dualtor/test_standalone_tunnel_route.py - dualtor/test_switchover_failure.py + - dualtor/test_switchover_faulty_ycable.py - dualtor/test_tor_ecn.py - dualtor/test_tunnel_memory_leak.py - dualtor_io/test_heartbeat_failure.py diff --git a/tests/common/dualtor/tunnel_traffic_utils.py b/tests/common/dualtor/tunnel_traffic_utils.py index 059ca8ad703..402061c7dc3 100644 --- a/tests/common/dualtor/tunnel_traffic_utils.py +++ b/tests/common/dualtor/tunnel_traffic_utils.py @@ -262,6 +262,7 @@ def __init__(self, standby_tor, active_tor=None, existing=True, inner_packet=Non self.listen_ports = sorted(self._get_t1_ptf_port_indexes(standby_tor, tbinfo)) self.ptfadapter = ptfadapter self.packet_count = packet_count + self.asic_type = standby_tor.facts["asic_type"] standby_tor_cfg_facts = self.standby_tor.config_facts( host=self.standby_tor.hostname, source="running" @@ -292,17 +293,15 @@ def __enter__(self): def __exit__(self, *exc_info): if exc_info[0]: return + if self.asic_type == "vs": + logging.info("Skipping traffic check on VS platform.") + return try: - result = testutils.verify_packet_any_port( + port_index, rec_pkt = testutils.verify_packet_any_port( ptfadapter, self.exp_pkt, ports=self.listen_ports ) - if isinstance(result, tuple): - port_index, rec_pkt = result - elif isinstance(result, bool): - logging.info("Using dummy testutils to skip traffic test.") - return except AssertionError as detail: logging.debug("Error occurred in polling for tunnel traffic", exc_info=True) if "Did not receive expected packet on any of ports" in str(detail): diff --git a/tests/dualtor/test_switchover_faulty_ycable.py b/tests/dualtor/test_switchover_faulty_ycable.py index c5a47cf43ff..4e68aa14b66 100644 --- a/tests/dualtor/test_switchover_faulty_ycable.py +++ b/tests/dualtor/test_switchover_faulty_ycable.py @@ -21,6 +21,18 @@ ] +@pytest.fixture(autouse=True) +def ignore_expected_loganalyzer_exceptions(duthosts, rand_one_dut_hostname, loganalyzer): + # Ignore in KVM test + KVMIgnoreRegex = [ + ".*Could not establish the active side for Y cable port.*", + ] + duthost = duthosts[rand_one_dut_hostname] + if loganalyzer: # Skip if loganalyzer is disabled + if duthost.facts["asic_type"] == "vs": + loganalyzer[duthost.hostname].ignore_regex.extend(KVMIgnoreRegex) + + @pytest.fixture(scope="module") def simulated_faulty_side(rand_unselected_dut): return rand_unselected_dut From 11dd4b739d9d83339295c1672d494d6318685abb Mon Sep 17 00:00:00 2001 From: Dayou Liu <113053330+dayouliu1@users.noreply.github.com> Date: Wed, 13 Nov 2024 06:52:23 -0800 Subject: [PATCH 151/221] fix check_dut_asic_type fixture index error (#14830) Updated the rand_one_dut_hostname and selected_rand_dut fixtures to set rand_one_dut_hostname_var whenever needed, specifically in the case the fixture is dynamically loaded. Removed old method of setting rand_one_dut_hostname_var. --- tests/conftest.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index b9ba2c76de9..f0531bb5ba0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -493,6 +493,8 @@ def rand_one_dut_hostname(request): """ """ global rand_one_dut_hostname_var + if rand_one_dut_hostname_var is None: + set_rand_one_dut_hostname(request) return rand_one_dut_hostname_var @@ -507,6 +509,8 @@ def rand_selected_dut(duthosts, rand_one_dut_hostname): @pytest.fixture(scope="module") def selected_rand_dut(request): global rand_one_dut_hostname_var + if rand_one_dut_hostname_var is None: + set_rand_one_dut_hostname(request) return rand_one_dut_hostname_var @@ -1699,12 +1703,6 @@ def pytest_generate_tests(metafunc): # noqa E302 if dut_fixture_name and "selected_dut" in metafunc.fixturenames: metafunc.parametrize("selected_dut", duts_selected, scope="module", indirect=True) - # When rand_one_dut_hostname used and select a dut for test, initialize rand_one_dut_hostname_var - # rand_one_dut_hostname and rand_selected_dut will use this variable for setup test case - # selected_rand_dut will use this variable for setup TACACS - if "rand_one_dut_hostname" in metafunc.fixturenames: - set_rand_one_dut_hostname(metafunc) - if "enum_dut_portname" in metafunc.fixturenames: metafunc.parametrize("enum_dut_portname", generate_port_lists(metafunc, "all_ports")) From 17208c4700150f546b6e4b94bb132e6b55cb2573 Mon Sep 17 00:00:00 2001 From: Xu Chen <112069142+XuChen-MSFT@users.noreply.github.com> Date: Wed, 13 Nov 2024 23:21:35 +0800 Subject: [PATCH 152/221] fix 7260 headroom pool watermark test failure (#15536) What is the motivation for this PR? observed consistent headroom wartermark test failure on 7260 and it's known issue of test script, as below RCA: RCA: summarize test step first: PTF send lots of pkt to multiple src ports to fill multiple PG's share buffer PTF send one or a few pkts to multiple src ports to trigger pfc on multiple PG check watermark before test headroom's watermark PTF send pkt to multiple src port to consum headroom pool, and test if watermark changes as expected after step2, already send 20 pkts into headroom to trigger PFC on 10 src ports (20 PG) but, so far, "upper_bound" value is static hardcode "2 * margin + 1", didn't consider headroom pool consumption in step2. since we use dynamically threshold calculating, it can get accurate threshold value, we pretty sure the headroom pool consumption equal "pgs_num" in step2. so I change "upper_bound" value to "2 * margin + self.pgs_num", and it pass the tests. How did you do it? change "upper_bound" value to "2 * margin + self.pgs_num" How did you verify/test it? this change already verified in MSFT nightly for 202305 and 202311 branch, just commit to github. Any platform specific information? this change is dedicated to below platform and topology: if (hwsku == 'Arista-7260CX3-D108C8' and self.testbed_type in ('t0-116', 'dualtor-120')) \ or (hwsku == 'Arista-7260CX3-C64' and self.testbed_type in ('dualtor-aa-56', 't1-64-lag')): upper_bound = 2 * margin + self.pgs_num if other platform and topology have hit similar issue, can add affected platform and topo to above condition checking. Note: for generic fix, qos refactor project will covert. --- tests/saitests/py3/sai_qos_tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index 9ec46133975..30212910941 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -3158,6 +3158,9 @@ def runTest(self): sys.stderr.flush() upper_bound = 2 * margin + 1 + if (hwsku == 'Arista-7260CX3-D108C8' and self.testbed_type in ('t0-116', 'dualtor-120')) \ + or (hwsku == 'Arista-7260CX3-C64' and self.testbed_type in ('dualtor-aa-56', 't1-64-lag')): + upper_bound = 2 * margin + self.pgs_num if self.wm_multiplier: hdrm_pool_wm = sai_thrift_read_headroom_pool_watermark( self.src_client, self.buf_pool_roid) From bc9aef9be7fc46be0dbd4911c5f03f2891afe001 Mon Sep 17 00:00:00 2001 From: veronica-arista <117375955+veronica-arista@users.noreply.github.com> Date: Wed, 13 Nov 2024 07:56:58 -0800 Subject: [PATCH 153/221] Fix qos node selection for single-asic (#15074) Fix single-asic issues from PR https://github.com/sonic-net/sonic-mgmt/pull/14925 The search for shortlink linecard logic added in that PR does not verify that a DUT is multi-asic for the single_dut_multi_asic tests and incorrectly tries to access the asics on a single-asic DUT. --- tests/qos/qos_sai_base.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/qos/qos_sai_base.py b/tests/qos/qos_sai_base.py index 1b2c5d92a66..92e315d128f 100644 --- a/tests/qos/qos_sai_base.py +++ b/tests/qos/qos_sai_base.py @@ -634,12 +634,18 @@ def select_src_dst_dut_and_asic(self, duthosts, request, tbinfo, lower_tor_host) dst_asic_index = 0 elif test_port_selection_criteria == "single_dut_multi_asic": + found_multi_asic_dut = False if topo in self.SUPPORTED_T0_TOPOS or isMellanoxDevice(duthost): pytest.skip("single_dut_multi_asic is not supported on T0 topologies") if topo not in self.SUPPORTED_T1_TOPOS and shortlink_indices: - src_dut_index = random.choice(shortlink_indices) + random.shuffle(shortlink_indices) + for idx in shortlink_indices: + a_dut = duthosts.frontend_nodes[idx] + if a_dut.sonichost.is_multi_asic: + src_dut_index = idx + found_multi_asic_dut = True + break else: - found_multi_asic_dut = False for a_dut_index in range(len(duthosts.frontend_nodes)): a_dut = duthosts.frontend_nodes[a_dut_index] if a_dut.sonichost.is_multi_asic: @@ -647,9 +653,9 @@ def select_src_dst_dut_and_asic(self, duthosts, request, tbinfo, lower_tor_host) found_multi_asic_dut = True logger.info("Using dut {} for single_dut_multi_asic testing".format(a_dut.hostname)) break - if not found_multi_asic_dut: - pytest.skip( - "Did not find any frontend node that is multi-asic - so can't run single_dut_multi_asic tests") + if not found_multi_asic_dut: + pytest.skip( + "Did not find any frontend node that is multi-asic - so can't run single_dut_multi_asic tests") dst_dut_index = src_dut_index src_asic_index = 0 dst_asic_index = 1 From 1155fb87fe7d7447335231135a3c21f4f8aab77c Mon Sep 17 00:00:00 2001 From: Sai <165318278+saiilla@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:47:24 -0800 Subject: [PATCH 154/221] Watchport blackbox test plan (#15222) * Create Watchport_Blackbox_Test _Plan.md * Update Watchport_Blackbox_Test _Plan.md * Update Watchport_Blackbox_Test _Plan.md * Update Watchport_Blackbox_Test _Plan.md --- .../tests/Watchport_Blackbox_Test _Plan.md | 256 ++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 sdn_tests/tests/Watchport_Blackbox_Test _Plan.md diff --git a/sdn_tests/tests/Watchport_Blackbox_Test _Plan.md b/sdn_tests/tests/Watchport_Blackbox_Test _Plan.md new file mode 100644 index 00000000000..4c6c34a00a9 --- /dev/null +++ b/sdn_tests/tests/Watchport_Blackbox_Test _Plan.md @@ -0,0 +1,256 @@ +# Objective + +This document captures the tests that are intended to be covered in the blackbox test environment for Watchport feature. + +# Overview + +Watchport is a feature that aims to quickly remove a link (that went down) from the WCMP/ECMP group it participates in before the controller (used interchangeably with the external view) can detect the link down event and take the appropriate recovery action. This is mainly to shorten the duration of traffic black hole problems that may arise if a down member exists in a WCMP/ECMP group. + +The test-plan aims to verify the correctness of the feature by picking up certain triggers and common use-cases. The testing will not cover the following: + +- Reference or object dependencies like whether a nexthop member exists before being referenced in the WCMP/ECMP group action. +- Traffic loss/convergence related scenarios. + +# Testbed Requirements + +The testbed requirements are the existence of a basic blackbox setup that comprises a SUT and control switch which are connected to each other on multiple links. + +# Test Cases + +## Configured weights are realized + + + + + + + + + + + + + + + + + + +
    TitleVerify basic WCMP/ECMP packet hashing works with watch port actions.
    Procedure
      +
    • Create a WCMP/ECMP group (herein referred to as Action Profile Group APG) with multiple members (herein referred to as Action Profile Members APM) with an associated watch port for each member.
    • +
    +
      +
    • Send different packets to the SUT from the control switch by varying a field in the packet header that will apply the hashing algorithm to select an APM from the APG.
    • +
    +
    Expected Results
      +
    • Verify the packets are distributed to all the members in the APG by comparing the actual number of packets received on each port vs the expected up members.
    • +
    +
    + +## + +## Member down handling + + + + + + + + + + + + + + + + + + +
    TitleVerify the watchport action when the watch port link is forced down.
    Procedure
      +
    • Create a WCMP/ECMP APG with multiple APM.
    • +
    +
      +
    • Bring down the watch port associated with one member of the APG.
    • +
    +
    Expected Results
      +
    • Verify that the member of the down port is excluded from the APG (via traffic tests) but the read request from P4RT (as in APP_DB) reflects the original set of Action Profile members.
    • +
    +
      +
    • Send different packets as in the earlier step and verify traffic is distributed only to the members whose watch port link is up.
    • +
    +
    + +## Member up handling + + + + + + + + + + + + + + + + + + +
    TitleVerify the watchport action when the watch port link comes up
    Procedure
      +
    • Disable link damping (if any) to ensure link up notifications are delivered instantly.
    • +
    +
      +
    • Bring up the watch port of an excluded member of an APG.
    • +
    +
      +
    • Resend packets with varying headers that will ensure all members are hashed.
    • +
    +
    Expected Results
      +
    • Verify that packets are distributed as per the new membership.
    • +
    +
    + +## Watch port for a single member group + + + + + + + + + + + + + + + + + + +
    TitleVerify watch port functionality for single member.
    Procedure
      +
    • Disable link damping (if any) to ensure link up notifications are delivered instantly.
    • +
    +
      +
    • Create a WCMP/ECMP APG with only one member
    • +
    +
      +
    • Send different packets to the SUT from the control switch by varying a field in the packet header.
    • +
    +
      +
    • Bring down the watch port associated with the member.
    • +
    +
      +
    • Bring up the watch port associated with the member in the APG.
    • +
    +
    Expected Results
      +
    • Verify that all packets are sent out on the same member while the associated watch port is up, no traffic loss.
    • +
    +
      +
    • Verify that all packets are dropped when the associated watch port is down.
    • +
    +
    + +## Modify operation on a watchport member + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleVerify watch port action along with the controller updates.
    Procedure
      +
    • Disable link damping (if any) to ensure link up notifications are delivered instantly.
    • +
    +
      +
    • Create a WCMP/ECMP APG with multiple members and watch ports.
    • +
    +
      +
    • Bring down one of the watch port associated with a member and verify the member is excluded from the selection process for this APG.
    • +
    +
      +
    • Send a modify APG request that removes the member whose watch port was brought down.
    • +
    +
      +
    • Bring the associated watch port up and verify that the deleted member does not get added back to the APG.
    • +
    +
      +
    • Send traffic with varying packet headers.
    • +
    +
    Expected Results
      +
    • Verify APP_DB state always reflects the membership consistent to the external view and not the membership that the switch implementation modified when the associated watch port went down/up.
    • +
    +
      +
    • Verify traffic is destined only to the members programmed by the controller and whose associated watch port is up.
    • +
    +
    Procedure
      +
    • Repeat the same steps as above but replace the modify APG with remove APG operation.
    • +
    +
    Expected Results
      +
    • Verify that bringing up the watch port does not result in any critical error reported by the switch. (No group exists since the group was removed)
    • +
    +
    + +## Specifying a down-port as watch port + + + + + + + + + + + + + + + + + + +
    TitleVerify the watch port action when the controller adds a member to the APG whose associated watch port is down.
    Procedure
      +
    • Disable link damping (if any) to ensure link up notifications are delivered instantly.
    • +
    +
      +
    • Create a WCMP/ECMP APG with some members whose watch ports are up and some down.
    • +
    +
      +
    • Send traffic and ensure only non-excluded member ports receive it, no traffic loss.
    • +
    +
      +
    • Bring up the watch port whose APM was excluded from the APG.
    • +
    +
    Expected Results
      +
    • Verify APP_STATE DB read always reflect all members.
    • +
    +
      +
    • Verify traffic is destined to only members in the APG whose associated watch ports are up and there is no overall traffic loss.
    • +
    +
    From 709ebdecad3c1b3d6e948578e00475ca4aaebdd2 Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:14:35 -0800 Subject: [PATCH 155/221] Skip RX_DRP check on Mellanox platform in test_drop_l3_ip_packet_non_dut_mac (#15248) --- tests/ip/test_ip_packet.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/ip/test_ip_packet.py b/tests/ip/test_ip_packet.py index 9d12aa3ee79..ab47b2cc1f7 100644 --- a/tests/ip/test_ip_packet.py +++ b/tests/ip/test_ip_packet.py @@ -739,8 +739,11 @@ def test_drop_l3_ip_packet_non_dut_mac(self, duthosts, enum_rand_one_per_hwsku_f return pytest_assert(rx_ok >= self.PKT_NUM_MIN, "Received {} packets in rx, not in expected range".format(rx_ok)) - pytest_assert(rx_drp >= self.PKT_NUM_MIN, - "Dropped {} packets in rx, not in expected range".format(rx_drp)) + asic_type = duthost.facts["asic_type"] + # Packet is dropped silently on Mellanox platform if the destination MAC address is not the router MAC + if asic_type not in ["mellanox"]: + pytest_assert(rx_drp >= self.PKT_NUM_MIN, + "Dropped {} packets in rx, not in expected range".format(rx_drp)) pytest_assert(tx_ok <= self.PKT_NUM_ZERO, "Forwarded {} packets in tx, not in expected range".format(tx_ok)) pytest_assert(max(tx_drp, tx_rif_err) <= self.PKT_NUM_ZERO, From 0f1148ee02c2edf71b79d259ebbbfaf934f9d20d Mon Sep 17 00:00:00 2001 From: Zain Budhwani <99770260+zbud-msft@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:07:25 -0800 Subject: [PATCH 156/221] Ensure correct testing telemetry config after config reload (#15071) What is the motivation for this PR? After config reload, other telemetry cases fail since testing telemetry config is no longer present. This causes that telemetry config will not have client_auth set to false which results in cert errors when running telemetry query. Added disable_loganalyzer to test_telemetry_queue_buffer_cnt since we see teardown loganalyzer errors complaining about non telemetry related syncd SAI_API logs How did you do it? Ensure that telemetry present after each config reload call. How did you verify/test it? Manual/Pipeline --- tests/common/helpers/telemetry_helper.py | 26 ++++++++++++------------ tests/telemetry/test_telemetry.py | 4 ++++ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/common/helpers/telemetry_helper.py b/tests/common/helpers/telemetry_helper.py index 2ae26114513..4124a43f53a 100644 --- a/tests/common/helpers/telemetry_helper.py +++ b/tests/common/helpers/telemetry_helper.py @@ -52,6 +52,19 @@ def setup_telemetry_forpyclient(duthost): client_auth_out = duthost.shell('sonic-db-cli CONFIG_DB HGET "%s|gnmi" "client_auth"' % (env.gnmi_config_table), module_ignore_errors=False)['stdout_lines'] client_auth = str(client_auth_out[0]) + + if client_auth == "true": + duthost.shell('sonic-db-cli CONFIG_DB HSET "%s|gnmi" "client_auth" "false"' % (env.gnmi_config_table), + module_ignore_errors=False) + duthost.shell("systemctl reset-failed %s" % (env.gnmi_container)) + duthost.service(name=env.gnmi_container, state="restarted") + # Wait until telemetry was restarted + py_assert(wait_until(100, 10, 0, duthost.is_service_fully_started, env.gnmi_container), + "%s not started." % (env.gnmi_container)) + logger.info("telemetry process restarted") + else: + logger.info('client auth is false. No need to restart telemetry') + return client_auth @@ -83,19 +96,6 @@ def _context_for_setup_streaming_telemetry(request, duthosts, enum_rand_one_per_ env = GNMIEnvironment(duthost, GNMIEnvironment.TELEMETRY_MODE) default_client_auth = setup_telemetry_forpyclient(duthost) - if default_client_auth == "true": - duthost.shell('sonic-db-cli CONFIG_DB HSET "%s|gnmi" "client_auth" "false"' % (env.gnmi_config_table), - module_ignore_errors=False) - duthost.shell("systemctl reset-failed %s" % (env.gnmi_container)) - duthost.service(name=env.gnmi_container, state="restarted") - else: - logger.info('client auth is false. No need to restart telemetry') - - # Wait until telemetry was restarted - py_assert(wait_until(100, 10, 0, duthost.is_service_fully_started, env.gnmi_container), - "%s not started." % (env.gnmi_container)) - logger.info("telemetry process restarted. Now run pyclient on ptfdocker") - # Wait until the TCP port was opened dut_ip = duthost.mgmt_ip if is_ipv6: diff --git a/tests/telemetry/test_telemetry.py b/tests/telemetry/test_telemetry.py index c975f532fd4..be487aac402 100644 --- a/tests/telemetry/test_telemetry.py +++ b/tests/telemetry/test_telemetry.py @@ -8,6 +8,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until from tests.common.helpers.gnmi_utils import GNMIEnvironment +from tests.common.helpers.telemetry_helper import setup_telemetry_forpyclient from telemetry_utils import assert_equal, get_list_stdout, get_dict_stdout, skip_201911_and_older from telemetry_utils import generate_client_cli, parse_gnmi_output, check_gnmi_cli_running from tests.common import config_reload @@ -31,6 +32,8 @@ def load_new_cfg(duthost, data): duthost.copy(content=json.dumps(data, indent=4), dest=CFG_DB_PATH) config_reload(duthost, config_source='config_db', safe_reload=True) + # config reload overrides testing telemetry config, ensure testing config exists + setup_telemetry_forpyclient(duthost) def get_buffer_queues_cnt(ptfhost, gnxi_path, dut_ip, iface, gnmi_port): @@ -129,6 +132,7 @@ def test_telemetry_ouput(duthosts, enum_rand_one_per_hwsku_hostname, ptfhost, @pytest.mark.parametrize('setup_streaming_telemetry', [False], indirect=True) +@pytest.mark.disable_loganalyzer def test_telemetry_queue_buffer_cnt(duthosts, enum_rand_one_per_hwsku_hostname, ptfhost, setup_streaming_telemetry, gnxi_path): """ From 4f001242c965f03a626951e18f158b8c03b9083a Mon Sep 17 00:00:00 2001 From: prabhataravind <108555774+prabhataravind@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:27:36 -0800 Subject: [PATCH 157/221] [copp]: Add test cases to verify rate-limiting for the following cases (#14670) * [copp]: Add test cases to verify rate-limiting for the following cases * Neighbor miss (subnet hit) packets * Neighbor miss after decap for IPinIP encapsulated packets Signed-off-by: Prabhat Aravind * Skip traffic tests for kvm testbeds Signed-off-by: Prabhat Aravind * Address review comment * Use default rate of 600PPS for default trap group and associated tests Signed-off-by: Prabhat Aravind * remove skip_traffic_test fixture the fixture has been deprecated recently Signed-off-by: Prabhat Aravind --------- Signed-off-by: Prabhat Aravind --- .../test/files/ptftests/py3/copp_tests.py | 133 ++++++++++++++---- .../tests_mark_conditions.yaml | 5 + tests/copp/conftest.py | 16 +++ tests/copp/copp_utils.py | 40 ++++++ tests/copp/scripts/update_copp_config.py | 9 +- tests/copp/test_copp.py | 45 +++++- 6 files changed, 209 insertions(+), 39 deletions(-) diff --git a/ansible/roles/test/files/ptftests/py3/copp_tests.py b/ansible/roles/test/files/ptftests/py3/copp_tests.py index 42fd1435845..92211065432 100644 --- a/ansible/roles/test/files/ptftests/py3/copp_tests.py +++ b/ansible/roles/test/files/ptftests/py3/copp_tests.py @@ -26,6 +26,8 @@ # SSHTest # IP2METest # DefaultTest +# VlanSubnetTest +# VlanSubnetIPinIPTest import datetime import os @@ -34,6 +36,7 @@ import threading import time +import ptf.packet as scapy import ptf.testutils as testutils from ptf.base_tests import BaseTest @@ -45,9 +48,6 @@ class ControlPlaneBaseTest(BaseTest): PPS_LIMIT = 600 PPS_LIMIT_MIN = PPS_LIMIT * 0.9 PPS_LIMIT_MAX = PPS_LIMIT * 1.3 - DEFAULT_PPS_LIMIT = 300 - DEFAULT_PPS_LIMIT_MIN = DEFAULT_PPS_LIMIT * 0.9 - DEFAULT_PPS_LIMIT_MAX = DEFAULT_PPS_LIMIT * 1.3 NO_POLICER_LIMIT = PPS_LIMIT * 1.4 TARGET_PORT = "3" # Historically we have port 3 as a target port TASK_TIMEOUT = 600 # Wait up to 10 minutes for tasks to complete @@ -69,6 +69,8 @@ def __init__(self): self.myip = test_params.get('myip', None) self.peerip = test_params.get('peerip', None) + self.vlanip = test_params.get('vlanip', None) + self.loopbackip = test_params.get('loopbackip', None) self.default_server_send_rate_limit_pps = test_params.get( 'send_rate_limit', 2000) @@ -83,6 +85,7 @@ def __init__(self): self.asic_type = test_params.get('asic_type', None) self.platform = test_params.get('platform', None) self.topo_type = test_params.get('topo_type', None) + self.ip_version = test_params.get('ip_version', None) def log(self, message, debug=False): current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") @@ -219,14 +222,14 @@ def copp_test(self, packet, send_intf, recv_intf): return send_count, recv_count, time_delta, time_delta_ms, tx_pps, rx_pps - def contruct_packet(self, port_number): + def construct_packet(self, port_number): raise NotImplementedError def check_constraints(self, send_count, recv_count, time_delta_ms, rx_pps): raise NotImplementedError def one_port_test(self, port_number): - packet = self.contruct_packet(port_number) + packet = self.construct_packet(port_number) send_count, recv_count, time_delta, time_delta_ms, tx_pps, rx_pps = \ self.copp_test(bytes(packet), (0, port_number), (1, port_number)) @@ -289,7 +292,7 @@ def runTest(self): self.log("ARPTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] src_ip = self.myip dst_ip = self.peerip @@ -319,7 +322,7 @@ def runTest(self): self.log("DHCPTopoT1Test") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] packet = testutils.simple_udp_packet( @@ -368,7 +371,7 @@ def runTest(self): self.log("DHCPTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] packet = testutils.simple_udp_packet( @@ -417,7 +420,7 @@ def runTest(self): self.log("DHCP6Test") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] packet = testutils.simple_udpv6_packet( @@ -445,7 +448,7 @@ def runTest(self): self.log("DHCP6TopoT1Test") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] packet = testutils.simple_udpv6_packet( @@ -485,7 +488,7 @@ def runTest(self): self.log("LLDPTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] packet = testutils.simple_eth_packet( @@ -525,7 +528,7 @@ def runTest(self): # as its destination MAC address. eth_type is to indicate # the length of the data in Ethernet 802.3 frame. pktlen # = 117 = 103 (0x67) + 6 (dst MAC) + 6 (dst MAC) + 2 (len) - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] packet = testutils.simple_eth_packet( @@ -547,7 +550,7 @@ def runTest(self): self.log("BGPTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): dst_mac = self.peer_mac[port_number] dst_ip = self.peerip @@ -586,15 +589,15 @@ def check_constraints(self, send_count, recv_count, time_delta_ms, rx_pps): else: self.log("Checking constraints (DefaultPolicyApplied):") self.log( - "DEFAULT_PPS_LIMIT_MIN (%d) <= rx_pps (%d) <= DEFAULT_PPS_LIMIT_MAX (%d): %s" % - (int(self.DEFAULT_PPS_LIMIT_MIN), + "PPS_LIMIT_MIN (%d) <= rx_pps (%d) <= PPS_LIMIT_MAX (%d): %s" % + (int(self.PPS_LIMIT_MIN), int(rx_pps), - int(self.DEFAULT_PPS_LIMIT_MAX), - str(self.DEFAULT_PPS_LIMIT_MIN <= rx_pps <= self.DEFAULT_PPS_LIMIT_MAX)) + int(self.PPS_LIMIT_MAX), + str(self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX)) ) - assert self.DEFAULT_PPS_LIMIT_MIN <= rx_pps <= self.DEFAULT_PPS_LIMIT_MAX, "Copp policer constraint " \ + assert self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX, "Copp policer constraint " \ "check failed, Actual PPS: {} Expected PPS range: {} - {}".format( - rx_pps, self.DEFAULT_PPS_LIMIT_MIN, self.DEFAULT_PPS_LIMIT_MAX) + rx_pps, self.PPS_LIMIT_MIN, self.PPS_LIMIT_MAX) # SONIC config contains policer CIR=6000 for LACP @@ -606,7 +609,7 @@ def runTest(self): self.log("LACPTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): packet = testutils.simple_eth_packet( pktlen=14, eth_dst='01:80:c2:00:00:02', @@ -626,7 +629,7 @@ def runTest(self): self.log("SNMPTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] dst_mac = self.peer_mac[port_number] dst_ip = self.peerip @@ -650,7 +653,7 @@ def runTest(self): self.log("SSHTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): dst_mac = self.peer_mac[port_number] src_ip = self.myip dst_ip = self.peerip @@ -681,7 +684,7 @@ def one_port_test(self, port_number): if port[0] == 0: continue - packet = self.contruct_packet(port[1]) + packet = self.construct_packet(port[1]) send_count, recv_count, time_delta, time_delta_ms, tx_pps, rx_pps = \ self.copp_test(bytes(packet), (0, port_number), (1, port_number)) @@ -689,7 +692,7 @@ def one_port_test(self, port_number): self.check_constraints( send_count, recv_count, time_delta_ms, rx_pps) - def contruct_packet(self, port_number): + def construct_packet(self, port_number): src_mac = self.my_mac[port_number] dst_mac = self.peer_mac[port_number] dst_ip = self.peerip @@ -703,6 +706,7 @@ def contruct_packet(self, port_number): return packet +# Verify policer functionality for TTL 1 packets class DefaultTest(PolicyTest): def __init__(self): PolicyTest.__init__(self) @@ -711,7 +715,7 @@ def runTest(self): self.log("DefaultTest") self.run_suite() - def contruct_packet(self, port_number): + def construct_packet(self, port_number): dst_mac = self.peer_mac[port_number] src_ip = self.myip dst_ip = self.peerip @@ -726,3 +730,82 @@ def contruct_packet(self, port_number): ) return packet + + +# Verify policer functionality for Vlan subnet packets +class VlanSubnetTest(PolicyTest): + def __init__(self): + PolicyTest.__init__(self) + + def runTest(self): + self.log("VlanSubnetTest") + self.run_suite() + + def construct_packet(self, port_number): + dst_mac = self.peer_mac[port_number] + src_ip = self.myip + dst_ip = self.vlanip + + if self.ip_version == "4": + packet = testutils.simple_tcp_packet( + eth_dst=dst_mac, + ip_dst=dst_ip, + ip_src=src_ip, + ip_ttl=25, + tcp_sport=5000, + tcp_dport=8000 + ) + else: + packet = testutils.simple_tcpv6_packet( + eth_dst=dst_mac, + ipv6_dst=dst_ip, + ipv6_src=src_ip, + ipv6_hlim=25, + tcp_sport=5000, + tcp_dport=8000 + ) + + return packet + + +# Verify policer functionality for Vlan subnet IPinIP packets +class VlanSubnetIPinIPTest(PolicyTest): + def __init__(self): + PolicyTest.__init__(self) + + def runTest(self): + self.log("VlanSubnetIpinIPTest") + self.run_suite() + + def construct_packet(self, port_number): + dst_mac = self.peer_mac[port_number] + inner_src_ip = self.myip + inner_dst_ip = self.vlanip + outer_dst_ip = self.loopbackip + + if self.ip_version == "4": + inner_packet = testutils.simple_tcp_packet( + ip_dst=inner_dst_ip, + ip_src=inner_src_ip, + ip_ttl=25, + tcp_sport=5000, + tcp_dport=8000 + ).getlayer(scapy.IP) + else: + inner_packet = testutils.simple_tcpv6_packet( + ipv6_dst=inner_dst_ip, + ipv6_src=inner_src_ip, + ipv6_hlim=25, + tcp_sport=5000, + tcp_dport=8000 + ).getlayer(scapy.IPv6) + + packet = testutils.simple_ipv4ip_packet( + eth_dst=dst_mac, + ip_src='1.1.1.1', + ip_dst=outer_dst_ip, + ip_ttl=40, + inner_frame=inner_packet + ) + + return packet diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index baa5e89f28f..05eecad5dc5 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -262,6 +262,11 @@ copp/test_copp.py::TestCOPP::test_trap_config_save_after_reboot: - "build_version.split('.')[0].isdigit() and int(build_version.split('.')[0]) > 20220531 and hwsku in ['Arista-7050-QX-32S', 'Arista-7050QX32S-Q32', 'Arista-7050-QX32', 'Arista-7050QX-32S-S4Q31', 'Arista-7060CX-32S-D48C8', 'Arista-7060CX-32S-C32', 'Arista-7060CX-32S-Q32', 'Arista-7060CX-32S-C32-T1']" - "(topo_name not in ['ptf32', 'ptf64', 't0', 't0-64', 't0-52', 't0-116', 't1', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 'm0', 'm0-2vlan', 'mx'] and 't2' not in topo_type)" +copp/test_copp.py::TestCOPP::test_trap_neighbor_miss: + skip: + reason: "Copp test_trap_neighbor_miss is not supported on this topology" + conditions: + - "(topo_name not in ['t0', 't0-64', 't0-52', 't0-116'])" ####################################### ##### crm ##### diff --git a/tests/copp/conftest.py b/tests/copp/conftest.py index e514e983e56..bc7a2cac3c6 100644 --- a/tests/copp/conftest.py +++ b/tests/copp/conftest.py @@ -32,6 +32,22 @@ def pytest_addoption(parser): ) +@pytest.fixture(params=["4", "6"]) +def ip_versions(request): + """ + Parameterized fixture for IP versions. + """ + yield request.param + + +@pytest.fixture(params=["VlanSubnet", "VlanSubnetIPinIP"]) +def packet_type(request): + """ + Parameterized fixture for packet types used for neighbor miss tests + """ + yield request.param + + @pytest.fixture(autouse=True, scope="module") def is_backend_topology(duthosts, enum_rand_one_per_hwsku_frontend_hostname, tbinfo): """ diff --git a/tests/copp/copp_utils.py b/tests/copp/copp_utils.py index 0b44aa3bca2..3dad9acf8fb 100644 --- a/tests/copp/copp_utils.py +++ b/tests/copp/copp_utils.py @@ -7,6 +7,7 @@ import re import logging import json +import ipaddress from tests.common.config_reload import config_reload @@ -434,3 +435,42 @@ def install_trap(dut, feature_name): feature_name (str): feature name """ enable_feature_entry(dut, feature_name) + + +def get_vlan_ip(duthost, ip_version): + """ + @Summary: Get an IP on the Vlan subnet + @param duthost: Ansible host instance of the device + @return: Return a vlan IP, e.g., "192.168.0.2" + """ + + mg_facts = duthost.minigraph_facts( + host=duthost.hostname)['ansible_facts'] + mg_vlans = mg_facts['minigraph_vlans'] + + if not mg_vlans: + return None + + mg_vlan_intfs = mg_facts['minigraph_vlan_interfaces'] + + if ip_version == "4": + vlan_subnet = ipaddress.ip_network(mg_vlan_intfs[0]['subnet']) + else: + vlan_subnet = ipaddress.ip_network(mg_vlan_intfs[1]['subnet']) + + ip_addr = str(vlan_subnet[2]) + return ip_addr + + +def get_lo_ipv4(duthost): + + loopback_ip = None + mg_facts = duthost.minigraph_facts( + host=duthost.hostname)['ansible_facts'] + + for intf in mg_facts["minigraph_lo_interfaces"]: + if ipaddress.ip_address(intf["addr"]).version == 4: + loopback_ip = intf["addr"] + break + + return loopback_ip diff --git a/tests/copp/scripts/update_copp_config.py b/tests/copp/scripts/update_copp_config.py index 1322a2bce63..6336cfc9d52 100644 --- a/tests/copp/scripts/update_copp_config.py +++ b/tests/copp/scripts/update_copp_config.py @@ -64,7 +64,6 @@ def generate_limited_pps_config(pps_limit, input_config_file, output_config_file config_format (str): The format of the input COPP config file """ - DEFAULT_PPS_LIMIT = "300" with open(input_config_file) as input_stream: copp_config = json.load(input_stream) @@ -84,13 +83,9 @@ def generate_limited_pps_config(pps_limit, input_config_file, output_config_file # # Setting these two values to pps_limit restricts the policer to allowing exactly # that number of packets per second, which is what we want for our tests. - # For default trap, use a different CIR other than 600 to easily identify - # if it is getting hit. For queue4_group3, use the default value in copp + # For queue4_group3, use the default value in copp # configuration as this is lower than 600 PPS - if tg == "default": - group_config["cir"] = DEFAULT_PPS_LIMIT - group_config["cbs"] = DEFAULT_PPS_LIMIT - elif tg == "queue4_group3": + if tg == "queue4_group3": if asic_type == "cisco-8000": group_config["cir"] = "400" group_config["cbs"] = "400" diff --git a/tests/copp/test_copp.py b/tests/copp/test_copp.py index 324a3e6679e..4dd08bd84d9 100644 --- a/tests/copp/test_copp.py +++ b/tests/copp/test_copp.py @@ -51,7 +51,9 @@ "swap_syncd", "topo", "myip", + "myip6", "peerip", + "peerip6", "nn_target_interface", "nn_target_namespace", "send_rate_limit", @@ -81,7 +83,8 @@ class TestCOPP(object): "BGP", "LACP", "LLDP", - "UDLD"]) + "UDLD", + "Default"]) def test_policer(self, protocol, duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, copp_testbed, dut_type): """ @@ -97,6 +100,21 @@ def test_policer(self, protocol, duthosts, enum_rand_one_per_hwsku_frontend_host copp_testbed, dut_type) + @pytest.mark.disable_loganalyzer + def test_trap_neighbor_miss(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, + ptfhost, check_image_version, copp_testbed, dut_type, + ip_versions, packet_type): # noqa F811 + """ + Validates that neighbor miss (subnet hit) packets are rate-limited + + """ + duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + logger.info("Verify IPV{} {} packets are rate limited".format(ip_versions, packet_type)) + pytest_assert( + wait_until(60, 20, 0, _copp_runner, duthost, ptfhost, packet_type, copp_testbed, dut_type, + ip_version=ip_versions), + "Traffic check for {} packets failed".format(packet_type)) + @pytest.mark.disable_loganalyzer def test_add_new_trap(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, check_image_version, copp_testbed, dut_type, backup_restore_config_db): @@ -273,21 +291,27 @@ def ignore_expected_loganalyzer_exceptions(enum_rand_one_per_hwsku_frontend_host loganalyzer[enum_rand_one_per_hwsku_frontend_hostname].ignore_regex.extend(ignoreRegex) -def _copp_runner(dut, ptf, protocol, test_params, dut_type, has_trap=True): +def _copp_runner(dut, ptf, protocol, test_params, dut_type, has_trap=True, + ip_version="4"): # noqa F811 """ Configures and runs the PTF test cases. """ + is_ipv4 = True if ip_version == "4" else False + params = {"verbose": False, "target_port": test_params.nn_target_port, - "myip": test_params.myip, - "peerip": test_params.peerip, + "myip": test_params.myip if is_ipv4 else test_params.myip6, + "peerip": test_params.peerip if is_ipv4 else test_params.peerip6, + "vlanip": copp_utils.get_vlan_ip(dut, ip_version), + "loopbackip": copp_utils.get_lo_ipv4(dut), "send_rate_limit": test_params.send_rate_limit, "has_trap": has_trap, "hw_sku": dut.facts["hwsku"], "asic_type": dut.facts["asic_type"], "platform": dut.facts["platform"], - "topo_type": test_params.topo_type} + "topo_type": test_params.topo_type, + "ip_version": ip_version} dut_ip = dut.mgmt_ip device_sockets = ["0-{}@tcp://127.0.0.1:10900".format(test_params.nn_target_port), @@ -349,14 +373,19 @@ def _gather_test_params(tbinfo, duthost, request, duts_minigraph_facts): if nn_target_interface not in mg_facts["minigraph_neighbors"]: continue for bgp_peer in mg_facts["minigraph_bgp"]: - if bgp_peer["name"] == mg_facts["minigraph_neighbors"][nn_target_interface]["name"] \ - and ipaddr.IPAddress(bgp_peer["addr"]).version == 4: + if myip is None and \ + bgp_peer["name"] == mg_facts["minigraph_neighbors"][nn_target_interface]["name"] \ + and ipaddr.IPAddress(bgp_peer["addr"]).version == 4: myip = bgp_peer["addr"] peerip = bgp_peer["peer_addr"] nn_target_namespace = mg_facts["minigraph_neighbors"][nn_target_interface]['namespace'] is_backend_topology = mg_facts.get(constants.IS_BACKEND_TOPOLOGY_KEY, False) if is_backend_topology and len(mg_facts["minigraph_vlan_sub_interfaces"]) > 0: nn_target_vlanid = mg_facts["minigraph_vlan_sub_interfaces"][0]["vlan"] + elif bgp_peer["name"] == mg_facts["minigraph_neighbors"][nn_target_interface]["name"] \ + and ipaddr.IPAddress(bgp_peer["addr"]).version == 6: + myip6 = bgp_peer["addr"] + peerip6 = bgp_peer["peer_addr"] break logging.info("nn_target_port {} nn_target_interface {} nn_target_namespace {} nn_target_vlanid {}" @@ -366,7 +395,9 @@ def _gather_test_params(tbinfo, duthost, request, duts_minigraph_facts): swap_syncd=swap_syncd, topo=topo, myip=myip, + myip6=myip6, peerip=peerip, + peerip6=peerip6, nn_target_interface=nn_target_interface, nn_target_namespace=nn_target_namespace, send_rate_limit=send_rate_limit, From 9e248f6451d42170b3c61687f0c648ea1c1fc41d Mon Sep 17 00:00:00 2001 From: ranepbhagyashree Date: Wed, 13 Nov 2024 14:52:50 -0800 Subject: [PATCH 158/221] nhop_group: Fix expected mac address dictionary for Cisco 8122 (#15409) * gr2_nhop_hmap: Fix gr2 mac address dictionary * nhop_group: Fix expected mac address dictionary for Cisco 8122 --- tests/ipfwd/test_nhop_group.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/ipfwd/test_nhop_group.py b/tests/ipfwd/test_nhop_group.py index 31711c18098..abfa90d5413 100644 --- a/tests/ipfwd/test_nhop_group.py +++ b/tests/ipfwd/test_nhop_group.py @@ -758,6 +758,36 @@ def built_and_send_tcp_ip_packet(): 45: 'c0:ff:ee:00:00:12', 46: 'c0:ff:ee:00:00:0e', 47: 'c0:ff:ee:00:00:0f', 48: 'c0:ff:ee:00:00:0b', 49: 'c0:ff:ee:00:00:12'} + gr2_asic_flow_map = {0: 'c0:ff:ee:00:00:11', 1: 'c0:ff:ee:00:00:12', + 2: 'c0:ff:ee:00:00:0c', + 3: 'c0:ff:ee:00:00:0f', 4: 'c0:ff:ee:00:00:0b', + 5: 'c0:ff:ee:00:00:10', 6: 'c0:ff:ee:00:00:12', + 7: 'c0:ff:ee:00:00:12', 8: 'c0:ff:ee:00:00:0b', + 9: 'c0:ff:ee:00:00:0e', + 10: 'c0:ff:ee:00:00:10', 11: 'c0:ff:ee:00:00:0c', + 12: 'c0:ff:ee:00:00:0c', 13: 'c0:ff:ee:00:00:11', + 14: 'c0:ff:ee:00:00:0c', + 15: 'c0:ff:ee:00:00:0f', 16: 'c0:ff:ee:00:00:10', + 17: 'c0:ff:ee:00:00:0b', 18: 'c0:ff:ee:00:00:10', + 19: 'c0:ff:ee:00:00:0f', 20: 'c0:ff:ee:00:00:0b', + 21: 'c0:ff:ee:00:00:12', 22: 'c0:ff:ee:00:00:0f', + 23: 'c0:ff:ee:00:00:0d', 24: 'c0:ff:ee:00:00:0c', + 25: 'c0:ff:ee:00:00:0c', + 26: 'c0:ff:ee:00:00:10', 27: 'c0:ff:ee:00:00:0d', + 28: 'c0:ff:ee:00:00:11', 29: 'c0:ff:ee:00:00:12', + 30: 'c0:ff:ee:00:00:0e', 31: 'c0:ff:ee:00:00:11', + 32: 'c0:ff:ee:00:00:0e', 33: 'c0:ff:ee:00:00:0b', + 34: 'c0:ff:ee:00:00:0e', + 35: 'c0:ff:ee:00:00:0b', 36: 'c0:ff:ee:00:00:11', + 37: 'c0:ff:ee:00:00:11', 38: 'c0:ff:ee:00:00:10', + 39: 'c0:ff:ee:00:00:12', + 40: 'c0:ff:ee:00:00:11', 41: 'c0:ff:ee:00:00:0f', + 42: 'c0:ff:ee:00:00:11', 43: 'c0:ff:ee:00:00:0f', + 44: 'c0:ff:ee:00:00:0f', 45: 'c0:ff:ee:00:00:0b', + 46: 'c0:ff:ee:00:00:0f', + 47: 'c0:ff:ee:00:00:0d', 48: 'c0:ff:ee:00:00:0e', + 49: 'c0:ff:ee:00:00:0e'} + # Make sure a given flow always hash to same nexthop/neighbor. This is done to try to find issue # where SAI vendor changes Hash Function across SAI releases. Please note this will not catch the issue every time # as there is always probability even after change of Hash Function same nexthop/neighbor is selected. @@ -768,7 +798,7 @@ def built_and_send_tcp_ip_packet(): "th4": th_asic_flow_map, "td3": td3_asic_flow_map, "gr": gr_asic_flow_map, "spc1": spc_asic_flow_map, "spc2": spc_asic_flow_map, "spc3": spc_asic_flow_map, - "spc4": spc_asic_flow_map} + "spc4": spc_asic_flow_map, "gr2": gr2_asic_flow_map} vendor = duthost.facts["asic_type"] hostvars = duthost.host.options['variable_manager']._hostvars[duthost.hostname] From 9ab879e7a12cef061163cc4148b6fea6440b7400 Mon Sep 17 00:00:00 2001 From: Dashuai Zhang <164845223+sdszhang@users.noreply.github.com> Date: Thu, 14 Nov 2024 10:30:51 +1100 Subject: [PATCH 159/221] skip multidut bgp instead of assert if testbed doesn't support. (#15537) test case fails if the testbed doesn't support snappi bgp convergence setup. --- .../bgp/test_bgp_outbound_downlink_port_flap.py | 4 ++-- .../test_bgp_outbound_downlink_process_crash.py | 4 ++-- .../multidut/bgp/test_bgp_outbound_tsa.py | 14 +++++++------- .../bgp/test_bgp_outbound_uplink_multi_po_flap.py | 10 +++++----- .../bgp/test_bgp_outbound_uplink_po_flap.py | 4 ++-- .../bgp/test_bgp_outbound_uplink_po_member_flap.py | 4 ++-- .../bgp/test_bgp_outbound_uplink_process_crash.py | 4 ++-- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_port_flap.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_port_flap.py index 2c5b48533c1..5ff65ea6daa 100755 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_port_flap.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_port_flap.py @@ -68,7 +68,7 @@ def test_bgp_outbound_downlink_port_flap(snappi_api, snappi_extra_params.multi_dut_params.flap_details = FLAP_DETAILS snappi_extra_params.test_name = "T1 Interconnectivity flap" if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -78,7 +78,7 @@ def test_bgp_outbound_downlink_port_flap(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_process_crash.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_process_crash.py index a0ac0f9f15e..15e727a186d 100755 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_process_crash.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_downlink_process_crash.py @@ -66,7 +66,7 @@ def test_bgp_outbound_downlink_process_crash(snappi_api, } snappi_extra_params.multi_dut_params.host_name = t1_t2_device_hostnames[2] if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -76,7 +76,7 @@ def test_bgp_outbound_downlink_process_crash(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_tsa.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_tsa.py index 2db762e9dc3..567a9804741 100644 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_tsa.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_tsa.py @@ -62,7 +62,7 @@ def test_dut_configuration(multidut_snappi_ports_for_bgp, # noq if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: @@ -103,7 +103,7 @@ def test_bgp_outbound_uplink_tsa(snappi_api, snappi_extra_params.device_name = t1_t2_device_hostnames[1] if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -113,7 +113,7 @@ def test_bgp_outbound_uplink_tsa(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: @@ -161,7 +161,7 @@ def test_bgp_outbound_downlink_tsa(snappi_api, snappi_extra_params.device_name = t1_t2_device_hostnames[2] if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -171,7 +171,7 @@ def test_bgp_outbound_downlink_tsa(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: @@ -217,7 +217,7 @@ def test_bgp_outbound_supervisor_tsa(snappi_api, snappi_extra_params.device_name = t1_t2_device_hostnames[3] if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -227,7 +227,7 @@ def test_bgp_outbound_supervisor_tsa(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_multi_po_flap.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_multi_po_flap.py index a983e3642d1..414e7790ccf 100644 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_multi_po_flap.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_multi_po_flap.py @@ -62,7 +62,7 @@ def test_dut_configuration(multidut_snappi_ports_for_bgp, # noq if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: @@ -103,7 +103,7 @@ def test_bgp_outbound_uplink_complete_blackout(snappi_api, snappi_extra_params.multi_dut_params.BLACKOUT_PERCENTAGE = 100 if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -112,7 +112,7 @@ def test_bgp_outbound_uplink_complete_blackout(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: @@ -156,7 +156,7 @@ def test_bgp_outbound_uplink_partial_blackout(snappi_api, snappi_extra_params.multi_dut_params.BLACKOUT_PERCENTAGE = 50 if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -165,7 +165,7 @@ def test_bgp_outbound_uplink_partial_blackout(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_flap.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_flap.py index 59fa935e80d..1e9c2715a86 100755 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_flap.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_flap.py @@ -68,7 +68,7 @@ def test_bgp_outbound_uplink_po_flap(snappi_api, snappi_extra_params.multi_dut_params.flap_details = FLAP_DETAILS if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -77,7 +77,7 @@ def test_bgp_outbound_uplink_po_flap(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_member_flap.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_member_flap.py index 3c273641a7a..04135c39d10 100755 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_member_flap.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_po_member_flap.py @@ -68,7 +68,7 @@ def test_bgp_outbound_uplink_po_member_flap(snappi_api, snappi_extra_params.multi_dut_params.flap_details = FLAP_DETAILS if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -77,7 +77,7 @@ def test_bgp_outbound_uplink_po_member_flap(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: diff --git a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_process_crash.py b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_process_crash.py index d27cde536b7..ef9b209cedb 100755 --- a/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_process_crash.py +++ b/tests/snappi_tests/multidut/bgp/test_bgp_outbound_uplink_process_crash.py @@ -66,7 +66,7 @@ def test_bgp_outbound_uplink_process_crash(snappi_api, } snappi_extra_params.multi_dut_params.host_name = t1_t2_device_hostnames[1] if (len(t1_t2_device_hostnames) < 3) or (len(duthosts) < 3): - pytest_assert(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") + pytest_require(False, "Need minimum of 3 devices : One T1 and Two T2 line cards") ansible_dut_hostnames = [] for duthost in duthosts: @@ -76,7 +76,7 @@ def test_bgp_outbound_uplink_process_crash(snappi_api, if device_hostname not in ansible_dut_hostnames: logger.info('!!!!! Attention: {} not in : {} derived from ansible dut hostnames'. format(device_hostname, ansible_dut_hostnames)) - pytest_assert(False, "Mismatch between the dut hostnames in ansible and in variables.py files") + pytest_require(False, "Mismatch between the dut hostnames in ansible and in variables.py files") for duthost in duthosts: if t1_t2_device_hostnames[0] in duthost.hostname: From b0051823c0ece42c3aa6c75f456c7406658f4cc6 Mon Sep 17 00:00:00 2001 From: Dashuai Zhang <164845223+sdszhang@users.noreply.github.com> Date: Thu, 14 Nov 2024 10:35:21 +1100 Subject: [PATCH 160/221] [snappi][master only] add enum with completeness_level back in (#15538) Summary: The fix in #15057 was overwritten by recent changes. This PR add it back into master. #15539 add it back into 202405. Will open another PR for 202405 as the fix will be slight different. test_pfc_pause_single_lossless_prio_reboot: the parameter/fixture sequence is different between master and 202405 branch. this change moves the enum_dut_lossless_prio_with_completeness_level back to original position. so it will be same as 202405 branch. test_pfc_pause_single_lossy_prio_reboot: add enum_dut_lossy_prio_with_completeness_level back in. --- .../pfc/test_multidut_pfc_pause_lossless_with_snappi.py | 4 ++-- .../pfc/test_multidut_pfc_pause_lossy_with_snappi.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py index a3e40541bb5..bc131deb4fc 100644 --- a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py +++ b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossless_with_snappi.py @@ -141,12 +141,12 @@ def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # n fanout_graph_facts_multidut, # noqa: F811 duthosts, localhost, + enum_dut_lossless_prio_with_completeness_level, # noqa: F811 prio_dscp_map, # noqa: F811 lossless_prio_list, # noqa: F811 all_prio_list, # noqa: F811 get_snappi_ports, # noqa: F811 tbinfo, # noqa: F811 - enum_dut_lossless_prio_with_completeness_level, # noqa: F811 setup_ports_and_dut, # noqa: F811 disable_pfcwd, # noqa: F811 reboot_duts): # noqa: F811 @@ -159,10 +159,10 @@ def test_pfc_pause_single_lossless_prio_reboot(snappi_api, # n fanout_graph_facts_multidut (pytest fixture): fanout graph duthosts (pytest fixture): list of DUTs localhost (pytest fixture): localhost handle + enum_dut_lossless_prio_with_completeness_level (str): lossless priority to test, e.g., 's6100-1|3' all_prio_list (pytest fixture): list of all the priorities prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). lossless_prio_list (pytest fixture): list of all the lossless priorities - enum_dut_lossless_prio_with_completeness_level (str): lossless priority to test, e.g., 's6100-1|3' tbinfo (pytest fixture): fixture provides information about testbed get_snappi_ports (pytest fixture): gets snappi ports and connected DUT port info and returns as a list Returns: diff --git a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py index 8a03b72ac0e..e44c5a86de1 100644 --- a/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py +++ b/tests/snappi_tests/multidut/pfc/test_multidut_pfc_pause_lossy_with_snappi.py @@ -136,7 +136,7 @@ def test_pfc_pause_single_lossy_prio_reboot(snappi_api, # noqa: F811 fanout_graph_facts_multidut, # noqa: F811 duthosts, localhost, - enum_dut_lossy_prio, + enum_dut_lossy_prio_with_completeness_level, prio_dscp_map, # noqa: F811 lossy_prio_list, # noqa: F811 all_prio_list, # noqa: F811 @@ -154,7 +154,7 @@ def test_pfc_pause_single_lossy_prio_reboot(snappi_api, # noqa: F811 fanout_graph_facts_multidut (pytest fixture): fanout graph duthosts (pytest fixture): list of DUTs localhost (pytest fixture): localhost handle - enum_dut_lossy_prio (str): name of lossy priority to test, e.g., 's6100-1|2' + enum_dut_lossy_prio_with_completeness_level (str): name of lossy priority to test, e.g., 's6100-1|2' prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority). lossy_prio_list (pytest fixture): list of all the lossy priorities all_prio_list (pytest fixture): list of all the priorities @@ -166,7 +166,7 @@ def test_pfc_pause_single_lossy_prio_reboot(snappi_api, # noqa: F811 """ testbed_config, port_config_list, snappi_ports = setup_ports_and_dut - _, lossy_prio = enum_dut_lossy_prio.split('|') + _, lossy_prio = enum_dut_lossy_prio_with_completeness_level.split('|') lossy_prio = int(lossy_prio) pause_prio_list = [lossy_prio] test_prio_list = [lossy_prio] From a3811f551ed6bb6cb33b57abcd368f23562a7ceb Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:53:59 +0800 Subject: [PATCH 161/221] Add nhop group test to onboarding PR test (#15531) What is the motivation for this PR? Elastictest performs well in distribute running PR test in multiple KVMs, which support us to add more test scripts to PR checker. But some traffic test using ptfadapter can't be tested on KVM platform, we need to skip traffic test if needed How did you do it? Add nhop group test to onboarding PR test and skip traffic test How did you verify/test it? --- .azure-pipelines/pr_test_scripts.yaml | 1 + ...sts_mark_conditions_skip_traffic_test.yaml | 6 ++++ tests/common/vs_data.py | 2 ++ tests/ipfwd/test_nhop_group.py | 30 +++++++++++++++---- 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 tests/common/vs_data.py diff --git a/.azure-pipelines/pr_test_scripts.yaml b/.azure-pipelines/pr_test_scripts.yaml index b48fd5685b5..1cd4372e2bf 100644 --- a/.azure-pipelines/pr_test_scripts.yaml +++ b/.azure-pipelines/pr_test_scripts.yaml @@ -475,6 +475,7 @@ onboarding_t0: onboarding_t1: - lldp/test_lldp_syncd.py + - ipfwd/test_nhop_group.py specific_param: t0-sonic: diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml index 18371c03db6..12cccb05cd6 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions_skip_traffic_test.yaml @@ -279,6 +279,12 @@ ipfwd/test_dir_bcast.py: conditions: - "asic_type in ['vs']" +ipfwd/test_nhop_group.py: + skip_traffic_test: + reason: "Skip traffic test for KVM testbed" + conditions: + - "asic_type in ['vs']" + ####################################### ##### route ##### ####################################### diff --git a/tests/common/vs_data.py b/tests/common/vs_data.py new file mode 100644 index 00000000000..047173d2ce2 --- /dev/null +++ b/tests/common/vs_data.py @@ -0,0 +1,2 @@ +def is_vs_device(dut): + return dut.facts["asic_type"] == "vs" diff --git a/tests/ipfwd/test_nhop_group.py b/tests/ipfwd/test_nhop_group.py index abfa90d5413..86a1500b685 100644 --- a/tests/ipfwd/test_nhop_group.py +++ b/tests/ipfwd/test_nhop_group.py @@ -15,6 +15,7 @@ from tests.common.cisco_data import is_cisco_device from tests.common.mellanox_data import is_mellanox_device, get_chip_type from tests.common.innovium_data import is_innovium_device +from tests.common.vs_data import is_vs_device from tests.common.utilities import wait_until from tests.common.platform.device_utils import fanout_switch_port_lookup, toggle_one_link @@ -457,6 +458,8 @@ def test_nhop_group_member_count(duthost, tbinfo, loganalyzer): ) elif is_mellanox_device(duthost): logger.info("skip this check on Mellanox as ASIC resources are shared") + elif is_vs_device(duthost): + logger.info("skip this check on VS as no real ASIC") else: pytest_assert( crm_after["available_nhop_grp"] == 0, @@ -516,8 +519,13 @@ def built_and_send_tcp_ip_packet(): for flow_count in range(50): pkt, exp_pkt = build_pkt(rtr_mac, ip_route, ip_ttl, flow_count) testutils.send(ptfadapter, gather_facts['dst_port_ids'][0], pkt, 10) - (_, recv_pkt) = testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, + verify_result = testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, ports=gather_facts['src_port_ids']) + if isinstance(verify_result, bool): + logger.info("Using dummy testutils to skip traffic test.") + return + else: + _, recv_pkt = verify_result assert recv_pkt @@ -564,7 +572,8 @@ def built_and_send_tcp_ip_packet(): asic.stop_service("bgp") time.sleep(15) logger.info("Toggle link {} on {}".format(fanout_port, fanout)) - toggle_one_link(duthost, gather_facts['src_port'][0], fanout, fanout_port) + if is_vs_device(duthost) is False: + toggle_one_link(duthost, gather_facts['src_port'][0], fanout, fanout_port) time.sleep(15) built_and_send_tcp_ip_packet() @@ -804,6 +813,10 @@ def built_and_send_tcp_ip_packet(): hostvars = duthost.host.options['variable_manager']._hostvars[duthost.hostname] mgFacts = duthost.get_extended_minigraph_facts(tbinfo) dutAsic = None + if vendor == "vs": + logger.info("Skipping following traffic validation on VS platform") + return + for asic, nexthop_map in list(SUPPORTED_ASIC_TO_NEXTHOP_SELECTED_MAP.items()): vendorAsic = "{0}_{1}_hwskus".format(vendor, asic) if vendorAsic in list(hostvars.keys()) and mgFacts["minigraph_hwsku"] in hostvars[vendorAsic]: @@ -871,7 +884,8 @@ def test_nhop_group_interface_flap(duthosts, enum_rand_one_per_hwsku_frontend_ho fanout, fanout_port = fanout_switch_port_lookup(fanouthosts, duthost.hostname, gather_facts['src_port'][i]) logger.debug("Shut fanout sw: %s, port: %s", fanout, fanout_port) - fanout.shutdown(fanout_port) + if is_vs_device(duthost) is False: + fanout.no_shutdown(fanout_port) nhop.add_ip_route(ip_prefix, ips) nhop.program_routes() @@ -890,13 +904,19 @@ def test_nhop_group_interface_flap(duthosts, enum_rand_one_per_hwsku_frontend_ho fanout, fanout_port = fanout_switch_port_lookup(fanouthosts, duthost.hostname, gather_facts['src_port'][i]) logger.debug("No Shut fanout sw: %s, port: %s", fanout, fanout_port) - fanout.no_shutdown(fanout_port) + if is_vs_device(duthost) is False: + fanout.no_shutdown(fanout_port) time.sleep(20) duthost.shell("portstat -c") ptfadapter.dataplane.flush() testutils.send(ptfadapter, gather_facts['dst_port_ids'][0], pkt, pkt_count) - (_, recv_pkt) = testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, + verify_result = testutils.verify_packet_any_port(test=ptfadapter, pkt=exp_pkt, ports=gather_facts['src_port_ids']) + if isinstance(verify_result, bool): + logger.info("Using dummy testutils to skip traffic test.") + return + else: + _, recv_pkt = verify_result # Make sure routing is done pytest_assert(scapy.Ether(recv_pkt).ttl == (ip_ttl - 1), "Routed Packet TTL not decremented") pytest_assert(scapy.Ether(recv_pkt).src == rtr_mac, "Routed Packet Source Mac is not router MAC") From 52112624553cfec32101779473ae8b386f59c126 Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Thu, 14 Nov 2024 14:43:47 +1100 Subject: [PATCH 162/221] Update pfc_gen_t2.py (#15527) Cherry pick PR #11037 While running PFCWD test cases, encountered concatenation issue on sonic fanout. root@xx37-root-fanout:/tmp# sudo nice --20 python pfc_gen_t2.py -p 16 -t 65535 -s 8 -n 1000000 -i Ethernet152 -r 1.76.0.62 Traceback (most recent call last): File "/tmp/pfc_gen_t2.py", line 340, in main() File "/tmp/pfc_gen_t2.py", line 264, in main fo_logger.debug(fo_str + ' sendmmsg got errno ' + str(errno) + ' for socket ' + s.getsockname()) TypeError: can only concatenate str (not "tuple") to str We converted s.getsockname() into str and able to proceed further. Cc: sanjair-git, @rraghav-cisco Signed-off-by: Austin Pham --- tests/common/helpers/pfc_gen_t2.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/common/helpers/pfc_gen_t2.py b/tests/common/helpers/pfc_gen_t2.py index baf292b79ac..04f1d50dd76 100755 --- a/tests/common/helpers/pfc_gen_t2.py +++ b/tests/common/helpers/pfc_gen_t2.py @@ -261,13 +261,14 @@ def main(): num_sent = _sendmmsg(s.fileno(), m_msghdr[0], num_to_send, 0) # direct to c library api if num_sent < 0: errno = get_errno() - fo_logger.debug(fo_str + ' sendmmsg got errno ' + str(errno) + ' for socket ' + s.getsockname()) + fo_logger.debug(fo_str + ' sendmmsg got errno ' + str(errno) + ' for socket ' + + str(s.getsockname())) break else: if num_sent != num_to_send: fo_logger.debug(fo_str + ' sendmmsg iteration ' + str(iters) + ' only sent ' + str(num_sent) + ' out of requested ' + str(num_to_send) + - ' for socket ' + s.getsockname()) + ' for socket ' + str(s.getsockname())) # Count across all sockets total_num_sent += num_sent iters += 1 @@ -302,14 +303,16 @@ def main(): num_sent = _sendmmsg(s.fileno(), m_msghdr[0], num_to_send, 0) if num_sent < 0: errno = get_errno() - fo_logger.debug(fo_str + ' sendmmsg got errno ' + str(errno) + ' for socket ' + s.getsockname()) + fo_logger.debug(fo_str + ' sendmmsg got errno ' + str(errno) + ' for socket ' + + str(s.getsockname())) test_failed = True break else: if num_sent != num_to_send: fo_logger.debug(fo_str + ' sendmmsg iteration ' + str(iters) + ' only sent ' + str(num_sent) + - ' out of requested ' + str(num_to_send) + ' for socket ' + s.getsockname()) + ' out of requested ' + str(num_to_send) + ' for socket ' + + str(s.getsockname())) total_pkts_remaining[index] -= num_sent total_pkts_sent[index] += num_sent if total_pkts_remaining[index] <= 0: From 51520037fe15e497f0e7db0630fc3456535ade04 Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Thu, 14 Nov 2024 14:45:24 +1100 Subject: [PATCH 163/221] fix: fix flaky pfc_storm (#15544) Description of PR Summary: Fix flaky pfc_storm stom_restored Fixes # (issue) 30115860 Approach What is the motivation for this PR? Currently we detect flaky in detecting storm restore. The reason was because the storm terminated early and restore itself before LogAnalyzer can detect restoration. As a result, we want to keep this to be stormed long enough. After the end of each test case, we have stop_storm so it would be fine. Signed-off-by: Austin Pham --- tests/pfcwd/test_pfcwd_function.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/pfcwd/test_pfcwd_function.py b/tests/pfcwd/test_pfcwd_function.py index 92c5d12e015..22a082b4fde 100644 --- a/tests/pfcwd/test_pfcwd_function.py +++ b/tests/pfcwd/test_pfcwd_function.py @@ -464,7 +464,9 @@ def storm_setup(self, init=False, detect=True): if self.dut.topo_type == 't2' and self.fanout[self.peer_device].os == 'sonic': gen_file = 'pfc_gen_t2.py' - pfc_send_time = 60 + # We want to set the timer to be high here to keep the storm long enough for manual termination + # in the test instead of having it terminated by itself + pfc_send_time = 240 else: gen_file = 'pfc_gen.py' pfc_send_time = None From 1e6d920e5cb95aba85177ca5aac4faca1f7e0822 Mon Sep 17 00:00:00 2001 From: Justin Wong <51811017+justin-wong-ce@users.noreply.github.com> Date: Wed, 13 Nov 2024 20:21:08 -0800 Subject: [PATCH 164/221] Add missing skip conditions for hash/test_generic_hash.py tests for broadcom asics (#15211) Summary: Add missing skip condition for one of the test cases in hash/test_generic_hash.py Continuation of #15091 --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 05eecad5dc5..14f6b68bc0c 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -918,9 +918,9 @@ hash/test_generic_hash.py::test_ecmp_and_lag_hash: hash/test_generic_hash.py::test_ecmp_and_lag_hash[CRC-INNER_IP_PROTOCOL: skip: - reason: "On Mellanox platforms, due to HW limitation, it would not support CRC algorithm on INNER_IP_PROTOCOL field" + reason: "On Mellanox platforms, due to HW limitation, it would not support CRC algorithm on INNER_IP_PROTOCOL field. For broadcom, ECMP hash is not supported in broadcom SAI." conditions: - - "asic_type in ['mellanox']" + - "asic_type in ['broadcom', 'mellanox']" hash/test_generic_hash.py::test_ecmp_hash: skip: From 14f20261e06ed8247eb71eac499c25f5e551d072 Mon Sep 17 00:00:00 2001 From: Riff Date: Wed, 13 Nov 2024 22:43:40 -0800 Subject: [PATCH 165/221] Update topo generator and add the topology for 96 downlinks, 32 uplinks and 2 peer links. (#15454) What is the motivation for this PR? Creating topology can be tedious when the number of ports becomes large. Setting hundreds of VM configurations manually are not efficient. How did you do it? This PR updates the topology generator python script to support T0 topology generation with specific downlinks, uplinks and peer links. Besides, it also creates an example topology t0-isolated-d96u32s2.yml, so we can unblock the device testing with 96 downlinks, 32 uplinks and 2 peer links. How did you verify/test it? --- ansible/generate_topo.py | 115 +- ansible/templates/topo_t0-isolated.j2 | 70 ++ ansible/templates/topo_t1-isolated.j2 | 7 +- ansible/vars/topo_t0-isolated-d96u32s2.yml | 948 ++++++++++++++++ ansible/vars/topo_t1-isolated-d128.yml | 640 ++++++----- ansible/vars/topo_t1-isolated-d224u8.yml | 1160 ++++++++++++-------- 6 files changed, 2196 insertions(+), 744 deletions(-) create mode 100644 ansible/templates/topo_t0-isolated.j2 create mode 100644 ansible/vars/topo_t0-isolated-d96u32s2.yml diff --git a/ansible/generate_topo.py b/ansible/generate_topo.py index b78b15bf724..b340e028e32 100755 --- a/ansible/generate_topo.py +++ b/ansible/generate_topo.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 -from typing import Any, Dict, List -import ipaddress +import copy +from typing import Any, Dict, List, Tuple +from ipaddress import IPv4Network, IPv6Network import click import jinja2 @@ -22,24 +23,31 @@ } +vlan_group_cfgs = [ + {"name": "one_vlan_a", "vlan_count": 1, "v4_prefix": "192.168.0.0/21", "v6_prefix": "fc02:1000::0/64"}, + {"name": "two_vlan_a", "vlan_count": 2, "v4_prefix": "192.168.0.0/22", "v6_prefix": "fc02:100::0/64"}, + {"name": "four_vlan_a", "vlan_count": 4, "v4_prefix": "192.168.0.0/22", "v6_prefix": "fc02:100::0/64"}, +] + + # Utility functions to calculate IP addresses def calc_ipv4_pair(subnet_str, port_id): - subnet = ipaddress.IPv4Network(subnet_str) + subnet = IPv4Network(subnet_str) return (str(subnet.network_address + 2*port_id), str(subnet.network_address + 2*port_id + 1)) def calc_ipv6_pair(subnet_str, port_id): - subnet = ipaddress.IPv6Network(subnet_str) + subnet = IPv6Network(subnet_str) return (str(subnet.network_address + 4*port_id+1), str(subnet.network_address + 4*port_id + 2)) def calc_ipv4(subnet_str, port_id): - subnet = ipaddress.IPv4Network(subnet_str) + subnet = IPv4Network(subnet_str) return str(subnet.network_address + port_id) def calc_ipv6(subnet_str, port_id): - subnet = ipaddress.IPv6Network(subnet_str) + subnet = IPv6Network(subnet_str) return str(subnet.network_address + port_id) @@ -72,7 +80,7 @@ def __init__(self, self.dut_intf_ipv4, self.pc_intf_ipv4 = calc_ipv4_pair("10.0.0.0", self.ip_offset) self.dut_intf_ipv6, self.pc_intf_ipv6 = calc_ipv6_pair("FC00::", self.ip_offset) self.loopback_ipv4 = calc_ipv4("100.1.0.0", self.ip_offset+1) - self.loopback_ipv6 = calc_ipv6("2064:100::", self.ip_offset+1) + self.loopback_ipv6 = calc_ipv6("2064:100::", (self.ip_offset+1) * 2**64) # Backplane IPs will go with the VM ID self.bp_ipv4 = calc_ipv4("10.10.246.1", self.vm_offset+1) @@ -85,7 +93,50 @@ def __init__(self, port_id: int): self.port_id = port_id -def generate_topo(role: str, port_count: int, uplink_ports: List[int], peer_ports: List[int]): +class Vlan: + """ Class to represent a VLAN in the topology """ + def __init__(self, + vlan_id: int, + hostifs: List[HostInterface], + v4_prefix: IPv4Network, + v6_prefix: IPv6Network): + + self.id = vlan_id + self.intfs = hostifs + self.port_ids = [hostif.port_id for hostif in hostifs] + self.v4_prefix = copy.deepcopy(v4_prefix) + self.v4_prefix.network_address += 1 + self.v6_prefix = copy.deepcopy(v6_prefix) + self.v6_prefix.network_address += 1 + + +class VlanGroup: + """ Class to represent a group of VLANs in the topology """ + def __init__(self, name: str, vlan_count: int, hostifs: List[HostInterface], v4_prefix: str, v6_prefix: str): + self.name = name + self.vlans = [] + + # Split host if into the number of VLANs + hostif_count_per_vlan = len(hostifs) // vlan_count + hostif_groups = [hostifs[i*hostif_count_per_vlan:(i+1)*hostif_count_per_vlan] for i in range(vlan_count)] + + v4_prefix = IPv4Network(v4_prefix) + v6_prefix = IPv6Network(v6_prefix) + for vlan_index in range(len(hostif_groups)): + vlan = Vlan(1000 + vlan_index * 100, hostif_groups[vlan_index], v4_prefix, v6_prefix) + self.vlans.append(vlan) + + # Move to next subnet based on the prefix length + v4_prefix.network_address += 2**(32 - v4_prefix.prefixlen) + v6_prefix.network_address += 2**96 + + +def generate_topo(role: str, + port_count: int, + uplink_ports: List[int], + peer_ports: List[int] + ) -> Tuple[List[VM], List[HostInterface]]: + dut_role_cfg = roles_cfg[role] vm_list = [] @@ -131,10 +182,25 @@ def generate_topo(role: str, port_count: int, uplink_ports: List[int], peer_port return vm_list, hostif_list -def generate_topo_file_content(role: str, - template_file: str, - vm_list: List[VM], - hostif_list: List[HostInterface]): +def generate_vlan_groups(hostif_list: List[HostInterface]) -> List[VlanGroup]: + if len(hostif_list) == 0: + return [] + + vlan_groups = [] + for vlan_group_cfg in vlan_group_cfgs: + vlan_group = VlanGroup(vlan_group_cfg["name"], vlan_group_cfg["vlan_count"], hostif_list, + vlan_group_cfg["v4_prefix"], vlan_group_cfg["v6_prefix"]) + vlan_groups.append(vlan_group) + + return vlan_groups + + +def generate_topo_file(role: str, + template_file: str, + vm_list: List[VM], + hostif_list: List[HostInterface], + vlan_group_list: List[VlanGroup] + ) -> str: with open(template_file) as f: template = jinja2.Template(f.read()) @@ -142,17 +208,18 @@ def generate_topo_file_content(role: str, output = template.render(role=role, dut=roles_cfg[role], vm_list=vm_list, - hostif_list=hostif_list) + hostif_list=hostif_list, + vlan_group_list=vlan_group_list) return output -def output_topo_file(role: str, - keyword: str, - downlink_port_count: int, - uplink_port_count: int, - peer_port_count: int, - file_content: str): +def write_topo_file(role: str, + keyword: str, + downlink_port_count: int, + uplink_port_count: int, + peer_port_count: int, + file_content: str): downlink_keyword = f"d{downlink_port_count}" if downlink_port_count > 0 else "" uplink_keyword = f"u{uplink_port_count}" if uplink_port_count > 0 else "" peer_keyword = f"s{peer_port_count}" if peer_port_count > 0 else "" @@ -166,7 +233,7 @@ def output_topo_file(role: str, @click.command() -@click.option("--role", "-r", required=True, type=click.Choice(['t1']), help="Role of the device") +@click.option("--role", "-r", required=True, type=click.Choice(['t0', 't1']), help="Role of the device") @click.option("--keyword", "-k", required=True, type=str, help="Keyword for the topology file") @click.option("--template", "-t", required=True, type=str, help="Path to the Jinja template file") @click.option("--port-count", "-c", required=True, type=int, help="Number of ports on the device") @@ -180,14 +247,16 @@ def main(role: str, keyword: str, template: str, port_count: int, uplinks: str, Examples (in the ansible directory): - ./generate_topo.py -r t1 -k isolated -t t1-isolated -c 128 - ./generate_topo.py -r t1 -k isolated -t t1-isolated -c 232 -u 48,49,58,59,164,165,174,175 + - ./generate_topo.py -r t0 -k isolated -t t0-isolated -c 130 -p 128,129 -u 25,26,27,28,29,30,31,32 """ uplink_ports = [int(port) for port in uplinks.split(",")] if uplinks != "" else [] peer_ports = [int(port) for port in peers.split(",")] if peers != "" else [] vm_list, hostif_list = generate_topo(role, port_count, uplink_ports, peer_ports) - file_content = generate_topo_file_content(role, f"templates/topo_{template}.j2", vm_list, hostif_list) - output_topo_file(role, keyword, port_count - len(uplink_ports) - len(peer_ports), len(uplink_ports), - len(peer_ports), file_content) + vlan_group_list = generate_vlan_groups(hostif_list) + file_content = generate_topo_file(role, f"templates/topo_{template}.j2", vm_list, hostif_list, vlan_group_list) + write_topo_file(role, keyword, port_count - len(uplink_ports) - len(peer_ports), len(uplink_ports), + len(peer_ports), file_content) if __name__ == "__main__": diff --git a/ansible/templates/topo_t0-isolated.j2 b/ansible/templates/topo_t0-isolated.j2 new file mode 100644 index 00000000000..4794c9a1a64 --- /dev/null +++ b/ansible/templates/topo_t0-isolated.j2 @@ -0,0 +1,70 @@ +topology: + host_interfaces: +{%- for hostif in hostif_list %} + - {{ hostif.port_id }} +{%- endfor %} +{%- if vm_list | length == 0 %} + VMs: {} +{%- else %} + VMs: + {%- for vm in vm_list %} + {{ vm.name }}: + vlans: + - {{ vm.vlans[0] }} + vm_offset: {{ vm.vm_offset }} + {%- endfor %} +{%- endif %} + DUT: + vlan_configs: + default_vlan_config: {{ vlan_group_list[0].name }} +{%- for vlan_group in vlan_group_list %} + {{ vlan_group.name }}: + {%- for vlan in vlan_group.vlans %} + Vlan{{ vlan.id }}: + id: {{ vlan.id }} + intfs: {{ vlan.port_ids }} + prefix: {{ vlan.v4_prefix }} + prefix_v6: {{ vlan.v6_prefix }} + tag: {{ vlan.id }} + {%- endfor %} +{%- endfor %} + +configuration_properties: + common: + dut_asn: {{ dut.asn }} + dut_type: ToRRouter + swrole: leaf + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine_asn: 65534 + leaf_asn_start: 64600 + tor_asn_start: 65500 + failure_rate: 0 + +configuration: +{%- for vm in vm_list %} + {{vm.name}}: + properties: + - common + bgp: + asn: {{vm.asn}} + peers: + {{vm.peer_asn}}: + - {{vm.dut_intf_ipv4}} + - {{vm.dut_intf_ipv6}} + interfaces: + Loopback0: + ipv4: {{vm.loopback_ipv4}}/32 + ipv6: {{vm.loopback_ipv6}}/128 + Ethernet1: + ipv4: {{vm.pc_intf_ipv4}}/31 + ipv6: {{vm.pc_intf_ipv6}}/126 + bp_interface: + ipv4: {{vm.bp_ipv4}}/24 + ipv6: {{vm.bp_ipv6}}/64 +{%- endfor %} diff --git a/ansible/templates/topo_t1-isolated.j2 b/ansible/templates/topo_t1-isolated.j2 index 0c58680063d..4f03b9eeba1 100644 --- a/ansible/templates/topo_t1-isolated.j2 +++ b/ansible/templates/topo_t1-isolated.j2 @@ -28,6 +28,11 @@ configuration: {{vm.name}}: properties: - common + {%- if vm.role == 't0' %} + - tor + {%- elif vm.role == 't2' %} + - spine + {%- endif %} bgp: asn: {{vm.asn}} peers: @@ -41,7 +46,7 @@ configuration: Ethernet1: ipv4: {{vm.pc_intf_ipv4}}/31 ipv6: {{vm.pc_intf_ipv6}}/126 - bp_interfaces: + bp_interface: ipv4: {{vm.bp_ipv4}}/24 ipv6: {{vm.bp_ipv6}}/64 {%- endfor %} diff --git a/ansible/vars/topo_t0-isolated-d96u32s2.yml b/ansible/vars/topo_t0-isolated-d96u32s2.yml new file mode 100644 index 00000000000..24f1a4d2040 --- /dev/null +++ b/ansible/vars/topo_t0-isolated-d96u32s2.yml @@ -0,0 +1,948 @@ +topology: + host_interfaces: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 + - 16 + - 17 + - 18 + - 19 + - 20 + - 21 + - 22 + - 23 + - 24 + - 41 + - 42 + - 43 + - 44 + - 45 + - 46 + - 47 + - 48 + - 49 + - 50 + - 51 + - 52 + - 53 + - 54 + - 55 + - 56 + - 57 + - 58 + - 59 + - 60 + - 61 + - 62 + - 63 + - 64 + - 65 + - 66 + - 67 + - 68 + - 69 + - 70 + - 71 + - 72 + - 73 + - 74 + - 75 + - 76 + - 77 + - 78 + - 79 + - 80 + - 81 + - 82 + - 83 + - 84 + - 85 + - 86 + - 87 + - 88 + - 105 + - 106 + - 107 + - 108 + - 109 + - 110 + - 111 + - 112 + - 113 + - 114 + - 115 + - 116 + - 117 + - 118 + - 119 + - 120 + - 121 + - 122 + - 123 + - 124 + - 125 + - 126 + - 127 + VMs: + ARISTA01T1: + vlans: + - 25 + vm_offset: 0 + ARISTA02T1: + vlans: + - 26 + vm_offset: 1 + ARISTA03T1: + vlans: + - 27 + vm_offset: 2 + ARISTA04T1: + vlans: + - 28 + vm_offset: 3 + ARISTA05T1: + vlans: + - 29 + vm_offset: 4 + ARISTA06T1: + vlans: + - 30 + vm_offset: 5 + ARISTA07T1: + vlans: + - 31 + vm_offset: 6 + ARISTA08T1: + vlans: + - 32 + vm_offset: 7 + ARISTA09T1: + vlans: + - 33 + vm_offset: 8 + ARISTA10T1: + vlans: + - 34 + vm_offset: 9 + ARISTA11T1: + vlans: + - 35 + vm_offset: 10 + ARISTA12T1: + vlans: + - 36 + vm_offset: 11 + ARISTA13T1: + vlans: + - 37 + vm_offset: 12 + ARISTA14T1: + vlans: + - 38 + vm_offset: 13 + ARISTA15T1: + vlans: + - 39 + vm_offset: 14 + ARISTA16T1: + vlans: + - 40 + vm_offset: 15 + ARISTA17T1: + vlans: + - 89 + vm_offset: 16 + ARISTA18T1: + vlans: + - 90 + vm_offset: 17 + ARISTA19T1: + vlans: + - 91 + vm_offset: 18 + ARISTA20T1: + vlans: + - 92 + vm_offset: 19 + ARISTA21T1: + vlans: + - 93 + vm_offset: 20 + ARISTA22T1: + vlans: + - 94 + vm_offset: 21 + ARISTA23T1: + vlans: + - 95 + vm_offset: 22 + ARISTA24T1: + vlans: + - 96 + vm_offset: 23 + ARISTA25T1: + vlans: + - 97 + vm_offset: 24 + ARISTA26T1: + vlans: + - 98 + vm_offset: 25 + ARISTA27T1: + vlans: + - 99 + vm_offset: 26 + ARISTA28T1: + vlans: + - 100 + vm_offset: 27 + ARISTA29T1: + vlans: + - 101 + vm_offset: 28 + ARISTA30T1: + vlans: + - 102 + vm_offset: 29 + ARISTA31T1: + vlans: + - 103 + vm_offset: 30 + ARISTA32T1: + vlans: + - 104 + vm_offset: 31 + ARISTA01PT0: + vlans: + - 128 + vm_offset: 32 + ARISTA02PT0: + vlans: + - 129 + vm_offset: 33 + DUT: + vlan_configs: + default_vlan_config: one_vlan_a + one_vlan_a: + Vlan1000: + id: 1000 + intfs: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127] + prefix: 192.168.0.1/21 + prefix_v6: fc02:1000::1/64 + tag: 1000 + two_vlan_a: + Vlan1000: + id: 1000 + intfs: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] + prefix: 192.168.0.1/22 + prefix_v6: fc02:100::1/64 + tag: 1000 + Vlan1100: + id: 1100 + intfs: [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127] + prefix: 192.168.4.1/22 + prefix_v6: fc02:101::1/64 + tag: 1100 + four_vlan_a: + Vlan1000: + id: 1000 + intfs: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] + prefix: 192.168.0.1/22 + prefix_v6: fc02:100::1/64 + tag: 1000 + Vlan1100: + id: 1100 + intfs: [24, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] + prefix: 192.168.4.1/22 + prefix_v6: fc02:101::1/64 + tag: 1100 + Vlan1200: + id: 1200 + intfs: [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87] + prefix: 192.168.8.1/22 + prefix_v6: fc02:102::1/64 + tag: 1200 + Vlan1300: + id: 1300 + intfs: [88, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127] + prefix: 192.168.12.1/22 + prefix_v6: fc02:103::1/64 + tag: 1300 + +configuration_properties: + common: + dut_asn: 65100 + dut_type: ToRRouter + swrole: leaf + nhipv4: 10.10.246.254 + nhipv6: FC0A::FF + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine_asn: 65534 + leaf_asn_start: 64600 + tor_asn_start: 65500 + failure_rate: 0 + +configuration: + ARISTA01T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.0 + - fc00::1 + interfaces: + Loopback0: + ipv4: 100.1.0.1/32 + ipv6: 2064:100:0:1::/128 + Ethernet1: + ipv4: 10.0.0.1/31 + ipv6: fc00::2/126 + bp_interface: + ipv4: 10.10.246.2/24 + ipv6: fc0a::2/64 + ARISTA02T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.2 + - fc00::5 + interfaces: + Loopback0: + ipv4: 100.1.0.2/32 + ipv6: 2064:100:0:2::/128 + Ethernet1: + ipv4: 10.0.0.3/31 + ipv6: fc00::6/126 + bp_interface: + ipv4: 10.10.246.3/24 + ipv6: fc0a::3/64 + ARISTA03T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.4 + - fc00::9 + interfaces: + Loopback0: + ipv4: 100.1.0.3/32 + ipv6: 2064:100:0:3::/128 + Ethernet1: + ipv4: 10.0.0.5/31 + ipv6: fc00::a/126 + bp_interface: + ipv4: 10.10.246.4/24 + ipv6: fc0a::4/64 + ARISTA04T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.6 + - fc00::d + interfaces: + Loopback0: + ipv4: 100.1.0.4/32 + ipv6: 2064:100:0:4::/128 + Ethernet1: + ipv4: 10.0.0.7/31 + ipv6: fc00::e/126 + bp_interface: + ipv4: 10.10.246.5/24 + ipv6: fc0a::5/64 + ARISTA05T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.8 + - fc00::11 + interfaces: + Loopback0: + ipv4: 100.1.0.5/32 + ipv6: 2064:100:0:5::/128 + Ethernet1: + ipv4: 10.0.0.9/31 + ipv6: fc00::12/126 + bp_interface: + ipv4: 10.10.246.6/24 + ipv6: fc0a::6/64 + ARISTA06T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.10 + - fc00::15 + interfaces: + Loopback0: + ipv4: 100.1.0.6/32 + ipv6: 2064:100:0:6::/128 + Ethernet1: + ipv4: 10.0.0.11/31 + ipv6: fc00::16/126 + bp_interface: + ipv4: 10.10.246.7/24 + ipv6: fc0a::7/64 + ARISTA07T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.12 + - fc00::19 + interfaces: + Loopback0: + ipv4: 100.1.0.7/32 + ipv6: 2064:100:0:7::/128 + Ethernet1: + ipv4: 10.0.0.13/31 + ipv6: fc00::1a/126 + bp_interface: + ipv4: 10.10.246.8/24 + ipv6: fc0a::8/64 + ARISTA08T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.14 + - fc00::1d + interfaces: + Loopback0: + ipv4: 100.1.0.8/32 + ipv6: 2064:100:0:8::/128 + Ethernet1: + ipv4: 10.0.0.15/31 + ipv6: fc00::1e/126 + bp_interface: + ipv4: 10.10.246.9/24 + ipv6: fc0a::9/64 + ARISTA09T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.16 + - fc00::21 + interfaces: + Loopback0: + ipv4: 100.1.0.9/32 + ipv6: 2064:100:0:9::/128 + Ethernet1: + ipv4: 10.0.0.17/31 + ipv6: fc00::22/126 + bp_interface: + ipv4: 10.10.246.10/24 + ipv6: fc0a::a/64 + ARISTA10T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.18 + - fc00::25 + interfaces: + Loopback0: + ipv4: 100.1.0.10/32 + ipv6: 2064:100:0:a::/128 + Ethernet1: + ipv4: 10.0.0.19/31 + ipv6: fc00::26/126 + bp_interface: + ipv4: 10.10.246.11/24 + ipv6: fc0a::b/64 + ARISTA11T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.20 + - fc00::29 + interfaces: + Loopback0: + ipv4: 100.1.0.11/32 + ipv6: 2064:100:0:b::/128 + Ethernet1: + ipv4: 10.0.0.21/31 + ipv6: fc00::2a/126 + bp_interface: + ipv4: 10.10.246.12/24 + ipv6: fc0a::c/64 + ARISTA12T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.22 + - fc00::2d + interfaces: + Loopback0: + ipv4: 100.1.0.12/32 + ipv6: 2064:100:0:c::/128 + Ethernet1: + ipv4: 10.0.0.23/31 + ipv6: fc00::2e/126 + bp_interface: + ipv4: 10.10.246.13/24 + ipv6: fc0a::d/64 + ARISTA13T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.24 + - fc00::31 + interfaces: + Loopback0: + ipv4: 100.1.0.13/32 + ipv6: 2064:100:0:d::/128 + Ethernet1: + ipv4: 10.0.0.25/31 + ipv6: fc00::32/126 + bp_interface: + ipv4: 10.10.246.14/24 + ipv6: fc0a::e/64 + ARISTA14T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.26 + - fc00::35 + interfaces: + Loopback0: + ipv4: 100.1.0.14/32 + ipv6: 2064:100:0:e::/128 + Ethernet1: + ipv4: 10.0.0.27/31 + ipv6: fc00::36/126 + bp_interface: + ipv4: 10.10.246.15/24 + ipv6: fc0a::f/64 + ARISTA15T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.28 + - fc00::39 + interfaces: + Loopback0: + ipv4: 100.1.0.15/32 + ipv6: 2064:100:0:f::/128 + Ethernet1: + ipv4: 10.0.0.29/31 + ipv6: fc00::3a/126 + bp_interface: + ipv4: 10.10.246.16/24 + ipv6: fc0a::10/64 + ARISTA16T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.30 + - fc00::3d + interfaces: + Loopback0: + ipv4: 100.1.0.16/32 + ipv6: 2064:100:0:10::/128 + Ethernet1: + ipv4: 10.0.0.31/31 + ipv6: fc00::3e/126 + bp_interface: + ipv4: 10.10.246.17/24 + ipv6: fc0a::11/64 + ARISTA17T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.32 + - fc00::41 + interfaces: + Loopback0: + ipv4: 100.1.0.17/32 + ipv6: 2064:100:0:11::/128 + Ethernet1: + ipv4: 10.0.0.33/31 + ipv6: fc00::42/126 + bp_interface: + ipv4: 10.10.246.18/24 + ipv6: fc0a::12/64 + ARISTA18T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.34 + - fc00::45 + interfaces: + Loopback0: + ipv4: 100.1.0.18/32 + ipv6: 2064:100:0:12::/128 + Ethernet1: + ipv4: 10.0.0.35/31 + ipv6: fc00::46/126 + bp_interface: + ipv4: 10.10.246.19/24 + ipv6: fc0a::13/64 + ARISTA19T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.36 + - fc00::49 + interfaces: + Loopback0: + ipv4: 100.1.0.19/32 + ipv6: 2064:100:0:13::/128 + Ethernet1: + ipv4: 10.0.0.37/31 + ipv6: fc00::4a/126 + bp_interface: + ipv4: 10.10.246.20/24 + ipv6: fc0a::14/64 + ARISTA20T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.38 + - fc00::4d + interfaces: + Loopback0: + ipv4: 100.1.0.20/32 + ipv6: 2064:100:0:14::/128 + Ethernet1: + ipv4: 10.0.0.39/31 + ipv6: fc00::4e/126 + bp_interface: + ipv4: 10.10.246.21/24 + ipv6: fc0a::15/64 + ARISTA21T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.40 + - fc00::51 + interfaces: + Loopback0: + ipv4: 100.1.0.21/32 + ipv6: 2064:100:0:15::/128 + Ethernet1: + ipv4: 10.0.0.41/31 + ipv6: fc00::52/126 + bp_interface: + ipv4: 10.10.246.22/24 + ipv6: fc0a::16/64 + ARISTA22T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.42 + - fc00::55 + interfaces: + Loopback0: + ipv4: 100.1.0.22/32 + ipv6: 2064:100:0:16::/128 + Ethernet1: + ipv4: 10.0.0.43/31 + ipv6: fc00::56/126 + bp_interface: + ipv4: 10.10.246.23/24 + ipv6: fc0a::17/64 + ARISTA23T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.44 + - fc00::59 + interfaces: + Loopback0: + ipv4: 100.1.0.23/32 + ipv6: 2064:100:0:17::/128 + Ethernet1: + ipv4: 10.0.0.45/31 + ipv6: fc00::5a/126 + bp_interface: + ipv4: 10.10.246.24/24 + ipv6: fc0a::18/64 + ARISTA24T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.46 + - fc00::5d + interfaces: + Loopback0: + ipv4: 100.1.0.24/32 + ipv6: 2064:100:0:18::/128 + Ethernet1: + ipv4: 10.0.0.47/31 + ipv6: fc00::5e/126 + bp_interface: + ipv4: 10.10.246.25/24 + ipv6: fc0a::19/64 + ARISTA25T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.48 + - fc00::61 + interfaces: + Loopback0: + ipv4: 100.1.0.25/32 + ipv6: 2064:100:0:19::/128 + Ethernet1: + ipv4: 10.0.0.49/31 + ipv6: fc00::62/126 + bp_interface: + ipv4: 10.10.246.26/24 + ipv6: fc0a::1a/64 + ARISTA26T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.50 + - fc00::65 + interfaces: + Loopback0: + ipv4: 100.1.0.26/32 + ipv6: 2064:100:0:1a::/128 + Ethernet1: + ipv4: 10.0.0.51/31 + ipv6: fc00::66/126 + bp_interface: + ipv4: 10.10.246.27/24 + ipv6: fc0a::1b/64 + ARISTA27T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.52 + - fc00::69 + interfaces: + Loopback0: + ipv4: 100.1.0.27/32 + ipv6: 2064:100:0:1b::/128 + Ethernet1: + ipv4: 10.0.0.53/31 + ipv6: fc00::6a/126 + bp_interface: + ipv4: 10.10.246.28/24 + ipv6: fc0a::1c/64 + ARISTA28T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.54 + - fc00::6d + interfaces: + Loopback0: + ipv4: 100.1.0.28/32 + ipv6: 2064:100:0:1c::/128 + Ethernet1: + ipv4: 10.0.0.55/31 + ipv6: fc00::6e/126 + bp_interface: + ipv4: 10.10.246.29/24 + ipv6: fc0a::1d/64 + ARISTA29T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.56 + - fc00::71 + interfaces: + Loopback0: + ipv4: 100.1.0.29/32 + ipv6: 2064:100:0:1d::/128 + Ethernet1: + ipv4: 10.0.0.57/31 + ipv6: fc00::72/126 + bp_interface: + ipv4: 10.10.246.30/24 + ipv6: fc0a::1e/64 + ARISTA30T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.58 + - fc00::75 + interfaces: + Loopback0: + ipv4: 100.1.0.30/32 + ipv6: 2064:100:0:1e::/128 + Ethernet1: + ipv4: 10.0.0.59/31 + ipv6: fc00::76/126 + bp_interface: + ipv4: 10.10.246.31/24 + ipv6: fc0a::1f/64 + ARISTA31T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.60 + - fc00::79 + interfaces: + Loopback0: + ipv4: 100.1.0.31/32 + ipv6: 2064:100:0:1f::/128 + Ethernet1: + ipv4: 10.0.0.61/31 + ipv6: fc00::7a/126 + bp_interface: + ipv4: 10.10.246.32/24 + ipv6: fc0a::20/64 + ARISTA32T1: + properties: + - common + bgp: + asn: 64600 + peers: + 65100: + - 10.0.0.62 + - fc00::7d + interfaces: + Loopback0: + ipv4: 100.1.0.32/32 + ipv6: 2064:100:0:20::/128 + Ethernet1: + ipv4: 10.0.0.63/31 + ipv6: fc00::7e/126 + bp_interface: + ipv4: 10.10.246.33/24 + ipv6: fc0a::21/64 + ARISTA01PT0: + properties: + - common + bgp: + asn: 65100 + peers: + 65100: + - 10.0.0.64 + - fc00::81 + interfaces: + Loopback0: + ipv4: 100.1.0.33/32 + ipv6: 2064:100:0:21::/128 + Ethernet1: + ipv4: 10.0.0.65/31 + ipv6: fc00::82/126 + bp_interface: + ipv4: 10.10.246.34/24 + ipv6: fc0a::22/64 + ARISTA02PT0: + properties: + - common + bgp: + asn: 65100 + peers: + 65100: + - 10.0.0.66 + - fc00::85 + interfaces: + Loopback0: + ipv4: 100.1.0.34/32 + ipv6: 2064:100:0:22::/128 + Ethernet1: + ipv4: 10.0.0.67/31 + ipv6: fc00::86/126 + bp_interface: + ipv4: 10.10.246.35/24 + ipv6: fc0a::23/64 diff --git a/ansible/vars/topo_t1-isolated-d128.yml b/ansible/vars/topo_t1-isolated-d128.yml index 1873728bd2e..536e06a7c1c 100644 --- a/ansible/vars/topo_t1-isolated-d128.yml +++ b/ansible/vars/topo_t1-isolated-d128.yml @@ -533,6 +533,7 @@ configuration: ARISTA01T0: properties: - common + - tor bgp: asn: 64001 peers: @@ -542,16 +543,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.1/32 - ipv6: 2064:100::1/128 + ipv6: 2064:100:0:1::/128 Ethernet1: ipv4: 10.0.0.1/31 ipv6: fc00::2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.2/24 ipv6: fc0a::2/64 ARISTA02T0: properties: - common + - tor bgp: asn: 64002 peers: @@ -561,16 +563,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.2/32 - ipv6: 2064:100::2/128 + ipv6: 2064:100:0:2::/128 Ethernet1: ipv4: 10.0.0.3/31 ipv6: fc00::6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.3/24 ipv6: fc0a::3/64 ARISTA03T0: properties: - common + - tor bgp: asn: 64003 peers: @@ -580,16 +583,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.3/32 - ipv6: 2064:100::3/128 + ipv6: 2064:100:0:3::/128 Ethernet1: ipv4: 10.0.0.5/31 ipv6: fc00::a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.4/24 ipv6: fc0a::4/64 ARISTA04T0: properties: - common + - tor bgp: asn: 64004 peers: @@ -599,16 +603,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.4/32 - ipv6: 2064:100::4/128 + ipv6: 2064:100:0:4::/128 Ethernet1: ipv4: 10.0.0.7/31 ipv6: fc00::e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.5/24 ipv6: fc0a::5/64 ARISTA05T0: properties: - common + - tor bgp: asn: 64005 peers: @@ -618,16 +623,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.5/32 - ipv6: 2064:100::5/128 + ipv6: 2064:100:0:5::/128 Ethernet1: ipv4: 10.0.0.9/31 ipv6: fc00::12/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.6/24 ipv6: fc0a::6/64 ARISTA06T0: properties: - common + - tor bgp: asn: 64006 peers: @@ -637,16 +643,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.6/32 - ipv6: 2064:100::6/128 + ipv6: 2064:100:0:6::/128 Ethernet1: ipv4: 10.0.0.11/31 ipv6: fc00::16/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.7/24 ipv6: fc0a::7/64 ARISTA07T0: properties: - common + - tor bgp: asn: 64007 peers: @@ -656,16 +663,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.7/32 - ipv6: 2064:100::7/128 + ipv6: 2064:100:0:7::/128 Ethernet1: ipv4: 10.0.0.13/31 ipv6: fc00::1a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.8/24 ipv6: fc0a::8/64 ARISTA08T0: properties: - common + - tor bgp: asn: 64008 peers: @@ -675,16 +683,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.8/32 - ipv6: 2064:100::8/128 + ipv6: 2064:100:0:8::/128 Ethernet1: ipv4: 10.0.0.15/31 ipv6: fc00::1e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.9/24 ipv6: fc0a::9/64 ARISTA09T0: properties: - common + - tor bgp: asn: 64009 peers: @@ -694,16 +703,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.9/32 - ipv6: 2064:100::9/128 + ipv6: 2064:100:0:9::/128 Ethernet1: ipv4: 10.0.0.17/31 ipv6: fc00::22/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.10/24 ipv6: fc0a::a/64 ARISTA10T0: properties: - common + - tor bgp: asn: 64010 peers: @@ -713,16 +723,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.10/32 - ipv6: 2064:100::a/128 + ipv6: 2064:100:0:a::/128 Ethernet1: ipv4: 10.0.0.19/31 ipv6: fc00::26/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.11/24 ipv6: fc0a::b/64 ARISTA11T0: properties: - common + - tor bgp: asn: 64011 peers: @@ -732,16 +743,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.11/32 - ipv6: 2064:100::b/128 + ipv6: 2064:100:0:b::/128 Ethernet1: ipv4: 10.0.0.21/31 ipv6: fc00::2a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.12/24 ipv6: fc0a::c/64 ARISTA12T0: properties: - common + - tor bgp: asn: 64012 peers: @@ -751,16 +763,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.12/32 - ipv6: 2064:100::c/128 + ipv6: 2064:100:0:c::/128 Ethernet1: ipv4: 10.0.0.23/31 ipv6: fc00::2e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.13/24 ipv6: fc0a::d/64 ARISTA13T0: properties: - common + - tor bgp: asn: 64013 peers: @@ -770,16 +783,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.13/32 - ipv6: 2064:100::d/128 + ipv6: 2064:100:0:d::/128 Ethernet1: ipv4: 10.0.0.25/31 ipv6: fc00::32/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.14/24 ipv6: fc0a::e/64 ARISTA14T0: properties: - common + - tor bgp: asn: 64014 peers: @@ -789,16 +803,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.14/32 - ipv6: 2064:100::e/128 + ipv6: 2064:100:0:e::/128 Ethernet1: ipv4: 10.0.0.27/31 ipv6: fc00::36/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.15/24 ipv6: fc0a::f/64 ARISTA15T0: properties: - common + - tor bgp: asn: 64015 peers: @@ -808,16 +823,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.15/32 - ipv6: 2064:100::f/128 + ipv6: 2064:100:0:f::/128 Ethernet1: ipv4: 10.0.0.29/31 ipv6: fc00::3a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.16/24 ipv6: fc0a::10/64 ARISTA16T0: properties: - common + - tor bgp: asn: 64016 peers: @@ -827,16 +843,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.16/32 - ipv6: 2064:100::10/128 + ipv6: 2064:100:0:10::/128 Ethernet1: ipv4: 10.0.0.31/31 ipv6: fc00::3e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.17/24 ipv6: fc0a::11/64 ARISTA17T0: properties: - common + - tor bgp: asn: 64017 peers: @@ -846,16 +863,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.17/32 - ipv6: 2064:100::11/128 + ipv6: 2064:100:0:11::/128 Ethernet1: ipv4: 10.0.0.33/31 ipv6: fc00::42/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.18/24 ipv6: fc0a::12/64 ARISTA18T0: properties: - common + - tor bgp: asn: 64018 peers: @@ -865,16 +883,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.18/32 - ipv6: 2064:100::12/128 + ipv6: 2064:100:0:12::/128 Ethernet1: ipv4: 10.0.0.35/31 ipv6: fc00::46/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.19/24 ipv6: fc0a::13/64 ARISTA19T0: properties: - common + - tor bgp: asn: 64019 peers: @@ -884,16 +903,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.19/32 - ipv6: 2064:100::13/128 + ipv6: 2064:100:0:13::/128 Ethernet1: ipv4: 10.0.0.37/31 ipv6: fc00::4a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.20/24 ipv6: fc0a::14/64 ARISTA20T0: properties: - common + - tor bgp: asn: 64020 peers: @@ -903,16 +923,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.20/32 - ipv6: 2064:100::14/128 + ipv6: 2064:100:0:14::/128 Ethernet1: ipv4: 10.0.0.39/31 ipv6: fc00::4e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.21/24 ipv6: fc0a::15/64 ARISTA21T0: properties: - common + - tor bgp: asn: 64021 peers: @@ -922,16 +943,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.21/32 - ipv6: 2064:100::15/128 + ipv6: 2064:100:0:15::/128 Ethernet1: ipv4: 10.0.0.41/31 ipv6: fc00::52/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.22/24 ipv6: fc0a::16/64 ARISTA22T0: properties: - common + - tor bgp: asn: 64022 peers: @@ -941,16 +963,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.22/32 - ipv6: 2064:100::16/128 + ipv6: 2064:100:0:16::/128 Ethernet1: ipv4: 10.0.0.43/31 ipv6: fc00::56/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.23/24 ipv6: fc0a::17/64 ARISTA23T0: properties: - common + - tor bgp: asn: 64023 peers: @@ -960,16 +983,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.23/32 - ipv6: 2064:100::17/128 + ipv6: 2064:100:0:17::/128 Ethernet1: ipv4: 10.0.0.45/31 ipv6: fc00::5a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.24/24 ipv6: fc0a::18/64 ARISTA24T0: properties: - common + - tor bgp: asn: 64024 peers: @@ -979,16 +1003,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.24/32 - ipv6: 2064:100::18/128 + ipv6: 2064:100:0:18::/128 Ethernet1: ipv4: 10.0.0.47/31 ipv6: fc00::5e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.25/24 ipv6: fc0a::19/64 ARISTA25T0: properties: - common + - tor bgp: asn: 64025 peers: @@ -998,16 +1023,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.25/32 - ipv6: 2064:100::19/128 + ipv6: 2064:100:0:19::/128 Ethernet1: ipv4: 10.0.0.49/31 ipv6: fc00::62/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.26/24 ipv6: fc0a::1a/64 ARISTA26T0: properties: - common + - tor bgp: asn: 64026 peers: @@ -1017,16 +1043,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.26/32 - ipv6: 2064:100::1a/128 + ipv6: 2064:100:0:1a::/128 Ethernet1: ipv4: 10.0.0.51/31 ipv6: fc00::66/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.27/24 ipv6: fc0a::1b/64 ARISTA27T0: properties: - common + - tor bgp: asn: 64027 peers: @@ -1036,16 +1063,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.27/32 - ipv6: 2064:100::1b/128 + ipv6: 2064:100:0:1b::/128 Ethernet1: ipv4: 10.0.0.53/31 ipv6: fc00::6a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.28/24 ipv6: fc0a::1c/64 ARISTA28T0: properties: - common + - tor bgp: asn: 64028 peers: @@ -1055,16 +1083,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.28/32 - ipv6: 2064:100::1c/128 + ipv6: 2064:100:0:1c::/128 Ethernet1: ipv4: 10.0.0.55/31 ipv6: fc00::6e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.29/24 ipv6: fc0a::1d/64 ARISTA29T0: properties: - common + - tor bgp: asn: 64029 peers: @@ -1074,16 +1103,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.29/32 - ipv6: 2064:100::1d/128 + ipv6: 2064:100:0:1d::/128 Ethernet1: ipv4: 10.0.0.57/31 ipv6: fc00::72/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.30/24 ipv6: fc0a::1e/64 ARISTA30T0: properties: - common + - tor bgp: asn: 64030 peers: @@ -1093,16 +1123,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.30/32 - ipv6: 2064:100::1e/128 + ipv6: 2064:100:0:1e::/128 Ethernet1: ipv4: 10.0.0.59/31 ipv6: fc00::76/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.31/24 ipv6: fc0a::1f/64 ARISTA31T0: properties: - common + - tor bgp: asn: 64031 peers: @@ -1112,16 +1143,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.31/32 - ipv6: 2064:100::1f/128 + ipv6: 2064:100:0:1f::/128 Ethernet1: ipv4: 10.0.0.61/31 ipv6: fc00::7a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.32/24 ipv6: fc0a::20/64 ARISTA32T0: properties: - common + - tor bgp: asn: 64032 peers: @@ -1131,16 +1163,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.32/32 - ipv6: 2064:100::20/128 + ipv6: 2064:100:0:20::/128 Ethernet1: ipv4: 10.0.0.63/31 ipv6: fc00::7e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.33/24 ipv6: fc0a::21/64 ARISTA33T0: properties: - common + - tor bgp: asn: 64033 peers: @@ -1150,16 +1183,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.33/32 - ipv6: 2064:100::21/128 + ipv6: 2064:100:0:21::/128 Ethernet1: ipv4: 10.0.0.65/31 ipv6: fc00::82/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.34/24 ipv6: fc0a::22/64 ARISTA34T0: properties: - common + - tor bgp: asn: 64034 peers: @@ -1169,16 +1203,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.34/32 - ipv6: 2064:100::22/128 + ipv6: 2064:100:0:22::/128 Ethernet1: ipv4: 10.0.0.67/31 ipv6: fc00::86/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.35/24 ipv6: fc0a::23/64 ARISTA35T0: properties: - common + - tor bgp: asn: 64035 peers: @@ -1188,16 +1223,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.35/32 - ipv6: 2064:100::23/128 + ipv6: 2064:100:0:23::/128 Ethernet1: ipv4: 10.0.0.69/31 ipv6: fc00::8a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.36/24 ipv6: fc0a::24/64 ARISTA36T0: properties: - common + - tor bgp: asn: 64036 peers: @@ -1207,16 +1243,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.36/32 - ipv6: 2064:100::24/128 + ipv6: 2064:100:0:24::/128 Ethernet1: ipv4: 10.0.0.71/31 ipv6: fc00::8e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.37/24 ipv6: fc0a::25/64 ARISTA37T0: properties: - common + - tor bgp: asn: 64037 peers: @@ -1226,16 +1263,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.37/32 - ipv6: 2064:100::25/128 + ipv6: 2064:100:0:25::/128 Ethernet1: ipv4: 10.0.0.73/31 ipv6: fc00::92/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.38/24 ipv6: fc0a::26/64 ARISTA38T0: properties: - common + - tor bgp: asn: 64038 peers: @@ -1245,16 +1283,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.38/32 - ipv6: 2064:100::26/128 + ipv6: 2064:100:0:26::/128 Ethernet1: ipv4: 10.0.0.75/31 ipv6: fc00::96/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.39/24 ipv6: fc0a::27/64 ARISTA39T0: properties: - common + - tor bgp: asn: 64039 peers: @@ -1264,16 +1303,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.39/32 - ipv6: 2064:100::27/128 + ipv6: 2064:100:0:27::/128 Ethernet1: ipv4: 10.0.0.77/31 ipv6: fc00::9a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.40/24 ipv6: fc0a::28/64 ARISTA40T0: properties: - common + - tor bgp: asn: 64040 peers: @@ -1283,16 +1323,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.40/32 - ipv6: 2064:100::28/128 + ipv6: 2064:100:0:28::/128 Ethernet1: ipv4: 10.0.0.79/31 ipv6: fc00::9e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.41/24 ipv6: fc0a::29/64 ARISTA41T0: properties: - common + - tor bgp: asn: 64041 peers: @@ -1302,16 +1343,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.41/32 - ipv6: 2064:100::29/128 + ipv6: 2064:100:0:29::/128 Ethernet1: ipv4: 10.0.0.81/31 ipv6: fc00::a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.42/24 ipv6: fc0a::2a/64 ARISTA42T0: properties: - common + - tor bgp: asn: 64042 peers: @@ -1321,16 +1363,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.42/32 - ipv6: 2064:100::2a/128 + ipv6: 2064:100:0:2a::/128 Ethernet1: ipv4: 10.0.0.83/31 ipv6: fc00::a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.43/24 ipv6: fc0a::2b/64 ARISTA43T0: properties: - common + - tor bgp: asn: 64043 peers: @@ -1340,16 +1383,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.43/32 - ipv6: 2064:100::2b/128 + ipv6: 2064:100:0:2b::/128 Ethernet1: ipv4: 10.0.0.85/31 ipv6: fc00::aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.44/24 ipv6: fc0a::2c/64 ARISTA44T0: properties: - common + - tor bgp: asn: 64044 peers: @@ -1359,16 +1403,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.44/32 - ipv6: 2064:100::2c/128 + ipv6: 2064:100:0:2c::/128 Ethernet1: ipv4: 10.0.0.87/31 ipv6: fc00::ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.45/24 ipv6: fc0a::2d/64 ARISTA45T0: properties: - common + - tor bgp: asn: 64045 peers: @@ -1378,16 +1423,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.45/32 - ipv6: 2064:100::2d/128 + ipv6: 2064:100:0:2d::/128 Ethernet1: ipv4: 10.0.0.89/31 ipv6: fc00::b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.46/24 ipv6: fc0a::2e/64 ARISTA46T0: properties: - common + - tor bgp: asn: 64046 peers: @@ -1397,16 +1443,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.46/32 - ipv6: 2064:100::2e/128 + ipv6: 2064:100:0:2e::/128 Ethernet1: ipv4: 10.0.0.91/31 ipv6: fc00::b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.47/24 ipv6: fc0a::2f/64 ARISTA47T0: properties: - common + - tor bgp: asn: 64047 peers: @@ -1416,16 +1463,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.47/32 - ipv6: 2064:100::2f/128 + ipv6: 2064:100:0:2f::/128 Ethernet1: ipv4: 10.0.0.93/31 ipv6: fc00::ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.48/24 ipv6: fc0a::30/64 ARISTA48T0: properties: - common + - tor bgp: asn: 64048 peers: @@ -1435,16 +1483,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.48/32 - ipv6: 2064:100::30/128 + ipv6: 2064:100:0:30::/128 Ethernet1: ipv4: 10.0.0.95/31 ipv6: fc00::be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.49/24 ipv6: fc0a::31/64 ARISTA49T0: properties: - common + - tor bgp: asn: 64049 peers: @@ -1454,16 +1503,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.49/32 - ipv6: 2064:100::31/128 + ipv6: 2064:100:0:31::/128 Ethernet1: ipv4: 10.0.0.97/31 ipv6: fc00::c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.50/24 ipv6: fc0a::32/64 ARISTA50T0: properties: - common + - tor bgp: asn: 64050 peers: @@ -1473,16 +1523,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.50/32 - ipv6: 2064:100::32/128 + ipv6: 2064:100:0:32::/128 Ethernet1: ipv4: 10.0.0.99/31 ipv6: fc00::c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.51/24 ipv6: fc0a::33/64 ARISTA51T0: properties: - common + - tor bgp: asn: 64051 peers: @@ -1492,16 +1543,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.51/32 - ipv6: 2064:100::33/128 + ipv6: 2064:100:0:33::/128 Ethernet1: ipv4: 10.0.0.101/31 ipv6: fc00::ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.52/24 ipv6: fc0a::34/64 ARISTA52T0: properties: - common + - tor bgp: asn: 64052 peers: @@ -1511,16 +1563,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.52/32 - ipv6: 2064:100::34/128 + ipv6: 2064:100:0:34::/128 Ethernet1: ipv4: 10.0.0.103/31 ipv6: fc00::ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.53/24 ipv6: fc0a::35/64 ARISTA53T0: properties: - common + - tor bgp: asn: 64053 peers: @@ -1530,16 +1583,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.53/32 - ipv6: 2064:100::35/128 + ipv6: 2064:100:0:35::/128 Ethernet1: ipv4: 10.0.0.105/31 ipv6: fc00::d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.54/24 ipv6: fc0a::36/64 ARISTA54T0: properties: - common + - tor bgp: asn: 64054 peers: @@ -1549,16 +1603,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.54/32 - ipv6: 2064:100::36/128 + ipv6: 2064:100:0:36::/128 Ethernet1: ipv4: 10.0.0.107/31 ipv6: fc00::d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.55/24 ipv6: fc0a::37/64 ARISTA55T0: properties: - common + - tor bgp: asn: 64055 peers: @@ -1568,16 +1623,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.55/32 - ipv6: 2064:100::37/128 + ipv6: 2064:100:0:37::/128 Ethernet1: ipv4: 10.0.0.109/31 ipv6: fc00::da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.56/24 ipv6: fc0a::38/64 ARISTA56T0: properties: - common + - tor bgp: asn: 64056 peers: @@ -1587,16 +1643,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.56/32 - ipv6: 2064:100::38/128 + ipv6: 2064:100:0:38::/128 Ethernet1: ipv4: 10.0.0.111/31 ipv6: fc00::de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.57/24 ipv6: fc0a::39/64 ARISTA57T0: properties: - common + - tor bgp: asn: 64057 peers: @@ -1606,16 +1663,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.57/32 - ipv6: 2064:100::39/128 + ipv6: 2064:100:0:39::/128 Ethernet1: ipv4: 10.0.0.113/31 ipv6: fc00::e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.58/24 ipv6: fc0a::3a/64 ARISTA58T0: properties: - common + - tor bgp: asn: 64058 peers: @@ -1625,16 +1683,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.58/32 - ipv6: 2064:100::3a/128 + ipv6: 2064:100:0:3a::/128 Ethernet1: ipv4: 10.0.0.115/31 ipv6: fc00::e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.59/24 ipv6: fc0a::3b/64 ARISTA59T0: properties: - common + - tor bgp: asn: 64059 peers: @@ -1644,16 +1703,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.59/32 - ipv6: 2064:100::3b/128 + ipv6: 2064:100:0:3b::/128 Ethernet1: ipv4: 10.0.0.117/31 ipv6: fc00::ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.60/24 ipv6: fc0a::3c/64 ARISTA60T0: properties: - common + - tor bgp: asn: 64060 peers: @@ -1663,16 +1723,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.60/32 - ipv6: 2064:100::3c/128 + ipv6: 2064:100:0:3c::/128 Ethernet1: ipv4: 10.0.0.119/31 ipv6: fc00::ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.61/24 ipv6: fc0a::3d/64 ARISTA61T0: properties: - common + - tor bgp: asn: 64061 peers: @@ -1682,16 +1743,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.61/32 - ipv6: 2064:100::3d/128 + ipv6: 2064:100:0:3d::/128 Ethernet1: ipv4: 10.0.0.121/31 ipv6: fc00::f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.62/24 ipv6: fc0a::3e/64 ARISTA62T0: properties: - common + - tor bgp: asn: 64062 peers: @@ -1701,16 +1763,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.62/32 - ipv6: 2064:100::3e/128 + ipv6: 2064:100:0:3e::/128 Ethernet1: ipv4: 10.0.0.123/31 ipv6: fc00::f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.63/24 ipv6: fc0a::3f/64 ARISTA63T0: properties: - common + - tor bgp: asn: 64063 peers: @@ -1720,16 +1783,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.63/32 - ipv6: 2064:100::3f/128 + ipv6: 2064:100:0:3f::/128 Ethernet1: ipv4: 10.0.0.125/31 ipv6: fc00::fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.64/24 ipv6: fc0a::40/64 ARISTA64T0: properties: - common + - tor bgp: asn: 64064 peers: @@ -1739,16 +1803,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.64/32 - ipv6: 2064:100::40/128 + ipv6: 2064:100:0:40::/128 Ethernet1: ipv4: 10.0.0.127/31 ipv6: fc00::fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.65/24 ipv6: fc0a::41/64 ARISTA65T0: properties: - common + - tor bgp: asn: 64065 peers: @@ -1758,16 +1823,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.65/32 - ipv6: 2064:100::41/128 + ipv6: 2064:100:0:41::/128 Ethernet1: ipv4: 10.0.0.129/31 ipv6: fc00::102/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.66/24 ipv6: fc0a::42/64 ARISTA66T0: properties: - common + - tor bgp: asn: 64066 peers: @@ -1777,16 +1843,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.66/32 - ipv6: 2064:100::42/128 + ipv6: 2064:100:0:42::/128 Ethernet1: ipv4: 10.0.0.131/31 ipv6: fc00::106/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.67/24 ipv6: fc0a::43/64 ARISTA67T0: properties: - common + - tor bgp: asn: 64067 peers: @@ -1796,16 +1863,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.67/32 - ipv6: 2064:100::43/128 + ipv6: 2064:100:0:43::/128 Ethernet1: ipv4: 10.0.0.133/31 ipv6: fc00::10a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.68/24 ipv6: fc0a::44/64 ARISTA68T0: properties: - common + - tor bgp: asn: 64068 peers: @@ -1815,16 +1883,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.68/32 - ipv6: 2064:100::44/128 + ipv6: 2064:100:0:44::/128 Ethernet1: ipv4: 10.0.0.135/31 ipv6: fc00::10e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.69/24 ipv6: fc0a::45/64 ARISTA69T0: properties: - common + - tor bgp: asn: 64069 peers: @@ -1834,16 +1903,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.69/32 - ipv6: 2064:100::45/128 + ipv6: 2064:100:0:45::/128 Ethernet1: ipv4: 10.0.0.137/31 ipv6: fc00::112/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.70/24 ipv6: fc0a::46/64 ARISTA70T0: properties: - common + - tor bgp: asn: 64070 peers: @@ -1853,16 +1923,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.70/32 - ipv6: 2064:100::46/128 + ipv6: 2064:100:0:46::/128 Ethernet1: ipv4: 10.0.0.139/31 ipv6: fc00::116/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.71/24 ipv6: fc0a::47/64 ARISTA71T0: properties: - common + - tor bgp: asn: 64071 peers: @@ -1872,16 +1943,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.71/32 - ipv6: 2064:100::47/128 + ipv6: 2064:100:0:47::/128 Ethernet1: ipv4: 10.0.0.141/31 ipv6: fc00::11a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.72/24 ipv6: fc0a::48/64 ARISTA72T0: properties: - common + - tor bgp: asn: 64072 peers: @@ -1891,16 +1963,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.72/32 - ipv6: 2064:100::48/128 + ipv6: 2064:100:0:48::/128 Ethernet1: ipv4: 10.0.0.143/31 ipv6: fc00::11e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.73/24 ipv6: fc0a::49/64 ARISTA73T0: properties: - common + - tor bgp: asn: 64073 peers: @@ -1910,16 +1983,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.73/32 - ipv6: 2064:100::49/128 + ipv6: 2064:100:0:49::/128 Ethernet1: ipv4: 10.0.0.145/31 ipv6: fc00::122/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.74/24 ipv6: fc0a::4a/64 ARISTA74T0: properties: - common + - tor bgp: asn: 64074 peers: @@ -1929,16 +2003,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.74/32 - ipv6: 2064:100::4a/128 + ipv6: 2064:100:0:4a::/128 Ethernet1: ipv4: 10.0.0.147/31 ipv6: fc00::126/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.75/24 ipv6: fc0a::4b/64 ARISTA75T0: properties: - common + - tor bgp: asn: 64075 peers: @@ -1948,16 +2023,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.75/32 - ipv6: 2064:100::4b/128 + ipv6: 2064:100:0:4b::/128 Ethernet1: ipv4: 10.0.0.149/31 ipv6: fc00::12a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.76/24 ipv6: fc0a::4c/64 ARISTA76T0: properties: - common + - tor bgp: asn: 64076 peers: @@ -1967,16 +2043,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.76/32 - ipv6: 2064:100::4c/128 + ipv6: 2064:100:0:4c::/128 Ethernet1: ipv4: 10.0.0.151/31 ipv6: fc00::12e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.77/24 ipv6: fc0a::4d/64 ARISTA77T0: properties: - common + - tor bgp: asn: 64077 peers: @@ -1986,16 +2063,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.77/32 - ipv6: 2064:100::4d/128 + ipv6: 2064:100:0:4d::/128 Ethernet1: ipv4: 10.0.0.153/31 ipv6: fc00::132/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.78/24 ipv6: fc0a::4e/64 ARISTA78T0: properties: - common + - tor bgp: asn: 64078 peers: @@ -2005,16 +2083,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.78/32 - ipv6: 2064:100::4e/128 + ipv6: 2064:100:0:4e::/128 Ethernet1: ipv4: 10.0.0.155/31 ipv6: fc00::136/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.79/24 ipv6: fc0a::4f/64 ARISTA79T0: properties: - common + - tor bgp: asn: 64079 peers: @@ -2024,16 +2103,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.79/32 - ipv6: 2064:100::4f/128 + ipv6: 2064:100:0:4f::/128 Ethernet1: ipv4: 10.0.0.157/31 ipv6: fc00::13a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.80/24 ipv6: fc0a::50/64 ARISTA80T0: properties: - common + - tor bgp: asn: 64080 peers: @@ -2043,16 +2123,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.80/32 - ipv6: 2064:100::50/128 + ipv6: 2064:100:0:50::/128 Ethernet1: ipv4: 10.0.0.159/31 ipv6: fc00::13e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.81/24 ipv6: fc0a::51/64 ARISTA81T0: properties: - common + - tor bgp: asn: 64081 peers: @@ -2062,16 +2143,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.81/32 - ipv6: 2064:100::51/128 + ipv6: 2064:100:0:51::/128 Ethernet1: ipv4: 10.0.0.161/31 ipv6: fc00::142/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.82/24 ipv6: fc0a::52/64 ARISTA82T0: properties: - common + - tor bgp: asn: 64082 peers: @@ -2081,16 +2163,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.82/32 - ipv6: 2064:100::52/128 + ipv6: 2064:100:0:52::/128 Ethernet1: ipv4: 10.0.0.163/31 ipv6: fc00::146/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.83/24 ipv6: fc0a::53/64 ARISTA83T0: properties: - common + - tor bgp: asn: 64083 peers: @@ -2100,16 +2183,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.83/32 - ipv6: 2064:100::53/128 + ipv6: 2064:100:0:53::/128 Ethernet1: ipv4: 10.0.0.165/31 ipv6: fc00::14a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.84/24 ipv6: fc0a::54/64 ARISTA84T0: properties: - common + - tor bgp: asn: 64084 peers: @@ -2119,16 +2203,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.84/32 - ipv6: 2064:100::54/128 + ipv6: 2064:100:0:54::/128 Ethernet1: ipv4: 10.0.0.167/31 ipv6: fc00::14e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.85/24 ipv6: fc0a::55/64 ARISTA85T0: properties: - common + - tor bgp: asn: 64085 peers: @@ -2138,16 +2223,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.85/32 - ipv6: 2064:100::55/128 + ipv6: 2064:100:0:55::/128 Ethernet1: ipv4: 10.0.0.169/31 ipv6: fc00::152/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.86/24 ipv6: fc0a::56/64 ARISTA86T0: properties: - common + - tor bgp: asn: 64086 peers: @@ -2157,16 +2243,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.86/32 - ipv6: 2064:100::56/128 + ipv6: 2064:100:0:56::/128 Ethernet1: ipv4: 10.0.0.171/31 ipv6: fc00::156/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.87/24 ipv6: fc0a::57/64 ARISTA87T0: properties: - common + - tor bgp: asn: 64087 peers: @@ -2176,16 +2263,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.87/32 - ipv6: 2064:100::57/128 + ipv6: 2064:100:0:57::/128 Ethernet1: ipv4: 10.0.0.173/31 ipv6: fc00::15a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.88/24 ipv6: fc0a::58/64 ARISTA88T0: properties: - common + - tor bgp: asn: 64088 peers: @@ -2195,16 +2283,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.88/32 - ipv6: 2064:100::58/128 + ipv6: 2064:100:0:58::/128 Ethernet1: ipv4: 10.0.0.175/31 ipv6: fc00::15e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.89/24 ipv6: fc0a::59/64 ARISTA89T0: properties: - common + - tor bgp: asn: 64089 peers: @@ -2214,16 +2303,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.89/32 - ipv6: 2064:100::59/128 + ipv6: 2064:100:0:59::/128 Ethernet1: ipv4: 10.0.0.177/31 ipv6: fc00::162/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.90/24 ipv6: fc0a::5a/64 ARISTA90T0: properties: - common + - tor bgp: asn: 64090 peers: @@ -2233,16 +2323,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.90/32 - ipv6: 2064:100::5a/128 + ipv6: 2064:100:0:5a::/128 Ethernet1: ipv4: 10.0.0.179/31 ipv6: fc00::166/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.91/24 ipv6: fc0a::5b/64 ARISTA91T0: properties: - common + - tor bgp: asn: 64091 peers: @@ -2252,16 +2343,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.91/32 - ipv6: 2064:100::5b/128 + ipv6: 2064:100:0:5b::/128 Ethernet1: ipv4: 10.0.0.181/31 ipv6: fc00::16a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.92/24 ipv6: fc0a::5c/64 ARISTA92T0: properties: - common + - tor bgp: asn: 64092 peers: @@ -2271,16 +2363,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.92/32 - ipv6: 2064:100::5c/128 + ipv6: 2064:100:0:5c::/128 Ethernet1: ipv4: 10.0.0.183/31 ipv6: fc00::16e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.93/24 ipv6: fc0a::5d/64 ARISTA93T0: properties: - common + - tor bgp: asn: 64093 peers: @@ -2290,16 +2383,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.93/32 - ipv6: 2064:100::5d/128 + ipv6: 2064:100:0:5d::/128 Ethernet1: ipv4: 10.0.0.185/31 ipv6: fc00::172/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.94/24 ipv6: fc0a::5e/64 ARISTA94T0: properties: - common + - tor bgp: asn: 64094 peers: @@ -2309,16 +2403,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.94/32 - ipv6: 2064:100::5e/128 + ipv6: 2064:100:0:5e::/128 Ethernet1: ipv4: 10.0.0.187/31 ipv6: fc00::176/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.95/24 ipv6: fc0a::5f/64 ARISTA95T0: properties: - common + - tor bgp: asn: 64095 peers: @@ -2328,16 +2423,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.95/32 - ipv6: 2064:100::5f/128 + ipv6: 2064:100:0:5f::/128 Ethernet1: ipv4: 10.0.0.189/31 ipv6: fc00::17a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.96/24 ipv6: fc0a::60/64 ARISTA96T0: properties: - common + - tor bgp: asn: 64096 peers: @@ -2347,16 +2443,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.96/32 - ipv6: 2064:100::60/128 + ipv6: 2064:100:0:60::/128 Ethernet1: ipv4: 10.0.0.191/31 ipv6: fc00::17e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.97/24 ipv6: fc0a::61/64 ARISTA97T0: properties: - common + - tor bgp: asn: 64097 peers: @@ -2366,16 +2463,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.97/32 - ipv6: 2064:100::61/128 + ipv6: 2064:100:0:61::/128 Ethernet1: ipv4: 10.0.0.193/31 ipv6: fc00::182/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.98/24 ipv6: fc0a::62/64 ARISTA98T0: properties: - common + - tor bgp: asn: 64098 peers: @@ -2385,16 +2483,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.98/32 - ipv6: 2064:100::62/128 + ipv6: 2064:100:0:62::/128 Ethernet1: ipv4: 10.0.0.195/31 ipv6: fc00::186/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.99/24 ipv6: fc0a::63/64 ARISTA99T0: properties: - common + - tor bgp: asn: 64099 peers: @@ -2404,16 +2503,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.99/32 - ipv6: 2064:100::63/128 + ipv6: 2064:100:0:63::/128 Ethernet1: ipv4: 10.0.0.197/31 ipv6: fc00::18a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.100/24 ipv6: fc0a::64/64 ARISTA100T0: properties: - common + - tor bgp: asn: 64100 peers: @@ -2423,16 +2523,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.100/32 - ipv6: 2064:100::64/128 + ipv6: 2064:100:0:64::/128 Ethernet1: ipv4: 10.0.0.199/31 ipv6: fc00::18e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.101/24 ipv6: fc0a::65/64 ARISTA101T0: properties: - common + - tor bgp: asn: 64101 peers: @@ -2442,16 +2543,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.101/32 - ipv6: 2064:100::65/128 + ipv6: 2064:100:0:65::/128 Ethernet1: ipv4: 10.0.0.201/31 ipv6: fc00::192/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.102/24 ipv6: fc0a::66/64 ARISTA102T0: properties: - common + - tor bgp: asn: 64102 peers: @@ -2461,16 +2563,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.102/32 - ipv6: 2064:100::66/128 + ipv6: 2064:100:0:66::/128 Ethernet1: ipv4: 10.0.0.203/31 ipv6: fc00::196/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.103/24 ipv6: fc0a::67/64 ARISTA103T0: properties: - common + - tor bgp: asn: 64103 peers: @@ -2480,16 +2583,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.103/32 - ipv6: 2064:100::67/128 + ipv6: 2064:100:0:67::/128 Ethernet1: ipv4: 10.0.0.205/31 ipv6: fc00::19a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.104/24 ipv6: fc0a::68/64 ARISTA104T0: properties: - common + - tor bgp: asn: 64104 peers: @@ -2499,16 +2603,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.104/32 - ipv6: 2064:100::68/128 + ipv6: 2064:100:0:68::/128 Ethernet1: ipv4: 10.0.0.207/31 ipv6: fc00::19e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.105/24 ipv6: fc0a::69/64 ARISTA105T0: properties: - common + - tor bgp: asn: 64105 peers: @@ -2518,16 +2623,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.105/32 - ipv6: 2064:100::69/128 + ipv6: 2064:100:0:69::/128 Ethernet1: ipv4: 10.0.0.209/31 ipv6: fc00::1a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.106/24 ipv6: fc0a::6a/64 ARISTA106T0: properties: - common + - tor bgp: asn: 64106 peers: @@ -2537,16 +2643,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.106/32 - ipv6: 2064:100::6a/128 + ipv6: 2064:100:0:6a::/128 Ethernet1: ipv4: 10.0.0.211/31 ipv6: fc00::1a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.107/24 ipv6: fc0a::6b/64 ARISTA107T0: properties: - common + - tor bgp: asn: 64107 peers: @@ -2556,16 +2663,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.107/32 - ipv6: 2064:100::6b/128 + ipv6: 2064:100:0:6b::/128 Ethernet1: ipv4: 10.0.0.213/31 ipv6: fc00::1aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.108/24 ipv6: fc0a::6c/64 ARISTA108T0: properties: - common + - tor bgp: asn: 64108 peers: @@ -2575,16 +2683,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.108/32 - ipv6: 2064:100::6c/128 + ipv6: 2064:100:0:6c::/128 Ethernet1: ipv4: 10.0.0.215/31 ipv6: fc00::1ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.109/24 ipv6: fc0a::6d/64 ARISTA109T0: properties: - common + - tor bgp: asn: 64109 peers: @@ -2594,16 +2703,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.109/32 - ipv6: 2064:100::6d/128 + ipv6: 2064:100:0:6d::/128 Ethernet1: ipv4: 10.0.0.217/31 ipv6: fc00::1b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.110/24 ipv6: fc0a::6e/64 ARISTA110T0: properties: - common + - tor bgp: asn: 64110 peers: @@ -2613,16 +2723,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.110/32 - ipv6: 2064:100::6e/128 + ipv6: 2064:100:0:6e::/128 Ethernet1: ipv4: 10.0.0.219/31 ipv6: fc00::1b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.111/24 ipv6: fc0a::6f/64 ARISTA111T0: properties: - common + - tor bgp: asn: 64111 peers: @@ -2632,16 +2743,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.111/32 - ipv6: 2064:100::6f/128 + ipv6: 2064:100:0:6f::/128 Ethernet1: ipv4: 10.0.0.221/31 ipv6: fc00::1ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.112/24 ipv6: fc0a::70/64 ARISTA112T0: properties: - common + - tor bgp: asn: 64112 peers: @@ -2651,16 +2763,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.112/32 - ipv6: 2064:100::70/128 + ipv6: 2064:100:0:70::/128 Ethernet1: ipv4: 10.0.0.223/31 ipv6: fc00::1be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.113/24 ipv6: fc0a::71/64 ARISTA113T0: properties: - common + - tor bgp: asn: 64113 peers: @@ -2670,16 +2783,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.113/32 - ipv6: 2064:100::71/128 + ipv6: 2064:100:0:71::/128 Ethernet1: ipv4: 10.0.0.225/31 ipv6: fc00::1c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.114/24 ipv6: fc0a::72/64 ARISTA114T0: properties: - common + - tor bgp: asn: 64114 peers: @@ -2689,16 +2803,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.114/32 - ipv6: 2064:100::72/128 + ipv6: 2064:100:0:72::/128 Ethernet1: ipv4: 10.0.0.227/31 ipv6: fc00::1c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.115/24 ipv6: fc0a::73/64 ARISTA115T0: properties: - common + - tor bgp: asn: 64115 peers: @@ -2708,16 +2823,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.115/32 - ipv6: 2064:100::73/128 + ipv6: 2064:100:0:73::/128 Ethernet1: ipv4: 10.0.0.229/31 ipv6: fc00::1ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.116/24 ipv6: fc0a::74/64 ARISTA116T0: properties: - common + - tor bgp: asn: 64116 peers: @@ -2727,16 +2843,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.116/32 - ipv6: 2064:100::74/128 + ipv6: 2064:100:0:74::/128 Ethernet1: ipv4: 10.0.0.231/31 ipv6: fc00::1ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.117/24 ipv6: fc0a::75/64 ARISTA117T0: properties: - common + - tor bgp: asn: 64117 peers: @@ -2746,16 +2863,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.117/32 - ipv6: 2064:100::75/128 + ipv6: 2064:100:0:75::/128 Ethernet1: ipv4: 10.0.0.233/31 ipv6: fc00::1d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.118/24 ipv6: fc0a::76/64 ARISTA118T0: properties: - common + - tor bgp: asn: 64118 peers: @@ -2765,16 +2883,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.118/32 - ipv6: 2064:100::76/128 + ipv6: 2064:100:0:76::/128 Ethernet1: ipv4: 10.0.0.235/31 ipv6: fc00::1d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.119/24 ipv6: fc0a::77/64 ARISTA119T0: properties: - common + - tor bgp: asn: 64119 peers: @@ -2784,16 +2903,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.119/32 - ipv6: 2064:100::77/128 + ipv6: 2064:100:0:77::/128 Ethernet1: ipv4: 10.0.0.237/31 ipv6: fc00::1da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.120/24 ipv6: fc0a::78/64 ARISTA120T0: properties: - common + - tor bgp: asn: 64120 peers: @@ -2803,16 +2923,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.120/32 - ipv6: 2064:100::78/128 + ipv6: 2064:100:0:78::/128 Ethernet1: ipv4: 10.0.0.239/31 ipv6: fc00::1de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.121/24 ipv6: fc0a::79/64 ARISTA121T0: properties: - common + - tor bgp: asn: 64121 peers: @@ -2822,16 +2943,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.121/32 - ipv6: 2064:100::79/128 + ipv6: 2064:100:0:79::/128 Ethernet1: ipv4: 10.0.0.241/31 ipv6: fc00::1e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.122/24 ipv6: fc0a::7a/64 ARISTA122T0: properties: - common + - tor bgp: asn: 64122 peers: @@ -2841,16 +2963,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.122/32 - ipv6: 2064:100::7a/128 + ipv6: 2064:100:0:7a::/128 Ethernet1: ipv4: 10.0.0.243/31 ipv6: fc00::1e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.123/24 ipv6: fc0a::7b/64 ARISTA123T0: properties: - common + - tor bgp: asn: 64123 peers: @@ -2860,16 +2983,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.123/32 - ipv6: 2064:100::7b/128 + ipv6: 2064:100:0:7b::/128 Ethernet1: ipv4: 10.0.0.245/31 ipv6: fc00::1ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.124/24 ipv6: fc0a::7c/64 ARISTA124T0: properties: - common + - tor bgp: asn: 64124 peers: @@ -2879,16 +3003,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.124/32 - ipv6: 2064:100::7c/128 + ipv6: 2064:100:0:7c::/128 Ethernet1: ipv4: 10.0.0.247/31 ipv6: fc00::1ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.125/24 ipv6: fc0a::7d/64 ARISTA125T0: properties: - common + - tor bgp: asn: 64125 peers: @@ -2898,16 +3023,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.125/32 - ipv6: 2064:100::7d/128 + ipv6: 2064:100:0:7d::/128 Ethernet1: ipv4: 10.0.0.249/31 ipv6: fc00::1f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.126/24 ipv6: fc0a::7e/64 ARISTA126T0: properties: - common + - tor bgp: asn: 64126 peers: @@ -2917,16 +3043,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.126/32 - ipv6: 2064:100::7e/128 + ipv6: 2064:100:0:7e::/128 Ethernet1: ipv4: 10.0.0.251/31 ipv6: fc00::1f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.127/24 ipv6: fc0a::7f/64 ARISTA127T0: properties: - common + - tor bgp: asn: 64127 peers: @@ -2936,16 +3063,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.127/32 - ipv6: 2064:100::7f/128 + ipv6: 2064:100:0:7f::/128 Ethernet1: ipv4: 10.0.0.253/31 ipv6: fc00::1fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.128/24 ipv6: fc0a::80/64 ARISTA128T0: properties: - common + - tor bgp: asn: 64128 peers: @@ -2955,10 +3083,10 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.128/32 - ipv6: 2064:100::80/128 + ipv6: 2064:100:0:80::/128 Ethernet1: ipv4: 10.0.0.255/31 ipv6: fc00::1fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.129/24 ipv6: fc0a::81/64 diff --git a/ansible/vars/topo_t1-isolated-d224u8.yml b/ansible/vars/topo_t1-isolated-d224u8.yml index f2f809366d5..6c82ab9448b 100644 --- a/ansible/vars/topo_t1-isolated-d224u8.yml +++ b/ansible/vars/topo_t1-isolated-d224u8.yml @@ -949,6 +949,7 @@ configuration: ARISTA01T0: properties: - common + - tor bgp: asn: 64001 peers: @@ -958,16 +959,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.1/32 - ipv6: 2064:100::1/128 + ipv6: 2064:100:0:1::/128 Ethernet1: ipv4: 10.0.0.1/31 ipv6: fc00::2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.2/24 ipv6: fc0a::2/64 ARISTA02T0: properties: - common + - tor bgp: asn: 64002 peers: @@ -977,16 +979,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.2/32 - ipv6: 2064:100::2/128 + ipv6: 2064:100:0:2::/128 Ethernet1: ipv4: 10.0.0.3/31 ipv6: fc00::6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.3/24 ipv6: fc0a::3/64 ARISTA03T0: properties: - common + - tor bgp: asn: 64003 peers: @@ -996,16 +999,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.3/32 - ipv6: 2064:100::3/128 + ipv6: 2064:100:0:3::/128 Ethernet1: ipv4: 10.0.0.5/31 ipv6: fc00::a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.4/24 ipv6: fc0a::4/64 ARISTA04T0: properties: - common + - tor bgp: asn: 64004 peers: @@ -1015,16 +1019,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.4/32 - ipv6: 2064:100::4/128 + ipv6: 2064:100:0:4::/128 Ethernet1: ipv4: 10.0.0.7/31 ipv6: fc00::e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.5/24 ipv6: fc0a::5/64 ARISTA05T0: properties: - common + - tor bgp: asn: 64005 peers: @@ -1034,16 +1039,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.5/32 - ipv6: 2064:100::5/128 + ipv6: 2064:100:0:5::/128 Ethernet1: ipv4: 10.0.0.9/31 ipv6: fc00::12/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.6/24 ipv6: fc0a::6/64 ARISTA06T0: properties: - common + - tor bgp: asn: 64006 peers: @@ -1053,16 +1059,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.6/32 - ipv6: 2064:100::6/128 + ipv6: 2064:100:0:6::/128 Ethernet1: ipv4: 10.0.0.11/31 ipv6: fc00::16/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.7/24 ipv6: fc0a::7/64 ARISTA07T0: properties: - common + - tor bgp: asn: 64007 peers: @@ -1072,16 +1079,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.7/32 - ipv6: 2064:100::7/128 + ipv6: 2064:100:0:7::/128 Ethernet1: ipv4: 10.0.0.13/31 ipv6: fc00::1a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.8/24 ipv6: fc0a::8/64 ARISTA08T0: properties: - common + - tor bgp: asn: 64008 peers: @@ -1091,16 +1099,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.8/32 - ipv6: 2064:100::8/128 + ipv6: 2064:100:0:8::/128 Ethernet1: ipv4: 10.0.0.15/31 ipv6: fc00::1e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.9/24 ipv6: fc0a::9/64 ARISTA09T0: properties: - common + - tor bgp: asn: 64009 peers: @@ -1110,16 +1119,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.9/32 - ipv6: 2064:100::9/128 + ipv6: 2064:100:0:9::/128 Ethernet1: ipv4: 10.0.0.17/31 ipv6: fc00::22/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.10/24 ipv6: fc0a::a/64 ARISTA10T0: properties: - common + - tor bgp: asn: 64010 peers: @@ -1129,16 +1139,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.10/32 - ipv6: 2064:100::a/128 + ipv6: 2064:100:0:a::/128 Ethernet1: ipv4: 10.0.0.19/31 ipv6: fc00::26/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.11/24 ipv6: fc0a::b/64 ARISTA11T0: properties: - common + - tor bgp: asn: 64011 peers: @@ -1148,16 +1159,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.11/32 - ipv6: 2064:100::b/128 + ipv6: 2064:100:0:b::/128 Ethernet1: ipv4: 10.0.0.21/31 ipv6: fc00::2a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.12/24 ipv6: fc0a::c/64 ARISTA12T0: properties: - common + - tor bgp: asn: 64012 peers: @@ -1167,16 +1179,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.12/32 - ipv6: 2064:100::c/128 + ipv6: 2064:100:0:c::/128 Ethernet1: ipv4: 10.0.0.23/31 ipv6: fc00::2e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.13/24 ipv6: fc0a::d/64 ARISTA13T0: properties: - common + - tor bgp: asn: 64013 peers: @@ -1186,16 +1199,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.13/32 - ipv6: 2064:100::d/128 + ipv6: 2064:100:0:d::/128 Ethernet1: ipv4: 10.0.0.25/31 ipv6: fc00::32/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.14/24 ipv6: fc0a::e/64 ARISTA14T0: properties: - common + - tor bgp: asn: 64014 peers: @@ -1205,16 +1219,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.14/32 - ipv6: 2064:100::e/128 + ipv6: 2064:100:0:e::/128 Ethernet1: ipv4: 10.0.0.27/31 ipv6: fc00::36/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.15/24 ipv6: fc0a::f/64 ARISTA15T0: properties: - common + - tor bgp: asn: 64015 peers: @@ -1224,16 +1239,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.15/32 - ipv6: 2064:100::f/128 + ipv6: 2064:100:0:f::/128 Ethernet1: ipv4: 10.0.0.29/31 ipv6: fc00::3a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.16/24 ipv6: fc0a::10/64 ARISTA16T0: properties: - common + - tor bgp: asn: 64016 peers: @@ -1243,16 +1259,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.16/32 - ipv6: 2064:100::10/128 + ipv6: 2064:100:0:10::/128 Ethernet1: ipv4: 10.0.0.31/31 ipv6: fc00::3e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.17/24 ipv6: fc0a::11/64 ARISTA17T0: properties: - common + - tor bgp: asn: 64017 peers: @@ -1262,16 +1279,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.17/32 - ipv6: 2064:100::11/128 + ipv6: 2064:100:0:11::/128 Ethernet1: ipv4: 10.0.0.33/31 ipv6: fc00::42/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.18/24 ipv6: fc0a::12/64 ARISTA18T0: properties: - common + - tor bgp: asn: 64018 peers: @@ -1281,16 +1299,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.18/32 - ipv6: 2064:100::12/128 + ipv6: 2064:100:0:12::/128 Ethernet1: ipv4: 10.0.0.35/31 ipv6: fc00::46/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.19/24 ipv6: fc0a::13/64 ARISTA19T0: properties: - common + - tor bgp: asn: 64019 peers: @@ -1300,16 +1319,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.19/32 - ipv6: 2064:100::13/128 + ipv6: 2064:100:0:13::/128 Ethernet1: ipv4: 10.0.0.37/31 ipv6: fc00::4a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.20/24 ipv6: fc0a::14/64 ARISTA20T0: properties: - common + - tor bgp: asn: 64020 peers: @@ -1319,16 +1339,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.20/32 - ipv6: 2064:100::14/128 + ipv6: 2064:100:0:14::/128 Ethernet1: ipv4: 10.0.0.39/31 ipv6: fc00::4e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.21/24 ipv6: fc0a::15/64 ARISTA21T0: properties: - common + - tor bgp: asn: 64021 peers: @@ -1338,16 +1359,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.21/32 - ipv6: 2064:100::15/128 + ipv6: 2064:100:0:15::/128 Ethernet1: ipv4: 10.0.0.41/31 ipv6: fc00::52/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.22/24 ipv6: fc0a::16/64 ARISTA22T0: properties: - common + - tor bgp: asn: 64022 peers: @@ -1357,16 +1379,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.22/32 - ipv6: 2064:100::16/128 + ipv6: 2064:100:0:16::/128 Ethernet1: ipv4: 10.0.0.43/31 ipv6: fc00::56/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.23/24 ipv6: fc0a::17/64 ARISTA23T0: properties: - common + - tor bgp: asn: 64023 peers: @@ -1376,16 +1399,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.23/32 - ipv6: 2064:100::17/128 + ipv6: 2064:100:0:17::/128 Ethernet1: ipv4: 10.0.0.45/31 ipv6: fc00::5a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.24/24 ipv6: fc0a::18/64 ARISTA24T0: properties: - common + - tor bgp: asn: 64024 peers: @@ -1395,16 +1419,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.24/32 - ipv6: 2064:100::18/128 + ipv6: 2064:100:0:18::/128 Ethernet1: ipv4: 10.0.0.47/31 ipv6: fc00::5e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.25/24 ipv6: fc0a::19/64 ARISTA25T0: properties: - common + - tor bgp: asn: 64025 peers: @@ -1414,16 +1439,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.25/32 - ipv6: 2064:100::19/128 + ipv6: 2064:100:0:19::/128 Ethernet1: ipv4: 10.0.0.49/31 ipv6: fc00::62/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.26/24 ipv6: fc0a::1a/64 ARISTA26T0: properties: - common + - tor bgp: asn: 64026 peers: @@ -1433,16 +1459,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.26/32 - ipv6: 2064:100::1a/128 + ipv6: 2064:100:0:1a::/128 Ethernet1: ipv4: 10.0.0.51/31 ipv6: fc00::66/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.27/24 ipv6: fc0a::1b/64 ARISTA27T0: properties: - common + - tor bgp: asn: 64027 peers: @@ -1452,16 +1479,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.27/32 - ipv6: 2064:100::1b/128 + ipv6: 2064:100:0:1b::/128 Ethernet1: ipv4: 10.0.0.53/31 ipv6: fc00::6a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.28/24 ipv6: fc0a::1c/64 ARISTA28T0: properties: - common + - tor bgp: asn: 64028 peers: @@ -1471,16 +1499,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.28/32 - ipv6: 2064:100::1c/128 + ipv6: 2064:100:0:1c::/128 Ethernet1: ipv4: 10.0.0.55/31 ipv6: fc00::6e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.29/24 ipv6: fc0a::1d/64 ARISTA29T0: properties: - common + - tor bgp: asn: 64029 peers: @@ -1490,16 +1519,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.29/32 - ipv6: 2064:100::1d/128 + ipv6: 2064:100:0:1d::/128 Ethernet1: ipv4: 10.0.0.57/31 ipv6: fc00::72/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.30/24 ipv6: fc0a::1e/64 ARISTA30T0: properties: - common + - tor bgp: asn: 64030 peers: @@ -1509,16 +1539,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.30/32 - ipv6: 2064:100::1e/128 + ipv6: 2064:100:0:1e::/128 Ethernet1: ipv4: 10.0.0.59/31 ipv6: fc00::76/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.31/24 ipv6: fc0a::1f/64 ARISTA31T0: properties: - common + - tor bgp: asn: 64031 peers: @@ -1528,16 +1559,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.31/32 - ipv6: 2064:100::1f/128 + ipv6: 2064:100:0:1f::/128 Ethernet1: ipv4: 10.0.0.61/31 ipv6: fc00::7a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.32/24 ipv6: fc0a::20/64 ARISTA32T0: properties: - common + - tor bgp: asn: 64032 peers: @@ -1547,16 +1579,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.32/32 - ipv6: 2064:100::20/128 + ipv6: 2064:100:0:20::/128 Ethernet1: ipv4: 10.0.0.63/31 ipv6: fc00::7e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.33/24 ipv6: fc0a::21/64 ARISTA33T0: properties: - common + - tor bgp: asn: 64033 peers: @@ -1566,16 +1599,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.33/32 - ipv6: 2064:100::21/128 + ipv6: 2064:100:0:21::/128 Ethernet1: ipv4: 10.0.0.65/31 ipv6: fc00::82/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.34/24 ipv6: fc0a::22/64 ARISTA34T0: properties: - common + - tor bgp: asn: 64034 peers: @@ -1585,16 +1619,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.34/32 - ipv6: 2064:100::22/128 + ipv6: 2064:100:0:22::/128 Ethernet1: ipv4: 10.0.0.67/31 ipv6: fc00::86/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.35/24 ipv6: fc0a::23/64 ARISTA35T0: properties: - common + - tor bgp: asn: 64035 peers: @@ -1604,16 +1639,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.35/32 - ipv6: 2064:100::23/128 + ipv6: 2064:100:0:23::/128 Ethernet1: ipv4: 10.0.0.69/31 ipv6: fc00::8a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.36/24 ipv6: fc0a::24/64 ARISTA36T0: properties: - common + - tor bgp: asn: 64036 peers: @@ -1623,16 +1659,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.36/32 - ipv6: 2064:100::24/128 + ipv6: 2064:100:0:24::/128 Ethernet1: ipv4: 10.0.0.71/31 ipv6: fc00::8e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.37/24 ipv6: fc0a::25/64 ARISTA37T0: properties: - common + - tor bgp: asn: 64037 peers: @@ -1642,16 +1679,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.37/32 - ipv6: 2064:100::25/128 + ipv6: 2064:100:0:25::/128 Ethernet1: ipv4: 10.0.0.73/31 ipv6: fc00::92/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.38/24 ipv6: fc0a::26/64 ARISTA38T0: properties: - common + - tor bgp: asn: 64038 peers: @@ -1661,16 +1699,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.38/32 - ipv6: 2064:100::26/128 + ipv6: 2064:100:0:26::/128 Ethernet1: ipv4: 10.0.0.75/31 ipv6: fc00::96/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.39/24 ipv6: fc0a::27/64 ARISTA39T0: properties: - common + - tor bgp: asn: 64039 peers: @@ -1680,16 +1719,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.39/32 - ipv6: 2064:100::27/128 + ipv6: 2064:100:0:27::/128 Ethernet1: ipv4: 10.0.0.77/31 ipv6: fc00::9a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.40/24 ipv6: fc0a::28/64 ARISTA40T0: properties: - common + - tor bgp: asn: 64040 peers: @@ -1699,16 +1739,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.40/32 - ipv6: 2064:100::28/128 + ipv6: 2064:100:0:28::/128 Ethernet1: ipv4: 10.0.0.79/31 ipv6: fc00::9e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.41/24 ipv6: fc0a::29/64 ARISTA41T0: properties: - common + - tor bgp: asn: 64041 peers: @@ -1718,16 +1759,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.41/32 - ipv6: 2064:100::29/128 + ipv6: 2064:100:0:29::/128 Ethernet1: ipv4: 10.0.0.81/31 ipv6: fc00::a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.42/24 ipv6: fc0a::2a/64 ARISTA42T0: properties: - common + - tor bgp: asn: 64042 peers: @@ -1737,16 +1779,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.42/32 - ipv6: 2064:100::2a/128 + ipv6: 2064:100:0:2a::/128 Ethernet1: ipv4: 10.0.0.83/31 ipv6: fc00::a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.43/24 ipv6: fc0a::2b/64 ARISTA43T0: properties: - common + - tor bgp: asn: 64043 peers: @@ -1756,16 +1799,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.43/32 - ipv6: 2064:100::2b/128 + ipv6: 2064:100:0:2b::/128 Ethernet1: ipv4: 10.0.0.85/31 ipv6: fc00::aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.44/24 ipv6: fc0a::2c/64 ARISTA44T0: properties: - common + - tor bgp: asn: 64044 peers: @@ -1775,16 +1819,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.44/32 - ipv6: 2064:100::2c/128 + ipv6: 2064:100:0:2c::/128 Ethernet1: ipv4: 10.0.0.87/31 ipv6: fc00::ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.45/24 ipv6: fc0a::2d/64 ARISTA45T0: properties: - common + - tor bgp: asn: 64045 peers: @@ -1794,16 +1839,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.45/32 - ipv6: 2064:100::2d/128 + ipv6: 2064:100:0:2d::/128 Ethernet1: ipv4: 10.0.0.89/31 ipv6: fc00::b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.46/24 ipv6: fc0a::2e/64 ARISTA46T0: properties: - common + - tor bgp: asn: 64046 peers: @@ -1813,16 +1859,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.46/32 - ipv6: 2064:100::2e/128 + ipv6: 2064:100:0:2e::/128 Ethernet1: ipv4: 10.0.0.91/31 ipv6: fc00::b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.47/24 ipv6: fc0a::2f/64 ARISTA47T0: properties: - common + - tor bgp: asn: 64047 peers: @@ -1832,16 +1879,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.47/32 - ipv6: 2064:100::2f/128 + ipv6: 2064:100:0:2f::/128 Ethernet1: ipv4: 10.0.0.93/31 ipv6: fc00::ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.48/24 ipv6: fc0a::30/64 ARISTA48T0: properties: - common + - tor bgp: asn: 64048 peers: @@ -1851,16 +1899,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.48/32 - ipv6: 2064:100::30/128 + ipv6: 2064:100:0:30::/128 Ethernet1: ipv4: 10.0.0.95/31 ipv6: fc00::be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.49/24 ipv6: fc0a::31/64 ARISTA01T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -1870,16 +1919,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.49/32 - ipv6: 2064:100::31/128 + ipv6: 2064:100:0:31::/128 Ethernet1: ipv4: 10.0.0.97/31 ipv6: fc00::c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.50/24 ipv6: fc0a::32/64 ARISTA02T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -1889,16 +1939,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.50/32 - ipv6: 2064:100::32/128 + ipv6: 2064:100:0:32::/128 Ethernet1: ipv4: 10.0.0.99/31 ipv6: fc00::c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.51/24 ipv6: fc0a::33/64 ARISTA49T0: properties: - common + - tor bgp: asn: 64049 peers: @@ -1908,16 +1959,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.51/32 - ipv6: 2064:100::33/128 + ipv6: 2064:100:0:33::/128 Ethernet1: ipv4: 10.0.0.101/31 ipv6: fc00::ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.52/24 ipv6: fc0a::34/64 ARISTA50T0: properties: - common + - tor bgp: asn: 64050 peers: @@ -1927,16 +1979,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.52/32 - ipv6: 2064:100::34/128 + ipv6: 2064:100:0:34::/128 Ethernet1: ipv4: 10.0.0.103/31 ipv6: fc00::ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.53/24 ipv6: fc0a::35/64 ARISTA51T0: properties: - common + - tor bgp: asn: 64051 peers: @@ -1946,16 +1999,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.53/32 - ipv6: 2064:100::35/128 + ipv6: 2064:100:0:35::/128 Ethernet1: ipv4: 10.0.0.105/31 ipv6: fc00::d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.54/24 ipv6: fc0a::36/64 ARISTA52T0: properties: - common + - tor bgp: asn: 64052 peers: @@ -1965,16 +2019,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.54/32 - ipv6: 2064:100::36/128 + ipv6: 2064:100:0:36::/128 Ethernet1: ipv4: 10.0.0.107/31 ipv6: fc00::d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.55/24 ipv6: fc0a::37/64 ARISTA53T0: properties: - common + - tor bgp: asn: 64053 peers: @@ -1984,16 +2039,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.55/32 - ipv6: 2064:100::37/128 + ipv6: 2064:100:0:37::/128 Ethernet1: ipv4: 10.0.0.109/31 ipv6: fc00::da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.56/24 ipv6: fc0a::38/64 ARISTA54T0: properties: - common + - tor bgp: asn: 64054 peers: @@ -2003,16 +2059,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.56/32 - ipv6: 2064:100::38/128 + ipv6: 2064:100:0:38::/128 Ethernet1: ipv4: 10.0.0.111/31 ipv6: fc00::de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.57/24 ipv6: fc0a::39/64 ARISTA55T0: properties: - common + - tor bgp: asn: 64055 peers: @@ -2022,16 +2079,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.57/32 - ipv6: 2064:100::39/128 + ipv6: 2064:100:0:39::/128 Ethernet1: ipv4: 10.0.0.113/31 ipv6: fc00::e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.58/24 ipv6: fc0a::3a/64 ARISTA56T0: properties: - common + - tor bgp: asn: 64056 peers: @@ -2041,16 +2099,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.58/32 - ipv6: 2064:100::3a/128 + ipv6: 2064:100:0:3a::/128 Ethernet1: ipv4: 10.0.0.115/31 ipv6: fc00::e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.59/24 ipv6: fc0a::3b/64 ARISTA03T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -2060,16 +2119,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.59/32 - ipv6: 2064:100::3b/128 + ipv6: 2064:100:0:3b::/128 Ethernet1: ipv4: 10.0.0.117/31 ipv6: fc00::ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.60/24 ipv6: fc0a::3c/64 ARISTA04T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -2079,16 +2139,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.60/32 - ipv6: 2064:100::3c/128 + ipv6: 2064:100:0:3c::/128 Ethernet1: ipv4: 10.0.0.119/31 ipv6: fc00::ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.61/24 ipv6: fc0a::3d/64 ARISTA57T0: properties: - common + - tor bgp: asn: 64057 peers: @@ -2098,16 +2159,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.61/32 - ipv6: 2064:100::3d/128 + ipv6: 2064:100:0:3d::/128 Ethernet1: ipv4: 10.0.0.121/31 ipv6: fc00::f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.62/24 ipv6: fc0a::3e/64 ARISTA58T0: properties: - common + - tor bgp: asn: 64058 peers: @@ -2117,16 +2179,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.62/32 - ipv6: 2064:100::3e/128 + ipv6: 2064:100:0:3e::/128 Ethernet1: ipv4: 10.0.0.123/31 ipv6: fc00::f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.63/24 ipv6: fc0a::3f/64 ARISTA59T0: properties: - common + - tor bgp: asn: 64059 peers: @@ -2136,16 +2199,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.63/32 - ipv6: 2064:100::3f/128 + ipv6: 2064:100:0:3f::/128 Ethernet1: ipv4: 10.0.0.125/31 ipv6: fc00::fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.64/24 ipv6: fc0a::40/64 ARISTA60T0: properties: - common + - tor bgp: asn: 64060 peers: @@ -2155,16 +2219,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.64/32 - ipv6: 2064:100::40/128 + ipv6: 2064:100:0:40::/128 Ethernet1: ipv4: 10.0.0.127/31 ipv6: fc00::fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.65/24 ipv6: fc0a::41/64 ARISTA61T0: properties: - common + - tor bgp: asn: 64061 peers: @@ -2174,16 +2239,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.65/32 - ipv6: 2064:100::41/128 + ipv6: 2064:100:0:41::/128 Ethernet1: ipv4: 10.0.0.129/31 ipv6: fc00::102/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.66/24 ipv6: fc0a::42/64 ARISTA62T0: properties: - common + - tor bgp: asn: 64062 peers: @@ -2193,16 +2259,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.66/32 - ipv6: 2064:100::42/128 + ipv6: 2064:100:0:42::/128 Ethernet1: ipv4: 10.0.0.131/31 ipv6: fc00::106/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.67/24 ipv6: fc0a::43/64 ARISTA63T0: properties: - common + - tor bgp: asn: 64063 peers: @@ -2212,16 +2279,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.67/32 - ipv6: 2064:100::43/128 + ipv6: 2064:100:0:43::/128 Ethernet1: ipv4: 10.0.0.133/31 ipv6: fc00::10a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.68/24 ipv6: fc0a::44/64 ARISTA64T0: properties: - common + - tor bgp: asn: 64064 peers: @@ -2231,16 +2299,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.68/32 - ipv6: 2064:100::44/128 + ipv6: 2064:100:0:44::/128 Ethernet1: ipv4: 10.0.0.135/31 ipv6: fc00::10e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.69/24 ipv6: fc0a::45/64 ARISTA65T0: properties: - common + - tor bgp: asn: 64065 peers: @@ -2250,16 +2319,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.69/32 - ipv6: 2064:100::45/128 + ipv6: 2064:100:0:45::/128 Ethernet1: ipv4: 10.0.0.137/31 ipv6: fc00::112/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.70/24 ipv6: fc0a::46/64 ARISTA66T0: properties: - common + - tor bgp: asn: 64066 peers: @@ -2269,16 +2339,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.70/32 - ipv6: 2064:100::46/128 + ipv6: 2064:100:0:46::/128 Ethernet1: ipv4: 10.0.0.139/31 ipv6: fc00::116/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.71/24 ipv6: fc0a::47/64 ARISTA67T0: properties: - common + - tor bgp: asn: 64067 peers: @@ -2288,16 +2359,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.71/32 - ipv6: 2064:100::47/128 + ipv6: 2064:100:0:47::/128 Ethernet1: ipv4: 10.0.0.141/31 ipv6: fc00::11a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.72/24 ipv6: fc0a::48/64 ARISTA68T0: properties: - common + - tor bgp: asn: 64068 peers: @@ -2307,16 +2379,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.72/32 - ipv6: 2064:100::48/128 + ipv6: 2064:100:0:48::/128 Ethernet1: ipv4: 10.0.0.143/31 ipv6: fc00::11e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.73/24 ipv6: fc0a::49/64 ARISTA69T0: properties: - common + - tor bgp: asn: 64069 peers: @@ -2326,16 +2399,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.73/32 - ipv6: 2064:100::49/128 + ipv6: 2064:100:0:49::/128 Ethernet1: ipv4: 10.0.0.145/31 ipv6: fc00::122/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.74/24 ipv6: fc0a::4a/64 ARISTA70T0: properties: - common + - tor bgp: asn: 64070 peers: @@ -2345,16 +2419,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.74/32 - ipv6: 2064:100::4a/128 + ipv6: 2064:100:0:4a::/128 Ethernet1: ipv4: 10.0.0.147/31 ipv6: fc00::126/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.75/24 ipv6: fc0a::4b/64 ARISTA71T0: properties: - common + - tor bgp: asn: 64071 peers: @@ -2364,16 +2439,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.75/32 - ipv6: 2064:100::4b/128 + ipv6: 2064:100:0:4b::/128 Ethernet1: ipv4: 10.0.0.149/31 ipv6: fc00::12a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.76/24 ipv6: fc0a::4c/64 ARISTA72T0: properties: - common + - tor bgp: asn: 64072 peers: @@ -2383,16 +2459,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.76/32 - ipv6: 2064:100::4c/128 + ipv6: 2064:100:0:4c::/128 Ethernet1: ipv4: 10.0.0.151/31 ipv6: fc00::12e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.77/24 ipv6: fc0a::4d/64 ARISTA73T0: properties: - common + - tor bgp: asn: 64073 peers: @@ -2402,16 +2479,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.77/32 - ipv6: 2064:100::4d/128 + ipv6: 2064:100:0:4d::/128 Ethernet1: ipv4: 10.0.0.153/31 ipv6: fc00::132/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.78/24 ipv6: fc0a::4e/64 ARISTA74T0: properties: - common + - tor bgp: asn: 64074 peers: @@ -2421,16 +2499,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.78/32 - ipv6: 2064:100::4e/128 + ipv6: 2064:100:0:4e::/128 Ethernet1: ipv4: 10.0.0.155/31 ipv6: fc00::136/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.79/24 ipv6: fc0a::4f/64 ARISTA75T0: properties: - common + - tor bgp: asn: 64075 peers: @@ -2440,16 +2519,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.79/32 - ipv6: 2064:100::4f/128 + ipv6: 2064:100:0:4f::/128 Ethernet1: ipv4: 10.0.0.157/31 ipv6: fc00::13a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.80/24 ipv6: fc0a::50/64 ARISTA76T0: properties: - common + - tor bgp: asn: 64076 peers: @@ -2459,16 +2539,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.80/32 - ipv6: 2064:100::50/128 + ipv6: 2064:100:0:50::/128 Ethernet1: ipv4: 10.0.0.159/31 ipv6: fc00::13e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.81/24 ipv6: fc0a::51/64 ARISTA77T0: properties: - common + - tor bgp: asn: 64077 peers: @@ -2478,16 +2559,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.81/32 - ipv6: 2064:100::51/128 + ipv6: 2064:100:0:51::/128 Ethernet1: ipv4: 10.0.0.161/31 ipv6: fc00::142/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.82/24 ipv6: fc0a::52/64 ARISTA78T0: properties: - common + - tor bgp: asn: 64078 peers: @@ -2497,16 +2579,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.82/32 - ipv6: 2064:100::52/128 + ipv6: 2064:100:0:52::/128 Ethernet1: ipv4: 10.0.0.163/31 ipv6: fc00::146/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.83/24 ipv6: fc0a::53/64 ARISTA79T0: properties: - common + - tor bgp: asn: 64079 peers: @@ -2516,16 +2599,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.83/32 - ipv6: 2064:100::53/128 + ipv6: 2064:100:0:53::/128 Ethernet1: ipv4: 10.0.0.165/31 ipv6: fc00::14a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.84/24 ipv6: fc0a::54/64 ARISTA80T0: properties: - common + - tor bgp: asn: 64080 peers: @@ -2535,16 +2619,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.84/32 - ipv6: 2064:100::54/128 + ipv6: 2064:100:0:54::/128 Ethernet1: ipv4: 10.0.0.167/31 ipv6: fc00::14e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.85/24 ipv6: fc0a::55/64 ARISTA81T0: properties: - common + - tor bgp: asn: 64081 peers: @@ -2554,16 +2639,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.85/32 - ipv6: 2064:100::55/128 + ipv6: 2064:100:0:55::/128 Ethernet1: ipv4: 10.0.0.169/31 ipv6: fc00::152/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.86/24 ipv6: fc0a::56/64 ARISTA82T0: properties: - common + - tor bgp: asn: 64082 peers: @@ -2573,16 +2659,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.86/32 - ipv6: 2064:100::56/128 + ipv6: 2064:100:0:56::/128 Ethernet1: ipv4: 10.0.0.171/31 ipv6: fc00::156/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.87/24 ipv6: fc0a::57/64 ARISTA83T0: properties: - common + - tor bgp: asn: 64083 peers: @@ -2592,16 +2679,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.87/32 - ipv6: 2064:100::57/128 + ipv6: 2064:100:0:57::/128 Ethernet1: ipv4: 10.0.0.173/31 ipv6: fc00::15a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.88/24 ipv6: fc0a::58/64 ARISTA84T0: properties: - common + - tor bgp: asn: 64084 peers: @@ -2611,16 +2699,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.88/32 - ipv6: 2064:100::58/128 + ipv6: 2064:100:0:58::/128 Ethernet1: ipv4: 10.0.0.175/31 ipv6: fc00::15e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.89/24 ipv6: fc0a::59/64 ARISTA85T0: properties: - common + - tor bgp: asn: 64085 peers: @@ -2630,16 +2719,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.89/32 - ipv6: 2064:100::59/128 + ipv6: 2064:100:0:59::/128 Ethernet1: ipv4: 10.0.0.177/31 ipv6: fc00::162/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.90/24 ipv6: fc0a::5a/64 ARISTA86T0: properties: - common + - tor bgp: asn: 64086 peers: @@ -2649,16 +2739,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.90/32 - ipv6: 2064:100::5a/128 + ipv6: 2064:100:0:5a::/128 Ethernet1: ipv4: 10.0.0.179/31 ipv6: fc00::166/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.91/24 ipv6: fc0a::5b/64 ARISTA87T0: properties: - common + - tor bgp: asn: 64087 peers: @@ -2668,16 +2759,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.91/32 - ipv6: 2064:100::5b/128 + ipv6: 2064:100:0:5b::/128 Ethernet1: ipv4: 10.0.0.181/31 ipv6: fc00::16a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.92/24 ipv6: fc0a::5c/64 ARISTA88T0: properties: - common + - tor bgp: asn: 64088 peers: @@ -2687,16 +2779,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.92/32 - ipv6: 2064:100::5c/128 + ipv6: 2064:100:0:5c::/128 Ethernet1: ipv4: 10.0.0.183/31 ipv6: fc00::16e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.93/24 ipv6: fc0a::5d/64 ARISTA89T0: properties: - common + - tor bgp: asn: 64089 peers: @@ -2706,16 +2799,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.93/32 - ipv6: 2064:100::5d/128 + ipv6: 2064:100:0:5d::/128 Ethernet1: ipv4: 10.0.0.185/31 ipv6: fc00::172/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.94/24 ipv6: fc0a::5e/64 ARISTA90T0: properties: - common + - tor bgp: asn: 64090 peers: @@ -2725,16 +2819,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.94/32 - ipv6: 2064:100::5e/128 + ipv6: 2064:100:0:5e::/128 Ethernet1: ipv4: 10.0.0.187/31 ipv6: fc00::176/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.95/24 ipv6: fc0a::5f/64 ARISTA91T0: properties: - common + - tor bgp: asn: 64091 peers: @@ -2744,16 +2839,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.95/32 - ipv6: 2064:100::5f/128 + ipv6: 2064:100:0:5f::/128 Ethernet1: ipv4: 10.0.0.189/31 ipv6: fc00::17a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.96/24 ipv6: fc0a::60/64 ARISTA92T0: properties: - common + - tor bgp: asn: 64092 peers: @@ -2763,16 +2859,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.96/32 - ipv6: 2064:100::60/128 + ipv6: 2064:100:0:60::/128 Ethernet1: ipv4: 10.0.0.191/31 ipv6: fc00::17e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.97/24 ipv6: fc0a::61/64 ARISTA93T0: properties: - common + - tor bgp: asn: 64093 peers: @@ -2782,16 +2879,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.97/32 - ipv6: 2064:100::61/128 + ipv6: 2064:100:0:61::/128 Ethernet1: ipv4: 10.0.0.193/31 ipv6: fc00::182/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.98/24 ipv6: fc0a::62/64 ARISTA94T0: properties: - common + - tor bgp: asn: 64094 peers: @@ -2801,16 +2899,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.98/32 - ipv6: 2064:100::62/128 + ipv6: 2064:100:0:62::/128 Ethernet1: ipv4: 10.0.0.195/31 ipv6: fc00::186/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.99/24 ipv6: fc0a::63/64 ARISTA95T0: properties: - common + - tor bgp: asn: 64095 peers: @@ -2820,16 +2919,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.99/32 - ipv6: 2064:100::63/128 + ipv6: 2064:100:0:63::/128 Ethernet1: ipv4: 10.0.0.197/31 ipv6: fc00::18a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.100/24 ipv6: fc0a::64/64 ARISTA96T0: properties: - common + - tor bgp: asn: 64096 peers: @@ -2839,16 +2939,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.100/32 - ipv6: 2064:100::64/128 + ipv6: 2064:100:0:64::/128 Ethernet1: ipv4: 10.0.0.199/31 ipv6: fc00::18e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.101/24 ipv6: fc0a::65/64 ARISTA97T0: properties: - common + - tor bgp: asn: 64097 peers: @@ -2858,16 +2959,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.101/32 - ipv6: 2064:100::65/128 + ipv6: 2064:100:0:65::/128 Ethernet1: ipv4: 10.0.0.201/31 ipv6: fc00::192/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.102/24 ipv6: fc0a::66/64 ARISTA98T0: properties: - common + - tor bgp: asn: 64098 peers: @@ -2877,16 +2979,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.102/32 - ipv6: 2064:100::66/128 + ipv6: 2064:100:0:66::/128 Ethernet1: ipv4: 10.0.0.203/31 ipv6: fc00::196/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.103/24 ipv6: fc0a::67/64 ARISTA99T0: properties: - common + - tor bgp: asn: 64099 peers: @@ -2896,16 +2999,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.103/32 - ipv6: 2064:100::67/128 + ipv6: 2064:100:0:67::/128 Ethernet1: ipv4: 10.0.0.205/31 ipv6: fc00::19a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.104/24 ipv6: fc0a::68/64 ARISTA100T0: properties: - common + - tor bgp: asn: 64100 peers: @@ -2915,16 +3019,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.104/32 - ipv6: 2064:100::68/128 + ipv6: 2064:100:0:68::/128 Ethernet1: ipv4: 10.0.0.207/31 ipv6: fc00::19e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.105/24 ipv6: fc0a::69/64 ARISTA101T0: properties: - common + - tor bgp: asn: 64101 peers: @@ -2934,16 +3039,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.105/32 - ipv6: 2064:100::69/128 + ipv6: 2064:100:0:69::/128 Ethernet1: ipv4: 10.0.0.209/31 ipv6: fc00::1a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.106/24 ipv6: fc0a::6a/64 ARISTA102T0: properties: - common + - tor bgp: asn: 64102 peers: @@ -2953,16 +3059,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.106/32 - ipv6: 2064:100::6a/128 + ipv6: 2064:100:0:6a::/128 Ethernet1: ipv4: 10.0.0.211/31 ipv6: fc00::1a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.107/24 ipv6: fc0a::6b/64 ARISTA103T0: properties: - common + - tor bgp: asn: 64103 peers: @@ -2972,16 +3079,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.107/32 - ipv6: 2064:100::6b/128 + ipv6: 2064:100:0:6b::/128 Ethernet1: ipv4: 10.0.0.213/31 ipv6: fc00::1aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.108/24 ipv6: fc0a::6c/64 ARISTA104T0: properties: - common + - tor bgp: asn: 64104 peers: @@ -2991,16 +3099,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.108/32 - ipv6: 2064:100::6c/128 + ipv6: 2064:100:0:6c::/128 Ethernet1: ipv4: 10.0.0.215/31 ipv6: fc00::1ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.109/24 ipv6: fc0a::6d/64 ARISTA105T0: properties: - common + - tor bgp: asn: 64105 peers: @@ -3010,16 +3119,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.109/32 - ipv6: 2064:100::6d/128 + ipv6: 2064:100:0:6d::/128 Ethernet1: ipv4: 10.0.0.217/31 ipv6: fc00::1b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.110/24 ipv6: fc0a::6e/64 ARISTA106T0: properties: - common + - tor bgp: asn: 64106 peers: @@ -3029,16 +3139,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.110/32 - ipv6: 2064:100::6e/128 + ipv6: 2064:100:0:6e::/128 Ethernet1: ipv4: 10.0.0.219/31 ipv6: fc00::1b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.111/24 ipv6: fc0a::6f/64 ARISTA107T0: properties: - common + - tor bgp: asn: 64107 peers: @@ -3048,16 +3159,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.111/32 - ipv6: 2064:100::6f/128 + ipv6: 2064:100:0:6f::/128 Ethernet1: ipv4: 10.0.0.221/31 ipv6: fc00::1ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.112/24 ipv6: fc0a::70/64 ARISTA108T0: properties: - common + - tor bgp: asn: 64108 peers: @@ -3067,16 +3179,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.112/32 - ipv6: 2064:100::70/128 + ipv6: 2064:100:0:70::/128 Ethernet1: ipv4: 10.0.0.223/31 ipv6: fc00::1be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.113/24 ipv6: fc0a::71/64 ARISTA109T0: properties: - common + - tor bgp: asn: 64109 peers: @@ -3086,16 +3199,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.113/32 - ipv6: 2064:100::71/128 + ipv6: 2064:100:0:71::/128 Ethernet1: ipv4: 10.0.0.225/31 ipv6: fc00::1c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.114/24 ipv6: fc0a::72/64 ARISTA110T0: properties: - common + - tor bgp: asn: 64110 peers: @@ -3105,16 +3219,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.114/32 - ipv6: 2064:100::72/128 + ipv6: 2064:100:0:72::/128 Ethernet1: ipv4: 10.0.0.227/31 ipv6: fc00::1c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.115/24 ipv6: fc0a::73/64 ARISTA111T0: properties: - common + - tor bgp: asn: 64111 peers: @@ -3124,16 +3239,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.115/32 - ipv6: 2064:100::73/128 + ipv6: 2064:100:0:73::/128 Ethernet1: ipv4: 10.0.0.229/31 ipv6: fc00::1ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.116/24 ipv6: fc0a::74/64 ARISTA112T0: properties: - common + - tor bgp: asn: 64112 peers: @@ -3143,16 +3259,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.116/32 - ipv6: 2064:100::74/128 + ipv6: 2064:100:0:74::/128 Ethernet1: ipv4: 10.0.0.231/31 ipv6: fc00::1ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.117/24 ipv6: fc0a::75/64 ARISTA113T0: properties: - common + - tor bgp: asn: 64113 peers: @@ -3162,16 +3279,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.117/32 - ipv6: 2064:100::75/128 + ipv6: 2064:100:0:75::/128 Ethernet1: ipv4: 10.0.0.233/31 ipv6: fc00::1d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.118/24 ipv6: fc0a::76/64 ARISTA114T0: properties: - common + - tor bgp: asn: 64114 peers: @@ -3181,16 +3299,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.118/32 - ipv6: 2064:100::76/128 + ipv6: 2064:100:0:76::/128 Ethernet1: ipv4: 10.0.0.235/31 ipv6: fc00::1d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.119/24 ipv6: fc0a::77/64 ARISTA115T0: properties: - common + - tor bgp: asn: 64115 peers: @@ -3200,16 +3319,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.119/32 - ipv6: 2064:100::77/128 + ipv6: 2064:100:0:77::/128 Ethernet1: ipv4: 10.0.0.237/31 ipv6: fc00::1da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.120/24 ipv6: fc0a::78/64 ARISTA116T0: properties: - common + - tor bgp: asn: 64116 peers: @@ -3219,16 +3339,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.120/32 - ipv6: 2064:100::78/128 + ipv6: 2064:100:0:78::/128 Ethernet1: ipv4: 10.0.0.239/31 ipv6: fc00::1de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.121/24 ipv6: fc0a::79/64 ARISTA117T0: properties: - common + - tor bgp: asn: 64117 peers: @@ -3238,16 +3359,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.121/32 - ipv6: 2064:100::79/128 + ipv6: 2064:100:0:79::/128 Ethernet1: ipv4: 10.0.0.241/31 ipv6: fc00::1e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.122/24 ipv6: fc0a::7a/64 ARISTA118T0: properties: - common + - tor bgp: asn: 64118 peers: @@ -3257,16 +3379,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.122/32 - ipv6: 2064:100::7a/128 + ipv6: 2064:100:0:7a::/128 Ethernet1: ipv4: 10.0.0.243/31 ipv6: fc00::1e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.123/24 ipv6: fc0a::7b/64 ARISTA119T0: properties: - common + - tor bgp: asn: 64119 peers: @@ -3276,16 +3399,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.123/32 - ipv6: 2064:100::7b/128 + ipv6: 2064:100:0:7b::/128 Ethernet1: ipv4: 10.0.0.245/31 ipv6: fc00::1ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.124/24 ipv6: fc0a::7c/64 ARISTA120T0: properties: - common + - tor bgp: asn: 64120 peers: @@ -3295,16 +3419,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.124/32 - ipv6: 2064:100::7c/128 + ipv6: 2064:100:0:7c::/128 Ethernet1: ipv4: 10.0.0.247/31 ipv6: fc00::1ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.125/24 ipv6: fc0a::7d/64 ARISTA121T0: properties: - common + - tor bgp: asn: 64121 peers: @@ -3314,16 +3439,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.125/32 - ipv6: 2064:100::7d/128 + ipv6: 2064:100:0:7d::/128 Ethernet1: ipv4: 10.0.0.249/31 ipv6: fc00::1f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.126/24 ipv6: fc0a::7e/64 ARISTA122T0: properties: - common + - tor bgp: asn: 64122 peers: @@ -3333,16 +3459,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.126/32 - ipv6: 2064:100::7e/128 + ipv6: 2064:100:0:7e::/128 Ethernet1: ipv4: 10.0.0.251/31 ipv6: fc00::1f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.127/24 ipv6: fc0a::7f/64 ARISTA123T0: properties: - common + - tor bgp: asn: 64123 peers: @@ -3352,16 +3479,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.127/32 - ipv6: 2064:100::7f/128 + ipv6: 2064:100:0:7f::/128 Ethernet1: ipv4: 10.0.0.253/31 ipv6: fc00::1fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.128/24 ipv6: fc0a::80/64 ARISTA124T0: properties: - common + - tor bgp: asn: 64124 peers: @@ -3371,16 +3499,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.128/32 - ipv6: 2064:100::80/128 + ipv6: 2064:100:0:80::/128 Ethernet1: ipv4: 10.0.0.255/31 ipv6: fc00::1fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.129/24 ipv6: fc0a::81/64 ARISTA125T0: properties: - common + - tor bgp: asn: 64125 peers: @@ -3390,16 +3519,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.129/32 - ipv6: 2064:100::81/128 + ipv6: 2064:100:0:81::/128 Ethernet1: ipv4: 10.0.1.1/31 ipv6: fc00::202/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.130/24 ipv6: fc0a::82/64 ARISTA126T0: properties: - common + - tor bgp: asn: 64126 peers: @@ -3409,16 +3539,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.130/32 - ipv6: 2064:100::82/128 + ipv6: 2064:100:0:82::/128 Ethernet1: ipv4: 10.0.1.3/31 ipv6: fc00::206/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.131/24 ipv6: fc0a::83/64 ARISTA127T0: properties: - common + - tor bgp: asn: 64127 peers: @@ -3428,16 +3559,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.131/32 - ipv6: 2064:100::83/128 + ipv6: 2064:100:0:83::/128 Ethernet1: ipv4: 10.0.1.5/31 ipv6: fc00::20a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.132/24 ipv6: fc0a::84/64 ARISTA128T0: properties: - common + - tor bgp: asn: 64128 peers: @@ -3447,16 +3579,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.132/32 - ipv6: 2064:100::84/128 + ipv6: 2064:100:0:84::/128 Ethernet1: ipv4: 10.0.1.7/31 ipv6: fc00::20e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.133/24 ipv6: fc0a::85/64 ARISTA129T0: properties: - common + - tor bgp: asn: 64129 peers: @@ -3466,16 +3599,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.133/32 - ipv6: 2064:100::85/128 + ipv6: 2064:100:0:85::/128 Ethernet1: ipv4: 10.0.1.9/31 ipv6: fc00::212/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.134/24 ipv6: fc0a::86/64 ARISTA130T0: properties: - common + - tor bgp: asn: 64130 peers: @@ -3485,16 +3619,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.134/32 - ipv6: 2064:100::86/128 + ipv6: 2064:100:0:86::/128 Ethernet1: ipv4: 10.0.1.11/31 ipv6: fc00::216/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.135/24 ipv6: fc0a::87/64 ARISTA131T0: properties: - common + - tor bgp: asn: 64131 peers: @@ -3504,16 +3639,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.135/32 - ipv6: 2064:100::87/128 + ipv6: 2064:100:0:87::/128 Ethernet1: ipv4: 10.0.1.13/31 ipv6: fc00::21a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.136/24 ipv6: fc0a::88/64 ARISTA132T0: properties: - common + - tor bgp: asn: 64132 peers: @@ -3523,16 +3659,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.136/32 - ipv6: 2064:100::88/128 + ipv6: 2064:100:0:88::/128 Ethernet1: ipv4: 10.0.1.15/31 ipv6: fc00::21e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.137/24 ipv6: fc0a::89/64 ARISTA133T0: properties: - common + - tor bgp: asn: 64133 peers: @@ -3542,16 +3679,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.137/32 - ipv6: 2064:100::89/128 + ipv6: 2064:100:0:89::/128 Ethernet1: ipv4: 10.0.1.17/31 ipv6: fc00::222/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.138/24 ipv6: fc0a::8a/64 ARISTA134T0: properties: - common + - tor bgp: asn: 64134 peers: @@ -3561,16 +3699,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.138/32 - ipv6: 2064:100::8a/128 + ipv6: 2064:100:0:8a::/128 Ethernet1: ipv4: 10.0.1.19/31 ipv6: fc00::226/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.139/24 ipv6: fc0a::8b/64 ARISTA135T0: properties: - common + - tor bgp: asn: 64135 peers: @@ -3580,16 +3719,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.139/32 - ipv6: 2064:100::8b/128 + ipv6: 2064:100:0:8b::/128 Ethernet1: ipv4: 10.0.1.21/31 ipv6: fc00::22a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.140/24 ipv6: fc0a::8c/64 ARISTA136T0: properties: - common + - tor bgp: asn: 64136 peers: @@ -3599,16 +3739,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.140/32 - ipv6: 2064:100::8c/128 + ipv6: 2064:100:0:8c::/128 Ethernet1: ipv4: 10.0.1.23/31 ipv6: fc00::22e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.141/24 ipv6: fc0a::8d/64 ARISTA137T0: properties: - common + - tor bgp: asn: 64137 peers: @@ -3618,16 +3759,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.141/32 - ipv6: 2064:100::8d/128 + ipv6: 2064:100:0:8d::/128 Ethernet1: ipv4: 10.0.1.25/31 ipv6: fc00::232/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.142/24 ipv6: fc0a::8e/64 ARISTA138T0: properties: - common + - tor bgp: asn: 64138 peers: @@ -3637,16 +3779,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.142/32 - ipv6: 2064:100::8e/128 + ipv6: 2064:100:0:8e::/128 Ethernet1: ipv4: 10.0.1.27/31 ipv6: fc00::236/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.143/24 ipv6: fc0a::8f/64 ARISTA139T0: properties: - common + - tor bgp: asn: 64139 peers: @@ -3656,16 +3799,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.143/32 - ipv6: 2064:100::8f/128 + ipv6: 2064:100:0:8f::/128 Ethernet1: ipv4: 10.0.1.29/31 ipv6: fc00::23a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.144/24 ipv6: fc0a::90/64 ARISTA140T0: properties: - common + - tor bgp: asn: 64140 peers: @@ -3675,16 +3819,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.144/32 - ipv6: 2064:100::90/128 + ipv6: 2064:100:0:90::/128 Ethernet1: ipv4: 10.0.1.31/31 ipv6: fc00::23e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.145/24 ipv6: fc0a::91/64 ARISTA141T0: properties: - common + - tor bgp: asn: 64141 peers: @@ -3694,16 +3839,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.145/32 - ipv6: 2064:100::91/128 + ipv6: 2064:100:0:91::/128 Ethernet1: ipv4: 10.0.1.33/31 ipv6: fc00::242/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.146/24 ipv6: fc0a::92/64 ARISTA142T0: properties: - common + - tor bgp: asn: 64142 peers: @@ -3713,16 +3859,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.146/32 - ipv6: 2064:100::92/128 + ipv6: 2064:100:0:92::/128 Ethernet1: ipv4: 10.0.1.35/31 ipv6: fc00::246/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.147/24 ipv6: fc0a::93/64 ARISTA143T0: properties: - common + - tor bgp: asn: 64143 peers: @@ -3732,16 +3879,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.147/32 - ipv6: 2064:100::93/128 + ipv6: 2064:100:0:93::/128 Ethernet1: ipv4: 10.0.1.37/31 ipv6: fc00::24a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.148/24 ipv6: fc0a::94/64 ARISTA144T0: properties: - common + - tor bgp: asn: 64144 peers: @@ -3751,16 +3899,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.148/32 - ipv6: 2064:100::94/128 + ipv6: 2064:100:0:94::/128 Ethernet1: ipv4: 10.0.1.39/31 ipv6: fc00::24e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.149/24 ipv6: fc0a::95/64 ARISTA145T0: properties: - common + - tor bgp: asn: 64145 peers: @@ -3770,16 +3919,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.149/32 - ipv6: 2064:100::95/128 + ipv6: 2064:100:0:95::/128 Ethernet1: ipv4: 10.0.1.41/31 ipv6: fc00::252/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.150/24 ipv6: fc0a::96/64 ARISTA146T0: properties: - common + - tor bgp: asn: 64146 peers: @@ -3789,16 +3939,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.150/32 - ipv6: 2064:100::96/128 + ipv6: 2064:100:0:96::/128 Ethernet1: ipv4: 10.0.1.43/31 ipv6: fc00::256/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.151/24 ipv6: fc0a::97/64 ARISTA147T0: properties: - common + - tor bgp: asn: 64147 peers: @@ -3808,16 +3959,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.151/32 - ipv6: 2064:100::97/128 + ipv6: 2064:100:0:97::/128 Ethernet1: ipv4: 10.0.1.45/31 ipv6: fc00::25a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.152/24 ipv6: fc0a::98/64 ARISTA148T0: properties: - common + - tor bgp: asn: 64148 peers: @@ -3827,16 +3979,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.152/32 - ipv6: 2064:100::98/128 + ipv6: 2064:100:0:98::/128 Ethernet1: ipv4: 10.0.1.47/31 ipv6: fc00::25e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.153/24 ipv6: fc0a::99/64 ARISTA149T0: properties: - common + - tor bgp: asn: 64149 peers: @@ -3846,16 +3999,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.153/32 - ipv6: 2064:100::99/128 + ipv6: 2064:100:0:99::/128 Ethernet1: ipv4: 10.0.1.49/31 ipv6: fc00::262/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.154/24 ipv6: fc0a::9a/64 ARISTA150T0: properties: - common + - tor bgp: asn: 64150 peers: @@ -3865,16 +4019,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.154/32 - ipv6: 2064:100::9a/128 + ipv6: 2064:100:0:9a::/128 Ethernet1: ipv4: 10.0.1.51/31 ipv6: fc00::266/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.155/24 ipv6: fc0a::9b/64 ARISTA151T0: properties: - common + - tor bgp: asn: 64151 peers: @@ -3884,16 +4039,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.155/32 - ipv6: 2064:100::9b/128 + ipv6: 2064:100:0:9b::/128 Ethernet1: ipv4: 10.0.1.53/31 ipv6: fc00::26a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.156/24 ipv6: fc0a::9c/64 ARISTA152T0: properties: - common + - tor bgp: asn: 64152 peers: @@ -3903,16 +4059,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.156/32 - ipv6: 2064:100::9c/128 + ipv6: 2064:100:0:9c::/128 Ethernet1: ipv4: 10.0.1.55/31 ipv6: fc00::26e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.157/24 ipv6: fc0a::9d/64 ARISTA153T0: properties: - common + - tor bgp: asn: 64153 peers: @@ -3922,16 +4079,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.157/32 - ipv6: 2064:100::9d/128 + ipv6: 2064:100:0:9d::/128 Ethernet1: ipv4: 10.0.1.57/31 ipv6: fc00::272/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.158/24 ipv6: fc0a::9e/64 ARISTA154T0: properties: - common + - tor bgp: asn: 64154 peers: @@ -3941,16 +4099,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.158/32 - ipv6: 2064:100::9e/128 + ipv6: 2064:100:0:9e::/128 Ethernet1: ipv4: 10.0.1.59/31 ipv6: fc00::276/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.159/24 ipv6: fc0a::9f/64 ARISTA155T0: properties: - common + - tor bgp: asn: 64155 peers: @@ -3960,16 +4119,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.159/32 - ipv6: 2064:100::9f/128 + ipv6: 2064:100:0:9f::/128 Ethernet1: ipv4: 10.0.1.61/31 ipv6: fc00::27a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.160/24 ipv6: fc0a::a0/64 ARISTA156T0: properties: - common + - tor bgp: asn: 64156 peers: @@ -3979,16 +4139,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.160/32 - ipv6: 2064:100::a0/128 + ipv6: 2064:100:0:a0::/128 Ethernet1: ipv4: 10.0.1.63/31 ipv6: fc00::27e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.161/24 ipv6: fc0a::a1/64 ARISTA157T0: properties: - common + - tor bgp: asn: 64157 peers: @@ -3998,16 +4159,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.161/32 - ipv6: 2064:100::a1/128 + ipv6: 2064:100:0:a1::/128 Ethernet1: ipv4: 10.0.1.65/31 ipv6: fc00::282/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.162/24 ipv6: fc0a::a2/64 ARISTA158T0: properties: - common + - tor bgp: asn: 64158 peers: @@ -4017,16 +4179,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.162/32 - ipv6: 2064:100::a2/128 + ipv6: 2064:100:0:a2::/128 Ethernet1: ipv4: 10.0.1.67/31 ipv6: fc00::286/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.163/24 ipv6: fc0a::a3/64 ARISTA159T0: properties: - common + - tor bgp: asn: 64159 peers: @@ -4036,16 +4199,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.163/32 - ipv6: 2064:100::a3/128 + ipv6: 2064:100:0:a3::/128 Ethernet1: ipv4: 10.0.1.69/31 ipv6: fc00::28a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.164/24 ipv6: fc0a::a4/64 ARISTA160T0: properties: - common + - tor bgp: asn: 64160 peers: @@ -4055,16 +4219,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.164/32 - ipv6: 2064:100::a4/128 + ipv6: 2064:100:0:a4::/128 Ethernet1: ipv4: 10.0.1.71/31 ipv6: fc00::28e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.165/24 ipv6: fc0a::a5/64 ARISTA05T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -4074,16 +4239,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.165/32 - ipv6: 2064:100::a5/128 + ipv6: 2064:100:0:a5::/128 Ethernet1: ipv4: 10.0.1.73/31 ipv6: fc00::292/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.166/24 ipv6: fc0a::a6/64 ARISTA06T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -4093,16 +4259,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.166/32 - ipv6: 2064:100::a6/128 + ipv6: 2064:100:0:a6::/128 Ethernet1: ipv4: 10.0.1.75/31 ipv6: fc00::296/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.167/24 ipv6: fc0a::a7/64 ARISTA161T0: properties: - common + - tor bgp: asn: 64161 peers: @@ -4112,16 +4279,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.167/32 - ipv6: 2064:100::a7/128 + ipv6: 2064:100:0:a7::/128 Ethernet1: ipv4: 10.0.1.77/31 ipv6: fc00::29a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.168/24 ipv6: fc0a::a8/64 ARISTA162T0: properties: - common + - tor bgp: asn: 64162 peers: @@ -4131,16 +4299,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.168/32 - ipv6: 2064:100::a8/128 + ipv6: 2064:100:0:a8::/128 Ethernet1: ipv4: 10.0.1.79/31 ipv6: fc00::29e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.169/24 ipv6: fc0a::a9/64 ARISTA163T0: properties: - common + - tor bgp: asn: 64163 peers: @@ -4150,16 +4319,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.169/32 - ipv6: 2064:100::a9/128 + ipv6: 2064:100:0:a9::/128 Ethernet1: ipv4: 10.0.1.81/31 ipv6: fc00::2a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.170/24 ipv6: fc0a::aa/64 ARISTA164T0: properties: - common + - tor bgp: asn: 64164 peers: @@ -4169,16 +4339,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.170/32 - ipv6: 2064:100::aa/128 + ipv6: 2064:100:0:aa::/128 Ethernet1: ipv4: 10.0.1.83/31 ipv6: fc00::2a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.171/24 ipv6: fc0a::ab/64 ARISTA165T0: properties: - common + - tor bgp: asn: 64165 peers: @@ -4188,16 +4359,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.171/32 - ipv6: 2064:100::ab/128 + ipv6: 2064:100:0:ab::/128 Ethernet1: ipv4: 10.0.1.85/31 ipv6: fc00::2aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.172/24 ipv6: fc0a::ac/64 ARISTA166T0: properties: - common + - tor bgp: asn: 64166 peers: @@ -4207,16 +4379,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.172/32 - ipv6: 2064:100::ac/128 + ipv6: 2064:100:0:ac::/128 Ethernet1: ipv4: 10.0.1.87/31 ipv6: fc00::2ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.173/24 ipv6: fc0a::ad/64 ARISTA167T0: properties: - common + - tor bgp: asn: 64167 peers: @@ -4226,16 +4399,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.173/32 - ipv6: 2064:100::ad/128 + ipv6: 2064:100:0:ad::/128 Ethernet1: ipv4: 10.0.1.89/31 ipv6: fc00::2b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.174/24 ipv6: fc0a::ae/64 ARISTA168T0: properties: - common + - tor bgp: asn: 64168 peers: @@ -4245,16 +4419,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.174/32 - ipv6: 2064:100::ae/128 + ipv6: 2064:100:0:ae::/128 Ethernet1: ipv4: 10.0.1.91/31 ipv6: fc00::2b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.175/24 ipv6: fc0a::af/64 ARISTA07T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -4264,16 +4439,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.175/32 - ipv6: 2064:100::af/128 + ipv6: 2064:100:0:af::/128 Ethernet1: ipv4: 10.0.1.93/31 ipv6: fc00::2ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.176/24 ipv6: fc0a::b0/64 ARISTA08T2: properties: - common + - spine bgp: asn: 65200 peers: @@ -4283,16 +4459,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.176/32 - ipv6: 2064:100::b0/128 + ipv6: 2064:100:0:b0::/128 Ethernet1: ipv4: 10.0.1.95/31 ipv6: fc00::2be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.177/24 ipv6: fc0a::b1/64 ARISTA169T0: properties: - common + - tor bgp: asn: 64169 peers: @@ -4302,16 +4479,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.177/32 - ipv6: 2064:100::b1/128 + ipv6: 2064:100:0:b1::/128 Ethernet1: ipv4: 10.0.1.97/31 ipv6: fc00::2c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.178/24 ipv6: fc0a::b2/64 ARISTA170T0: properties: - common + - tor bgp: asn: 64170 peers: @@ -4321,16 +4499,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.178/32 - ipv6: 2064:100::b2/128 + ipv6: 2064:100:0:b2::/128 Ethernet1: ipv4: 10.0.1.99/31 ipv6: fc00::2c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.179/24 ipv6: fc0a::b3/64 ARISTA171T0: properties: - common + - tor bgp: asn: 64171 peers: @@ -4340,16 +4519,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.179/32 - ipv6: 2064:100::b3/128 + ipv6: 2064:100:0:b3::/128 Ethernet1: ipv4: 10.0.1.101/31 ipv6: fc00::2ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.180/24 ipv6: fc0a::b4/64 ARISTA172T0: properties: - common + - tor bgp: asn: 64172 peers: @@ -4359,16 +4539,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.180/32 - ipv6: 2064:100::b4/128 + ipv6: 2064:100:0:b4::/128 Ethernet1: ipv4: 10.0.1.103/31 ipv6: fc00::2ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.181/24 ipv6: fc0a::b5/64 ARISTA173T0: properties: - common + - tor bgp: asn: 64173 peers: @@ -4378,16 +4559,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.181/32 - ipv6: 2064:100::b5/128 + ipv6: 2064:100:0:b5::/128 Ethernet1: ipv4: 10.0.1.105/31 ipv6: fc00::2d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.182/24 ipv6: fc0a::b6/64 ARISTA174T0: properties: - common + - tor bgp: asn: 64174 peers: @@ -4397,16 +4579,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.182/32 - ipv6: 2064:100::b6/128 + ipv6: 2064:100:0:b6::/128 Ethernet1: ipv4: 10.0.1.107/31 ipv6: fc00::2d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.183/24 ipv6: fc0a::b7/64 ARISTA175T0: properties: - common + - tor bgp: asn: 64175 peers: @@ -4416,16 +4599,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.183/32 - ipv6: 2064:100::b7/128 + ipv6: 2064:100:0:b7::/128 Ethernet1: ipv4: 10.0.1.109/31 ipv6: fc00::2da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.184/24 ipv6: fc0a::b8/64 ARISTA176T0: properties: - common + - tor bgp: asn: 64176 peers: @@ -4435,16 +4619,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.184/32 - ipv6: 2064:100::b8/128 + ipv6: 2064:100:0:b8::/128 Ethernet1: ipv4: 10.0.1.111/31 ipv6: fc00::2de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.185/24 ipv6: fc0a::b9/64 ARISTA177T0: properties: - common + - tor bgp: asn: 64177 peers: @@ -4454,16 +4639,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.185/32 - ipv6: 2064:100::b9/128 + ipv6: 2064:100:0:b9::/128 Ethernet1: ipv4: 10.0.1.113/31 ipv6: fc00::2e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.186/24 ipv6: fc0a::ba/64 ARISTA178T0: properties: - common + - tor bgp: asn: 64178 peers: @@ -4473,16 +4659,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.186/32 - ipv6: 2064:100::ba/128 + ipv6: 2064:100:0:ba::/128 Ethernet1: ipv4: 10.0.1.115/31 ipv6: fc00::2e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.187/24 ipv6: fc0a::bb/64 ARISTA179T0: properties: - common + - tor bgp: asn: 64179 peers: @@ -4492,16 +4679,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.187/32 - ipv6: 2064:100::bb/128 + ipv6: 2064:100:0:bb::/128 Ethernet1: ipv4: 10.0.1.117/31 ipv6: fc00::2ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.188/24 ipv6: fc0a::bc/64 ARISTA180T0: properties: - common + - tor bgp: asn: 64180 peers: @@ -4511,16 +4699,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.188/32 - ipv6: 2064:100::bc/128 + ipv6: 2064:100:0:bc::/128 Ethernet1: ipv4: 10.0.1.119/31 ipv6: fc00::2ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.189/24 ipv6: fc0a::bd/64 ARISTA181T0: properties: - common + - tor bgp: asn: 64181 peers: @@ -4530,16 +4719,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.189/32 - ipv6: 2064:100::bd/128 + ipv6: 2064:100:0:bd::/128 Ethernet1: ipv4: 10.0.1.121/31 ipv6: fc00::2f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.190/24 ipv6: fc0a::be/64 ARISTA182T0: properties: - common + - tor bgp: asn: 64182 peers: @@ -4549,16 +4739,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.190/32 - ipv6: 2064:100::be/128 + ipv6: 2064:100:0:be::/128 Ethernet1: ipv4: 10.0.1.123/31 ipv6: fc00::2f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.191/24 ipv6: fc0a::bf/64 ARISTA183T0: properties: - common + - tor bgp: asn: 64183 peers: @@ -4568,16 +4759,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.191/32 - ipv6: 2064:100::bf/128 + ipv6: 2064:100:0:bf::/128 Ethernet1: ipv4: 10.0.1.125/31 ipv6: fc00::2fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.192/24 ipv6: fc0a::c0/64 ARISTA184T0: properties: - common + - tor bgp: asn: 64184 peers: @@ -4587,16 +4779,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.192/32 - ipv6: 2064:100::c0/128 + ipv6: 2064:100:0:c0::/128 Ethernet1: ipv4: 10.0.1.127/31 ipv6: fc00::2fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.193/24 ipv6: fc0a::c1/64 ARISTA185T0: properties: - common + - tor bgp: asn: 64185 peers: @@ -4606,16 +4799,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.193/32 - ipv6: 2064:100::c1/128 + ipv6: 2064:100:0:c1::/128 Ethernet1: ipv4: 10.0.1.129/31 ipv6: fc00::302/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.194/24 ipv6: fc0a::c2/64 ARISTA186T0: properties: - common + - tor bgp: asn: 64186 peers: @@ -4625,16 +4819,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.194/32 - ipv6: 2064:100::c2/128 + ipv6: 2064:100:0:c2::/128 Ethernet1: ipv4: 10.0.1.131/31 ipv6: fc00::306/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.195/24 ipv6: fc0a::c3/64 ARISTA187T0: properties: - common + - tor bgp: asn: 64187 peers: @@ -4644,16 +4839,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.195/32 - ipv6: 2064:100::c3/128 + ipv6: 2064:100:0:c3::/128 Ethernet1: ipv4: 10.0.1.133/31 ipv6: fc00::30a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.196/24 ipv6: fc0a::c4/64 ARISTA188T0: properties: - common + - tor bgp: asn: 64188 peers: @@ -4663,16 +4859,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.196/32 - ipv6: 2064:100::c4/128 + ipv6: 2064:100:0:c4::/128 Ethernet1: ipv4: 10.0.1.135/31 ipv6: fc00::30e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.197/24 ipv6: fc0a::c5/64 ARISTA189T0: properties: - common + - tor bgp: asn: 64189 peers: @@ -4682,16 +4879,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.197/32 - ipv6: 2064:100::c5/128 + ipv6: 2064:100:0:c5::/128 Ethernet1: ipv4: 10.0.1.137/31 ipv6: fc00::312/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.198/24 ipv6: fc0a::c6/64 ARISTA190T0: properties: - common + - tor bgp: asn: 64190 peers: @@ -4701,16 +4899,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.198/32 - ipv6: 2064:100::c6/128 + ipv6: 2064:100:0:c6::/128 Ethernet1: ipv4: 10.0.1.139/31 ipv6: fc00::316/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.199/24 ipv6: fc0a::c7/64 ARISTA191T0: properties: - common + - tor bgp: asn: 64191 peers: @@ -4720,16 +4919,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.199/32 - ipv6: 2064:100::c7/128 + ipv6: 2064:100:0:c7::/128 Ethernet1: ipv4: 10.0.1.141/31 ipv6: fc00::31a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.200/24 ipv6: fc0a::c8/64 ARISTA192T0: properties: - common + - tor bgp: asn: 64192 peers: @@ -4739,16 +4939,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.200/32 - ipv6: 2064:100::c8/128 + ipv6: 2064:100:0:c8::/128 Ethernet1: ipv4: 10.0.1.143/31 ipv6: fc00::31e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.201/24 ipv6: fc0a::c9/64 ARISTA193T0: properties: - common + - tor bgp: asn: 64193 peers: @@ -4758,16 +4959,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.201/32 - ipv6: 2064:100::c9/128 + ipv6: 2064:100:0:c9::/128 Ethernet1: ipv4: 10.0.1.145/31 ipv6: fc00::322/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.202/24 ipv6: fc0a::ca/64 ARISTA194T0: properties: - common + - tor bgp: asn: 64194 peers: @@ -4777,16 +4979,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.202/32 - ipv6: 2064:100::ca/128 + ipv6: 2064:100:0:ca::/128 Ethernet1: ipv4: 10.0.1.147/31 ipv6: fc00::326/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.203/24 ipv6: fc0a::cb/64 ARISTA195T0: properties: - common + - tor bgp: asn: 64195 peers: @@ -4796,16 +4999,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.203/32 - ipv6: 2064:100::cb/128 + ipv6: 2064:100:0:cb::/128 Ethernet1: ipv4: 10.0.1.149/31 ipv6: fc00::32a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.204/24 ipv6: fc0a::cc/64 ARISTA196T0: properties: - common + - tor bgp: asn: 64196 peers: @@ -4815,16 +5019,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.204/32 - ipv6: 2064:100::cc/128 + ipv6: 2064:100:0:cc::/128 Ethernet1: ipv4: 10.0.1.151/31 ipv6: fc00::32e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.205/24 ipv6: fc0a::cd/64 ARISTA197T0: properties: - common + - tor bgp: asn: 64197 peers: @@ -4834,16 +5039,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.205/32 - ipv6: 2064:100::cd/128 + ipv6: 2064:100:0:cd::/128 Ethernet1: ipv4: 10.0.1.153/31 ipv6: fc00::332/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.206/24 ipv6: fc0a::ce/64 ARISTA198T0: properties: - common + - tor bgp: asn: 64198 peers: @@ -4853,16 +5059,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.206/32 - ipv6: 2064:100::ce/128 + ipv6: 2064:100:0:ce::/128 Ethernet1: ipv4: 10.0.1.155/31 ipv6: fc00::336/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.207/24 ipv6: fc0a::cf/64 ARISTA199T0: properties: - common + - tor bgp: asn: 64199 peers: @@ -4872,16 +5079,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.207/32 - ipv6: 2064:100::cf/128 + ipv6: 2064:100:0:cf::/128 Ethernet1: ipv4: 10.0.1.157/31 ipv6: fc00::33a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.208/24 ipv6: fc0a::d0/64 ARISTA200T0: properties: - common + - tor bgp: asn: 64200 peers: @@ -4891,16 +5099,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.208/32 - ipv6: 2064:100::d0/128 + ipv6: 2064:100:0:d0::/128 Ethernet1: ipv4: 10.0.1.159/31 ipv6: fc00::33e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.209/24 ipv6: fc0a::d1/64 ARISTA201T0: properties: - common + - tor bgp: asn: 64201 peers: @@ -4910,16 +5119,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.209/32 - ipv6: 2064:100::d1/128 + ipv6: 2064:100:0:d1::/128 Ethernet1: ipv4: 10.0.1.161/31 ipv6: fc00::342/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.210/24 ipv6: fc0a::d2/64 ARISTA202T0: properties: - common + - tor bgp: asn: 64202 peers: @@ -4929,16 +5139,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.210/32 - ipv6: 2064:100::d2/128 + ipv6: 2064:100:0:d2::/128 Ethernet1: ipv4: 10.0.1.163/31 ipv6: fc00::346/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.211/24 ipv6: fc0a::d3/64 ARISTA203T0: properties: - common + - tor bgp: asn: 64203 peers: @@ -4948,16 +5159,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.211/32 - ipv6: 2064:100::d3/128 + ipv6: 2064:100:0:d3::/128 Ethernet1: ipv4: 10.0.1.165/31 ipv6: fc00::34a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.212/24 ipv6: fc0a::d4/64 ARISTA204T0: properties: - common + - tor bgp: asn: 64204 peers: @@ -4967,16 +5179,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.212/32 - ipv6: 2064:100::d4/128 + ipv6: 2064:100:0:d4::/128 Ethernet1: ipv4: 10.0.1.167/31 ipv6: fc00::34e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.213/24 ipv6: fc0a::d5/64 ARISTA205T0: properties: - common + - tor bgp: asn: 64205 peers: @@ -4986,16 +5199,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.213/32 - ipv6: 2064:100::d5/128 + ipv6: 2064:100:0:d5::/128 Ethernet1: ipv4: 10.0.1.169/31 ipv6: fc00::352/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.214/24 ipv6: fc0a::d6/64 ARISTA206T0: properties: - common + - tor bgp: asn: 64206 peers: @@ -5005,16 +5219,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.214/32 - ipv6: 2064:100::d6/128 + ipv6: 2064:100:0:d6::/128 Ethernet1: ipv4: 10.0.1.171/31 ipv6: fc00::356/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.215/24 ipv6: fc0a::d7/64 ARISTA207T0: properties: - common + - tor bgp: asn: 64207 peers: @@ -5024,16 +5239,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.215/32 - ipv6: 2064:100::d7/128 + ipv6: 2064:100:0:d7::/128 Ethernet1: ipv4: 10.0.1.173/31 ipv6: fc00::35a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.216/24 ipv6: fc0a::d8/64 ARISTA208T0: properties: - common + - tor bgp: asn: 64208 peers: @@ -5043,16 +5259,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.216/32 - ipv6: 2064:100::d8/128 + ipv6: 2064:100:0:d8::/128 Ethernet1: ipv4: 10.0.1.175/31 ipv6: fc00::35e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.217/24 ipv6: fc0a::d9/64 ARISTA209T0: properties: - common + - tor bgp: asn: 64209 peers: @@ -5062,16 +5279,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.217/32 - ipv6: 2064:100::d9/128 + ipv6: 2064:100:0:d9::/128 Ethernet1: ipv4: 10.0.1.177/31 ipv6: fc00::362/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.218/24 ipv6: fc0a::da/64 ARISTA210T0: properties: - common + - tor bgp: asn: 64210 peers: @@ -5081,16 +5299,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.218/32 - ipv6: 2064:100::da/128 + ipv6: 2064:100:0:da::/128 Ethernet1: ipv4: 10.0.1.179/31 ipv6: fc00::366/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.219/24 ipv6: fc0a::db/64 ARISTA211T0: properties: - common + - tor bgp: asn: 64211 peers: @@ -5100,16 +5319,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.219/32 - ipv6: 2064:100::db/128 + ipv6: 2064:100:0:db::/128 Ethernet1: ipv4: 10.0.1.181/31 ipv6: fc00::36a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.220/24 ipv6: fc0a::dc/64 ARISTA212T0: properties: - common + - tor bgp: asn: 64212 peers: @@ -5119,16 +5339,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.220/32 - ipv6: 2064:100::dc/128 + ipv6: 2064:100:0:dc::/128 Ethernet1: ipv4: 10.0.1.183/31 ipv6: fc00::36e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.221/24 ipv6: fc0a::dd/64 ARISTA213T0: properties: - common + - tor bgp: asn: 64213 peers: @@ -5138,16 +5359,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.221/32 - ipv6: 2064:100::dd/128 + ipv6: 2064:100:0:dd::/128 Ethernet1: ipv4: 10.0.1.185/31 ipv6: fc00::372/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.222/24 ipv6: fc0a::de/64 ARISTA214T0: properties: - common + - tor bgp: asn: 64214 peers: @@ -5157,16 +5379,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.222/32 - ipv6: 2064:100::de/128 + ipv6: 2064:100:0:de::/128 Ethernet1: ipv4: 10.0.1.187/31 ipv6: fc00::376/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.223/24 ipv6: fc0a::df/64 ARISTA215T0: properties: - common + - tor bgp: asn: 64215 peers: @@ -5176,16 +5399,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.223/32 - ipv6: 2064:100::df/128 + ipv6: 2064:100:0:df::/128 Ethernet1: ipv4: 10.0.1.189/31 ipv6: fc00::37a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.224/24 ipv6: fc0a::e0/64 ARISTA216T0: properties: - common + - tor bgp: asn: 64216 peers: @@ -5195,16 +5419,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.224/32 - ipv6: 2064:100::e0/128 + ipv6: 2064:100:0:e0::/128 Ethernet1: ipv4: 10.0.1.191/31 ipv6: fc00::37e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.225/24 ipv6: fc0a::e1/64 ARISTA217T0: properties: - common + - tor bgp: asn: 64217 peers: @@ -5214,16 +5439,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.225/32 - ipv6: 2064:100::e1/128 + ipv6: 2064:100:0:e1::/128 Ethernet1: ipv4: 10.0.1.193/31 ipv6: fc00::382/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.226/24 ipv6: fc0a::e2/64 ARISTA218T0: properties: - common + - tor bgp: asn: 64218 peers: @@ -5233,16 +5459,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.226/32 - ipv6: 2064:100::e2/128 + ipv6: 2064:100:0:e2::/128 Ethernet1: ipv4: 10.0.1.195/31 ipv6: fc00::386/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.227/24 ipv6: fc0a::e3/64 ARISTA219T0: properties: - common + - tor bgp: asn: 64219 peers: @@ -5252,16 +5479,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.227/32 - ipv6: 2064:100::e3/128 + ipv6: 2064:100:0:e3::/128 Ethernet1: ipv4: 10.0.1.197/31 ipv6: fc00::38a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.228/24 ipv6: fc0a::e4/64 ARISTA220T0: properties: - common + - tor bgp: asn: 64220 peers: @@ -5271,16 +5499,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.228/32 - ipv6: 2064:100::e4/128 + ipv6: 2064:100:0:e4::/128 Ethernet1: ipv4: 10.0.1.199/31 ipv6: fc00::38e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.229/24 ipv6: fc0a::e5/64 ARISTA221T0: properties: - common + - tor bgp: asn: 64221 peers: @@ -5290,16 +5519,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.229/32 - ipv6: 2064:100::e5/128 + ipv6: 2064:100:0:e5::/128 Ethernet1: ipv4: 10.0.1.201/31 ipv6: fc00::392/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.230/24 ipv6: fc0a::e6/64 ARISTA222T0: properties: - common + - tor bgp: asn: 64222 peers: @@ -5309,16 +5539,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.230/32 - ipv6: 2064:100::e6/128 + ipv6: 2064:100:0:e6::/128 Ethernet1: ipv4: 10.0.1.203/31 ipv6: fc00::396/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.231/24 ipv6: fc0a::e7/64 ARISTA223T0: properties: - common + - tor bgp: asn: 64223 peers: @@ -5328,16 +5559,17 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.231/32 - ipv6: 2064:100::e7/128 + ipv6: 2064:100:0:e7::/128 Ethernet1: ipv4: 10.0.1.205/31 ipv6: fc00::39a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.232/24 ipv6: fc0a::e8/64 ARISTA224T0: properties: - common + - tor bgp: asn: 64224 peers: @@ -5347,10 +5579,10 @@ configuration: interfaces: Loopback0: ipv4: 100.1.0.232/32 - ipv6: 2064:100::e8/128 + ipv6: 2064:100:0:e8::/128 Ethernet1: ipv4: 10.0.1.207/31 ipv6: fc00::39e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.233/24 ipv6: fc0a::e9/64 From 1f31f953524006216319b090b73496db09128d9b Mon Sep 17 00:00:00 2001 From: Chuan Wu <103085864+echuawu@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:51:21 +0800 Subject: [PATCH 166/221] Update fanout deploy yaml file to support using 2024 image (#14389) Update fanout deploy yaml file to support using 2024 image in fanout switch Change-Id: Id21693e0cfa8d317669e6b2ab7428b208aeaea1f --- ansible/roles/fanout/tasks/fanout_sonic.yml | 8 ++++++++ ansible/roles/fanout/tasks/sonic/fanout_sonic_202405.yml | 1 + 2 files changed, 9 insertions(+) create mode 120000 ansible/roles/fanout/tasks/sonic/fanout_sonic_202405.yml diff --git a/ansible/roles/fanout/tasks/fanout_sonic.yml b/ansible/roles/fanout/tasks/fanout_sonic.yml index cf0a1e161fd..74f07d4a780 100644 --- a/ansible/roles/fanout/tasks/fanout_sonic.yml +++ b/ansible/roles/fanout/tasks/fanout_sonic.yml @@ -64,3 +64,11 @@ sonic/fanout_sonic_202311.yml when: dry_run is not defined and incremental is not defined when: "'2023' in fanout_sonic_version['build_version']" + +- name: deploy SONiC fanout with image version 202405 + block: + - name: deploy SONiC fanout not incremental and not dry_run + include_tasks: + sonic/fanout_sonic_202405.yml + when: dry_run is not defined and incremental is not defined + when: "'2024' in fanout_sonic_version['build_version']" diff --git a/ansible/roles/fanout/tasks/sonic/fanout_sonic_202405.yml b/ansible/roles/fanout/tasks/sonic/fanout_sonic_202405.yml new file mode 120000 index 00000000000..2f92d838450 --- /dev/null +++ b/ansible/roles/fanout/tasks/sonic/fanout_sonic_202405.yml @@ -0,0 +1 @@ +fanout_sonic_202311.yml \ No newline at end of file From 4efbf3ef0da138beee72af144e712c6188befdee Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Thu, 14 Nov 2024 15:03:07 +0800 Subject: [PATCH 167/221] Move get_bgp_speaker_runningconfig to common (#15528) What is the motivation for this PR? In script test_bgp_dual_asn.py, there is an import from the folder tests/generic_config_updater. To minimize cross-module dependencies, we have refactored this function to a common location. How did you do it? How did you verify/test it? --- tests/bgp/test_bgp_dual_asn.py | 2 +- tests/common/gu_utils.py | 22 +++++++++++++++++++ .../test_bgp_speaker.py | 22 +------------------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/tests/bgp/test_bgp_dual_asn.py b/tests/bgp/test_bgp_dual_asn.py index 9ad279d95f2..c5f6fadd4cf 100644 --- a/tests/bgp/test_bgp_dual_asn.py +++ b/tests/bgp/test_bgp_dual_asn.py @@ -12,7 +12,7 @@ from tests.common.utilities import wait_until from tests.common.helpers.assertions import pytest_assert from bgp_helpers import update_routes -from tests.generic_config_updater.test_bgp_speaker import get_bgp_speaker_runningconfig +from tests.common.gu_utils import get_bgp_speaker_runningconfig from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile from tests.common.gu_utils import ( diff --git a/tests/common/gu_utils.py b/tests/common/gu_utils.py index e62ece315cf..1d6648e40ac 100644 --- a/tests/common/gu_utils.py +++ b/tests/common/gu_utils.py @@ -3,6 +3,7 @@ import pytest import os import time +import re from jsonpointer import JsonPointer from tests.common.helpers.assertions import pytest_assert from tests.common.utilities import wait_until @@ -477,3 +478,24 @@ def expect_acl_rule_removed(duthost, rulename, setup): removed = len(output) == 0 pytest_assert(removed, "'{}' showed a rule, this following rule should have been removed".format(cmds)) + + +def get_bgp_speaker_runningconfig(duthost): + """ Get bgp speaker config that contains src_address and ip_range + + Sample output in t0: + ['\n neighbor BGPSLBPassive update-source 10.1.0.32', + '\n neighbor BGPVac update-source 10.1.0.32', + '\n bgp listen range 10.255.0.0/25 peer-group BGPSLBPassive', + '\n bgp listen range 192.168.0.0/21 peer-group BGPVac'] + """ + cmds = "show runningconfiguration bgp" + output = duthost.shell(cmds) + pytest_assert(not output['rc'], "'{}' failed with rc={}".format(cmds, output['rc'])) + + # Sample: + # neighbor BGPSLBPassive update-source 10.1.0.32 + # bgp listen range 192.168.0.0/21 peer-group BGPVac + bgp_speaker_pattern = r"\s+neighbor.*update-source.*|\s+bgp listen range.*" + bgp_speaker_config = re.findall(bgp_speaker_pattern, output['stdout']) + return bgp_speaker_config diff --git a/tests/generic_config_updater/test_bgp_speaker.py b/tests/generic_config_updater/test_bgp_speaker.py index 6dcdeda193d..79b8f7a762f 100644 --- a/tests/generic_config_updater/test_bgp_speaker.py +++ b/tests/generic_config_updater/test_bgp_speaker.py @@ -7,6 +7,7 @@ from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload +from tests.common.gu_utils import get_bgp_speaker_runningconfig pytestmark = [ pytest.mark.topology('t0'), # BGP Speaker is limited to t0 only @@ -56,27 +57,6 @@ def lo_intf_ips(rand_selected_dut, tbinfo): pytest_assert(True, "Required ipv4 and ipv6 to start the test") -def get_bgp_speaker_runningconfig(duthost): - """ Get bgp speaker config that contains src_address and ip_range - - Sample output in t0: - ['\n neighbor BGPSLBPassive update-source 10.1.0.32', - '\n neighbor BGPVac update-source 10.1.0.32', - '\n bgp listen range 10.255.0.0/25 peer-group BGPSLBPassive', - '\n bgp listen range 192.168.0.0/21 peer-group BGPVac'] - """ - cmds = "show runningconfiguration bgp" - output = duthost.shell(cmds) - pytest_assert(not output['rc'], "'{}' failed with rc={}".format(cmds, output['rc'])) - - # Sample: - # neighbor BGPSLBPassive update-source 10.1.0.32 - # bgp listen range 192.168.0.0/21 peer-group BGPVac - bgp_speaker_pattern = r"\s+neighbor.*update-source.*|\s+bgp listen range.*" - bgp_speaker_config = re.findall(bgp_speaker_pattern, output['stdout']) - return bgp_speaker_config - - @pytest.fixture(autouse=True) def setup_env(duthosts, rand_one_dut_hostname): """ From 0c934e3ab781f35dfbe9f1e0e36e7df38f6da514 Mon Sep 17 00:00:00 2001 From: Xincun Li <147451452+xincunli-sonic@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:14:44 -0800 Subject: [PATCH 168/221] Add scope into JSON patch of existing GCU testcases for Multi ASIC. (#14098) ### Description of PR Summary: Improve existing GCU test cases for multi asic. ### Approach #### What is the motivation for this PR? In multi asic, by default, there is no namespace when we do replace or remove operation, which will fail due to the path is incomplete. #### How did you do it? When testcase is running, the apply-patch wrapper in test code will inject the localhost namespace into payload. --- tests/bgp/test_bgp_bbr.py | 3 ++ tests/bgp/test_bgp_bbr_default_state.py | 3 ++ tests/bgp/test_bgp_dual_asn.py | 3 ++ tests/common/gu_utils.py | 32 +++++++++++++++++++ tests/generic_config_updater/gu_utils.py | 2 ++ tests/generic_config_updater/test_aaa.py | 14 ++++++++ .../generic_config_updater/test_bgp_prefix.py | 5 +++ .../test_bgp_sentinel.py | 5 +++ .../test_bgp_speaker.py | 5 +++ tests/generic_config_updater/test_bgpl.py | 6 ++++ tests/generic_config_updater/test_cacl.py | 15 +++++++++ .../generic_config_updater/test_dhcp_relay.py | 5 +++ .../test_ecn_config_update.py | 2 ++ .../test_eth_interface.py | 11 +++++++ .../test_incremental_qos.py | 2 ++ tests/generic_config_updater/test_ip_bgp.py | 6 ++++ .../test_kubernetes_config.py | 2 ++ .../test_lo_interface.py | 8 +++++ .../test_mgmt_interface.py | 2 ++ ...est_mmu_dynamic_threshold_config_update.py | 2 ++ .../test_monitor_config.py | 2 ++ tests/generic_config_updater/test_ntp.py | 7 ++++ .../test_pfcwd_interval.py | 2 ++ .../test_pfcwd_status.py | 3 ++ .../test_pg_headroom_update.py | 2 ++ .../test_portchannel_interface.py | 6 ++++ tests/generic_config_updater/test_syslog.py | 6 ++++ .../test_vlan_interface.py | 7 ++++ 28 files changed, 168 insertions(+) diff --git a/tests/bgp/test_bgp_bbr.py b/tests/bgp/test_bgp_bbr.py index 281968d5648..a71beb2dbe1 100644 --- a/tests/bgp/test_bgp_bbr.py +++ b/tests/bgp/test_bgp_bbr.py @@ -22,6 +22,7 @@ from tests.common.utilities import wait_until, delete_running_config from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic pytestmark = [ @@ -75,6 +76,7 @@ def add_bbr_config_to_running_config(duthost, status): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -97,6 +99,7 @@ def config_bbr_by_gcu(duthost, status): "value": "{}".format(status) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/bgp/test_bgp_bbr_default_state.py b/tests/bgp/test_bgp_bbr_default_state.py index bf6019c671b..5e8e8b0181c 100644 --- a/tests/bgp/test_bgp_bbr_default_state.py +++ b/tests/bgp/test_bgp_bbr_default_state.py @@ -11,6 +11,7 @@ from tests.common.utilities import delete_running_config from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.config_reload import config_reload @@ -54,6 +55,7 @@ def add_bbr_config_to_running_config(duthost, status): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) try: @@ -73,6 +75,7 @@ def config_bbr_by_gcu(duthost, status): "value": "{}".format(status) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) try: diff --git a/tests/bgp/test_bgp_dual_asn.py b/tests/bgp/test_bgp_dual_asn.py index c5f6fadd4cf..45b1e1b5a00 100644 --- a/tests/bgp/test_bgp_dual_asn.py +++ b/tests/bgp/test_bgp_dual_asn.py @@ -15,6 +15,7 @@ from tests.common.gu_utils import get_bgp_speaker_runningconfig from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import ( create_checkpoint, delete_checkpoint, @@ -367,6 +368,7 @@ def bgp_peer_range_add_config( } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -402,6 +404,7 @@ def bgp_peer_range_delete_config( {"op": "remove", "path": "/BGP_PEER_RANGE/{}".format(ip_range_name)}, {"op": "remove", "path": "/BGP_PEER_RANGE/{}".format(ipv6_range_name)}, ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/common/gu_utils.py b/tests/common/gu_utils.py index 1d6648e40ac..07435568d5b 100644 --- a/tests/common/gu_utils.py +++ b/tests/common/gu_utils.py @@ -20,6 +20,8 @@ BASE_DIR = os.path.dirname(os.path.realpath(__file__)) FILES_DIR = os.path.join(BASE_DIR, "files") TMP_DIR = '/tmp' +HOST_NAME = "/localhost" +ASIC_PREFIX = "/asic" def generate_tmpfile(duthost): @@ -34,6 +36,36 @@ def delete_tmpfile(duthost, tmpfile): duthost.file(path=tmpfile, state='absent') +def format_json_patch_for_multiasic(duthost, json_data, is_asic_specific=False): + if is_asic_specific: + return json_data + + json_patch = [] + if duthost.is_multi_asic: + num_asic = duthost.facts.get('num_asic') + + for operation in json_data: + path = operation["path"] + if path.startswith(HOST_NAME) and ASIC_PREFIX in path: + json_patch.append(operation) + else: + template = { + "op": operation["op"], + "path": "{}{}".format(HOST_NAME, path) + } + + if operation["op"] in ["add", "replace", "test"]: + template["value"] = operation["value"] + json_patch.append(template.copy()) + for asic_index in range(num_asic): + asic_ns = "{}{}".format(ASIC_PREFIX, asic_index) + template["path"] = "{}{}".format(asic_ns, path) + json_patch.append(template.copy()) + json_data = json_patch + + return json_data + + def apply_patch(duthost, json_data, dest_file): """Run apply-patch on target duthost diff --git a/tests/generic_config_updater/gu_utils.py b/tests/generic_config_updater/gu_utils.py index 6032b26145f..6203adaaaf6 100644 --- a/tests/generic_config_updater/gu_utils.py +++ b/tests/generic_config_updater/gu_utils.py @@ -2,6 +2,7 @@ import logging import json from tests.common.gu_utils import apply_patch, generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic BASE_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -39,6 +40,7 @@ def load_and_apply_json_patch(duthost, file_name, setup): with open(os.path.join(TEMPLATES_DIR, file_name)) as file: json_patch = json.load(file) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) duts_to_apply = [duthost] outputs = [] if setup["is_dualtor"]: diff --git a/tests/generic_config_updater/test_aaa.py b/tests/generic_config_updater/test_aaa.py index 52bdaeffa57..802895ab1ea 100644 --- a/tests/generic_config_updater/test_aaa.py +++ b/tests/generic_config_updater/test_aaa.py @@ -5,6 +5,7 @@ from tests.common.fixtures.tacacs import get_aaa_sub_options_value from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload pytestmark = [ @@ -168,6 +169,7 @@ def aaa_tc1_add_config(duthost): "value": aaa_config } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -206,6 +208,7 @@ def aaa_tc1_replace(duthost): "value": "tacacs+" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -243,6 +246,7 @@ def aaa_tc1_add_duplicate(duthost): "value": "tacacs+" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -269,6 +273,7 @@ def aaa_tc1_remove(duthost): "path": "/AAA" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -313,6 +318,7 @@ def tacacs_global_tc2_add_config(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -352,6 +358,7 @@ def tacacs_global_tc2_invalid_input(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -375,6 +382,7 @@ def tacacs_global_tc2_duplicate_input(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -400,6 +408,7 @@ def tacacs_global_tc2_remove(duthost): "path": "/TACPLUS" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -443,6 +452,7 @@ def tacacs_server_tc3_add_init(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -481,6 +491,7 @@ def tacacs_server_tc3_add_max(duthost): } json_patch.append(patch) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -521,6 +532,7 @@ def tacacs_server_tc3_replace_invalid(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -542,6 +554,7 @@ def tacacs_server_tc3_add_duplicate(duthost): "value": TACACS_SERVER_OPTION } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -566,6 +579,7 @@ def tacacs_server_tc3_remove(duthost): "path": "/TACPLUS_SERVER" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_bgp_prefix.py b/tests/generic_config_updater/test_bgp_prefix.py index 3f40de54ed9..84f26560239 100644 --- a/tests/generic_config_updater/test_bgp_prefix.py +++ b/tests/generic_config_updater/test_bgp_prefix.py @@ -5,6 +5,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_failure, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload pytestmark = [ @@ -115,6 +116,7 @@ def bgp_prefix_tc1_add_config(duthost, community, community_table): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -155,6 +157,7 @@ def bgp_prefix_tc1_xfail(duthost, community_table): "value": prefixes_v4 } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -182,6 +185,7 @@ def bgp_prefix_tc1_replace(duthost, community, community_table): "value": PREFIXES_V4_DUMMY } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -215,6 +219,7 @@ def bgp_prefix_tc1_remove(duthost, community): "path": "/BGP_ALLOWED_PREFIXES" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_bgp_sentinel.py b/tests/generic_config_updater/test_bgp_sentinel.py index be35f1a13b4..bfcb14852c7 100644 --- a/tests/generic_config_updater/test_bgp_sentinel.py +++ b/tests/generic_config_updater/test_bgp_sentinel.py @@ -6,6 +6,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload @@ -129,6 +130,7 @@ def bgp_sentinel_tc1_add_config(duthost, lo_intf_ips): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -168,6 +170,7 @@ def bgp_sentinel_tc1_add_dummy_ip_range(duthost): "value": "{}".format(DUMMY_IP_RANGE_V6) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -201,6 +204,7 @@ def bgp_sentinel_tc1_rm_dummy_ip_range(duthost): "path": "/BGP_SENTINELS/{}/ip_range/1".format(BGPSENTINEL_V6) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -235,6 +239,7 @@ def bgp_sentinel_tc1_replace_src_address(duthost): "value": "{}".format(DUMMY_SRC_ADDRESS_V6) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_bgp_speaker.py b/tests/generic_config_updater/test_bgp_speaker.py index 79b8f7a762f..853e17d3e11 100644 --- a/tests/generic_config_updater/test_bgp_speaker.py +++ b/tests/generic_config_updater/test_bgp_speaker.py @@ -6,6 +6,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import get_bgp_speaker_runningconfig @@ -124,6 +125,7 @@ def bgp_speaker_tc1_add_config(duthost, lo_intf_ips, vlan_intf_ip_ranges): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -163,6 +165,7 @@ def bgp_speaker_tc1_add_dummy_ip_range(duthost): "value": "{}".format(DUMMY_IP_RANGE_V6) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -195,6 +198,7 @@ def bgp_speaker_tc1_rm_dummy_ip_range(duthost): "path": "/BGP_PEER_RANGE/{}/ip_range/1".format(BGPSPEAKER_V6) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -229,6 +233,7 @@ def bgp_speaker_tc1_replace_src_address(duthost): "value": "{}".format(DUMMY_SRC_ADDRESS_V6) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_bgpl.py b/tests/generic_config_updater/test_bgpl.py index b42ad26e662..3d8e164bcd8 100644 --- a/tests/generic_config_updater/test_bgpl.py +++ b/tests/generic_config_updater/test_bgpl.py @@ -7,6 +7,7 @@ from tests.common.helpers.generators import generate_ip_through_default_route from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload pytestmark = [ @@ -113,6 +114,7 @@ def bgpmon_tc1_add_init(duthost, bgpmon_setup_info): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -146,6 +148,7 @@ def bgpmon_tc1_add_duplicate(duthost, bgpmon_setup_info): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -170,6 +173,7 @@ def bgpmon_tc1_admin_change(duthost, bgpmon_setup_info): "value": "down" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -212,6 +216,7 @@ def bgpmon_tc1_ip_change(duthost, bgpmon_setup_info): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -234,6 +239,7 @@ def bgpmon_tc1_remove(duthost): "path": "/BGP_MONITORS" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_cacl.py b/tests/generic_config_updater/test_cacl.py index 6c4e3ec968d..f62953d576e 100644 --- a/tests/generic_config_updater/test_cacl.py +++ b/tests/generic_config_updater/test_cacl.py @@ -6,6 +6,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_res_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.utilities import wait_until @@ -165,6 +166,7 @@ def cacl_tc1_add_new_table(duthost, protocol): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -200,6 +202,7 @@ def cacl_tc1_add_duplicate_table(duthost, protocol): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -259,6 +262,7 @@ def cacl_tc1_replace_table_variable(duthost, protocol): } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -305,6 +309,7 @@ def cacl_tc1_add_invalid_table(duthost, protocol): tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) @@ -322,6 +327,7 @@ def cacl_tc1_remove_unexisted_table(duthost): "path": "/ACL_RULE/SSH_ONLY_UNEXISTED" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -345,6 +351,7 @@ def cacl_tc1_remove_table(duthost, protocol): "path": "/ACL_TABLE/{}".format(table_name) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -406,6 +413,7 @@ def cacl_tc2_add_init_rule(duthost, protocol): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -463,6 +471,7 @@ def cacl_tc2_add_duplicate_rule(duthost, protocol): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -502,6 +511,7 @@ def cacl_tc2_replace_rule(duthost, protocol): "value": "8.8.8.8/32" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -544,6 +554,7 @@ def cacl_tc2_add_rule_to_unexisted_table(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -572,6 +583,7 @@ def cacl_tc2_remove_table_before_rule(duthost, protocol): "path": "/ACL_TABLE/{}".format(table) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -600,6 +612,7 @@ def cacl_tc2_remove_unexist_rule(duthost, protocol): "path": "/ACL_RULE/{}|TEST_DROP2".format(table) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) try: @@ -618,6 +631,7 @@ def cacl_tc2_remove_rule(duthost): "path": "/ACL_RULE" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -658,6 +672,7 @@ def cacl_external_client_add_new_table(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_dhcp_relay.py b/tests/generic_config_updater/test_dhcp_relay.py index 9dca17b1cb4..32d0fd5f2e9 100644 --- a/tests/generic_config_updater/test_dhcp_relay.py +++ b/tests/generic_config_updater/test_dhcp_relay.py @@ -7,6 +7,7 @@ utils_vlan_intfs_dict_add, utils_create_test_vlans # noqa F401 from tests.common.gu_utils import apply_patch, expect_op_success, expect_res_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload, rollback pytestmark = [ @@ -257,6 +258,7 @@ def test_dhcp_relay_tc1_rm_nonexist(rand_selected_dut, vlan_intfs_list): "op": "remove", "path": "/VLAN/Vlan" + str(vlan_intfs_list[0]) + "/dhcp_servers/5" }] + dhcp_rm_nonexist_json = format_json_patch_for_multiasic(duthost=rand_selected_dut, json_data=dhcp_rm_nonexist_json) tmpfile = generate_tmpfile(rand_selected_dut) logger.info("tmpfile {}".format(tmpfile)) @@ -277,6 +279,7 @@ def test_dhcp_relay_tc2_add_exist(rand_selected_dut, vlan_intfs_list): "path": "/VLAN/Vlan" + str(vlan_intfs_list[0]) + "/dhcp_servers/0", "value": "192.0." + str(vlan_intfs_list[0]) + ".1" }] + dhcp_add_exist_json = format_json_patch_for_multiasic(duthost=rand_selected_dut, json_data=dhcp_add_exist_json) tmpfile = generate_tmpfile(rand_selected_dut) logger.info("tmpfile {}".format(tmpfile)) @@ -316,6 +319,7 @@ def test_dhcp_relay_tc3_add_and_rm(rand_selected_dut, vlan_intfs_list): "path": "/VLAN/Vlan" + str(vlan_intfs_list[0]) + "/dhcp_servers/4", "value": "192.0." + str(vlan_intfs_list[0]) + ".5" }] + dhcp_add_rm_json = format_json_patch_for_multiasic(duthost=rand_selected_dut, json_data=dhcp_add_rm_json) tmpfile = generate_tmpfile(rand_selected_dut) logger.info("tmpfile {}".format(tmpfile)) @@ -360,6 +364,7 @@ def test_dhcp_relay_tc4_replace(rand_selected_dut, vlan_intfs_list): "path": "/VLAN/Vlan" + str(vlan_intfs_list[0]) + "/dhcp_servers/0", "value": "192.0." + str(vlan_intfs_list[0]) + ".8" }] + dhcp_replace_json = format_json_patch_for_multiasic(duthost=rand_selected_dut, json_data=dhcp_replace_json) tmpfile = generate_tmpfile(rand_selected_dut) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_ecn_config_update.py b/tests/generic_config_updater/test_ecn_config_update.py index a3459253981..bdb2dbb56d5 100644 --- a/tests/generic_config_updater/test_ecn_config_update.py +++ b/tests/generic_config_updater/test_ecn_config_update.py @@ -7,6 +7,7 @@ from tests.common.helpers.dut_utils import verify_orchagent_running_or_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import is_valid_platform_and_version @@ -107,6 +108,7 @@ def test_ecn_config_updates(duthost, ensure_dut_readiness, configdb_field, opera "path": "/WRED_PROFILE/AZURE_LOSSLESS/{}".format(field), "value": "{}".format(value)}) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) if is_valid_platform_and_version(duthost, "WRED_PROFILE", "ECN tuning", operation): diff --git a/tests/generic_config_updater/test_eth_interface.py b/tests/generic_config_updater/test_eth_interface.py index 7d63aaf8a95..c8a6a5a1525 100644 --- a/tests/generic_config_updater/test_eth_interface.py +++ b/tests/generic_config_updater/test_eth_interface.py @@ -7,6 +7,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.utilities import wait_until @@ -146,6 +147,7 @@ def test_remove_lanes(duthosts, rand_one_dut_hostname, ensure_dut_readiness): "path": "/PORT/Ethernet0/lanes" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -173,6 +175,7 @@ def test_replace_lanes(duthosts, rand_one_dut_hostname, ensure_dut_readiness): "value": "{}".format(update_lanes) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -198,6 +201,7 @@ def test_replace_mtu(duthosts, rand_one_dut_hostname, ensure_dut_readiness): "value": "{}".format(target_mtu) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -222,6 +226,7 @@ def test_toggle_pfc_asym(duthosts, rand_one_dut_hostname, ensure_dut_readiness, "value": "{}".format(pfc_asym) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -247,6 +252,7 @@ def test_replace_fec(duthosts, rand_one_dut_hostname, ensure_dut_readiness, fec) "value": "{}".format(fec) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -277,6 +283,7 @@ def test_update_invalid_index(duthosts, rand_one_dut_hostname, ensure_dut_readin "value": "abc1" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -315,6 +322,7 @@ def test_update_valid_index(duthosts, rand_one_dut_hostname, ensure_dut_readines "value": "{}".format(list(interfaces.values())[0]) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -337,6 +345,7 @@ def test_update_speed(duthosts, rand_one_dut_hostname, ensure_dut_readiness): "value": "{}".format(speed) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -364,6 +373,7 @@ def test_update_description(duthosts, rand_one_dut_hostname, ensure_dut_readines "value": "Updated description" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -385,6 +395,7 @@ def test_eth_interface_admin_change(duthosts, rand_one_dut_hostname, admin_statu "value": "{}".format(admin_status) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_incremental_qos.py b/tests/generic_config_updater/test_incremental_qos.py index 7856320fe53..0384793e005 100644 --- a/tests/generic_config_updater/test_incremental_qos.py +++ b/tests/generic_config_updater/test_incremental_qos.py @@ -9,6 +9,7 @@ from tests.common.gu_utils import apply_patch, expect_op_success, \ expect_op_failure # noqa F401 from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import is_valid_platform_and_version from tests.common.mellanox_data import is_mellanox_device @@ -236,6 +237,7 @@ def test_incremental_qos_config_updates(duthost, tbinfo, ensure_dut_readiness, c "path": "/BUFFER_POOL/{}".format(configdb_field), "value": "{}".format(value) }] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) diff --git a/tests/generic_config_updater/test_ip_bgp.py b/tests/generic_config_updater/test_ip_bgp.py index 70b9f318b67..9e3ec8b1c44 100644 --- a/tests/generic_config_updater/test_ip_bgp.py +++ b/tests/generic_config_updater/test_ip_bgp.py @@ -6,6 +6,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload logger = logging.getLogger(__name__) @@ -76,6 +77,7 @@ def add_deleted_ip_neighbor(duthost, ip_version=6): "value": ip_neighbor_config } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -100,6 +102,7 @@ def add_duplicate_ip_neighbor(duthost, ip_version=6): "value": ip_neighbor_config } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -132,6 +135,7 @@ def invalid_ip_neighbor(duthost, ip_version=6): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -157,6 +161,7 @@ def ip_neighbor_admin_change(duthost, ip_version=6): "value": "down" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -183,6 +188,7 @@ def delete_ip_neighbor(duthost, ip_version=6): "path": "/BGP_NEIGHBOR/{}".format(ip_neighbor_address) } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_kubernetes_config.py b/tests/generic_config_updater/test_kubernetes_config.py index 51d4234141d..a36dfeba5ab 100644 --- a/tests/generic_config_updater/test_kubernetes_config.py +++ b/tests/generic_config_updater/test_kubernetes_config.py @@ -5,6 +5,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload @@ -265,6 +266,7 @@ def k8s_config_update(duthost, test_data): for num, (json_patch, target_config, target_table, expected_result) in enumerate(test_data): tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) diff --git a/tests/generic_config_updater/test_lo_interface.py b/tests/generic_config_updater/test_lo_interface.py index 2b04831e87f..04e56711132 100644 --- a/tests/generic_config_updater/test_lo_interface.py +++ b/tests/generic_config_updater/test_lo_interface.py @@ -5,6 +5,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import create_path, check_show_ip_intf, check_vrf_route_for_intf @@ -111,6 +112,7 @@ def lo_interface_tc1_add_init(duthost, lo_intf): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -156,6 +158,7 @@ def lo_interface_tc1_add_duplicate(duthost, lo_intf): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -205,6 +208,7 @@ def lo_interface_tc1_xfail(duthost, lo_intf): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -258,6 +262,7 @@ def lo_interface_tc1_replace(duthost, lo_intf): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -283,6 +288,7 @@ def lo_interface_tc1_remove(duthost, lo_intf): "path": "/LOOPBACK_INTERFACE" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -325,6 +331,7 @@ def setup_vrf_config(duthost, lo_intf): "value": "Vrf_01" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -377,6 +384,7 @@ def test_lo_interface_tc2_vrf_change(rand_selected_dut, lo_intf): "value": "Vrf_02" } ] + json_patch = format_json_patch_for_multiasic(duthost=rand_selected_dut, json_data=json_patch) tmpfile = generate_tmpfile(rand_selected_dut) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_mgmt_interface.py b/tests/generic_config_updater/test_mgmt_interface.py index e5d9a220a55..cc31f4127b0 100644 --- a/tests/generic_config_updater/test_mgmt_interface.py +++ b/tests/generic_config_updater/test_mgmt_interface.py @@ -5,6 +5,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, create_path from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.utilities import wait_for_file_changed, FORCED_MGMT_ROUTE_PRIORITY @@ -56,6 +57,7 @@ def update_forced_mgmt_route(duthost, interface_address, interface_key, routes): else: json_patch[0]["op"] = "add" + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) diff --git a/tests/generic_config_updater/test_mmu_dynamic_threshold_config_update.py b/tests/generic_config_updater/test_mmu_dynamic_threshold_config_update.py index 0d80da1ed65..d9d38397f6a 100644 --- a/tests/generic_config_updater/test_mmu_dynamic_threshold_config_update.py +++ b/tests/generic_config_updater/test_mmu_dynamic_threshold_config_update.py @@ -7,6 +7,7 @@ from tests.common.helpers.dut_utils import verify_orchagent_running_or_assert from tests.common.gu_utils import apply_patch, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload pytestmark = [ @@ -122,6 +123,7 @@ def test_dynamic_th_config_updates(duthost, ensure_dut_readiness, operation, ski } json_patch.append(individual_patch) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {} created for json patch of updating dynamic threshold and operation: {}" .format(tmpfile, operation)) diff --git a/tests/generic_config_updater/test_monitor_config.py b/tests/generic_config_updater/test_monitor_config.py index 860a5676558..a184fe52d70 100644 --- a/tests/generic_config_updater/test_monitor_config.py +++ b/tests/generic_config_updater/test_monitor_config.py @@ -4,6 +4,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_res_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback, rollback_or_reload pytestmark = [ @@ -194,6 +195,7 @@ def monitor_config_add_config(duthost, get_valid_acl_ports): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_ntp.py b/tests/generic_config_updater/test_ntp.py index c54ef5a699e..9f8771ec35a 100644 --- a/tests/generic_config_updater/test_ntp.py +++ b/tests/generic_config_updater/test_ntp.py @@ -6,6 +6,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_failure, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.utilities import wait_until @@ -115,6 +116,7 @@ def ntp_server_tc1_add_config(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) json_patch_bc = [ { @@ -125,6 +127,7 @@ def ntp_server_tc1_add_config(duthost): } } ] + json_patch_bc = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch_bc) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -169,6 +172,7 @@ def ntp_server_tc1_xfail(duthost): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -199,6 +203,7 @@ def ntp_server_tc1_replace(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) json_patch_bc = [ { @@ -211,6 +216,7 @@ def ntp_server_tc1_replace(duthost): "value": {} } ] + json_patch_bc = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch_bc) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -245,6 +251,7 @@ def ntp_server_tc1_remove(duthost): "path": "/NTP_SERVER" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_pfcwd_interval.py b/tests/generic_config_updater/test_pfcwd_interval.py index fd6d8d16ec6..0a7e095aaef 100644 --- a/tests/generic_config_updater/test_pfcwd_interval.py +++ b/tests/generic_config_updater/test_pfcwd_interval.py @@ -6,6 +6,7 @@ from tests.common.utilities import wait_until from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import is_valid_platform_and_version @@ -164,6 +165,7 @@ def test_pfcwd_interval_config_updates(duthost, ensure_dut_readiness, oper, "path": "/PFC_WD/GLOBAL/POLL_INTERVAL", "value": "{}".format(value) }] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) diff --git a/tests/generic_config_updater/test_pfcwd_status.py b/tests/generic_config_updater/test_pfcwd_status.py index 76f5828d6b5..c522c800ef4 100644 --- a/tests/generic_config_updater/test_pfcwd_status.py +++ b/tests/generic_config_updater/test_pfcwd_status.py @@ -9,6 +9,7 @@ from tests.common.helpers.dut_utils import verify_orchagent_running_or_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import is_valid_platform_and_version @@ -213,6 +214,7 @@ def test_stop_pfcwd(duthost, extract_pfcwd_config, ensure_dut_readiness, port): exp_str = interface break + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: tmpfile = generate_tmpfile(duthost) output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) @@ -256,6 +258,7 @@ def test_start_pfcwd(duthost, extract_pfcwd_config, ensure_dut_readiness, stop_p exp_str = interface break + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: tmpfile = generate_tmpfile(duthost) output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) diff --git a/tests/generic_config_updater/test_pg_headroom_update.py b/tests/generic_config_updater/test_pg_headroom_update.py index 16a0b2e6f0c..d72ab4b1fbc 100644 --- a/tests/generic_config_updater/test_pg_headroom_update.py +++ b/tests/generic_config_updater/test_pg_headroom_update.py @@ -7,6 +7,7 @@ from tests.common.helpers.dut_utils import verify_orchagent_running_or_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import is_valid_platform_and_version, get_asic_name @@ -103,6 +104,7 @@ def test_pg_headroom_update(duthost, ensure_dut_readiness, operation, skip_when_ "path": "/BUFFER_PROFILE/{}/xoff".format(profile_name), "value": "{}".format(value)}) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) try: output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) if is_valid_platform_and_version(duthost, "BUFFER_PROFILE", "PG headroom modification", operation): diff --git a/tests/generic_config_updater/test_portchannel_interface.py b/tests/generic_config_updater/test_portchannel_interface.py index f7f8e0b29c4..a81021fc744 100644 --- a/tests/generic_config_updater/test_portchannel_interface.py +++ b/tests/generic_config_updater/test_portchannel_interface.py @@ -6,6 +6,7 @@ from tests.common.helpers.assertions import pytest_require from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import create_path, check_show_ip_intf @@ -99,6 +100,7 @@ def portchannel_interface_tc1_add_duplicate(duthost, portchannel_table): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -143,6 +145,7 @@ def portchannel_interface_tc1_xfail(duthost): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -185,6 +188,7 @@ def portchannel_interface_tc1_add_and_rm(duthost, portchannel_table): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -263,6 +267,7 @@ def portchannel_interface_tc2_replace(duthost): } json_patch.append(patch) + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -287,6 +292,7 @@ def portchannel_interface_tc2_incremental(duthost): "value": "Description for PortChannel101" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_syslog.py b/tests/generic_config_updater/test_syslog.py index bcf7d54b2f2..565a1404ef7 100644 --- a/tests/generic_config_updater/test_syslog.py +++ b/tests/generic_config_updater/test_syslog.py @@ -4,6 +4,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_res_success, expect_op_failure, expect_op_success from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload pytestmark = [ @@ -125,6 +126,7 @@ def syslog_server_tc1_add_init(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -162,6 +164,7 @@ def syslog_server_tc1_add_duplicate(duthost): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -205,6 +208,7 @@ def syslog_server_tc1_xfail(duthost): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -245,6 +249,7 @@ def syslog_server_tc1_replace(duthost): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -276,6 +281,7 @@ def syslog_server_tc1_remove(duthost): "path": "/SYSLOG_SERVER" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) diff --git a/tests/generic_config_updater/test_vlan_interface.py b/tests/generic_config_updater/test_vlan_interface.py index b0f697534b4..1b4372c308f 100644 --- a/tests/generic_config_updater/test_vlan_interface.py +++ b/tests/generic_config_updater/test_vlan_interface.py @@ -7,6 +7,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.common.gu_utils import apply_patch, expect_op_success, expect_op_failure from tests.common.gu_utils import generate_tmpfile, delete_tmpfile +from tests.common.gu_utils import format_json_patch_for_multiasic from tests.common.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload from tests.common.gu_utils import create_path, check_show_ip_intf @@ -148,6 +149,7 @@ def vlan_interface_tc1_add_duplicate(duthost, vlan_info): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) logger.info("json patch {}".format(json_patch)) @@ -233,6 +235,7 @@ def vlan_interface_tc1_xfail(duthost, vlan_info): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -304,6 +307,7 @@ def vlan_interface_tc1_add_new(duthost): } } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -362,6 +366,7 @@ def vlan_interface_tc1_replace(duthost, vlan_info): "value": {} } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -387,6 +392,7 @@ def vlan_interface_tc1_remove(duthost, vlan_info): "path": "/VLAN_INTERFACE" } ] + json_patch = format_json_patch_for_multiasic(duthost=duthost, json_data=json_patch) tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -430,6 +436,7 @@ def test_vlan_interface_tc2_incremental_change(rand_selected_dut): "value": "incremental test for Vlan{}".format(EXIST_VLAN_ID) } ] + json_patch = format_json_patch_for_multiasic(duthost=rand_selected_dut, json_data=json_patch) tmpfile = generate_tmpfile(rand_selected_dut) logger.info("tmpfile {}".format(tmpfile)) From e11e6dc057d868a51713cef7fee66fea3c470a8c Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Fri, 15 Nov 2024 10:35:28 +1100 Subject: [PATCH 169/221] fix flaky tests/autorestart/test_container_autorestart.py (#15526) Description of PR Summary: Fixes # (issue) Fixes 30114172 Approach What is the motivation for this PR? Increases the threshold timeout for container check for T2 since the BGP neighbor originally was setup to be 360 for T0. However the amount of BGP neighbor is much more comparing to T0. Upons investigation, this test case were flaky because our bgp were still in connecting status. Signed-off-by: Austin Pham --- tests/autorestart/test_container_autorestart.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/autorestart/test_container_autorestart.py b/tests/autorestart/test_container_autorestart.py index 591b2e8a75b..d7a983e35da 100644 --- a/tests/autorestart/test_container_autorestart.py +++ b/tests/autorestart/test_container_autorestart.py @@ -27,6 +27,7 @@ DHCP_SERVER = "dhcp_server" POST_CHECK_INTERVAL_SECS = 1 POST_CHECK_THRESHOLD_SECS = 360 +POST_CHECK_THRESHOLD_SECS_T2 = 600 PROGRAM_STATUS = "RUNNING" @@ -459,13 +460,16 @@ def postcheck_critical_processes_status(duthost, feature_autorestart_states, up_ if is_hiting_start_limit(duthost, feature_name): clear_failed_flag_and_restart(duthost, feature_name, feature_name) + post_check_threshold = POST_CHECK_THRESHOLD_SECS_T2 if duthost.get_facts().get("modular_chassis") \ + else POST_CHECK_THRESHOLD_SECS + critical_proceses = wait_until( - POST_CHECK_THRESHOLD_SECS, POST_CHECK_INTERVAL_SECS, 0, + post_check_threshold, POST_CHECK_INTERVAL_SECS, 0, check_all_critical_processes_status, duthost ) bgp_check = wait_until( - POST_CHECK_THRESHOLD_SECS, POST_CHECK_INTERVAL_SECS, 0, + post_check_threshold, POST_CHECK_INTERVAL_SECS, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established" ) From 5d985b9f4e4108d98cee7986394c2e78ad4511a2 Mon Sep 17 00:00:00 2001 From: vkjammala-arista <152394203+vkjammala-arista@users.noreply.github.com> Date: Fri, 15 Nov 2024 06:37:57 +0530 Subject: [PATCH 170/221] [dualtor] Fix snmp/* tests failure on fixture teardown (#15529) Approach What is the motivation for this PR? #15359 has introduced a "yield" statement inside the for loop of duthosts which is causing fixture teardown to fail with Failed: fixture function has more than one 'yield' message. How did you do it? Move "yield" statement out of this for loop of duthosts and do config rollback in a seperate for loop of duthosts. How did you verify/test it? Ran tests under snmp folder and tests are passing on Arista-7260CX3-D108C8 platform. Any platform specific information? --- tests/snmp/conftest.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/snmp/conftest.py b/tests/snmp/conftest.py index 15d47cebd3c..88db6acec52 100644 --- a/tests/snmp/conftest.py +++ b/tests/snmp/conftest.py @@ -68,14 +68,15 @@ def setup_check_snmp_ready(duthosts, localhost): if 'LOCATION' not in snmp_location_redis_vals: duthost.shell(f'sudo config snmp location add {yaml_snmp_location}') # set snmp cli - yield + yield + for duthost in duthosts: # rollback configuration rollback(duthost, SETUP_ENV_CP) - # remove snmp files downloaded - local_command = "find ./snmp/ -type f -name 'snmp.yml' -exec rm -f {} +" - localhost.shell(local_command) + # remove snmp files downloaded + local_command = "find ./snmp/ -type f -name 'snmp.yml' -exec rm -f {} +" + localhost.shell(local_command) def extract_redis_keys(item): From e5df7c9d2a506b77cd0786ecc795fd79982d5bf6 Mon Sep 17 00:00:00 2001 From: AkeelAli <701916+AkeelAli@users.noreply.github.com> Date: Thu, 14 Nov 2024 20:20:49 -0500 Subject: [PATCH 171/221] Disable proxy for POST requests to PTF (#15067) What is the motivation for this PR? Tests that make HTTP POST requests to PTFIP:exabgpPort for bgp updates were failing when proxy variables were set in the environment (gateway timeout 504). Workaround had been to unset these variables before starting the tests. This PR fixes the test scripts such that they don't use the env proxy when making such HTTP requests. How did you do it? Explicitly set the proxies to None when making post requests to ignore the corresponding environment variables. Precedent for this change exists: https://github.com/sonic-net/sonic-mgmt/blob/master/ansible/library/announce_routes.py#L163 How did you verify/test it? Following tests passed with the change despite the presence of proxy variables in the sonic-mgmt container environment (tested on DUT Cisco 8101): test_bgp_update_timer.py test_bgp_sentinel.py test_bgp_bbr.py test_bgp_speaker.py test_route_flap.py test_bgp_dual_asn.py --- tests/bgp/bgp_helpers.py | 2 +- tests/bgp/test_bgp_bbr.py | 2 +- tests/bgp/test_bgp_sentinel.py | 2 +- tests/bgp/test_bgp_speaker.py | 2 +- tests/bgp/test_bgp_suppress_fib.py | 2 +- tests/common/helpers/bgp.py | 6 +++--- tests/route/test_route_bgp_ecmp.py | 2 +- tests/route/test_route_flap.py | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/bgp/bgp_helpers.py b/tests/bgp/bgp_helpers.py index 2eb7e391f61..9ff615e4666 100644 --- a/tests/bgp/bgp_helpers.py +++ b/tests/bgp/bgp_helpers.py @@ -291,7 +291,7 @@ def update_routes(action, ptfip, port, route): url = 'http://%s:%d' % (ptfip, port) data = {'commands': msg} logging.info('Post url={}, data={}'.format(url, data)) - r = requests.post(url, data=data) + r = requests.post(url, data=data, proxies={"http": None, "https": None}) assert r.status_code == 200 diff --git a/tests/bgp/test_bgp_bbr.py b/tests/bgp/test_bgp_bbr.py index a71beb2dbe1..7fbbf91b5bb 100644 --- a/tests/bgp/test_bgp_bbr.py +++ b/tests/bgp/test_bgp_bbr.py @@ -274,7 +274,7 @@ def update_routes(action, ptfip, port, route): return url = 'http://%s:%d' % (ptfip, port) data = {'commands': msg} - r = requests.post(url, data=data) + r = requests.post(url, data=data, proxies={"http": None, "https": None}) assert r.status_code == 200 diff --git a/tests/bgp/test_bgp_sentinel.py b/tests/bgp/test_bgp_sentinel.py index 315bb3fb762..47d5500ca32 100644 --- a/tests/bgp/test_bgp_sentinel.py +++ b/tests/bgp/test_bgp_sentinel.py @@ -321,7 +321,7 @@ def change_route(operation, ptfip, neighbor, route, nexthop, port, community): url = "http://%s:%d" % (ptfip, port) data = {"command": "neighbor %s %s route %s next-hop %s local-preference 10000 community [%s]" % (neighbor, operation, route, nexthop, community)} - r = requests.post(url, data=data) + r = requests.post(url, data=data, proxies={"http": None, "https": None}) assert r.status_code == 200 diff --git a/tests/bgp/test_bgp_speaker.py b/tests/bgp/test_bgp_speaker.py index 28c6e26b1db..bd556a23c06 100644 --- a/tests/bgp/test_bgp_speaker.py +++ b/tests/bgp/test_bgp_speaker.py @@ -58,7 +58,7 @@ def withdraw_route(ptfip, neighbor, route, nexthop, port): def change_route(operation, ptfip, neighbor, route, nexthop, port): url = "http://%s:%d" % (ptfip, port) data = {"command": "neighbor %s %s route %s next-hop %s" % (neighbor, operation, route, nexthop)} - r = requests.post(url, data=data) + r = requests.post(url, data=data, proxies={"http": None, "https": None}) assert r.status_code == 200 diff --git a/tests/bgp/test_bgp_suppress_fib.py b/tests/bgp/test_bgp_suppress_fib.py index ea91f4ea461..4273e62517a 100644 --- a/tests/bgp/test_bgp_suppress_fib.py +++ b/tests/bgp/test_bgp_suppress_fib.py @@ -341,7 +341,7 @@ def install_route_from_exabgp(operation, ptfip, route_list, port): data = {"command": command} logger.info("url: {}".format(url)) logger.info("command: {}".format(data)) - r = requests.post(url, data=data, timeout=90) + r = requests.post(url, data=data, timeout=90, proxies={"http": None, "https": None}) assert r.status_code == 200 diff --git a/tests/common/helpers/bgp.py b/tests/common/helpers/bgp.py index 932fc9a11e9..4f14b1d3411 100644 --- a/tests/common/helpers/bgp.py +++ b/tests/common/helpers/bgp.py @@ -143,7 +143,7 @@ def teardown_session(self): msg = msg.format(self.peer_ip) logging.debug("teardown session: %s", msg) url = "http://%s:%d" % (self.ptfip, self.port) - resp = requests.post(url, data={"commands": msg}) + resp = requests.post(url, data={"commands": msg}, proxies={"http": None, "https": None}) logging.debug("teardown session return: %s" % resp) assert resp.status_code == 200 @@ -162,7 +162,7 @@ def announce_route(self, route): msg = msg.format(**route) logging.debug("announce route: %s", msg) url = "http://%s:%d" % (self.ptfip, self.port) - resp = requests.post(url, data={"commands": msg}) + resp = requests.post(url, data={"commands": msg}, proxies={"http": None, "https": None}) logging.debug("announce return: %s", resp) assert resp.status_code == 200 @@ -174,6 +174,6 @@ def withdraw_route(self, route): msg = msg.format(**route) logging.debug("withdraw route: %s", msg) url = "http://%s:%d" % (self.ptfip, self.port) - resp = requests.post(url, data={"commands": msg}) + resp = requests.post(url, data={"commands": msg}, proxies={"http": None, "https": None}) logging.debug("withdraw return: %s", resp) assert resp.status_code == 200 diff --git a/tests/route/test_route_bgp_ecmp.py b/tests/route/test_route_bgp_ecmp.py index 4b18b61aefe..aaa23a26a98 100644 --- a/tests/route/test_route_bgp_ecmp.py +++ b/tests/route/test_route_bgp_ecmp.py @@ -34,7 +34,7 @@ def change_route(operation, ptfip, route, nexthop, port, aspath): url = "http://%s:%d" % (ptfip, port) data = { "command": "%s route %s next-hop %s as-path [ %s ]" % (operation, route, nexthop, aspath)} - r = requests.post(url, data=data, timeout=30) + r = requests.post(url, data=data, timeout=30, proxies={"http": None, "https": None}) if r.status_code != 200: raise Exception( "Change routes failed: url={}, data={}, r.status_code={}, r.reason={}, r.headers={}, r.text={}".format( diff --git a/tests/route/test_route_flap.py b/tests/route/test_route_flap.py index 14b61b9f57f..b809ecf845c 100644 --- a/tests/route/test_route_flap.py +++ b/tests/route/test_route_flap.py @@ -77,7 +77,7 @@ def change_route(operation, ptfip, route, nexthop, port, aspath): url = "http://%s:%d" % (ptfip, port) data = { "command": "%s route %s next-hop %s as-path [ %s ]" % (operation, route, nexthop, aspath)} - r = requests.post(url, data=data) + r = requests.post(url, data=data, proxies={"http": None, "https": None}) assert r.status_code == 200 From ba00958b6df73718ffb4919a0d1f0b4f96544fdc Mon Sep 17 00:00:00 2001 From: Anant <127479400+AnantKishorSharma@users.noreply.github.com> Date: Fri, 15 Nov 2024 06:52:05 +0530 Subject: [PATCH 172/221] Skipping test_static_route on 8122 (#15272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What is the motivation for this PR? All 3 tests in test_static_route are failing on 8122. Tests are failing because “show flowcnt-route stats“ does not show the 1 test pkt that the test has sent. “show flowcnt-route stats“ does not show the test pkt because counter config itself failed. Counter config failed because FLOW_COUNTER_CAPABILITY was enabled recently on ASIC/SDK side for 8122 but 'enable_forwarding_route_counter' is not enabled on SONiC/asic_cfg.json on 8122. 'enable_forwarding_route_counter' is not enabled on SONiC/asic_cfg.json on 8122 because of scale limits (cannot scale more than 50k with the current LPM profile). As the feature is not enabled for this platform, need to skip this testcase How did you do it? Added a skip condition for test_static_route for 8122 platform Type of change
 -Test modification Back port request
 -202311 -202405 How did you verify/test it? Ran test_static_router.py on 8122 and verified it was skipped. --- .../common/plugins/conditional_mark/tests_mark_conditions.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 14f6b68bc0c..72121f410e1 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1652,11 +1652,12 @@ route/test_route_perf.py: route/test_static_route.py: skip: - reason: "Test not supported for 201911 images or older. Does not apply to standalone topos." + reason: "Test not supported for 201911 images or older. Does not apply to standalone topos. Not supported on cisco-8122 platform" conditions_logical_operator: OR conditions: - "release in ['201811', '201911']" - "'standalone' in topo_name" + - "platform in ['x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" route/test_static_route.py::test_static_route_ecmp_ipv6: # This test case may fail due to a known issue https://github.com/sonic-net/sonic-buildimage/issues/4930. From 1e86c382262213b8285a749ef2a417a342e24b02 Mon Sep 17 00:00:00 2001 From: Zhaohui Sun <94606222+ZhaohuiS@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:24:27 +0800 Subject: [PATCH 173/221] Skip srv6/test_srv6_basic_sanity.py for non cisco vs topologies (#15564) What is the motivation for this PR? PR introduced new srv6 script, it failed on other topologies, skip it for non cisco vs topologies. #13785 How did you do it? skip it for non cisco vs topologies. How did you verify/test it? Run srv6/test_srv6_basic_sanity.py on t0 testbed. Signed-off-by: Zhaohui Sun --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 72121f410e1..315189c4ed1 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1775,6 +1775,15 @@ span/test_port_mirroring.py: conditions: - "https://github.com/sonic-net/sonic-mgmt/issues/9647 and 'dualtor' in topo_name and asic_type in ['mellanox']" +####################################### +##### srv6 ##### +####################################### +srv6/test_srv6_basic_sanity.py: + skip: + reason: "It's a new test case, skip it for other topologies except cisco vs nodes." + conditions: + - topo_name not in ["ciscovs-7nodes", "ciscovs-5nodes"] + ####################################### ##### ssh ##### ####################################### From 70ef7edc5ab8e57c9f294440f597769dea4fd1b5 Mon Sep 17 00:00:00 2001 From: Longxiang Lyu <35479537+lolyu@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:20:59 +0800 Subject: [PATCH 174/221] [dualtor-io] Support using fix source IP for upstream packets (#15554) What is the motivation for this PR? Let's make the packets for each server belongs to same TCP flow, SONiC will use the same route to forward it. So any route change will forward/drop all the packets from the same server. How did you do it? Use fixed IP to generate packets for a single server. Signed-off-by: Longxiang --- tests/common/dualtor/data_plane_utils.py | 9 +++++---- tests/common/dualtor/dual_tor_io.py | 15 ++++++++++++--- tests/dualtor_io/test_tor_bgp_failure.py | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/common/dualtor/data_plane_utils.py b/tests/common/dualtor/data_plane_utils.py index febaa97d841..1f7b00371b4 100644 --- a/tests/common/dualtor/data_plane_utils.py +++ b/tests/common/dualtor/data_plane_utils.py @@ -161,14 +161,15 @@ def verify_and_report(tor_IO, verify, delay, allowed_disruption, def run_test( duthosts, activehost, ptfhost, ptfadapter, vmhost, action, tbinfo, tor_vlan_port, send_interval, traffic_direction, - stop_after, cable_type=CableType.active_standby # noqa F811 + stop_after, cable_type=CableType.active_standby, random_dst=None # noqa F811 ): io_ready = threading.Event() peerhost = get_peerhost(duthosts, activehost) tor_IO = DualTorIO( activehost, peerhost, ptfhost, ptfadapter, vmhost, tbinfo, - io_ready, tor_vlan_port=tor_vlan_port, send_interval=send_interval, cable_type=cable_type + io_ready, tor_vlan_port=tor_vlan_port, send_interval=send_interval, cable_type=cable_type, + random_dst=random_dst ) tor_IO.generate_traffic(traffic_direction) @@ -330,7 +331,7 @@ def send_server_to_t1_with_action(duthosts, ptfhost, ptfadapter, tbinfo, def server_to_t1_io_test(activehost, tor_vlan_port=None, delay=0, allowed_disruption=0, action=None, verify=False, send_interval=0.01, - stop_after=None): + stop_after=None, random_dst=None): """ Helper method for `send_server_to_t1_with_action`. Starts sender and sniffer before performing the action on the tor host. @@ -357,7 +358,7 @@ def server_to_t1_io_test(activehost, tor_vlan_port=None, tor_IO = run_test(duthosts, activehost, ptfhost, ptfadapter, vmhost, action, tbinfo, tor_vlan_port, send_interval, traffic_direction="server_to_t1", stop_after=stop_after, - cable_type=cable_type) + cable_type=cable_type, random_dst=random_dst) # If a delay is allowed but no numebr of allowed disruptions # is specified, default to 1 allowed disruption diff --git a/tests/common/dualtor/dual_tor_io.py b/tests/common/dualtor/dual_tor_io.py index 5df1e7b99ea..978c53aa8a8 100644 --- a/tests/common/dualtor/dual_tor_io.py +++ b/tests/common/dualtor/dual_tor_io.py @@ -38,7 +38,8 @@ class DualTorIO: """Class to conduct IO over ports in `active-standby` mode.""" def __init__(self, activehost, standbyhost, ptfhost, ptfadapter, vmhost, tbinfo, - io_ready, tor_vlan_port=None, send_interval=0.01, cable_type=CableType.active_standby): + io_ready, tor_vlan_port=None, send_interval=0.01, cable_type=CableType.active_standby, + random_dst=None): self.tor_pc_intf = None self.tor_vlan_intf = tor_vlan_port self.duthost = activehost @@ -54,6 +55,12 @@ def __init__(self, activehost, standbyhost, ptfhost, ptfadapter, vmhost, tbinfo, self.cable_type = cable_type + if random_dst is None: + # if random_dst is not set, default to true for active standby dualtor. + self.random_dst = (self.cable_type == CableType.active_standby) + else: + self.random_dst = random_dst + self.dataplane = self.ptfadapter.dataplane self.dataplane.flush() self.test_results = dict() @@ -390,8 +397,10 @@ def generate_upstream_traffic(self, src='server'): packet = tcp_tx_packet_orig.copy() packet[scapyall.Ether].src = eth_src packet[scapyall.IP].src = server_ip - packet[scapyall.IP].dst = dst_ips[vlan_intf] \ - if self.cable_type == CableType.active_active else self.random_host_ip() + if self.random_dst: + packet[scapyall.IP].dst = self.random_host_ip() + else: + packet[scapyall.IP].dst = dst_ips[vlan_intf] packet.load = payload packet[scapyall.TCP].chksum = None packet[scapyall.IP].chksum = None diff --git a/tests/dualtor_io/test_tor_bgp_failure.py b/tests/dualtor_io/test_tor_bgp_failure.py index c6643a08134..2ef58a13d52 100644 --- a/tests/dualtor_io/test_tor_bgp_failure.py +++ b/tests/dualtor_io/test_tor_bgp_failure.py @@ -182,7 +182,7 @@ def test_active_tor_shutdown_bgp_sessions_upstream( if cable_type == CableType.active_standby: send_server_to_t1_with_action( upper_tor_host, verify=True, delay=MUX_SIM_ALLOWED_DISRUPTION_SEC, - action=lambda: shutdown_bgp_sessions(upper_tor_host) + action=lambda: shutdown_bgp_sessions(upper_tor_host), random_dst=False ) if cable_type == CableType.active_active: From a7c567d8bb99b64ced3f893e5d509c138ef255d9 Mon Sep 17 00:00:00 2001 From: Chenyang Wang <49756587+cyw233@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:24:33 +1100 Subject: [PATCH 175/221] refactor: optimize BFD traffic test (#15550) Description of PR Optimize the BFD traffic test to reduce the running time. Summary: Fixes # (issue) Microsoft ADO 30056122 Approach What is the motivation for this PR? There are unnecessary setup steps in the BFD traffic test, which can be removed to reduce the running time. The running time will be decreased by at least 35 min after this change. How did you do it? How did you verify/test it? I ran the updated code and can confirm it's working well. co-authorized by: jianquanye@microsoft.com --- tests/bfd/bfd_base.py | 93 +--------------------------- tests/bfd/conftest.py | 3 - tests/bfd/test_bfd_traffic.py | 113 ++++++++++++++++++++++++++++------ 3 files changed, 95 insertions(+), 114 deletions(-) diff --git a/tests/bfd/bfd_base.py b/tests/bfd/bfd_base.py index e801cbfa870..b0f78a1868b 100644 --- a/tests/bfd/bfd_base.py +++ b/tests/bfd/bfd_base.py @@ -4,8 +4,7 @@ import pytest from tests.bfd.bfd_helpers import prepare_bfd_state, selecting_route_to_delete, \ - extract_ip_addresses_for_backend_portchannels, get_dut_asic_static_routes, extract_backend_portchannels, \ - get_src_dst_asic_next_hops + extract_ip_addresses_for_backend_portchannels, get_dut_asic_static_routes from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor logger = logging.getLogger(__name__) @@ -170,93 +169,3 @@ def select_src_dst_dut_with_asic(self, request, get_src_dst_asic_and_duts): "dst_prefix": dst_prefix, "version": version, } - - @pytest.fixture(scope="class") - def select_dut_and_src_dst_asic_index(self, duthosts): - if not duthosts.frontend_nodes: - pytest.skip("DUT does not have any frontend nodes") - - dut_index = random.choice(list(range(len(duthosts.frontend_nodes)))) - asic_namespace_list = duthosts.frontend_nodes[dut_index].get_asic_namespace_list() - if len(asic_namespace_list) < 2: - pytest.skip("DUT does not have more than one ASICs") - - # Random selection of src asic & dst asic on DUT - src_asic_namespace, dst_asic_namespace = random.sample(asic_namespace_list, 2) - src_asic_index = src_asic_namespace.split("asic")[1] - dst_asic_index = dst_asic_namespace.split("asic")[1] - - yield { - "dut_index": dut_index, - "src_asic_index": int(src_asic_index), - "dst_asic_index": int(dst_asic_index), - } - - @pytest.fixture(scope="class") - def get_src_dst_asic(self, request, duthosts, select_dut_and_src_dst_asic_index): - logger.info("Printing select_dut_and_src_dst_asic_index") - logger.info(select_dut_and_src_dst_asic_index) - - logger.info("Printing duthosts.frontend_nodes") - logger.info(duthosts.frontend_nodes) - dut = duthosts.frontend_nodes[select_dut_and_src_dst_asic_index["dut_index"]] - - logger.info("Printing dut asics") - logger.info(dut.asics) - - src_asic = dut.asics[select_dut_and_src_dst_asic_index["src_asic_index"]] - dst_asic = dut.asics[select_dut_and_src_dst_asic_index["dst_asic_index"]] - - request.config.src_asic = src_asic - request.config.dst_asic = dst_asic - request.config.dut = dut - - rtn_dict = { - "src_asic": src_asic, - "dst_asic": dst_asic, - "dut": dut, - } - - rtn_dict.update(select_dut_and_src_dst_asic_index) - yield rtn_dict - - @pytest.fixture(scope="class", params=["ipv4", "ipv6"]) - def prepare_traffic_test_variables(self, get_src_dst_asic, request): - version = request.param - logger.info("Version: %s", version) - - dut = get_src_dst_asic["dut"] - src_asic = get_src_dst_asic["src_asic"] - src_asic_index = get_src_dst_asic["src_asic_index"] - dst_asic = get_src_dst_asic["dst_asic"] - dst_asic_index = get_src_dst_asic["dst_asic_index"] - logger.info( - "DUT: {}, src_asic_index: {}, dst_asic_index: {}".format(dut.hostname, src_asic_index, dst_asic_index) - ) - - backend_port_channels = extract_backend_portchannels(dut) - src_asic_next_hops, dst_asic_next_hops, src_prefix, dst_prefix = get_src_dst_asic_next_hops( - version, - dut, - src_asic, - dst_asic, - request, - backend_port_channels, - ) - - src_asic_router_mac = src_asic.get_router_mac() - - yield { - "dut": dut, - "src_asic": src_asic, - "src_asic_index": src_asic_index, - "dst_asic": dst_asic, - "dst_asic_index": dst_asic_index, - "src_asic_next_hops": src_asic_next_hops, - "dst_asic_next_hops": dst_asic_next_hops, - "src_prefix": src_prefix, - "dst_prefix": dst_prefix, - "src_asic_router_mac": src_asic_router_mac, - "backend_port_channels": backend_port_channels, - "version": version, - } diff --git a/tests/bfd/conftest.py b/tests/bfd/conftest.py index 7892b067991..f69f7170d31 100644 --- a/tests/bfd/conftest.py +++ b/tests/bfd/conftest.py @@ -64,9 +64,6 @@ def bfd_cleanup_db(request, duthosts, enum_supervisor_dut_hostname): if hasattr(request.config, "src_dut") and hasattr(request.config, "dst_dut"): clear_bfd_configs(request.config.src_dut, request.config.src_asic.asic_index, request.config.src_prefix) clear_bfd_configs(request.config.dst_dut, request.config.dst_asic.asic_index, request.config.dst_prefix) - elif hasattr(request.config, "dut"): - clear_bfd_configs(request.config.dut, request.config.src_asic.asic_index, request.config.src_prefix) - clear_bfd_configs(request.config.dut, request.config.dst_asic.asic_index, request.config.dst_prefix) logger.info("Bringing up portchannels or respective members") portchannels_on_dut = None diff --git a/tests/bfd/test_bfd_traffic.py b/tests/bfd/test_bfd_traffic.py index fd3aa77d614..67833573c79 100644 --- a/tests/bfd/test_bfd_traffic.py +++ b/tests/bfd/test_bfd_traffic.py @@ -1,11 +1,12 @@ import logging +import random import pytest -from tests.bfd.bfd_base import BfdBase from tests.bfd.bfd_helpers import get_ptf_src_port, get_backend_interface_in_use_by_counter, \ get_random_bgp_neighbor_ip_of_asic, toggle_port_channel_or_member, get_port_channel_by_member, \ - wait_until_given_bfd_down, assert_traffic_switching, create_and_verify_bfd_state, verify_bfd_only + wait_until_given_bfd_down, assert_traffic_switching, verify_bfd_only, extract_backend_portchannels, \ + get_src_dst_asic_next_hops from tests.common.helpers.multi_thread_utils import SafeThreadPoolExecutor pytestmark = [ @@ -16,9 +17,99 @@ logger = logging.getLogger(__name__) -class TestBfdTraffic(BfdBase): +class TestBfdTraffic: PACKET_COUNT = 10000 + @pytest.fixture(scope="class") + def select_dut_and_src_dst_asic_index(self, duthosts): + if not duthosts.frontend_nodes: + pytest.skip("DUT does not have any frontend nodes") + + dut_index = random.choice(list(range(len(duthosts.frontend_nodes)))) + asic_namespace_list = duthosts.frontend_nodes[dut_index].get_asic_namespace_list() + if len(asic_namespace_list) < 2: + pytest.skip("DUT does not have more than one ASICs") + + # Random selection of src asic & dst asic on DUT + src_asic_namespace, dst_asic_namespace = random.sample(asic_namespace_list, 2) + src_asic_index = src_asic_namespace.split("asic")[1] + dst_asic_index = dst_asic_namespace.split("asic")[1] + + yield { + "dut_index": dut_index, + "src_asic_index": int(src_asic_index), + "dst_asic_index": int(dst_asic_index), + } + + @pytest.fixture(scope="class") + def get_src_dst_asic(self, request, duthosts, select_dut_and_src_dst_asic_index): + logger.info("Printing select_dut_and_src_dst_asic_index") + logger.info(select_dut_and_src_dst_asic_index) + + logger.info("Printing duthosts.frontend_nodes") + logger.info(duthosts.frontend_nodes) + dut = duthosts.frontend_nodes[select_dut_and_src_dst_asic_index["dut_index"]] + + logger.info("Printing dut asics") + logger.info(dut.asics) + + src_asic = dut.asics[select_dut_and_src_dst_asic_index["src_asic_index"]] + dst_asic = dut.asics[select_dut_and_src_dst_asic_index["dst_asic_index"]] + + request.config.src_asic = src_asic + request.config.dst_asic = dst_asic + request.config.dut = dut + + rtn_dict = { + "src_asic": src_asic, + "dst_asic": dst_asic, + "dut": dut, + } + + rtn_dict.update(select_dut_and_src_dst_asic_index) + yield rtn_dict + + @pytest.fixture(scope="class", params=["ipv4", "ipv6"]) + def prepare_traffic_test_variables(self, get_src_dst_asic, request): + version = request.param + logger.info("Version: %s", version) + + dut = get_src_dst_asic["dut"] + src_asic = get_src_dst_asic["src_asic"] + src_asic_index = get_src_dst_asic["src_asic_index"] + dst_asic = get_src_dst_asic["dst_asic"] + dst_asic_index = get_src_dst_asic["dst_asic_index"] + logger.info( + "DUT: {}, src_asic_index: {}, dst_asic_index: {}".format(dut.hostname, src_asic_index, dst_asic_index) + ) + + backend_port_channels = extract_backend_portchannels(dut) + src_asic_next_hops, dst_asic_next_hops, src_prefix, dst_prefix = get_src_dst_asic_next_hops( + version, + dut, + src_asic, + dst_asic, + request, + backend_port_channels, + ) + + src_asic_router_mac = src_asic.get_router_mac() + + yield { + "dut": dut, + "src_asic": src_asic, + "src_asic_index": src_asic_index, + "dst_asic": dst_asic, + "dst_asic_index": dst_asic_index, + "src_asic_next_hops": src_asic_next_hops, + "dst_asic_next_hops": dst_asic_next_hops, + "src_prefix": src_prefix, + "dst_prefix": dst_prefix, + "src_asic_router_mac": src_asic_router_mac, + "backend_port_channels": backend_port_channels, + "version": version, + } + def test_bfd_traffic_remote_port_channel_shutdown( self, request, @@ -44,10 +135,6 @@ def test_bfd_traffic_remote_port_channel_shutdown( ("dst", dst_asic, dst_prefix, dst_asic_next_hops), ] - with SafeThreadPoolExecutor(max_workers=8) as executor: - for _, asic, prefix, next_hops in src_dst_context: - executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) - dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: pytest.skip("No BGP neighbor found on asic{} of dut {}".format(dst_asic_index, dut.hostname)) @@ -155,10 +242,6 @@ def test_bfd_traffic_local_port_channel_shutdown( ("dst", dst_asic, dst_prefix, dst_asic_next_hops), ] - with SafeThreadPoolExecutor(max_workers=8) as executor: - for _, asic, prefix, next_hops in src_dst_context: - executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) - dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: pytest.skip("No BGP neighbor found on asic{} of dut {}".format(dst_asic_index, dut.hostname)) @@ -266,10 +349,6 @@ def test_bfd_traffic_remote_port_channel_member_shutdown( ("dst", dst_asic, dst_prefix, dst_asic_next_hops), ] - with SafeThreadPoolExecutor(max_workers=8) as executor: - for _, asic, prefix, next_hops in src_dst_context: - executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) - dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: pytest.skip("No BGP neighbor found on asic{} of dut {}".format(dst_asic_index, dut.hostname)) @@ -377,10 +456,6 @@ def test_bfd_traffic_local_port_channel_member_shutdown( ("dst", dst_asic, dst_prefix, dst_asic_next_hops), ] - with SafeThreadPoolExecutor(max_workers=8) as executor: - for _, asic, prefix, next_hops in src_dst_context: - executor.submit(create_and_verify_bfd_state, asic, prefix, dut, next_hops) - dst_neighbor_ip = get_random_bgp_neighbor_ip_of_asic(dut, dst_asic_index, version) if not dst_neighbor_ip: pytest.skip("No BGP neighbor found on asic{} of dut {}".format(dst_asic_index, dut.hostname)) From 1ca2a25558c344af0a0c84689a575940477623af Mon Sep 17 00:00:00 2001 From: Justin Wong <51811017+justin-wong-ce@users.noreply.github.com> Date: Thu, 14 Nov 2024 21:43:50 -0800 Subject: [PATCH 176/221] Add wait between mock dualtor setup commands (#15399) On topologies with higher number of interfaces (i.e. >100), config commands take more time to run properly. Executing the subsequent commands too quickly may cause the config to not change properly, causing problems in the mock dualtor setup. Adding a wait_until and delays to give more time for config changes. --- tests/common/dualtor/dual_tor_mock.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/common/dualtor/dual_tor_mock.py b/tests/common/dualtor/dual_tor_mock.py index a5d1bb12181..b883d28e6c4 100644 --- a/tests/common/dualtor/dual_tor_mock.py +++ b/tests/common/dualtor/dual_tor_mock.py @@ -11,6 +11,7 @@ from tests.common.dualtor.dual_tor_utils import tor_mux_intfs # noqa F401 from tests.common.helpers.assertions import pytest_assert from tests.common.platform.processes_utils import wait_critical_processes +from tests.common.utilities import wait_until __all__ = [ 'apply_active_state_to_orchagent', @@ -67,6 +68,9 @@ def set_dual_tor_state_to_orchagent(dut, state, tor_mux_intfs): # noqa F """ Helper function for setting active/standby state to orchagent """ + def check_config_applied(num_tor_mux_intfs): + out = dut.shell('redis-cli -n 0 keys "MUX_CABLE_TABLE:*" | wc -l') + return out['stdout_lines'][0] == str(num_tor_mux_intfs) logger.info("Applying {} state to orchagent".format(state)) intf_configs = [] @@ -97,6 +101,7 @@ def set_dual_tor_state_to_orchagent(dut, state, tor_mux_intfs): # noqa F logger.debug('SWSS config string is {}'.format(swss_config_str)) swss_filename = '/mux{}.json'.format(state) _apply_config_to_swss(dut, swss_config_str, swss_filename) + wait_until(120, 5, 5, check_config_applied, len(tor_mux_intfs)) def del_dual_tor_state_from_orchagent(dut, state, tor_mux_intfs): # noqa F811 @@ -295,6 +300,7 @@ def apply_dual_tor_neigh_entries(cleanup_mocked_configs, rand_selected_dut, tbin for ipv6, mac in list(mock_server_ipv6_mac_map.items()): cmds.append('ip -6 neigh replace {} lladdr {} dev {}'.format(ipv6, mac, vlan)) dut.shell_cmds(cmds=cmds) + time.sleep(5) return @@ -323,6 +329,7 @@ def apply_dual_tor_peer_switch_route(cleanup_mocked_configs, rand_selected_dut, # Use `ip route replace` in case a rule already exists for this IP # If there are no pre-existing routes, equivalent to `ip route add` dut.shell('ip route replace {} {}'.format(mock_peer_switch_loopback_ip, nexthop_str)) + time.sleep(5) return @@ -333,6 +340,12 @@ def apply_peer_switch_table_to_dut(cleanup_mocked_configs, rand_selected_dut, mo Adds the PEER_SWITCH table to config DB and the peer_switch field to the device metadata Also adds the 'subtype' field in the device metadata table and sets it to 'DualToR' ''' + def check_config_applied(): + out = dut.shell('redis-cli -n 4 HGETALL "DEVICE_METADATA|localhost"')['stdout_lines'][-1] + device_metadata_done = 'DualToR' in out + out = dut.shell('redis-cli -n 4 HGETALL "PEER_SWITCH|switch_hostname"')['stdout_lines'][0] + peerswitch_done = 'ipv4_address' in out + return device_metadata_done and peerswitch_done logger.info("Applying PEER_SWITCH table") dut = rand_selected_dut peer_switch_hostname = 'switch_hostname' @@ -359,6 +372,7 @@ def apply_peer_switch_table_to_dut(cleanup_mocked_configs, rand_selected_dut, mo logger.info("Restarting swss service") dut.shell('systemctl reset-failed swss; systemctl restart swss') wait_critical_processes(dut) + wait_until(120, 5, 5, check_config_applied) @pytest.fixture(scope='module') @@ -366,6 +380,11 @@ def apply_tunnel_table_to_dut(cleanup_mocked_configs, rand_selected_dut, mock_pe ''' Adds the TUNNEL table to config DB ''' + def check_config_applied(tunnel_params): + out = dut.shell('redis-cli -n 4 HGETALL "TUNNEL|MuxTunnel0" | wc -l')['stdout_lines'][0] + + # *2 because each key value pair is represented with 2 rows in redis-cli + return out == str(len(tunnel_params['TUNNEL']['MuxTunnel0'])*2) logger.info("Applying TUNNEL table") dut = rand_selected_dut @@ -389,6 +408,7 @@ def apply_tunnel_table_to_dut(cleanup_mocked_configs, rand_selected_dut, mock_pe dut.copy(content=json.dumps(tunnel_params, indent=2), dest="/tmp/tunnel_params.json") dut.shell("sonic-cfggen -j /tmp/tunnel_params.json --write-to-db") + wait_until(120, 5, 5, check_config_applied, tunnel_params) return @@ -399,6 +419,9 @@ def apply_mux_cable_table_to_dut(cleanup_mocked_configs, rand_selected_dut, ''' Adds the MUX_CABLE table to config DB ''' + def check_config_applied(num_tor_mux_intfs): + out = dut.shell('redis-cli -n 4 keys "MUX_CABLE|*" | wc -l') + return out['stdout_lines'][0] == str(num_tor_mux_intfs) logger.info("Applying MUX_CABLE table") dut = rand_selected_dut @@ -420,6 +443,7 @@ def apply_mux_cable_table_to_dut(cleanup_mocked_configs, rand_selected_dut, mux_cable_params = {'MUX_CABLE': mux_cable_params} dut.copy(content=json.dumps(mux_cable_params, indent=2), dest="/tmp/mux_cable_params.json") dut.shell("sonic-cfggen -j /tmp/mux_cable_params.json --write-to-db") + wait_until(120, 5, 5, check_config_applied, len(tor_mux_intfs)) return From c9b9d6acec47d77937a67c3441a74f4fb2859dce Mon Sep 17 00:00:00 2001 From: Javier Tan <47554099+Javier-Tan@users.noreply.github.com> Date: Fri, 15 Nov 2024 17:06:55 +1100 Subject: [PATCH 177/221] [tests/common/reboot.py]: Correct REBOOT_TYPE_SUPERVISOR "check" value (#15577) Description of PR Summary: Fixes #15444 Approach What is the motivation for this PR? Bad regex in supervisor reboot check is causing unwarranted test failures How did you do it? Remove bad regex flags in supervisor reboot checks How did you verify/test it? Ran affected tests to ensure behaviour was correct Signed-off-by: Javier Tan javiertan@microsoft.com --- tests/common/reboot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/reboot.py b/tests/common/reboot.py index 904f22c6c08..d6956646177 100644 --- a/tests/common/reboot.py +++ b/tests/common/reboot.py @@ -116,7 +116,7 @@ "timeout": 300, "wait": 120, # When linecards are rebooted due to supervisor cold reboot - "cause": r"^Reboot from Supervisor$|^reboot from Supervisor$", + "cause": r"Reboot from Supervisor|reboot from Supervisor", "test_reboot_cause_only": False }, REBOOT_TYPE_SUPERVISOR_HEARTBEAT_LOSS: { From eb0081706b5166d4fa36255e7eb9504eedb32901 Mon Sep 17 00:00:00 2001 From: arista-nwolfe <94405414+arista-nwolfe@users.noreply.github.com> Date: Fri, 15 Nov 2024 01:10:08 -0500 Subject: [PATCH 178/221] Fix condition intended to skip iBGP neighbors to work on single-asic (#15411) Fixes #13662 added support for running bgp/test_bgp_session_flap.py on T2 topology. However, the condition it added to skip iBGP neighbors only works on multi-asic LCs: if 'asic' not in v['description'].lower(): The better solution is to check the BGP session's peer group which will indicate if it's internal or not regardless of single-asic or multi-asic --- tests/bgp/test_bgp_session_flap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/bgp/test_bgp_session_flap.py b/tests/bgp/test_bgp_session_flap.py index f41fafc6894..3ed3d564ee9 100644 --- a/tests/bgp/test_bgp_session_flap.py +++ b/tests/bgp/test_bgp_session_flap.py @@ -66,7 +66,8 @@ def setup(tbinfo, nbrhosts, duthosts, enum_frontend_dut_hostname, enum_rand_one_ tor_neighbors = dict() neigh_asn = dict() for k, v in bgp_facts['bgp_neighbors'].items(): - if 'asic' not in v['description'].lower(): + # Skip iBGP neighbors + if "INTERNAL" not in v["peer group"] and "VOQ_CHASSIS" not in v["peer group"]: neigh_keys.append(v['description']) neigh_asn[v['description']] = v['remote AS'] tor_neighbors[v['description']] = nbrhosts[v['description']]["host"] From 3869cad918884365324c80b2b401755c191b5f7f Mon Sep 17 00:00:00 2001 From: ansrajpu-git <113939367+ansrajpu-git@users.noreply.github.com> Date: Fri, 15 Nov 2024 01:36:49 -0500 Subject: [PATCH 179/221] [Chassis][voq] Skip sonic-mgmt HdrmPoolSizeTest for Nokia-IXR7250E hwsku (#13513) Below test cases are skipped for hwsku in Nokia-IXR7250E-36x400G & platform asic in ['x86_64-nokia_ixr7250e_36x400g-r0'] -testQosSaiHeadroomPoolSize -testQosSaiHeadroomPoolWatermark Issue : #13503 What is the motivation for this PR? How did you do it? set skip for hwsku in Nokia-IXR7250E-36x400G & platform asic in ['x86_64-nokia_ixr7250e_36x400g-r0'] How did you verify/test it? Execute the qos test cases --- tests/common/plugins/conditional_mark/tests_mark_conditions.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 315189c4ed1..be3300b0241 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1481,6 +1481,7 @@ qos/test_qos_sai.py::TestQosSai::testQosSaiHeadroomPoolSize: and topo_type in ['t1-64-lag'] and hwsku not in ['Arista-7060CX-32S-C32', 'Celestica-DX010-C32', 'Arista-7260CX3-D108C8', 'Force10-S6100', 'Arista-7260CX3-Q64', 'Arista-7050CX3-32S-C32', 'Arista-7050CX3-32S-D48C8', 'Arista-7060CX-32S-D48C8'] and asic_type not in ['mellanox'] and asic_type in ['cisco-8000']" - "topo_type in ['m0', 'mx']" + - "'t2' in topo_name and asic_subtype in ['broadcom-dnx']" qos/test_qos_sai.py::TestQosSai::testQosSaiHeadroomPoolWatermark: skip: From d565dcdbdee84e440f3abf0be1036fd217be8132 Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Fri, 15 Nov 2024 17:51:55 +1100 Subject: [PATCH 180/221] chore: update comments on skipped test (#15581) Description of PR Summary: Fixes # (issue) 29946125 Approach What is the motivation for this PR? Updated comments for skipped test cases on cisco 8800 platform as discussed with cisco. Signed-off-by: Austin Pham --- tests/qos/test_qos_sai.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/qos/test_qos_sai.py b/tests/qos/test_qos_sai.py index 03ee7986cec..3463fc09800 100644 --- a/tests/qos/test_qos_sai.py +++ b/tests/qos/test_qos_sai.py @@ -327,6 +327,7 @@ def testQosSaiPfcXoffLimit( ptfhost, dutTestParams, dutConfig, dutQosConfig, ingressLosslessProfile, egressLosslessProfile ): + # NOTE: this test will be skipped for t2 cisco 8800 if it's not xoff_1 or xoff_2 """ Test QoS SAI XOFF limits @@ -430,6 +431,7 @@ def testPfcStormWithSharedHeadroomOccupancy( Raises: RunAnsibleModuleFail if ptf test fails """ + # NOTE: this is a mellanox test only and will be skipped for cisco 8800 normal_profile = ["xon_1", "xon_2"] if not dutConfig["dualTor"] and xonProfile not in normal_profile: pytest.skip( @@ -590,6 +592,7 @@ def testQosSaiPfcXonLimit( self, get_src_dst_asic_and_duts, xonProfile, ptfhost, dutTestParams, dutConfig, dutQosConfig, ingressLosslessProfile ): + # NOTE: cisco 8800 will skip this test if it's not xon_1 or xon_2 """ Test QoS SAI XON limits @@ -763,6 +766,7 @@ def testQosSaiHeadroomPoolSize( self, get_src_dst_asic_and_duts, ptfhost, dutTestParams, dutConfig, dutQosConfig, ingressLosslessProfile ): + # NOTE: cisco-8800 will skip this test since there are no headroom pool """ Test QoS SAI Headroom pool size @@ -875,6 +879,7 @@ def testQosSaiSharedReservationSize( self, sharedResSizeKey, ptfhost, dutTestParams, dutConfig, dutQosConfig, get_src_dst_asic_and_duts, check_skip_shared_res_test ): + # NOTE: Cisco T2 skip due to reduced number of port in multi asic """ Test QoS SAI shared reservation size Args: @@ -892,9 +897,11 @@ def testQosSaiSharedReservationSize( if ('modular_chassis' in get_src_dst_asic_and_duts['src_dut'].facts and get_src_dst_asic_and_duts['src_dut'].facts["modular_chassis"]): if dutConfig['dstDutAsic'] != "pac": + # Skipped due to reduced number of ports in multi-asic platforms pytest.skip("This test is skipped since not enough ports on cisco-8000 " "T2 Q200.") if "shared_res_size_2" in sharedResSizeKey: + # Skipped due to reduced number of ports in multi-asic platforms pytest.skip("This test is skipped since on cisco-8000 Q100, " "SQG thresholds have no impact on XOFF thresholds.") @@ -948,6 +955,7 @@ def testQosSaiHeadroomPoolWatermark( dutConfig, dutQosConfig, ingressLosslessProfile, sharedHeadroomPoolSize, resetWatermark ): + # NOTE: cisco 8800 will skip this test since there is no headroom pool """ Test QoS SAI Headroom pool watermark @@ -1214,6 +1222,7 @@ def testQosSaiLossyQueueVoq( ingressLossyProfile, duthost, localhost, get_src_dst_asic_and_duts, skip_src_dst_different_asic, dut_qos_maps # noqa: F811 ): + # NOTE: cisco 8800 will skip this test, this test only for single asic with long link """ Test QoS SAI Lossy queue with non_default voq and default voq Args: @@ -1368,6 +1377,7 @@ def testQosSaiDscpQueueMapping( @pytest.mark.parametrize("direction", ["downstream", "upstream"]) def testQosSaiSeparatedDscpQueueMapping(self, duthost, ptfhost, dutTestParams, dutConfig, direction, dut_qos_maps): # noqa F811 + # NOTE: cisco t2 8800 will skip this test since because of the topology """ Test QoS SAI DSCP to queue mapping. We will have separated DSCP_TO_TC_MAP for uplink/downlink ports on T1 if PCBB enabled. @@ -1430,6 +1440,7 @@ def testQosSaiSeparatedDscpQueueMapping(self, duthost, ptfhost, dutTestParams, def testQosSaiDot1pQueueMapping( self, ptfhost, dutTestParams, dutConfig ): + # NOTE: cisco 8800 will skip this test Dot1p-PG mapping is only supported on backend """ Test QoS SAI Dot1p to queue mapping @@ -1468,6 +1479,7 @@ def testQosSaiDot1pQueueMapping( def testQosSaiDot1pPgMapping( self, ptfhost, dutTestParams, dutConfig ): + # NOTE: cisco 8800 will skip this test Dot1p-PG mapping is only supported on backend """ Test QoS SAI Dot1p to PG mapping Args: @@ -1989,6 +2001,7 @@ def testIPIPQosSaiDscpToPgMapping( @pytest.mark.parametrize("direction", ["downstream", "upstream"]) def testQosSaiSeparatedDscpToPgMapping(self, duthost, request, ptfhost, dutTestParams, dutConfig, direction, dut_qos_maps): # noqa F811 + # NOTE: cisco 8800 will skip this test for both upstream and downstream """ Test QoS SAI DSCP to PG mapping ptf test. Since we are using different DSCP_TO_TC_MAP on uplink/downlink port, the test case also need to @@ -2207,6 +2220,7 @@ def testQosSaiLossyQueueVoqMultiSrc( self, ptfhost, dutTestParams, dutConfig, dutQosConfig, get_src_dst_asic_and_duts, skip_longlink ): + # NOTE: testQosSaiLossyQueueVoqMultiSrc[lossy_queue_voq_3] will be skipped for t2 cisco since it's multi-asic """ Test QoS SAI Lossy queue with multiple source ports, applicable for fair-voq and split-voq Args: @@ -2282,6 +2296,7 @@ def testQosSaiFullMeshTrafficSanity( get_src_dst_asic_and_duts, dut_qos_maps, # noqa F811 set_static_route_ptf64 ): + # NOTE: this test will skip for t2 cisco 8800 since it requires ptf64 topo """ Test QoS SAI traffic sanity Args: From 129959cbb22a2caa091f9ee3416f8f7674bf48fd Mon Sep 17 00:00:00 2001 From: "Austin (Thang Pham)" Date: Fri, 15 Nov 2024 20:18:23 +1100 Subject: [PATCH 181/221] fix: fix failure pfcwd_multiport (#15562) Description of PR Summary: Fixes # (issue) 30115858 Approach What is the motivation for this PR? From the original PR #10198 these changes were left out. After adding it back in it passed all the tests Signed-off-by: Austin Pham --- tests/pfcwd/test_pfcwd_function.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/pfcwd/test_pfcwd_function.py b/tests/pfcwd/test_pfcwd_function.py index 22a082b4fde..b9f60a65a59 100644 --- a/tests/pfcwd/test_pfcwd_function.py +++ b/tests/pfcwd/test_pfcwd_function.py @@ -518,6 +518,7 @@ def __init__(self, ptf, router_mac, tx_mac, pfc_params, is_dualtor): self.pfc_wd_rx_port_vlan_id = pfc_params['rx_port_vlan_id'] self.port_id_to_type_map = pfc_params['port_id_to_type_map'] self.port_type = pfc_params['port_type'] + self.is_dualtor = is_dualtor if is_dualtor: self.vlan_mac = "00:aa:bb:cc:dd:ee" else: @@ -569,7 +570,7 @@ def verify_rx_ingress(self, action): else: dst_port = "[ " + str(self.pfc_wd_rx_port_id) + " ]" ptf_params = {'router_mac': self.tx_mac, - 'vlan_mac': self.vlan_mac, + 'vlan_mac': self.vlan_mac if self.is_dualtor else self.tx_mac, 'queue_index': self.pfc_queue_index, 'pkt_count': self.pfc_wd_test_pkt_count, 'port_src': self.pfc_wd_test_port_id, @@ -635,7 +636,7 @@ def verify_other_pfc_pg(self): other_pg = self.pfc_queue_index + 1 ptf_params = {'router_mac': self.tx_mac, - 'vlan_mac': self.vlan_mac, + 'vlan_mac': self.vlan_mac if self.is_dualtor else self.tx_mac, 'queue_index': other_pg, 'pkt_count': self.pfc_wd_test_pkt_count, 'port_src': self.pfc_wd_test_port_id, From 32e7e9d4911466410ab6985fa28848d684cb4ba5 Mon Sep 17 00:00:00 2001 From: bingwang-ms <66248323+bingwang-ms@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:46:09 -0800 Subject: [PATCH 182/221] Wait BGP sessions after changing mgmt IP (#15570) --- tests/common/fixtures/duthost_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/fixtures/duthost_utils.py b/tests/common/fixtures/duthost_utils.py index d2913307fdf..f23ec06b152 100644 --- a/tests/common/fixtures/duthost_utils.py +++ b/tests/common/fixtures/duthost_utils.py @@ -754,7 +754,7 @@ def convert_and_restore_config_db_to_ipv6_only(duthosts): if config_db_modified[duthost.hostname]: logger.info(f"config changed. Doing config reload for {duthost.hostname}") try: - config_reload(duthost, wait=120) + config_reload(duthost, wait=120, wait_for_bgp=True) except AnsibleConnectionFailure as e: # IPV4 mgmt interface been deleted by config reload # In latest SONiC, config reload command will exit after mgmt interface restart From f992360638c718a3e22bfa5b87bda18d6bfedbeb Mon Sep 17 00:00:00 2001 From: Chris <156943338+ccroy-arista@users.noreply.github.com> Date: Sun, 17 Nov 2024 16:41:52 -0800 Subject: [PATCH 183/221] sonic-mgmt: fix t0-isolated-d128u128s2 topo (#15542) Description of PR This PR contains the following changes, in order to achieve a functional t0-isolated-d128u128s2 topo: The field 'bp_interfaces' in the t0-isolated-d128u128s2 yml file is corrected to 'bp_interface' i.e. w/o the 's'. Added more VMs, to support the larger number of VMs needed for the topo. Added the missing leaf template file for the topo. Fixed the synthesis of the MACs used in ansible roles so that it does not error out after 256 interfaces. Additionally, this PR fixed the 'bp_interfaces' for t0-isolated-d128u128s1 yml file. --- .../templates/t0-isolated-d128u128s2-leaf.j2 | 1 + .../roles/test/files/helpers/change_mac.sh | 5 +- ansible/testbed-new.yaml | 138 +++++++++- ansible/vars/topo_t0-isolated-d128u128s1.yml | 258 ++++++++--------- ansible/vars/topo_t0-isolated-d128u128s2.yml | 260 +++++++++--------- ansible/veos | 138 +++++++++- 6 files changed, 525 insertions(+), 275 deletions(-) create mode 100644 ansible/roles/eos/templates/t0-isolated-d128u128s2-leaf.j2 diff --git a/ansible/roles/eos/templates/t0-isolated-d128u128s2-leaf.j2 b/ansible/roles/eos/templates/t0-isolated-d128u128s2-leaf.j2 new file mode 100644 index 00000000000..a60cf79c0e0 --- /dev/null +++ b/ansible/roles/eos/templates/t0-isolated-d128u128s2-leaf.j2 @@ -0,0 +1 @@ +t0-leaf.j2 diff --git a/ansible/roles/test/files/helpers/change_mac.sh b/ansible/roles/test/files/helpers/change_mac.sh index 05f8dd66778..0952f51f38c 100644 --- a/ansible/roles/test/files/helpers/change_mac.sh +++ b/ansible/roles/test/files/helpers/change_mac.sh @@ -6,8 +6,9 @@ INTF_LIST=$(ls /sys/class/net | grep -E "^eth[0-9]+$") for INTF in ${INTF_LIST}; do ADDR="$(cat /sys/class/net/${INTF}/address)" - PREFIX="$(cut -c1-15 <<< ${ADDR})" - SUFFIX="$(printf "%02x" ${INTF##eth})" + PREFIX="$(cut -c1-13 <<< ${ADDR})" + INTF_ID=${INTF##eth} + SUFFIX="$(printf "%x:%02x" $(expr ${INTF_ID} / 256) $(expr ${INTF_ID} % 256))" MAC="${PREFIX}${SUFFIX}" echo "Update ${INTF} MAC address: ${ADDR}->$MAC" diff --git a/ansible/testbed-new.yaml b/ansible/testbed-new.yaml index d02fd2b1227..06f1f380877 100644 --- a/ansible/testbed-new.yaml +++ b/ansible/testbed-new.yaml @@ -242,9 +242,9 @@ veos_groups: eos: children: [vms_1, vms_2] # source: sonic-mgmt/veos vms_2: - host: [VM0200, VM0201, VM0202, VM0203] # source: sonic-mgmt/veos + host: [VM0300, VM0301, VM0302, VM0203] # source: sonic-mgmt/veos vms_1: - host: [VM0100, VM0101, VM0102, VM0103, VM0104, VM0105, VM0106, VM0107, VM0108, VM0109, VM0110, VM0111, VM0112, VM0113, VM0114, VM0115, VM0116, VM0117, VM0118, VM0119, VM0120, VM0121, VM0122, VM0123, VM0124, VM0125, VM0126, VM0127, VM0128, VM0129, VM0130, VM0131, VM0132, VM0133, VM0134, VM0135, VM0136, VM0137, VM0138, VM0139, VM0140, VM0141, VM0142, VM0143, VM0144, VM0145, VM0146, VM0147, VM0148, VM0149, VM0150, VM0151, VM0152, VM0153, VM0154, VM0155, VM0156, VM0157, VM0158, VM0159, VM0160, VM0161, VM0162, VM0163, VM0164, VM0165, VM0166, VM0167] # source: sonic-mgmt/veos + host: [VM0100, VM0101, VM0102, VM0103, VM0104, VM0105, VM0106, VM0107, VM0108, VM0109, VM0110, VM0111, VM0112, VM0113, VM0114, VM0115, VM0116, VM0117, VM0118, VM0119, VM0120, VM0121, VM0122, VM0123, VM0124, VM0125, VM0126, VM0127, VM0128, VM0129, VM0130, VM0131, VM0132, VM0133, VM0134, VM0135, VM0136, VM0137, VM0138, VM0139, VM0140, VM0141, VM0142, VM0143, VM0144, VM0145, VM0146, VM0147, VM0148, VM0149, VM0150, VM0151, VM0152, VM0153, VM0154, VM0155, VM0156, VM0157, VM0158, VM0159, VM0160, VM0161, VM0162, VM0163, VM0164, VM0165, VM0166, VM0167, VM0168, VM0169, VM0170, VM0171, VM0172, VM0173, VM0174, VM0175, VM0176, VM0177, VM0178, VM0179, VM0180, VM0181, VM0182, VM0183, VM0184, VM0185, VM0186, VM0187, VM0188, VM0189, VM0190, VM0191, VM0192, VM0193, VM0194, VM0195, VM0196, VM0197, VM0198, VM0199, VM0200, VM0201, VM0202, VM0203, VM0204, VM0205, VM0206, VM0207, VM0208, VM0209, VM0210, VM0211, VM0212, VM0213, VM0214, VM0215, VM0216, VM0217, VM0218, VM0219, VM0220, VM0221, VM0222, VM0223, VM0224, VM0225, VM0226, VM0227, VM0228, VM0229] # source: sonic-mgmt/veos vm_host: children: [vm_host_1, vm_host_2] # source: sonic-mgmt/veos vm_host_2: @@ -414,15 +414,139 @@ veos: ansible_host: 10.250.0.68 VM0167: ansible_host: 10.250.0.69 - vms_2: + VM0168: + ansible_host: 10.250.0.70 + VM0169: + ansible_host: 10.250.0.71 + VM0170: + ansible_host: 10.250.0.72 + VM0171: + ansible_host: 10.250.0.73 + VM0172: + ansible_host: 10.250.0.74 + VM0173: + ansible_host: 10.250.0.75 + VM0174: + ansible_host: 10.250.0.76 + VM0175: + ansible_host: 10.250.0.77 + VM0176: + ansible_host: 10.250.0.78 + VM0177: + ansible_host: 10.250.0.79 + VM0178: + ansible_host: 10.250.0.80 + VM0179: + ansible_host: 10.250.0.81 + VM0180: + ansible_host: 10.250.0.82 + VM0181: + ansible_host: 10.250.0.83 + VM0182: + ansible_host: 10.250.0.84 + VM0183: + ansible_host: 10.250.0.85 + VM0184: + ansible_host: 10.250.0.86 + VM0185: + ansible_host: 10.250.0.87 + VM0186: + ansible_host: 10.250.0.88 + VM0187: + ansible_host: 10.250.0.89 + VM0188: + ansible_host: 10.250.0.90 + VM0189: + ansible_host: 10.250.0.91 + VM0190: + ansible_host: 10.250.0.92 + VM0191: + ansible_host: 10.250.0.93 + VM0192: + ansible_host: 10.250.0.94 + VM0193: + ansible_host: 10.250.0.95 + VM0194: + ansible_host: 10.250.0.96 + VM0195: + ansible_host: 10.250.0.97 + VM0196: + ansible_host: 10.250.0.98 + VM0197: + ansible_host: 10.250.0.99 + VM0198: + ansible_host: 10.250.0.100 + VM0199: + ansible_host: 10.250.0.101 VM0200: - ansible_host: 10.250.0.51 + ansible_host: 10.250.0.102 VM0201: - ansible_host: 10.250.0.52 + ansible_host: 10.250.0.103 VM0202: - ansible_host: 10.250.0.53 + ansible_host: 10.250.0.104 VM0203: - ansible_host: 10.250.0.54 + ansible_host: 10.250.0.105 + VM0204: + ansible_host: 10.250.0.106 + VM0205: + ansible_host: 10.250.0.107 + VM0206: + ansible_host: 10.250.0.108 + VM0207: + ansible_host: 10.250.0.109 + VM0208: + ansible_host: 10.250.0.110 + VM0209: + ansible_host: 10.250.0.111 + VM0210: + ansible_host: 10.250.0.112 + VM0211: + ansible_host: 10.250.0.113 + VM0212: + ansible_host: 10.250.0.114 + VM0213: + ansible_host: 10.250.0.115 + VM0214: + ansible_host: 10.250.0.116 + VM0215: + ansible_host: 10.250.0.117 + VM0216: + ansible_host: 10.250.0.118 + VM0217: + ansible_host: 10.250.0.119 + VM0218: + ansible_host: 10.250.0.120 + VM0219: + ansible_host: 10.250.0.121 + VM0220: + ansible_host: 10.250.0.122 + VM0221: + ansible_host: 10.250.0.123 + VM0222: + ansible_host: 10.250.0.124 + VM0223: + ansible_host: 10.250.0.125 + VM0224: + ansible_host: 10.250.0.126 + VM0225: + ansible_host: 10.250.0.127 + VM0226: + ansible_host: 10.250.0.128 + VM0227: + ansible_host: 10.250.0.129 + VM0228: + ansible_host: 10.250.0.130 + VM0229: + ansible_host: 10.250.0.131 + vms_2: + VM0300: + ansible_host: 10.250.0.252 + VM0301: + ansible_host: 10.250.0.253 + VM0302: + ansible_host: 10.250.0.254 + VM0303: + ansible_host: 10.250.0.255 # testbed dictionary contains information about the testbed # testbed is used to generate testbed.csv diff --git a/ansible/vars/topo_t0-isolated-d128u128s1.yml b/ansible/vars/topo_t0-isolated-d128u128s1.yml index b187d8d09c3..75ae5f25da8 100644 --- a/ansible/vars/topo_t0-isolated-d128u128s1.yml +++ b/ansible/vars/topo_t0-isolated-d128u128s1.yml @@ -825,7 +825,7 @@ configuration: Ethernet1: ipv4: 10.0.0.65/31 ipv6: fc00::82/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.2/24 ipv6: fc0a::2/64 ARISTA02T1: @@ -844,7 +844,7 @@ configuration: Ethernet1: ipv4: 10.0.0.67/31 ipv6: fc00::86/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.3/24 ipv6: fc0a::3/64 ARISTA03T1: @@ -863,7 +863,7 @@ configuration: Ethernet1: ipv4: 10.0.0.69/31 ipv6: fc00::8a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.4/24 ipv6: fc0a::4/64 ARISTA04T1: @@ -882,7 +882,7 @@ configuration: Ethernet1: ipv4: 10.0.0.71/31 ipv6: fc00::8e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.5/24 ipv6: fc0a::5/64 ARISTA05T1: @@ -901,7 +901,7 @@ configuration: Ethernet1: ipv4: 10.0.0.73/31 ipv6: fc00::92/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.6/24 ipv6: fc0a::6/64 ARISTA06T1: @@ -920,7 +920,7 @@ configuration: Ethernet1: ipv4: 10.0.0.75/31 ipv6: fc00::96/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.7/24 ipv6: fc0a::7/64 ARISTA07T1: @@ -939,7 +939,7 @@ configuration: Ethernet1: ipv4: 10.0.0.77/31 ipv6: fc00::9a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.8/24 ipv6: fc0a::8/64 ARISTA08T1: @@ -958,7 +958,7 @@ configuration: Ethernet1: ipv4: 10.0.0.79/31 ipv6: fc00::9e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.9/24 ipv6: fc0a::9/64 ARISTA09T1: @@ -977,7 +977,7 @@ configuration: Ethernet1: ipv4: 10.0.0.81/31 ipv6: fc00::a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.10/24 ipv6: fc0a::a/64 ARISTA10T1: @@ -996,7 +996,7 @@ configuration: Ethernet1: ipv4: 10.0.0.83/31 ipv6: fc00::a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.11/24 ipv6: fc0a::b/64 ARISTA11T1: @@ -1015,7 +1015,7 @@ configuration: Ethernet1: ipv4: 10.0.0.85/31 ipv6: fc00::aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.12/24 ipv6: fc0a::c/64 ARISTA12T1: @@ -1034,7 +1034,7 @@ configuration: Ethernet1: ipv4: 10.0.0.87/31 ipv6: fc00::ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.13/24 ipv6: fc0a::d/64 ARISTA13T1: @@ -1053,7 +1053,7 @@ configuration: Ethernet1: ipv4: 10.0.0.89/31 ipv6: fc00::b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.14/24 ipv6: fc0a::e/64 ARISTA14T1: @@ -1072,7 +1072,7 @@ configuration: Ethernet1: ipv4: 10.0.0.91/31 ipv6: fc00::b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.15/24 ipv6: fc0a::f/64 ARISTA15T1: @@ -1091,7 +1091,7 @@ configuration: Ethernet1: ipv4: 10.0.0.93/31 ipv6: fc00::ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.16/24 ipv6: fc0a::10/64 ARISTA16T1: @@ -1110,7 +1110,7 @@ configuration: Ethernet1: ipv4: 10.0.0.95/31 ipv6: fc00::be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.17/24 ipv6: fc0a::11/64 ARISTA17T1: @@ -1129,7 +1129,7 @@ configuration: Ethernet1: ipv4: 10.0.0.97/31 ipv6: fc00::c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.18/24 ipv6: fc0a::12/64 ARISTA18T1: @@ -1148,7 +1148,7 @@ configuration: Ethernet1: ipv4: 10.0.0.99/31 ipv6: fc00::c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.19/24 ipv6: fc0a::13/64 ARISTA19T1: @@ -1167,7 +1167,7 @@ configuration: Ethernet1: ipv4: 10.0.0.101/31 ipv6: fc00::ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.20/24 ipv6: fc0a::14/64 ARISTA20T1: @@ -1186,7 +1186,7 @@ configuration: Ethernet1: ipv4: 10.0.0.103/31 ipv6: fc00::ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.21/24 ipv6: fc0a::15/64 ARISTA21T1: @@ -1205,7 +1205,7 @@ configuration: Ethernet1: ipv4: 10.0.0.105/31 ipv6: fc00::d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.22/24 ipv6: fc0a::16/64 ARISTA22T1: @@ -1224,7 +1224,7 @@ configuration: Ethernet1: ipv4: 10.0.0.107/31 ipv6: fc00::d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.23/24 ipv6: fc0a::17/64 ARISTA23T1: @@ -1243,7 +1243,7 @@ configuration: Ethernet1: ipv4: 10.0.0.109/31 ipv6: fc00::da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.24/24 ipv6: fc0a::18/64 ARISTA24T1: @@ -1262,7 +1262,7 @@ configuration: Ethernet1: ipv4: 10.0.0.111/31 ipv6: fc00::de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.25/24 ipv6: fc0a::19/64 ARISTA25T1: @@ -1281,7 +1281,7 @@ configuration: Ethernet1: ipv4: 10.0.0.113/31 ipv6: fc00::e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.26/24 ipv6: fc0a::1a/64 ARISTA26T1: @@ -1300,7 +1300,7 @@ configuration: Ethernet1: ipv4: 10.0.0.115/31 ipv6: fc00::e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.27/24 ipv6: fc0a::1b/64 ARISTA27T1: @@ -1319,7 +1319,7 @@ configuration: Ethernet1: ipv4: 10.0.0.117/31 ipv6: fc00::ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.28/24 ipv6: fc0a::1c/64 ARISTA28T1: @@ -1338,7 +1338,7 @@ configuration: Ethernet1: ipv4: 10.0.0.119/31 ipv6: fc00::ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.29/24 ipv6: fc0a::1d/64 ARISTA29T1: @@ -1357,7 +1357,7 @@ configuration: Ethernet1: ipv4: 10.0.0.121/31 ipv6: fc00::f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.30/24 ipv6: fc0a::1e/64 ARISTA30T1: @@ -1376,7 +1376,7 @@ configuration: Ethernet1: ipv4: 10.0.0.123/31 ipv6: fc00::f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.31/24 ipv6: fc0a::1f/64 ARISTA31T1: @@ -1395,7 +1395,7 @@ configuration: Ethernet1: ipv4: 10.0.0.125/31 ipv6: fc00::fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.32/24 ipv6: fc0a::20/64 ARISTA32T1: @@ -1414,7 +1414,7 @@ configuration: Ethernet1: ipv4: 10.0.0.127/31 ipv6: fc00::fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.33/24 ipv6: fc0a::21/64 ARISTA33T1: @@ -1433,7 +1433,7 @@ configuration: Ethernet1: ipv4: 10.0.0.129/31 ipv6: fc00::102/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.34/24 ipv6: fc0a::22/64 ARISTA34T1: @@ -1452,7 +1452,7 @@ configuration: Ethernet1: ipv4: 10.0.0.131/31 ipv6: fc00::106/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.35/24 ipv6: fc0a::23/64 ARISTA35T1: @@ -1471,7 +1471,7 @@ configuration: Ethernet1: ipv4: 10.0.0.133/31 ipv6: fc00::10a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.36/24 ipv6: fc0a::24/64 ARISTA36T1: @@ -1490,7 +1490,7 @@ configuration: Ethernet1: ipv4: 10.0.0.135/31 ipv6: fc00::10e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.37/24 ipv6: fc0a::25/64 ARISTA37T1: @@ -1509,7 +1509,7 @@ configuration: Ethernet1: ipv4: 10.0.0.137/31 ipv6: fc00::112/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.38/24 ipv6: fc0a::26/64 ARISTA38T1: @@ -1528,7 +1528,7 @@ configuration: Ethernet1: ipv4: 10.0.0.139/31 ipv6: fc00::116/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.39/24 ipv6: fc0a::27/64 ARISTA39T1: @@ -1547,7 +1547,7 @@ configuration: Ethernet1: ipv4: 10.0.0.141/31 ipv6: fc00::11a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.40/24 ipv6: fc0a::28/64 ARISTA40T1: @@ -1566,7 +1566,7 @@ configuration: Ethernet1: ipv4: 10.0.0.143/31 ipv6: fc00::11e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.41/24 ipv6: fc0a::29/64 ARISTA41T1: @@ -1585,7 +1585,7 @@ configuration: Ethernet1: ipv4: 10.0.0.145/31 ipv6: fc00::122/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.42/24 ipv6: fc0a::2a/64 ARISTA42T1: @@ -1604,7 +1604,7 @@ configuration: Ethernet1: ipv4: 10.0.0.147/31 ipv6: fc00::126/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.43/24 ipv6: fc0a::2b/64 ARISTA43T1: @@ -1623,7 +1623,7 @@ configuration: Ethernet1: ipv4: 10.0.0.149/31 ipv6: fc00::12a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.44/24 ipv6: fc0a::2c/64 ARISTA44T1: @@ -1642,7 +1642,7 @@ configuration: Ethernet1: ipv4: 10.0.0.151/31 ipv6: fc00::12e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.45/24 ipv6: fc0a::2d/64 ARISTA45T1: @@ -1661,7 +1661,7 @@ configuration: Ethernet1: ipv4: 10.0.0.153/31 ipv6: fc00::132/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.46/24 ipv6: fc0a::2e/64 ARISTA46T1: @@ -1680,7 +1680,7 @@ configuration: Ethernet1: ipv4: 10.0.0.155/31 ipv6: fc00::136/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.47/24 ipv6: fc0a::2f/64 ARISTA47T1: @@ -1699,7 +1699,7 @@ configuration: Ethernet1: ipv4: 10.0.0.157/31 ipv6: fc00::13a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.48/24 ipv6: fc0a::30/64 ARISTA48T1: @@ -1718,7 +1718,7 @@ configuration: Ethernet1: ipv4: 10.0.0.159/31 ipv6: fc00::13e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.49/24 ipv6: fc0a::31/64 ARISTA49T1: @@ -1737,7 +1737,7 @@ configuration: Ethernet1: ipv4: 10.0.0.161/31 ipv6: fc00::142/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.50/24 ipv6: fc0a::32/64 ARISTA50T1: @@ -1756,7 +1756,7 @@ configuration: Ethernet1: ipv4: 10.0.0.163/31 ipv6: fc00::146/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.51/24 ipv6: fc0a::33/64 ARISTA51T1: @@ -1775,7 +1775,7 @@ configuration: Ethernet1: ipv4: 10.0.0.165/31 ipv6: fc00::14a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.52/24 ipv6: fc0a::34/64 ARISTA52T1: @@ -1794,7 +1794,7 @@ configuration: Ethernet1: ipv4: 10.0.0.167/31 ipv6: fc00::14e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.53/24 ipv6: fc0a::35/64 ARISTA53T1: @@ -1813,7 +1813,7 @@ configuration: Ethernet1: ipv4: 10.0.0.169/31 ipv6: fc00::152/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.54/24 ipv6: fc0a::36/64 ARISTA54T1: @@ -1832,7 +1832,7 @@ configuration: Ethernet1: ipv4: 10.0.0.171/31 ipv6: fc00::156/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.55/24 ipv6: fc0a::37/64 ARISTA55T1: @@ -1851,7 +1851,7 @@ configuration: Ethernet1: ipv4: 10.0.0.173/31 ipv6: fc00::15a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.56/24 ipv6: fc0a::38/64 ARISTA56T1: @@ -1870,7 +1870,7 @@ configuration: Ethernet1: ipv4: 10.0.0.175/31 ipv6: fc00::15e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.57/24 ipv6: fc0a::39/64 ARISTA57T1: @@ -1889,7 +1889,7 @@ configuration: Ethernet1: ipv4: 10.0.0.177/31 ipv6: fc00::162/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.58/24 ipv6: fc0a::3a/64 ARISTA58T1: @@ -1908,7 +1908,7 @@ configuration: Ethernet1: ipv4: 10.0.0.179/31 ipv6: fc00::166/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.59/24 ipv6: fc0a::3b/64 ARISTA59T1: @@ -1927,7 +1927,7 @@ configuration: Ethernet1: ipv4: 10.0.0.181/31 ipv6: fc00::16a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.60/24 ipv6: fc0a::3c/64 ARISTA60T1: @@ -1946,7 +1946,7 @@ configuration: Ethernet1: ipv4: 10.0.0.183/31 ipv6: fc00::16e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.61/24 ipv6: fc0a::3d/64 ARISTA61T1: @@ -1965,7 +1965,7 @@ configuration: Ethernet1: ipv4: 10.0.0.185/31 ipv6: fc00::172/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.62/24 ipv6: fc0a::3e/64 ARISTA62T1: @@ -1984,7 +1984,7 @@ configuration: Ethernet1: ipv4: 10.0.0.187/31 ipv6: fc00::176/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.63/24 ipv6: fc0a::3f/64 ARISTA63T1: @@ -2003,7 +2003,7 @@ configuration: Ethernet1: ipv4: 10.0.0.189/31 ipv6: fc00::17a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.64/24 ipv6: fc0a::40/64 ARISTA64T1: @@ -2022,7 +2022,7 @@ configuration: Ethernet1: ipv4: 10.0.0.191/31 ipv6: fc00::17e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.65/24 ipv6: fc0a::41/64 ARISTA65T1: @@ -2041,7 +2041,7 @@ configuration: Ethernet1: ipv4: 10.0.1.65/31 ipv6: fc00::282/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.66/24 ipv6: fc0a::42/64 ARISTA66T1: @@ -2060,7 +2060,7 @@ configuration: Ethernet1: ipv4: 10.0.1.67/31 ipv6: fc00::286/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.67/24 ipv6: fc0a::43/64 ARISTA67T1: @@ -2079,7 +2079,7 @@ configuration: Ethernet1: ipv4: 10.0.1.69/31 ipv6: fc00::28a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.68/24 ipv6: fc0a::44/64 ARISTA68T1: @@ -2098,7 +2098,7 @@ configuration: Ethernet1: ipv4: 10.0.1.71/31 ipv6: fc00::28e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.69/24 ipv6: fc0a::45/64 ARISTA69T1: @@ -2117,7 +2117,7 @@ configuration: Ethernet1: ipv4: 10.0.1.73/31 ipv6: fc00::292/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.70/24 ipv6: fc0a::46/64 ARISTA70T1: @@ -2136,7 +2136,7 @@ configuration: Ethernet1: ipv4: 10.0.1.75/31 ipv6: fc00::296/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.71/24 ipv6: fc0a::47/64 ARISTA71T1: @@ -2155,7 +2155,7 @@ configuration: Ethernet1: ipv4: 10.0.1.77/31 ipv6: fc00::29a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.72/24 ipv6: fc0a::48/64 ARISTA72T1: @@ -2174,7 +2174,7 @@ configuration: Ethernet1: ipv4: 10.0.1.79/31 ipv6: fc00::29e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.73/24 ipv6: fc0a::49/64 ARISTA73T1: @@ -2193,7 +2193,7 @@ configuration: Ethernet1: ipv4: 10.0.1.81/31 ipv6: fc00::2a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.74/24 ipv6: fc0a::4a/64 ARISTA74T1: @@ -2212,7 +2212,7 @@ configuration: Ethernet1: ipv4: 10.0.1.83/31 ipv6: fc00::2a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.75/24 ipv6: fc0a::4b/64 ARISTA75T1: @@ -2231,7 +2231,7 @@ configuration: Ethernet1: ipv4: 10.0.1.85/31 ipv6: fc00::2aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.76/24 ipv6: fc0a::4c/64 ARISTA76T1: @@ -2250,7 +2250,7 @@ configuration: Ethernet1: ipv4: 10.0.1.87/31 ipv6: fc00::2ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.77/24 ipv6: fc0a::4d/64 ARISTA77T1: @@ -2269,7 +2269,7 @@ configuration: Ethernet1: ipv4: 10.0.1.89/31 ipv6: fc00::2b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.78/24 ipv6: fc0a::4e/64 ARISTA78T1: @@ -2288,7 +2288,7 @@ configuration: Ethernet1: ipv4: 10.0.1.91/31 ipv6: fc00::2b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.79/24 ipv6: fc0a::4f/64 ARISTA79T1: @@ -2307,7 +2307,7 @@ configuration: Ethernet1: ipv4: 10.0.1.93/31 ipv6: fc00::2ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.80/24 ipv6: fc0a::50/64 ARISTA80T1: @@ -2326,7 +2326,7 @@ configuration: Ethernet1: ipv4: 10.0.1.95/31 ipv6: fc00::2be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.81/24 ipv6: fc0a::51/64 ARISTA81T1: @@ -2345,7 +2345,7 @@ configuration: Ethernet1: ipv4: 10.0.1.97/31 ipv6: fc00::2c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.82/24 ipv6: fc0a::52/64 ARISTA82T1: @@ -2364,7 +2364,7 @@ configuration: Ethernet1: ipv4: 10.0.1.99/31 ipv6: fc00::2c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.83/24 ipv6: fc0a::53/64 ARISTA83T1: @@ -2383,7 +2383,7 @@ configuration: Ethernet1: ipv4: 10.0.1.101/31 ipv6: fc00::2ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.84/24 ipv6: fc0a::54/64 ARISTA84T1: @@ -2402,7 +2402,7 @@ configuration: Ethernet1: ipv4: 10.0.1.103/31 ipv6: fc00::2ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.85/24 ipv6: fc0a::55/64 ARISTA85T1: @@ -2421,7 +2421,7 @@ configuration: Ethernet1: ipv4: 10.0.1.105/31 ipv6: fc00::2d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.86/24 ipv6: fc0a::56/64 ARISTA86T1: @@ -2440,7 +2440,7 @@ configuration: Ethernet1: ipv4: 10.0.1.107/31 ipv6: fc00::2d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.87/24 ipv6: fc0a::57/64 ARISTA87T1: @@ -2459,7 +2459,7 @@ configuration: Ethernet1: ipv4: 10.0.1.109/31 ipv6: fc00::2da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.88/24 ipv6: fc0a::58/64 ARISTA88T1: @@ -2478,7 +2478,7 @@ configuration: Ethernet1: ipv4: 10.0.1.111/31 ipv6: fc00::2de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.89/24 ipv6: fc0a::59/64 ARISTA89T1: @@ -2497,7 +2497,7 @@ configuration: Ethernet1: ipv4: 10.0.1.113/31 ipv6: fc00::2e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.90/24 ipv6: fc0a::5a/64 ARISTA90T1: @@ -2516,7 +2516,7 @@ configuration: Ethernet1: ipv4: 10.0.1.115/31 ipv6: fc00::2e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.91/24 ipv6: fc0a::5b/64 ARISTA91T1: @@ -2535,7 +2535,7 @@ configuration: Ethernet1: ipv4: 10.0.1.117/31 ipv6: fc00::2ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.92/24 ipv6: fc0a::5c/64 ARISTA92T1: @@ -2554,7 +2554,7 @@ configuration: Ethernet1: ipv4: 10.0.1.119/31 ipv6: fc00::2ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.93/24 ipv6: fc0a::5d/64 ARISTA93T1: @@ -2573,7 +2573,7 @@ configuration: Ethernet1: ipv4: 10.0.1.121/31 ipv6: fc00::2f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.94/24 ipv6: fc0a::5e/64 ARISTA94T1: @@ -2592,7 +2592,7 @@ configuration: Ethernet1: ipv4: 10.0.1.123/31 ipv6: fc00::2f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.95/24 ipv6: fc0a::5f/64 ARISTA95T1: @@ -2611,7 +2611,7 @@ configuration: Ethernet1: ipv4: 10.0.1.125/31 ipv6: fc00::2fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.96/24 ipv6: fc0a::60/64 ARISTA96T1: @@ -2630,7 +2630,7 @@ configuration: Ethernet1: ipv4: 10.0.1.127/31 ipv6: fc00::2fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.97/24 ipv6: fc0a::61/64 ARISTA97T1: @@ -2649,7 +2649,7 @@ configuration: Ethernet1: ipv4: 10.0.1.129/31 ipv6: fc00::302/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.98/24 ipv6: fc0a::62/64 ARISTA98T1: @@ -2668,7 +2668,7 @@ configuration: Ethernet1: ipv4: 10.0.1.131/31 ipv6: fc00::306/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.99/24 ipv6: fc0a::63/64 ARISTA99T1: @@ -2687,7 +2687,7 @@ configuration: Ethernet1: ipv4: 10.0.1.133/31 ipv6: fc00::30a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.100/24 ipv6: fc0a::64/64 ARISTA100T1: @@ -2706,7 +2706,7 @@ configuration: Ethernet1: ipv4: 10.0.1.135/31 ipv6: fc00::30e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.101/24 ipv6: fc0a::65/64 ARISTA101T1: @@ -2725,7 +2725,7 @@ configuration: Ethernet1: ipv4: 10.0.1.137/31 ipv6: fc00::312/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.102/24 ipv6: fc0a::66/64 ARISTA102T1: @@ -2744,7 +2744,7 @@ configuration: Ethernet1: ipv4: 10.0.1.139/31 ipv6: fc00::316/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.103/24 ipv6: fc0a::67/64 ARISTA103T1: @@ -2763,7 +2763,7 @@ configuration: Ethernet1: ipv4: 10.0.1.141/31 ipv6: fc00::31a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.104/24 ipv6: fc0a::68/64 ARISTA104T1: @@ -2782,7 +2782,7 @@ configuration: Ethernet1: ipv4: 10.0.1.143/31 ipv6: fc00::31e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.105/24 ipv6: fc0a::69/64 ARISTA105T1: @@ -2801,7 +2801,7 @@ configuration: Ethernet1: ipv4: 10.0.1.145/31 ipv6: fc00::322/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.106/24 ipv6: fc0a::6a/64 ARISTA106T1: @@ -2820,7 +2820,7 @@ configuration: Ethernet1: ipv4: 10.0.1.147/31 ipv6: fc00::326/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.107/24 ipv6: fc0a::6b/64 ARISTA107T1: @@ -2839,7 +2839,7 @@ configuration: Ethernet1: ipv4: 10.0.1.149/31 ipv6: fc00::32a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.108/24 ipv6: fc0a::6c/64 ARISTA108T1: @@ -2858,7 +2858,7 @@ configuration: Ethernet1: ipv4: 10.0.1.151/31 ipv6: fc00::32e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.109/24 ipv6: fc0a::6d/64 ARISTA109T1: @@ -2877,7 +2877,7 @@ configuration: Ethernet1: ipv4: 10.0.1.153/31 ipv6: fc00::332/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.110/24 ipv6: fc0a::6e/64 ARISTA110T1: @@ -2896,7 +2896,7 @@ configuration: Ethernet1: ipv4: 10.0.1.155/31 ipv6: fc00::336/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.111/24 ipv6: fc0a::6f/64 ARISTA111T1: @@ -2915,7 +2915,7 @@ configuration: Ethernet1: ipv4: 10.0.1.157/31 ipv6: fc00::33a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.112/24 ipv6: fc0a::70/64 ARISTA112T1: @@ -2934,7 +2934,7 @@ configuration: Ethernet1: ipv4: 10.0.1.159/31 ipv6: fc00::33e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.113/24 ipv6: fc0a::71/64 ARISTA113T1: @@ -2953,7 +2953,7 @@ configuration: Ethernet1: ipv4: 10.0.1.161/31 ipv6: fc00::342/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.114/24 ipv6: fc0a::72/64 ARISTA114T1: @@ -2972,7 +2972,7 @@ configuration: Ethernet1: ipv4: 10.0.1.163/31 ipv6: fc00::346/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.115/24 ipv6: fc0a::73/64 ARISTA115T1: @@ -2991,7 +2991,7 @@ configuration: Ethernet1: ipv4: 10.0.1.165/31 ipv6: fc00::34a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.116/24 ipv6: fc0a::74/64 ARISTA116T1: @@ -3010,7 +3010,7 @@ configuration: Ethernet1: ipv4: 10.0.1.167/31 ipv6: fc00::34e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.117/24 ipv6: fc0a::75/64 ARISTA117T1: @@ -3029,7 +3029,7 @@ configuration: Ethernet1: ipv4: 10.0.1.169/31 ipv6: fc00::352/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.118/24 ipv6: fc0a::76/64 ARISTA118T1: @@ -3048,7 +3048,7 @@ configuration: Ethernet1: ipv4: 10.0.1.171/31 ipv6: fc00::356/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.119/24 ipv6: fc0a::77/64 ARISTA119T1: @@ -3067,7 +3067,7 @@ configuration: Ethernet1: ipv4: 10.0.1.173/31 ipv6: fc00::35a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.120/24 ipv6: fc0a::78/64 ARISTA120T1: @@ -3086,7 +3086,7 @@ configuration: Ethernet1: ipv4: 10.0.1.175/31 ipv6: fc00::35e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.121/24 ipv6: fc0a::79/64 ARISTA121T1: @@ -3105,7 +3105,7 @@ configuration: Ethernet1: ipv4: 10.0.1.177/31 ipv6: fc00::362/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.122/24 ipv6: fc0a::7a/64 ARISTA122T1: @@ -3124,7 +3124,7 @@ configuration: Ethernet1: ipv4: 10.0.1.179/31 ipv6: fc00::366/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.123/24 ipv6: fc0a::7b/64 ARISTA123T1: @@ -3143,7 +3143,7 @@ configuration: Ethernet1: ipv4: 10.0.1.181/31 ipv6: fc00::36a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.124/24 ipv6: fc0a::7c/64 ARISTA124T1: @@ -3162,7 +3162,7 @@ configuration: Ethernet1: ipv4: 10.0.1.183/31 ipv6: fc00::36e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.125/24 ipv6: fc0a::7d/64 ARISTA125T1: @@ -3181,7 +3181,7 @@ configuration: Ethernet1: ipv4: 10.0.1.185/31 ipv6: fc00::372/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.126/24 ipv6: fc0a::7e/64 ARISTA126T1: @@ -3200,7 +3200,7 @@ configuration: Ethernet1: ipv4: 10.0.1.187/31 ipv6: fc00::376/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.127/24 ipv6: fc0a::7f/64 ARISTA127T1: @@ -3219,7 +3219,7 @@ configuration: Ethernet1: ipv4: 10.0.1.189/31 ipv6: fc00::37a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.128/24 ipv6: fc0a::80/64 ARISTA128T1: @@ -3238,7 +3238,7 @@ configuration: Ethernet1: ipv4: 10.0.1.191/31 ipv6: fc00::37e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.129/24 ipv6: fc0a::81/64 ARISTA01PT0: @@ -3257,6 +3257,6 @@ configuration: Ethernet1: ipv4: 10.0.2.1/31 ipv6: fc00::402/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.130/24 ipv6: fc0a::82/64 diff --git a/ansible/vars/topo_t0-isolated-d128u128s2.yml b/ansible/vars/topo_t0-isolated-d128u128s2.yml index 5830728fee7..201b68672e5 100644 --- a/ansible/vars/topo_t0-isolated-d128u128s2.yml +++ b/ansible/vars/topo_t0-isolated-d128u128s2.yml @@ -829,7 +829,7 @@ configuration: Ethernet1: ipv4: 10.0.0.65/31 ipv6: fc00::82/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.2/24 ipv6: fc0a::2/64 ARISTA02T1: @@ -848,7 +848,7 @@ configuration: Ethernet1: ipv4: 10.0.0.67/31 ipv6: fc00::86/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.3/24 ipv6: fc0a::3/64 ARISTA03T1: @@ -867,7 +867,7 @@ configuration: Ethernet1: ipv4: 10.0.0.69/31 ipv6: fc00::8a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.4/24 ipv6: fc0a::4/64 ARISTA04T1: @@ -886,7 +886,7 @@ configuration: Ethernet1: ipv4: 10.0.0.71/31 ipv6: fc00::8e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.5/24 ipv6: fc0a::5/64 ARISTA05T1: @@ -905,7 +905,7 @@ configuration: Ethernet1: ipv4: 10.0.0.73/31 ipv6: fc00::92/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.6/24 ipv6: fc0a::6/64 ARISTA06T1: @@ -924,7 +924,7 @@ configuration: Ethernet1: ipv4: 10.0.0.75/31 ipv6: fc00::96/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.7/24 ipv6: fc0a::7/64 ARISTA07T1: @@ -943,7 +943,7 @@ configuration: Ethernet1: ipv4: 10.0.0.77/31 ipv6: fc00::9a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.8/24 ipv6: fc0a::8/64 ARISTA08T1: @@ -962,7 +962,7 @@ configuration: Ethernet1: ipv4: 10.0.0.79/31 ipv6: fc00::9e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.9/24 ipv6: fc0a::9/64 ARISTA09T1: @@ -981,7 +981,7 @@ configuration: Ethernet1: ipv4: 10.0.0.81/31 ipv6: fc00::a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.10/24 ipv6: fc0a::a/64 ARISTA10T1: @@ -1000,7 +1000,7 @@ configuration: Ethernet1: ipv4: 10.0.0.83/31 ipv6: fc00::a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.11/24 ipv6: fc0a::b/64 ARISTA11T1: @@ -1019,7 +1019,7 @@ configuration: Ethernet1: ipv4: 10.0.0.85/31 ipv6: fc00::aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.12/24 ipv6: fc0a::c/64 ARISTA12T1: @@ -1038,7 +1038,7 @@ configuration: Ethernet1: ipv4: 10.0.0.87/31 ipv6: fc00::ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.13/24 ipv6: fc0a::d/64 ARISTA13T1: @@ -1057,7 +1057,7 @@ configuration: Ethernet1: ipv4: 10.0.0.89/31 ipv6: fc00::b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.14/24 ipv6: fc0a::e/64 ARISTA14T1: @@ -1076,7 +1076,7 @@ configuration: Ethernet1: ipv4: 10.0.0.91/31 ipv6: fc00::b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.15/24 ipv6: fc0a::f/64 ARISTA15T1: @@ -1095,7 +1095,7 @@ configuration: Ethernet1: ipv4: 10.0.0.93/31 ipv6: fc00::ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.16/24 ipv6: fc0a::10/64 ARISTA16T1: @@ -1114,7 +1114,7 @@ configuration: Ethernet1: ipv4: 10.0.0.95/31 ipv6: fc00::be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.17/24 ipv6: fc0a::11/64 ARISTA17T1: @@ -1133,7 +1133,7 @@ configuration: Ethernet1: ipv4: 10.0.0.97/31 ipv6: fc00::c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.18/24 ipv6: fc0a::12/64 ARISTA18T1: @@ -1152,7 +1152,7 @@ configuration: Ethernet1: ipv4: 10.0.0.99/31 ipv6: fc00::c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.19/24 ipv6: fc0a::13/64 ARISTA19T1: @@ -1171,7 +1171,7 @@ configuration: Ethernet1: ipv4: 10.0.0.101/31 ipv6: fc00::ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.20/24 ipv6: fc0a::14/64 ARISTA20T1: @@ -1190,7 +1190,7 @@ configuration: Ethernet1: ipv4: 10.0.0.103/31 ipv6: fc00::ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.21/24 ipv6: fc0a::15/64 ARISTA21T1: @@ -1209,7 +1209,7 @@ configuration: Ethernet1: ipv4: 10.0.0.105/31 ipv6: fc00::d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.22/24 ipv6: fc0a::16/64 ARISTA22T1: @@ -1228,7 +1228,7 @@ configuration: Ethernet1: ipv4: 10.0.0.107/31 ipv6: fc00::d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.23/24 ipv6: fc0a::17/64 ARISTA23T1: @@ -1247,7 +1247,7 @@ configuration: Ethernet1: ipv4: 10.0.0.109/31 ipv6: fc00::da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.24/24 ipv6: fc0a::18/64 ARISTA24T1: @@ -1266,7 +1266,7 @@ configuration: Ethernet1: ipv4: 10.0.0.111/31 ipv6: fc00::de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.25/24 ipv6: fc0a::19/64 ARISTA25T1: @@ -1285,7 +1285,7 @@ configuration: Ethernet1: ipv4: 10.0.0.113/31 ipv6: fc00::e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.26/24 ipv6: fc0a::1a/64 ARISTA26T1: @@ -1304,7 +1304,7 @@ configuration: Ethernet1: ipv4: 10.0.0.115/31 ipv6: fc00::e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.27/24 ipv6: fc0a::1b/64 ARISTA27T1: @@ -1323,7 +1323,7 @@ configuration: Ethernet1: ipv4: 10.0.0.117/31 ipv6: fc00::ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.28/24 ipv6: fc0a::1c/64 ARISTA28T1: @@ -1342,7 +1342,7 @@ configuration: Ethernet1: ipv4: 10.0.0.119/31 ipv6: fc00::ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.29/24 ipv6: fc0a::1d/64 ARISTA29T1: @@ -1361,7 +1361,7 @@ configuration: Ethernet1: ipv4: 10.0.0.121/31 ipv6: fc00::f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.30/24 ipv6: fc0a::1e/64 ARISTA30T1: @@ -1380,7 +1380,7 @@ configuration: Ethernet1: ipv4: 10.0.0.123/31 ipv6: fc00::f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.31/24 ipv6: fc0a::1f/64 ARISTA31T1: @@ -1399,7 +1399,7 @@ configuration: Ethernet1: ipv4: 10.0.0.125/31 ipv6: fc00::fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.32/24 ipv6: fc0a::20/64 ARISTA32T1: @@ -1418,7 +1418,7 @@ configuration: Ethernet1: ipv4: 10.0.0.127/31 ipv6: fc00::fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.33/24 ipv6: fc0a::21/64 ARISTA33T1: @@ -1437,7 +1437,7 @@ configuration: Ethernet1: ipv4: 10.0.0.129/31 ipv6: fc00::102/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.34/24 ipv6: fc0a::22/64 ARISTA34T1: @@ -1456,7 +1456,7 @@ configuration: Ethernet1: ipv4: 10.0.0.131/31 ipv6: fc00::106/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.35/24 ipv6: fc0a::23/64 ARISTA35T1: @@ -1475,7 +1475,7 @@ configuration: Ethernet1: ipv4: 10.0.0.133/31 ipv6: fc00::10a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.36/24 ipv6: fc0a::24/64 ARISTA36T1: @@ -1494,7 +1494,7 @@ configuration: Ethernet1: ipv4: 10.0.0.135/31 ipv6: fc00::10e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.37/24 ipv6: fc0a::25/64 ARISTA37T1: @@ -1513,7 +1513,7 @@ configuration: Ethernet1: ipv4: 10.0.0.137/31 ipv6: fc00::112/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.38/24 ipv6: fc0a::26/64 ARISTA38T1: @@ -1532,7 +1532,7 @@ configuration: Ethernet1: ipv4: 10.0.0.139/31 ipv6: fc00::116/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.39/24 ipv6: fc0a::27/64 ARISTA39T1: @@ -1551,7 +1551,7 @@ configuration: Ethernet1: ipv4: 10.0.0.141/31 ipv6: fc00::11a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.40/24 ipv6: fc0a::28/64 ARISTA40T1: @@ -1570,7 +1570,7 @@ configuration: Ethernet1: ipv4: 10.0.0.143/31 ipv6: fc00::11e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.41/24 ipv6: fc0a::29/64 ARISTA41T1: @@ -1589,7 +1589,7 @@ configuration: Ethernet1: ipv4: 10.0.0.145/31 ipv6: fc00::122/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.42/24 ipv6: fc0a::2a/64 ARISTA42T1: @@ -1608,7 +1608,7 @@ configuration: Ethernet1: ipv4: 10.0.0.147/31 ipv6: fc00::126/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.43/24 ipv6: fc0a::2b/64 ARISTA43T1: @@ -1627,7 +1627,7 @@ configuration: Ethernet1: ipv4: 10.0.0.149/31 ipv6: fc00::12a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.44/24 ipv6: fc0a::2c/64 ARISTA44T1: @@ -1646,7 +1646,7 @@ configuration: Ethernet1: ipv4: 10.0.0.151/31 ipv6: fc00::12e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.45/24 ipv6: fc0a::2d/64 ARISTA45T1: @@ -1665,7 +1665,7 @@ configuration: Ethernet1: ipv4: 10.0.0.153/31 ipv6: fc00::132/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.46/24 ipv6: fc0a::2e/64 ARISTA46T1: @@ -1684,7 +1684,7 @@ configuration: Ethernet1: ipv4: 10.0.0.155/31 ipv6: fc00::136/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.47/24 ipv6: fc0a::2f/64 ARISTA47T1: @@ -1703,7 +1703,7 @@ configuration: Ethernet1: ipv4: 10.0.0.157/31 ipv6: fc00::13a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.48/24 ipv6: fc0a::30/64 ARISTA48T1: @@ -1722,7 +1722,7 @@ configuration: Ethernet1: ipv4: 10.0.0.159/31 ipv6: fc00::13e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.49/24 ipv6: fc0a::31/64 ARISTA49T1: @@ -1741,7 +1741,7 @@ configuration: Ethernet1: ipv4: 10.0.0.161/31 ipv6: fc00::142/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.50/24 ipv6: fc0a::32/64 ARISTA50T1: @@ -1760,7 +1760,7 @@ configuration: Ethernet1: ipv4: 10.0.0.163/31 ipv6: fc00::146/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.51/24 ipv6: fc0a::33/64 ARISTA51T1: @@ -1779,7 +1779,7 @@ configuration: Ethernet1: ipv4: 10.0.0.165/31 ipv6: fc00::14a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.52/24 ipv6: fc0a::34/64 ARISTA52T1: @@ -1798,7 +1798,7 @@ configuration: Ethernet1: ipv4: 10.0.0.167/31 ipv6: fc00::14e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.53/24 ipv6: fc0a::35/64 ARISTA53T1: @@ -1817,7 +1817,7 @@ configuration: Ethernet1: ipv4: 10.0.0.169/31 ipv6: fc00::152/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.54/24 ipv6: fc0a::36/64 ARISTA54T1: @@ -1836,7 +1836,7 @@ configuration: Ethernet1: ipv4: 10.0.0.171/31 ipv6: fc00::156/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.55/24 ipv6: fc0a::37/64 ARISTA55T1: @@ -1855,7 +1855,7 @@ configuration: Ethernet1: ipv4: 10.0.0.173/31 ipv6: fc00::15a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.56/24 ipv6: fc0a::38/64 ARISTA56T1: @@ -1874,7 +1874,7 @@ configuration: Ethernet1: ipv4: 10.0.0.175/31 ipv6: fc00::15e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.57/24 ipv6: fc0a::39/64 ARISTA57T1: @@ -1893,7 +1893,7 @@ configuration: Ethernet1: ipv4: 10.0.0.177/31 ipv6: fc00::162/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.58/24 ipv6: fc0a::3a/64 ARISTA58T1: @@ -1912,7 +1912,7 @@ configuration: Ethernet1: ipv4: 10.0.0.179/31 ipv6: fc00::166/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.59/24 ipv6: fc0a::3b/64 ARISTA59T1: @@ -1931,7 +1931,7 @@ configuration: Ethernet1: ipv4: 10.0.0.181/31 ipv6: fc00::16a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.60/24 ipv6: fc0a::3c/64 ARISTA60T1: @@ -1950,7 +1950,7 @@ configuration: Ethernet1: ipv4: 10.0.0.183/31 ipv6: fc00::16e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.61/24 ipv6: fc0a::3d/64 ARISTA61T1: @@ -1969,7 +1969,7 @@ configuration: Ethernet1: ipv4: 10.0.0.185/31 ipv6: fc00::172/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.62/24 ipv6: fc0a::3e/64 ARISTA62T1: @@ -1988,7 +1988,7 @@ configuration: Ethernet1: ipv4: 10.0.0.187/31 ipv6: fc00::176/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.63/24 ipv6: fc0a::3f/64 ARISTA63T1: @@ -2007,7 +2007,7 @@ configuration: Ethernet1: ipv4: 10.0.0.189/31 ipv6: fc00::17a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.64/24 ipv6: fc0a::40/64 ARISTA64T1: @@ -2026,7 +2026,7 @@ configuration: Ethernet1: ipv4: 10.0.0.191/31 ipv6: fc00::17e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.65/24 ipv6: fc0a::41/64 ARISTA65T1: @@ -2045,7 +2045,7 @@ configuration: Ethernet1: ipv4: 10.0.1.65/31 ipv6: fc00::282/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.66/24 ipv6: fc0a::42/64 ARISTA66T1: @@ -2064,7 +2064,7 @@ configuration: Ethernet1: ipv4: 10.0.1.67/31 ipv6: fc00::286/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.67/24 ipv6: fc0a::43/64 ARISTA67T1: @@ -2083,7 +2083,7 @@ configuration: Ethernet1: ipv4: 10.0.1.69/31 ipv6: fc00::28a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.68/24 ipv6: fc0a::44/64 ARISTA68T1: @@ -2102,7 +2102,7 @@ configuration: Ethernet1: ipv4: 10.0.1.71/31 ipv6: fc00::28e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.69/24 ipv6: fc0a::45/64 ARISTA69T1: @@ -2121,7 +2121,7 @@ configuration: Ethernet1: ipv4: 10.0.1.73/31 ipv6: fc00::292/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.70/24 ipv6: fc0a::46/64 ARISTA70T1: @@ -2140,7 +2140,7 @@ configuration: Ethernet1: ipv4: 10.0.1.75/31 ipv6: fc00::296/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.71/24 ipv6: fc0a::47/64 ARISTA71T1: @@ -2159,7 +2159,7 @@ configuration: Ethernet1: ipv4: 10.0.1.77/31 ipv6: fc00::29a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.72/24 ipv6: fc0a::48/64 ARISTA72T1: @@ -2178,7 +2178,7 @@ configuration: Ethernet1: ipv4: 10.0.1.79/31 ipv6: fc00::29e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.73/24 ipv6: fc0a::49/64 ARISTA73T1: @@ -2197,7 +2197,7 @@ configuration: Ethernet1: ipv4: 10.0.1.81/31 ipv6: fc00::2a2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.74/24 ipv6: fc0a::4a/64 ARISTA74T1: @@ -2216,7 +2216,7 @@ configuration: Ethernet1: ipv4: 10.0.1.83/31 ipv6: fc00::2a6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.75/24 ipv6: fc0a::4b/64 ARISTA75T1: @@ -2235,7 +2235,7 @@ configuration: Ethernet1: ipv4: 10.0.1.85/31 ipv6: fc00::2aa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.76/24 ipv6: fc0a::4c/64 ARISTA76T1: @@ -2254,7 +2254,7 @@ configuration: Ethernet1: ipv4: 10.0.1.87/31 ipv6: fc00::2ae/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.77/24 ipv6: fc0a::4d/64 ARISTA77T1: @@ -2273,7 +2273,7 @@ configuration: Ethernet1: ipv4: 10.0.1.89/31 ipv6: fc00::2b2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.78/24 ipv6: fc0a::4e/64 ARISTA78T1: @@ -2292,7 +2292,7 @@ configuration: Ethernet1: ipv4: 10.0.1.91/31 ipv6: fc00::2b6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.79/24 ipv6: fc0a::4f/64 ARISTA79T1: @@ -2311,7 +2311,7 @@ configuration: Ethernet1: ipv4: 10.0.1.93/31 ipv6: fc00::2ba/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.80/24 ipv6: fc0a::50/64 ARISTA80T1: @@ -2330,7 +2330,7 @@ configuration: Ethernet1: ipv4: 10.0.1.95/31 ipv6: fc00::2be/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.81/24 ipv6: fc0a::51/64 ARISTA81T1: @@ -2349,7 +2349,7 @@ configuration: Ethernet1: ipv4: 10.0.1.97/31 ipv6: fc00::2c2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.82/24 ipv6: fc0a::52/64 ARISTA82T1: @@ -2368,7 +2368,7 @@ configuration: Ethernet1: ipv4: 10.0.1.99/31 ipv6: fc00::2c6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.83/24 ipv6: fc0a::53/64 ARISTA83T1: @@ -2387,7 +2387,7 @@ configuration: Ethernet1: ipv4: 10.0.1.101/31 ipv6: fc00::2ca/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.84/24 ipv6: fc0a::54/64 ARISTA84T1: @@ -2406,7 +2406,7 @@ configuration: Ethernet1: ipv4: 10.0.1.103/31 ipv6: fc00::2ce/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.85/24 ipv6: fc0a::55/64 ARISTA85T1: @@ -2425,7 +2425,7 @@ configuration: Ethernet1: ipv4: 10.0.1.105/31 ipv6: fc00::2d2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.86/24 ipv6: fc0a::56/64 ARISTA86T1: @@ -2444,7 +2444,7 @@ configuration: Ethernet1: ipv4: 10.0.1.107/31 ipv6: fc00::2d6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.87/24 ipv6: fc0a::57/64 ARISTA87T1: @@ -2463,7 +2463,7 @@ configuration: Ethernet1: ipv4: 10.0.1.109/31 ipv6: fc00::2da/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.88/24 ipv6: fc0a::58/64 ARISTA88T1: @@ -2482,7 +2482,7 @@ configuration: Ethernet1: ipv4: 10.0.1.111/31 ipv6: fc00::2de/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.89/24 ipv6: fc0a::59/64 ARISTA89T1: @@ -2501,7 +2501,7 @@ configuration: Ethernet1: ipv4: 10.0.1.113/31 ipv6: fc00::2e2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.90/24 ipv6: fc0a::5a/64 ARISTA90T1: @@ -2520,7 +2520,7 @@ configuration: Ethernet1: ipv4: 10.0.1.115/31 ipv6: fc00::2e6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.91/24 ipv6: fc0a::5b/64 ARISTA91T1: @@ -2539,7 +2539,7 @@ configuration: Ethernet1: ipv4: 10.0.1.117/31 ipv6: fc00::2ea/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.92/24 ipv6: fc0a::5c/64 ARISTA92T1: @@ -2558,7 +2558,7 @@ configuration: Ethernet1: ipv4: 10.0.1.119/31 ipv6: fc00::2ee/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.93/24 ipv6: fc0a::5d/64 ARISTA93T1: @@ -2577,7 +2577,7 @@ configuration: Ethernet1: ipv4: 10.0.1.121/31 ipv6: fc00::2f2/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.94/24 ipv6: fc0a::5e/64 ARISTA94T1: @@ -2596,7 +2596,7 @@ configuration: Ethernet1: ipv4: 10.0.1.123/31 ipv6: fc00::2f6/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.95/24 ipv6: fc0a::5f/64 ARISTA95T1: @@ -2615,7 +2615,7 @@ configuration: Ethernet1: ipv4: 10.0.1.125/31 ipv6: fc00::2fa/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.96/24 ipv6: fc0a::60/64 ARISTA96T1: @@ -2634,7 +2634,7 @@ configuration: Ethernet1: ipv4: 10.0.1.127/31 ipv6: fc00::2fe/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.97/24 ipv6: fc0a::61/64 ARISTA97T1: @@ -2653,7 +2653,7 @@ configuration: Ethernet1: ipv4: 10.0.1.129/31 ipv6: fc00::302/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.98/24 ipv6: fc0a::62/64 ARISTA98T1: @@ -2672,7 +2672,7 @@ configuration: Ethernet1: ipv4: 10.0.1.131/31 ipv6: fc00::306/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.99/24 ipv6: fc0a::63/64 ARISTA99T1: @@ -2691,7 +2691,7 @@ configuration: Ethernet1: ipv4: 10.0.1.133/31 ipv6: fc00::30a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.100/24 ipv6: fc0a::64/64 ARISTA100T1: @@ -2710,7 +2710,7 @@ configuration: Ethernet1: ipv4: 10.0.1.135/31 ipv6: fc00::30e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.101/24 ipv6: fc0a::65/64 ARISTA101T1: @@ -2729,7 +2729,7 @@ configuration: Ethernet1: ipv4: 10.0.1.137/31 ipv6: fc00::312/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.102/24 ipv6: fc0a::66/64 ARISTA102T1: @@ -2748,7 +2748,7 @@ configuration: Ethernet1: ipv4: 10.0.1.139/31 ipv6: fc00::316/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.103/24 ipv6: fc0a::67/64 ARISTA103T1: @@ -2767,7 +2767,7 @@ configuration: Ethernet1: ipv4: 10.0.1.141/31 ipv6: fc00::31a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.104/24 ipv6: fc0a::68/64 ARISTA104T1: @@ -2786,7 +2786,7 @@ configuration: Ethernet1: ipv4: 10.0.1.143/31 ipv6: fc00::31e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.105/24 ipv6: fc0a::69/64 ARISTA105T1: @@ -2805,7 +2805,7 @@ configuration: Ethernet1: ipv4: 10.0.1.145/31 ipv6: fc00::322/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.106/24 ipv6: fc0a::6a/64 ARISTA106T1: @@ -2824,7 +2824,7 @@ configuration: Ethernet1: ipv4: 10.0.1.147/31 ipv6: fc00::326/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.107/24 ipv6: fc0a::6b/64 ARISTA107T1: @@ -2843,7 +2843,7 @@ configuration: Ethernet1: ipv4: 10.0.1.149/31 ipv6: fc00::32a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.108/24 ipv6: fc0a::6c/64 ARISTA108T1: @@ -2862,7 +2862,7 @@ configuration: Ethernet1: ipv4: 10.0.1.151/31 ipv6: fc00::32e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.109/24 ipv6: fc0a::6d/64 ARISTA109T1: @@ -2881,7 +2881,7 @@ configuration: Ethernet1: ipv4: 10.0.1.153/31 ipv6: fc00::332/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.110/24 ipv6: fc0a::6e/64 ARISTA110T1: @@ -2900,7 +2900,7 @@ configuration: Ethernet1: ipv4: 10.0.1.155/31 ipv6: fc00::336/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.111/24 ipv6: fc0a::6f/64 ARISTA111T1: @@ -2919,7 +2919,7 @@ configuration: Ethernet1: ipv4: 10.0.1.157/31 ipv6: fc00::33a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.112/24 ipv6: fc0a::70/64 ARISTA112T1: @@ -2938,7 +2938,7 @@ configuration: Ethernet1: ipv4: 10.0.1.159/31 ipv6: fc00::33e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.113/24 ipv6: fc0a::71/64 ARISTA113T1: @@ -2957,7 +2957,7 @@ configuration: Ethernet1: ipv4: 10.0.1.161/31 ipv6: fc00::342/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.114/24 ipv6: fc0a::72/64 ARISTA114T1: @@ -2976,7 +2976,7 @@ configuration: Ethernet1: ipv4: 10.0.1.163/31 ipv6: fc00::346/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.115/24 ipv6: fc0a::73/64 ARISTA115T1: @@ -2995,7 +2995,7 @@ configuration: Ethernet1: ipv4: 10.0.1.165/31 ipv6: fc00::34a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.116/24 ipv6: fc0a::74/64 ARISTA116T1: @@ -3014,7 +3014,7 @@ configuration: Ethernet1: ipv4: 10.0.1.167/31 ipv6: fc00::34e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.117/24 ipv6: fc0a::75/64 ARISTA117T1: @@ -3033,7 +3033,7 @@ configuration: Ethernet1: ipv4: 10.0.1.169/31 ipv6: fc00::352/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.118/24 ipv6: fc0a::76/64 ARISTA118T1: @@ -3052,7 +3052,7 @@ configuration: Ethernet1: ipv4: 10.0.1.171/31 ipv6: fc00::356/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.119/24 ipv6: fc0a::77/64 ARISTA119T1: @@ -3071,7 +3071,7 @@ configuration: Ethernet1: ipv4: 10.0.1.173/31 ipv6: fc00::35a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.120/24 ipv6: fc0a::78/64 ARISTA120T1: @@ -3090,7 +3090,7 @@ configuration: Ethernet1: ipv4: 10.0.1.175/31 ipv6: fc00::35e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.121/24 ipv6: fc0a::79/64 ARISTA121T1: @@ -3109,7 +3109,7 @@ configuration: Ethernet1: ipv4: 10.0.1.177/31 ipv6: fc00::362/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.122/24 ipv6: fc0a::7a/64 ARISTA122T1: @@ -3128,7 +3128,7 @@ configuration: Ethernet1: ipv4: 10.0.1.179/31 ipv6: fc00::366/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.123/24 ipv6: fc0a::7b/64 ARISTA123T1: @@ -3147,7 +3147,7 @@ configuration: Ethernet1: ipv4: 10.0.1.181/31 ipv6: fc00::36a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.124/24 ipv6: fc0a::7c/64 ARISTA124T1: @@ -3166,7 +3166,7 @@ configuration: Ethernet1: ipv4: 10.0.1.183/31 ipv6: fc00::36e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.125/24 ipv6: fc0a::7d/64 ARISTA125T1: @@ -3185,7 +3185,7 @@ configuration: Ethernet1: ipv4: 10.0.1.185/31 ipv6: fc00::372/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.126/24 ipv6: fc0a::7e/64 ARISTA126T1: @@ -3204,7 +3204,7 @@ configuration: Ethernet1: ipv4: 10.0.1.187/31 ipv6: fc00::376/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.127/24 ipv6: fc0a::7f/64 ARISTA127T1: @@ -3223,7 +3223,7 @@ configuration: Ethernet1: ipv4: 10.0.1.189/31 ipv6: fc00::37a/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.128/24 ipv6: fc0a::80/64 ARISTA128T1: @@ -3242,7 +3242,7 @@ configuration: Ethernet1: ipv4: 10.0.1.191/31 ipv6: fc00::37e/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.129/24 ipv6: fc0a::81/64 ARISTA01PT0: @@ -3261,7 +3261,7 @@ configuration: Ethernet1: ipv4: 10.0.2.1/31 ipv6: fc00::402/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.130/24 ipv6: fc0a::82/64 ARISTA02PT0: @@ -3280,6 +3280,6 @@ configuration: Ethernet1: ipv4: 10.0.2.3/31 ipv6: fc00::406/126 - bp_interfaces: + bp_interface: ipv4: 10.10.246.131/24 ipv6: fc0a::83/64 diff --git a/ansible/veos b/ansible/veos index 6d545542b13..634c7eaa421 100644 --- a/ansible/veos +++ b/ansible/veos @@ -208,17 +208,141 @@ vms_1: ansible_host: 10.250.0.68 VM0167: ansible_host: 10.250.0.69 - -vms_2: - hosts: + VM0168: + ansible_host: 10.250.0.70 + VM0169: + ansible_host: 10.250.0.71 + VM0170: + ansible_host: 10.250.0.72 + VM0171: + ansible_host: 10.250.0.73 + VM0172: + ansible_host: 10.250.0.74 + VM0173: + ansible_host: 10.250.0.75 + VM0174: + ansible_host: 10.250.0.76 + VM0175: + ansible_host: 10.250.0.77 + VM0176: + ansible_host: 10.250.0.78 + VM0177: + ansible_host: 10.250.0.79 + VM0178: + ansible_host: 10.250.0.80 + VM0179: + ansible_host: 10.250.0.81 + VM0180: + ansible_host: 10.250.0.82 + VM0181: + ansible_host: 10.250.0.83 + VM0182: + ansible_host: 10.250.0.84 + VM0183: + ansible_host: 10.250.0.85 + VM0184: + ansible_host: 10.250.0.86 + VM0185: + ansible_host: 10.250.0.87 + VM0186: + ansible_host: 10.250.0.88 + VM0187: + ansible_host: 10.250.0.89 + VM0188: + ansible_host: 10.250.0.90 + VM0189: + ansible_host: 10.250.0.91 + VM0190: + ansible_host: 10.250.0.92 + VM0191: + ansible_host: 10.250.0.93 + VM0192: + ansible_host: 10.250.0.94 + VM0193: + ansible_host: 10.250.0.95 + VM0194: + ansible_host: 10.250.0.96 + VM0195: + ansible_host: 10.250.0.97 + VM0196: + ansible_host: 10.250.0.98 + VM0197: + ansible_host: 10.250.0.99 + VM0198: + ansible_host: 10.250.0.100 + VM0199: + ansible_host: 10.250.0.101 VM0200: - ansible_host: 10.250.0.51 + ansible_host: 10.250.0.102 VM0201: - ansible_host: 10.250.0.52 + ansible_host: 10.250.0.103 VM0202: - ansible_host: 10.250.0.53 + ansible_host: 10.250.0.104 VM0203: - ansible_host: 10.250.0.54 + ansible_host: 10.250.0.105 + VM0204: + ansible_host: 10.250.0.106 + VM0205: + ansible_host: 10.250.0.107 + VM0206: + ansible_host: 10.250.0.108 + VM0207: + ansible_host: 10.250.0.109 + VM0208: + ansible_host: 10.250.0.110 + VM0209: + ansible_host: 10.250.0.111 + VM0210: + ansible_host: 10.250.0.112 + VM0211: + ansible_host: 10.250.0.113 + VM0212: + ansible_host: 10.250.0.114 + VM0213: + ansible_host: 10.250.0.115 + VM0214: + ansible_host: 10.250.0.116 + VM0215: + ansible_host: 10.250.0.117 + VM0216: + ansible_host: 10.250.0.118 + VM0217: + ansible_host: 10.250.0.119 + VM0218: + ansible_host: 10.250.0.120 + VM0219: + ansible_host: 10.250.0.121 + VM0220: + ansible_host: 10.250.0.122 + VM0221: + ansible_host: 10.250.0.123 + VM0222: + ansible_host: 10.250.0.124 + VM0223: + ansible_host: 10.250.0.125 + VM0224: + ansible_host: 10.250.0.126 + VM0225: + ansible_host: 10.250.0.127 + VM0226: + ansible_host: 10.250.0.128 + VM0227: + ansible_host: 10.250.0.129 + VM0228: + ansible_host: 10.250.0.130 + VM0229: + ansible_host: 10.250.0.131 + +vms_2: + hosts: + VM0300: + ansible_host: 10.250.0.252 + VM0301: + ansible_host: 10.250.0.253 + VM0302: + ansible_host: 10.250.0.254 + VM0303: + ansible_host: 10.250.0.255 # The groups below are helper to limit running playbooks to specific server(s) only server_1: From 946c6d8ba888d8e6c433e58995de5dbfb7816f5b Mon Sep 17 00:00:00 2001 From: xwjiang-ms <96218837+xwjiang-ms@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:23:05 +0800 Subject: [PATCH 184/221] Install azure-cli step by step to fix dpkg lock failure (#15558) What is the motivation for this PR? PR/nightly test have a chance to fail in installing azure-cli for unable to acquire dpkg lock, which means there are 2 or more processes are running apt install at the same time How did you do it? Install azure-cli step by step, and add a timeout for all apt action to acquire dpkg lock Ref: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-linux?pivots=apt How did you verify/test it? --- .../run-test-elastictest-template.yml | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 595a6cb3136..740bbc8db7b 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -178,7 +178,29 @@ steps: # Check if azure cli is installed. If not, try to install it if ! command -v az; then echo "Azure CLI is not installed. Trying to install it..." - curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + + echo "Get packages needed for the installation process" + sudo apt-get -o DPkg::Lock::Timeout=600 update + sudo apt-get -o DPkg::Lock::Timeout=600 -y install apt-transport-https ca-certificates curl gnupg lsb-release + + echo "Download and install the Microsoft signing key" + sudo mkdir -p /etc/apt/keyrings + curl -sLS https://packages.microsoft.com/keys/microsoft.asc | + gpg --dearmor | sudo tee /etc/apt/keyrings/microsoft.gpg > /dev/null + sudo chmod go+r /etc/apt/keyrings/microsoft.gpg + + echo "Add the Azure CLI software repository" + AZ_DIST=$(lsb_release -cs) + echo "Types: deb + URIs: https://packages.microsoft.com/repos/azure-cli/ + Suites: ${AZ_DIST} + Components: main + Architectures: $(dpkg --print-architecture) + Signed-by: /etc/apt/keyrings/microsoft.gpg" | sudo tee /etc/apt/sources.list.d/azure-cli.sources + + echo "Update repository information and install the azure-cli package" + sudo apt-get -o DPkg::Lock::Timeout=600 update + sudo apt-get -o DPkg::Lock::Timeout=600 -y install azure-cli else echo "Azure CLI is already installed" fi From 4146d8a5dca845b1caca2ca31b88aa498b3669ac Mon Sep 17 00:00:00 2001 From: vincentpcng <129542523+vincentpcng@users.noreply.github.com> Date: Sun, 17 Nov 2024 19:13:09 -0800 Subject: [PATCH 185/221] Add the port FEC BER mgmt test (#15481) * Add the port FEC BER mgmt test Signed-off-by: vincent ng * Add the port FEC BER mgmt test Signed-off-by: vincent ng * Add the port FEC BER mgmt test Signed-off-by: vincent ng --------- Signed-off-by: vincent ng --- tests/platform_tests/test_intf_fec.py | 34 ++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/platform_tests/test_intf_fec.py b/tests/platform_tests/test_intf_fec.py index 88b6fcdc557..7447ff13e56 100644 --- a/tests/platform_tests/test_intf_fec.py +++ b/tests/platform_tests/test_intf_fec.py @@ -11,7 +11,8 @@ SUPPORTED_PLATFORMS = [ "mlnx_msn", "8101_32fh", - "8111_32eh" + "8111_32eh", + "arista" ] SUPPORTED_SPEEDS = [ @@ -35,6 +36,9 @@ def test_verify_fec_oper_mode(duthosts, enum_rand_one_per_hwsku_frontend_hostnam """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + if "broadcom" in duthost.facts.get('platform_asic'): + pytest.skip("Skipping this test on platforms with Broadcom ASICs") + logging.info("Get output of '{}'".format("show interface status")) intf_status = duthost.show_and_parse("show interface status") @@ -63,6 +67,9 @@ def test_config_fec_oper_mode(duthosts, enum_rand_one_per_hwsku_frontend_hostnam """ duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + if "broadcom" in duthost.facts.get('platform_asic'): + pytest.skip("Skipping this test on platforms with Broadcom ASICs") + logging.info("Get output of '{}'".format("show interface status")) intf_status = duthost.show_and_parse("show interface status") @@ -119,6 +126,17 @@ def test_verify_fec_stats_counters(duthosts, enum_rand_one_per_hwsku_frontend_ho logging.info("Get output of 'show interfaces counters fec-stats'") intf_status = duthost.show_and_parse("show interfaces counters fec-stats") + def skip_ber_counters_test(intf_status: dict) -> bool: + """ + Check whether the BER fields (Pre-FEC and Post-FEC BER) + exists in the "show interfaces counters fec-stats" + CLI output + """ + if intf_status.get('fec_pre_ber') is None or intf_status.get('fec_post_ber') is None: + pytest.fail("Pre-FEC and Port-FEC BER fields missing on interface. intf_status: {}".format(intf_status)) + return True + return False + for intf in intf_status: intf_name = intf['iface'] speed = get_interface_speed(duthost, intf_name) @@ -147,3 +165,17 @@ def test_verify_fec_stats_counters(duthosts, enum_rand_one_per_hwsku_frontend_ho if fec_symbol_err_int > fec_corr_int: pytest.fail("FEC symbol errors:{} are higher than FEC correctable errors:{} for interface {}" .format(intf_name, fec_symbol_err_int, fec_corr_int)) + + if skip_ber_counters_test(intf): + continue + fec_pre_ber = intf.get('fec_pre_ber', '').lower() + fec_post_ber = intf.get('fec_post_ber', '').lower() + try: + if fec_pre_ber != "n/a": + float(fec_pre_ber) + if fec_post_ber != "n/a": + float(fec_post_ber) + except ValueError: + pytest.fail("Pre-FEC and Post-FEC BER are not valid floats for interface {}, \ + fec_pre_ber: {} fec_post_ber: {}" + .format(intf_name, fec_pre_ber, fec_post_ber)) From 3f7b7def527133b54d9683f07507b6fe015791a2 Mon Sep 17 00:00:00 2001 From: Dashuai Zhang <164845223+sdszhang@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:28:33 +1100 Subject: [PATCH 186/221] add back T0/T1 merge (#15598) Description of PR Summary: T0/T1 support in snappi multidut is being overwritten by recent commit. Adding it back in. Approach What is the motivation for this PR? Add back T0/T1 support for multidut snappi. How did you do it? Use T0/T1 specific function to get snappi ports instead of using variables.py co-authorized by: jianquanye@microsoft.com --- tests/snappi_tests/files/helper.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/snappi_tests/files/helper.py b/tests/snappi_tests/files/helper.py index 60be345f6d3..44b86b2c5ec 100644 --- a/tests/snappi_tests/files/helper.py +++ b/tests/snappi_tests/files/helper.py @@ -9,7 +9,7 @@ from tests.common.helpers.parallel import parallel_run from tests.common.utilities import wait_until from tests.common.snappi_tests.snappi_fixtures import get_snappi_ports_for_rdma, \ - snappi_dut_base_config + snappi_dut_base_config, is_snappi_multidut logger = logging.getLogger(__name__) @@ -101,12 +101,15 @@ def setup_ports_and_dut( "testbed {}, subtype {} in variables.py".format( MULTIDUT_TESTBED, testbed_subtype)) logger.info('Running test for testbed subtype: {}'.format(testbed_subtype)) - snappi_ports = get_snappi_ports_for_rdma( - get_snappi_ports, - rdma_ports, - tx_port_count, - rx_port_count, - MULTIDUT_TESTBED) + if is_snappi_multidut(duthosts): + snappi_ports = get_snappi_ports_for_rdma( + get_snappi_ports, + rdma_ports, + tx_port_count, + rx_port_count, + MULTIDUT_TESTBED) + else: + snappi_ports = get_snappi_ports testbed_config, port_config_list, snappi_ports = snappi_dut_base_config( duthosts, snappi_ports, snappi_api, setup=True) From 66228088abb90be622fa9f3f73d9b4ab722de395 Mon Sep 17 00:00:00 2001 From: Zhijian Li Date: Mon, 18 Nov 2024 22:31:13 -0800 Subject: [PATCH 187/221] [M0][test_acl] Wait BGP fully establish after reboot (#15616) We see TestAclWithReboot L3_Scenario test fail on Nokia-7215 M0 platform. The root cause is test start before BGP fully established. Update this testcase to fix M0 L3 scenario. --- tests/acl/test_acl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/acl/test_acl.py b/tests/acl/test_acl.py index 2908cfc2038..d9650ee5be3 100644 --- a/tests/acl/test_acl.py +++ b/tests/acl/test_acl.py @@ -1307,7 +1307,7 @@ def post_setup_hook(self, dut, localhost, populate_vlan_arp_entries, tbinfo, con # We need some additional delay on e1031 if dut.facts["platform"] == "x86_64-cel_e1031-r0": time.sleep(240) - if 't1' in tbinfo["topo"]["name"]: + if 't1' in tbinfo["topo"]["name"] or 'm0' in tbinfo["topo"]["name"]: # Wait BGP sessions up on T1 as we saw BGP sessions to T0 # established later than T2 bgp_neighbors = dut.get_bgp_neighbors() From 5cab7e6292ee01c10b99af20f03e59bb25648c4d Mon Sep 17 00:00:00 2001 From: rbpittman Date: Tue, 19 Nov 2024 03:53:19 -0500 Subject: [PATCH 188/221] Rename drop-checking iterative variables. (#15571) --- tests/saitests/py3/sai_qos_tests.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index 30212910941..8e47b276935 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -3478,22 +3478,23 @@ def get_pfc_tx_cnt(src_port_id, pg_cntr_idx): # Verify no ingress/egress drops for all ports pg_drop_counters = {port_id: sai_thrift_read_pg_drop_counters( self.src_client, port_list['src'][port_id]) for port_id in uniq_srcs} - for src_port_id in uniq_srcs: - for pg in range(len(pg_drop_counters[src_port_id])): - drops = pg_drop_counters[src_port_id][pg] - pg_drop_counters_bases[src_port_id][pg] + for uniq_src_port_id in uniq_srcs: + for pg in range(len(pg_drop_counters[uniq_src_port_id])): + drops = pg_drop_counters[uniq_src_port_id][pg] - pg_drop_counters_bases[uniq_src_port_id][pg] if pg in [3, 4]: - assert drops == 0, "Detected %d lossless drops on PG %d src port %d" % (drops, pg, src_port_id) + assert drops == 0, \ + "Detected %d lossless drops on PG %d src port %d" % (drops, pg, uniq_src_port_id) elif drops > 0: # When memory is full, any new lossy background traffic is dropped. print("Observed lossy drops %d on PG %d src port %d, expected." % - (drops, pg, src_port_id), file=sys.stderr) + (drops, pg, uniq_src_port_id), file=sys.stderr) xmit_counters_list = {port_id: sai_thrift_read_port_counters( self.dst_client, self.asic_type, port_list['dst'][port_id])[0] for port_id in uniq_dsts} - for dst_port_id in uniq_dsts: + for uniq_dst_port_id in uniq_dsts: for cntr in self.egress_counters: - drops = xmit_counters_list[dst_port_id][cntr] - \ - xmit_counters_bases[dst_port_id][cntr] - assert drops == 0, "Detected %d egress drops on dst port id %d" % (drops, dst_port_id) + drops = xmit_counters_list[uniq_dst_port_id][cntr] - \ + xmit_counters_bases[uniq_dst_port_id][cntr] + assert drops == 0, "Detected %d egress drops on dst port id %d" % (drops, uniq_dst_port_id) first_port_id = self.dst_port_ids[0] last_port_id = self.dst_port_ids[-1] From c1af3455f949ca4ed4ac9bf7dc98f31d606a8829 Mon Sep 17 00:00:00 2001 From: rbpittman Date: Tue, 19 Nov 2024 03:54:11 -0500 Subject: [PATCH 189/221] Xfail qos/test_qos_dscp_mapping.py for Cisco-8122 (#15509) * Skip qos/test_qos_dscp_mapping.py * Change skip to xfail with strict checking. --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index be3300b0241..ca8047fbfe3 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1366,6 +1366,13 @@ qos/test_pfc_pause.py::test_pfc_pause_lossless: skip: reason: "Fanout needs to send PFC frames fast enough to completely pause the queue" +qos/test_qos_dscp_mapping.py: + xfail: + reason: "ECN marking in combination with tunnel decap not yet supported" + strict: True + conditions: + - "asic_type in ['cisco-8000'] and platform in ['x86_64-8122_64eh_o-r0']" + qos/test_qos_dscp_mapping.py::TestQoSSaiDSCPQueueMapping_IPIP_Base::test_dscp_to_queue_mapping_pipe_mode: skip: reason: "Pipe decap mode not supported due to either SAI or platform limitation / M0/MX topo does not support qos" From 75952dbd48e68654f0c8a185a80b9e85e9ed1d6a Mon Sep 17 00:00:00 2001 From: Vivek Verma <137406113+vivekverma-arista@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:39:17 +0530 Subject: [PATCH 190/221] Fix testQosSaiDscpQueueMapping (#15109) What is the motivation for this PR? Regression introduced by #14232 14232 06:34:12 __init__._fixture_generator_decorator L0088 ERROR | KeyError(8) Traceback (most recent call last): File "/data/tests/common/plugins/log_section_start/__init__.py", line 84, in _fixture_generator_decorator res = next(it) File "/data/tests/qos/qos_sai_base.py", line 2455, in tc_to_dscp_count for dscp, tc in dscp_to_tc_map.items(): KeyError: 8 How did you do it? Get rid of assumption of 8TCs from the code. How did you verify/test it? Ran the test on Arista 7260X3 platform. --- tests/qos/qos_sai_base.py | 3 +-- tests/saitests/py3/sai_qos_tests.py | 9 ++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/qos/qos_sai_base.py b/tests/qos/qos_sai_base.py index 92e315d128f..574dbc3c2a9 100644 --- a/tests/qos/qos_sai_base.py +++ b/tests/qos/qos_sai_base.py @@ -2556,11 +2556,10 @@ def skip_longlink(self, dutQosConfig): def tc_to_dscp_count(self, get_src_dst_asic_and_duts): duthost = get_src_dst_asic_and_duts['src_dut'] tc_to_dscp_count_map = {} - for tc in range(8): - tc_to_dscp_count_map[tc] = 0 config_facts = duthost.asic_instance().config_facts(source="running")["ansible_facts"] dscp_to_tc_map = config_facts['DSCP_TO_TC_MAP']['AZURE'] for dscp, tc in dscp_to_tc_map.items(): + tc_to_dscp_count_map.setdefault(int(tc), 0) tc_to_dscp_count_map[int(tc)] += 1 yield tc_to_dscp_count_map diff --git a/tests/saitests/py3/sai_qos_tests.py b/tests/saitests/py3/sai_qos_tests.py index 8e47b276935..e7ef618eb49 100755 --- a/tests/saitests/py3/sai_qos_tests.py +++ b/tests/saitests/py3/sai_qos_tests.py @@ -941,9 +941,12 @@ def runTest(self): # queue 7 0 1 1 1 1 # noqa E501 if tc_to_dscp_count_map: - for tc in range(7): - assert (queue_results[tc] == tc_to_dscp_count_map[tc] + queue_results_base[tc]) - assert (queue_results[7] >= tc_to_dscp_count_map[7] + queue_results_base[7]) + for tc in tc_to_dscp_count_map.keys(): + if tc == 7: + # LAG ports can have LACP packets on queue 7, hence using >= comparison + assert (queue_results[tc] >= tc_to_dscp_count_map[tc] + queue_results_base[tc]) + else: + assert (queue_results[tc] == tc_to_dscp_count_map[tc] + queue_results_base[tc]) else: assert (queue_results[QUEUE_0] == 1 + queue_results_base[QUEUE_0]) assert (queue_results[QUEUE_3] == 1 + queue_results_base[QUEUE_3]) From 28633395c903f1d1970a64b55a4506e36977bca1 Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Tue, 19 Nov 2024 17:11:05 +0800 Subject: [PATCH 191/221] Add conditions into qos/test_qos_sai.py::TestQosSai:: (#15563) What is the motivation for this PR? In #14912, we added conditions for longer matching entries in conditional marks. However, some conditions were missed under the entry qos/test_qos_sai.py::TestQosSai:. This PR adds these missing conditions to entries that start with and extend beyond qos/test_qos_sai.py::TestQosSai:. How did you do it? This PR adds these missing conditions to entries that start with and extend beyond qos/test_qos_sai.py::TestQosSai:. How did you verify/test it? --- .../tests_mark_conditions.yaml | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index ca8047fbfe3..b6c9edab036 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1408,97 +1408,108 @@ qos/test_qos_sai.py::TestQosSai: qos/test_qos_sai.py::TestQosSai::testIPIPQosSaiDscpToPgMapping: skip: - reason: "For DSCP to PG mapping on IPinIP traffic , mellanox device has different behavior to community. For mellanox device, testQosSaiDscpToPgMapping can cover the scenarios / M0/MX topo does not support qos" + reason: "For DSCP to PG mapping on IPinIP traffic , mellanox device has different behavior to community. For mellanox device, testQosSaiDscpToPgMapping can cover the scenarios / Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type in ['mellanox']" - https://github.com/sonic-net/sonic-mgmt/issues/12906 - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testPfcStormWithSharedHeadroomOccupancy: skip: - reason: "This test is only for Mellanox. / M0/MX topo does not support qos" + reason: "This test is only for Mellanox." conditions_logical_operator: or conditions: - "asic_type in ['cisco-8000']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiBufferPoolWatermark: skip: - reason: "sai_thrift_read_buffer_pool_watermark are not supported on DNX / M0/MX topo does not support qos" + reason: "sai_thrift_read_buffer_pool_watermark are not supported on DNX / Unsupported testbed type." conditions_logical_operator: or conditions: - "platform in ['x86_64-nokia_ixr7250e_36x400g-r0', 'x86_64-arista_7800r3_48cq2_lc', 'x86_64-arista_7800r3_48cqm2_lc', 'x86_64-arista_7800r3a_36d2_lc', 'x86_64-arista_7800r3a_36dm2_lc','x86_64-arista_7800r3ak_36dm2_lc']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiDot1pPgMapping: skip: - reason: "Dot1p-PG mapping is only supported on backend. / M0/MX topo does not support qos" + reason: "Dot1p-PG mapping is only supported on backend." conditions_logical_operator: or conditions: - "'backend' not in topo_name" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiDot1pQueueMapping: skip: - reason: "Dot1p-queue mapping is only supported on backend. / M0/MX topo does not support qos" + reason: "Dot1p-queue mapping is only supported on backend." conditions_logical_operator: or conditions: - "'backend' not in topo_name" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiDscpQueueMapping: skip: - reason: "Dscp-queue mapping is not supported on backend. / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "'backend' in topo_name" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiDscpToPgMapping: skip: - reason: "Dscp-PG mapping is not supported on backend. / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "'backend' in topo_name" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiDwrrWeightChange: skip: - reason: "Skip DWRR weight change test on Mellanox platform. / M0/MX topo does not support qos" + reason: "Skip DWRR weight change test on Mellanox platform. / Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type in ['mellanox']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiFullMeshTrafficSanity: skip: - reason: "Unsupported platform or testbed type. / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000'] or topo_name not in ['ptf64']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiHeadroomPoolSize: skip: - reason: "Headroom pool size not supported. / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "https://github.com/sonic-net/sonic-mgmt/issues/12292 and hwsku in ['Force10-S6100'] and topo_type in ['t1-64-lag'] and hwsku not in ['Arista-7060CX-32S-C32', 'Celestica-DX010-C32', 'Arista-7260CX3-D108C8', 'Force10-S6100', 'Arista-7260CX3-Q64', 'Arista-7050CX3-32S-C32', 'Arista-7050CX3-32S-D48C8', 'Arista-7060CX-32S-D48C8'] and asic_type not in ['mellanox'] and asic_type in ['cisco-8000']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" - "'t2' in topo_name and asic_subtype in ['broadcom-dnx']" qos/test_qos_sai.py::TestQosSai::testQosSaiHeadroomPoolWatermark: skip: - reason: "sai_thrift_read_buffer_pool_watermark are not supported on DNX / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "platform in ['x86_64-nokia_ixr7250e_36x400g-r0', 'x86_64-arista_7800r3_48cq2_lc', 'x86_64-arista_7800r3_48cqm2_lc', 'x86_64-arista_7800r3a_36d2_lc', 'x86_64-arista_7800r3a_36dm2_lc', 'x86_64-arista_7800r3ak_36dm2_lc'] or asic_type in ['mellanox'] and asic_type in ['cisco-8000'] and https://github.com/sonic-net/sonic-mgmt/issues/12292 and hwsku in ['Force10-S6100'] and topo_type in ['t1-64-lag']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" xfail: reason: "Headroom pool size not supported." conditions: @@ -1506,66 +1517,73 @@ qos/test_qos_sai.py::TestQosSai::testQosSaiHeadroomPoolWatermark: qos/test_qos_sai.py::TestQosSai::testQosSaiLosslessVoq: skip: - reason: "Lossless Voq test is not supported / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000'] or platform in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiLossyQueueVoq: skip: - reason: "Lossy Queue Voq test is not supported / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000'] or platform in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiLossyQueueVoqMultiSrc: skip: - reason: "Lossy Queue Voq multiple source test is not supported / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000'] or platform in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiPGDrop: skip: - reason: "PG drop size test is not supported. / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000'] or platform in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiPgHeadroomWatermark: skip: - reason: "Priority Group Headroom Watermark is not supported on cisco asic. PG drop counter stat is covered as a part of testQosSaiPfcXoffLimit - / M0/MX topo does not support qos" + reason: "Unsupported testbed type." conditions_logical_operator: or conditions: - "asic_type in ['cisco-8000'] and platform not in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiPgSharedWatermark[None-wm_pg_shared_lossy]: xfail: - reason: "Image issue on Arista platforms" + reason: "Image issue on Arista platforms / Unsupported testbed type." conditions: - "platform in ['x86_64-arista_7050cx3_32s']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiQWatermarkAllPorts: skip: - reason: "All Port Watermark test is verified only on Cisco Platforms. / M0/MX topo does not support qos" + reason: "All Port Watermark test is verified only on Cisco Platforms." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiSharedReservationSize: skip: - reason: "Shared reservation size test is not supported. / M0/MX topo does not support qos" + reason: "Shared reservation size test is not supported." conditions_logical_operator: or conditions: - "asic_type not in ['cisco-8000'] or platform in ['x86_64-8122_64eh_o-r0']" - "topo_type in ['m0', 'mx']" + - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_tunnel_qos_remap.py::test_pfc_watermark_extra_lossless_active: xfail: From 4cfeeacee2b69da0815184df4a2fddded951828f Mon Sep 17 00:00:00 2001 From: Dawei Huang Date: Tue, 19 Nov 2024 15:30:37 -0600 Subject: [PATCH 192/221] Fix test_l2_configure failure (#15608) Description of PR Fix test_l2_configure failure by removing minigraph.xml temporarily Approach What is the motivation for this PR? Fix test failure How did you do it? Temporary remove minigraph.xml during config_reload How did you verify/test it? on physical and virtual switch, latest image Any platform specific information? no --- tests/l2/test_l2_configure.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/tests/l2/test_l2_configure.py b/tests/l2/test_l2_configure.py index bdb392b9e7f..5c3609a9a2b 100644 --- a/tests/l2/test_l2_configure.py +++ b/tests/l2/test_l2_configure.py @@ -4,15 +4,14 @@ import logging import pytest +import tempfile from tests.common import config_reload from tests.common.platform.processes_utils import wait_critical_processes from tests.common.helpers.assertions import pytest_assert CONFIG_DB = "/etc/sonic/config_db.json" -CONFIG_DB_BAK = "/etc/sonic/config_db.json.bak" -DUT_IMG_PATH = "/tmp/dut-sonic-img.bin" -LOCALHOST_IMG_PATH = "/tmp/localhost-sonic-img.bin" +MINIGRAPH = "/etc/sonic/minigraph.xml" logger = logging.getLogger(__name__) @@ -24,6 +23,20 @@ ] +def generate_backup_filename(prefix): + """ + @summary: Generate a backup filename. + + Args: + prefix: Prefix of the backup filename. + + Returns: + A backup filename. + """ + with tempfile.NamedTemporaryFile(prefix=prefix, suffix=".bak", delete=False) as f: + return f.name + + @pytest.fixture(autouse=True) def setup_env(duthosts, rand_one_dut_hostname): """ @@ -35,6 +48,7 @@ def setup_env(duthosts, rand_one_dut_hostname): rand_selected_dut: The fixture returns a randomly selected DuT. """ duthost = duthosts[rand_one_dut_hostname] + CONFIG_DB_BAK = generate_backup_filename("config_db.json") duthost.shell("sudo cp {} {}".format(CONFIG_DB, CONFIG_DB_BAK)) yield @@ -80,9 +94,10 @@ def get_db_version(duthost): return "" -def test_no_hardcoded_minigraph(duthosts, rand_one_dut_hostname, tbinfo): +def test_no_hardcoded_tables(duthosts, rand_one_dut_hostname, tbinfo): """ - @summary: A testcase asserts no hardcoded minigraph config is imported to config_db during L2 configuration. + @summary: A test case asserting no hardcoded tables (such as TELEMETRY and RESTAPI) + is migrated to config_db during L2 configuration. Args: duthosts: list of DUTs. @@ -99,8 +114,6 @@ def test_no_hardcoded_minigraph(duthosts, rand_one_dut_hostname, tbinfo): mgmt_fact = duthost.get_extended_minigraph_facts(tbinfo)["minigraph_mgmt_interface"] # Step 2: Configure DUT into L2 mode. - # Save original config - duthost.shell("sudo cp {} {}".format(CONFIG_DB, CONFIG_DB_BAK)) # Perform L2 configuration L2_INIT_CFG_FILE = "/tmp/init_l2_cfg.json" MGMT_CFG_FILE = "/tmp/mgmt_cfg.json" @@ -147,12 +160,17 @@ def test_no_hardcoded_minigraph(duthosts, rand_one_dut_hostname, tbinfo): logger.info( "Database version before L2 configuration reload: {}".format(db_version_before) ) + # Move minigraph away to avoid config coming from minigraph. + MINIGRAPH_BAK = generate_backup_filename("minigraph.xml") + duthost.shell("sudo mv {} {}".format(MINIGRAPH, MINIGRAPH_BAK)) config_reload(duthost) wait_critical_processes(duthost) db_version_after = get_db_version(duthost) logger.info( "Database version after L2 configuration reload: {}".format(db_version_after) ) + # Move minigraph back. + duthost.shell("sudo mv {} {}".format(MINIGRAPH_BAK, MINIGRAPH)) # Verify no minigraph config is present. for table in ["TELEMETRY", "RESTAPI"]: From 174c6bf76535d1022f7a652daa251d605a5b3d21 Mon Sep 17 00:00:00 2001 From: Riff Date: Tue, 19 Nov 2024 17:49:14 -0800 Subject: [PATCH 193/221] Update j2cli to jinjanator. (#15600) j2cli is not being maintained anymore and will start to fail to work on ubuntu 24.04, because it is trying to load the imp module, which is deprecated now. However, j2cli is being archived not being maintained anymore. The author recommends using other alternatives that is actively being maintained, such as jinjanator. Hence, making this change in order to support the latest OS. --- ansible/setup-management-network.sh | 8 ++++---- docs/testbed/README.testbed.Setup.md | 2 +- docs/testbed/README.testbed.VsSetup.md | 2 +- setup-container.sh | 12 +++++++++--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ansible/setup-management-network.sh b/ansible/setup-management-network.sh index 3347d216b6d..fd2eae5892b 100755 --- a/ansible/setup-management-network.sh +++ b/ansible/setup-management-network.sh @@ -33,10 +33,10 @@ echo "Refreshing apt package lists..." apt-get update echo -echo "STEP 1: Checking for j2cli package..." -if ! command -v j2; then - echo "j2cli not found, installing j2cli" - cmd="install --user j2cli==0.3.10" +echo "STEP 1: Checking for jinjanator package..." +if ! command -v jinjanate; then + echo "jinjanator not found, installing jinjanator" + cmd="install --user jinjanator==24.4.0" if ! command -v pip &> /dev/null; then pip3 $cmd else diff --git a/docs/testbed/README.testbed.Setup.md b/docs/testbed/README.testbed.Setup.md index f26f162befa..c6dcf6431fb 100644 --- a/docs/testbed/README.testbed.Setup.md +++ b/docs/testbed/README.testbed.Setup.md @@ -20,7 +20,7 @@ This document describes the steps to setup the testbed and deploy a topology. ``` - Install Python prerequisites ``` - sudo pip3 install j2cli + sudo pip3 install jinjanator ``` - Install Docker (all credits to https://docs.docker.com/engine/install/ubuntu/ ) ``` diff --git a/docs/testbed/README.testbed.VsSetup.md b/docs/testbed/README.testbed.VsSetup.md index f6eea3fab0e..daa38c6fbca 100644 --- a/docs/testbed/README.testbed.VsSetup.md +++ b/docs/testbed/README.testbed.VsSetup.md @@ -22,7 +22,7 @@ First, we need to prepare the host where we will be configuring the virtual test ``` sudo apt install python python-pip openssh-server # v0.3.10 Jinja2 is required, lower version may cause uncompatible issue - sudo pip install j2cli==0.3.10 + sudo pip install jinjanate==24.4.0 ``` 3. Run the host setup script to install required packages and initialize the management bridge network diff --git a/setup-container.sh b/setup-container.sh index 90bae4ef4f8..5318aa806e9 100755 --- a/setup-container.sh +++ b/setup-container.sh @@ -275,7 +275,7 @@ ROOT_PASS=${ROOT_PASS} EOF log_info "generate a Dockerfile: ${TMP_DIR}/Dockerfile" - j2 -o "${TMP_DIR}/Dockerfile" "${TMP_DIR}/Dockerfile.j2" "${TMP_DIR}/data.env" || \ + jinjanate -o "${TMP_DIR}/Dockerfile" "${TMP_DIR}/Dockerfile.j2" "${TMP_DIR}/data.env" || \ log_error "failed to generate a Dockerfile: ${TMP_DIR}/Dockerfile" log_info "building docker image from ${TMP_DIR}: ${LOCAL_IMAGE} ..." @@ -445,8 +445,14 @@ if docker ps -a --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then fi fi -if ! which j2 &> /dev/null; then - exit_failure "missing Jinja2 templates support: make sure j2cli package is installed" +if ! which jinjanate &> /dev/null; then + echo "jinjanator not found, installing jinjanator" + cmd="install --user jinjanator==24.4.0" + if ! command -v pip &> /dev/null; then + pip3 $cmd + else + pip $cmd + fi fi pull_sonic_mgmt_docker_image From 2c0cb9f3947df4db5a1a6e18d3a3469320a21afa Mon Sep 17 00:00:00 2001 From: Zain Budhwani <99770260+zbud-msft@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:15:38 -0800 Subject: [PATCH 194/221] Skip dhcp test events for mx (#15541) What is the motivation for this PR? isc-dhcpv4 process is not expected to run for MX topologies so skipping dhcp_relay events testing How did you do it? Check for switch type BmcMgmtToRRouter How did you verify/test it? Manual test/pipeline --- tests/telemetry/events/dhcp-relay_events.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/telemetry/events/dhcp-relay_events.py b/tests/telemetry/events/dhcp-relay_events.py index 331cdeaece2..dd2fdf8bfcc 100644 --- a/tests/telemetry/events/dhcp-relay_events.py +++ b/tests/telemetry/events/dhcp-relay_events.py @@ -18,6 +18,10 @@ def test_event(duthost, gnxi_path, ptfhost, ptfadapter, data_dir, validate_yang) features_states, succeeded = duthost.get_feature_status() if not succeeded or features_states["dhcp_relay"] != "enabled": pytest.skip("dhcp_relay is not enabled, skipping dhcp_relay events") + device_metadata = duthost.config_facts(host=duthost.hostname, source="running")['ansible_facts']['DEVICE_METADATA'] + switch_role = device_metadata['localhost'].get('type', '') + if switch_role == 'BmcMgmtToRRouter': + pytest.skip("Skipping dhcp_relay events for mx topologies") logger.info("Beginning to test dhcp-relay events") run_test(duthost, gnxi_path, ptfhost, data_dir, validate_yang, trigger_dhcp_relay_discard, "dhcp_relay_discard.json", "sonic-events-dhcp-relay:dhcp-relay-discard", tag, False, 30, ptfadapter) From 302332457e19e68ff40c39bf8520ae4d9e498a9a Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:27:12 +0800 Subject: [PATCH 195/221] Eliminate cross-feature dependency from macsec module (#15617) What is the motivation for this PR? Previously, the common script tests/conftest.py relied on importing a module from the feature-specific macsec folder, creating a cross-feature dependency. To eliminate this dependency and improve code organization, we created a Python package named macsec under the common path tests/common. The shared scripts were refactored and relocated into this new package, ensuring a cleaner and more modular structure. How did you do it? To eliminate this dependency and improve code organization, we created a Python package named macsec under the common path tests/common. The shared scripts were refactored and relocated into this new package, ensuring a cleaner and more modular structure. How did you verify/test it? --- tests/common/devices/ptf.py | 2 +- tests/common/macsec/__init__.py | 266 ++++++++++++++++++ .../macsec/macsec_config_helper.py | 4 +- tests/{ => common}/macsec/macsec_helper.py | 29 +- .../macsec/macsec_platform_helper.py | 0 tests/{ => common}/macsec/profile.json | 0 tests/conftest.py | 2 +- tests/macsec/__init__.py | 266 ------------------ tests/macsec/conftest.py | 2 +- tests/macsec/test_controlplane.py | 4 +- tests/macsec/test_dataplane.py | 4 +- tests/macsec/test_deployment.py | 2 +- tests/macsec/test_docker_restart.py | 2 +- tests/macsec/test_fault_handling.py | 7 +- tests/macsec/test_interop_protocol.py | 7 +- tests/macsec/test_interop_wan_isis.py | 6 +- 16 files changed, 307 insertions(+), 296 deletions(-) create mode 100644 tests/common/macsec/__init__.py rename tests/{ => common}/macsec/macsec_config_helper.py (97%) rename tests/{ => common}/macsec/macsec_helper.py (95%) rename tests/{ => common}/macsec/macsec_platform_helper.py (100%) rename tests/{ => common}/macsec/profile.json (100%) diff --git a/tests/common/devices/ptf.py b/tests/common/devices/ptf.py index 1e652052a33..048fcbdd35c 100644 --- a/tests/common/devices/ptf.py +++ b/tests/common/devices/ptf.py @@ -3,7 +3,7 @@ import tempfile from tests.common.devices.base import AnsibleHostBase -from tests.macsec.macsec_helper import load_macsec_info +from tests.common.macsec.macsec_helper import load_macsec_info logger = logging.getLogger(__name__) diff --git a/tests/common/macsec/__init__.py b/tests/common/macsec/__init__.py new file mode 100644 index 00000000000..234c61c8485 --- /dev/null +++ b/tests/common/macsec/__init__.py @@ -0,0 +1,266 @@ +import collections +import json +import logging +import os +import sys +from ipaddress import ip_address, IPv4Address + +import natsort +import pytest + +if sys.version_info.major > 2: + from pathlib import Path + sys.path.insert(0, str(Path(__file__).parent)) + +from .macsec_config_helper import enable_macsec_feature +from .macsec_config_helper import disable_macsec_feature +from .macsec_config_helper import setup_macsec_configuration +from .macsec_config_helper import cleanup_macsec_configuration +# flake8: noqa: F401 +from tests.common.plugins.sanity_check import sanity_check + +logger = logging.getLogger(__name__) + + +class MacsecPlugin(object): + """ + Pytest macsec plugin + """ + + def __init__(self): + with open(os.path.dirname(__file__) + '/profile.json') as f: + self.macsec_profiles = json.load(f) + for k, v in list(self.macsec_profiles.items()): + self.macsec_profiles[k]["name"] = k + # Set default value + if "rekey_period" not in v: + self.macsec_profiles[k]["rekey_period"] = 0 + + def _generate_macsec_profile(self, metafunc): + value = metafunc.config.getoption("macsec_profile") + if value == 'all': + return natsort.natsorted(list(self.macsec_profiles.keys())) + return [x for x in value.split(',') if x in self.macsec_profiles] + + def pytest_generate_tests(self, metafunc): + if 'macsec_profile' in metafunc.fixturenames: + profiles = self._generate_macsec_profile(metafunc) + assert profiles, "Specify valid macsec profile!" + metafunc.parametrize('macsec_profile', + [self.macsec_profiles[x] for x in profiles], + ids=profiles, + scope="module") + + def get_ctrl_nbr_names(self, macsec_duthost, nbrhosts, tbinfo): + return NotImplementedError() + + def downstream_neighbor(self,tbinfo, neighbor): + return NotImplementedError() + + def upstream_neighbor(self,tbinfo, neighbor): + return NotImplementedError() + + @pytest.fixture(scope="module") + def start_macsec_service(self, macsec_duthost, macsec_nbrhosts): + def __start_macsec_service(): + enable_macsec_feature(macsec_duthost, macsec_nbrhosts) + return __start_macsec_service + + @pytest.fixture(scope="module") + def stop_macsec_service(self, macsec_duthost, macsec_nbrhosts): + def __stop_macsec_service(): + disable_macsec_feature(macsec_duthost, macsec_nbrhosts) + return __stop_macsec_service + + @pytest.fixture(scope="module") + def macsec_feature(self, start_macsec_service, stop_macsec_service): + start_macsec_service() + yield + stop_macsec_service() + + @pytest.fixture(scope="module") + def startup_macsec(self, request, macsec_duthost, ctrl_links, macsec_profile, tbinfo): + topo_name = tbinfo['topo']['name'] + def __startup_macsec(): + profile = macsec_profile + if request.config.getoption("neighbor_type") == "eos": + if macsec_duthost.facts["asic_type"] == "vs" and profile['send_sci'] == "false": + # On EOS, portchannel mac is not same as the member port mac (being as SCI), + # then src mac is not equal to SCI in its sending packet. The receiver of vSONIC + # will drop it for macsec kernel module does not correctly handle it. + pytest.skip( + "macsec on dut vsonic, neighbor eos, send_sci false") + if 't2' not in topo_name: + cleanup_macsec_configuration(macsec_duthost, ctrl_links, profile['name']) + setup_macsec_configuration(macsec_duthost, ctrl_links, + profile['name'], profile['priority'], profile['cipher_suite'], + profile['primary_cak'], profile['primary_ckn'], profile['policy'], + profile['send_sci'], profile['rekey_period']) + logger.info( + "Setup MACsec configuration with arguments:\n{}".format(locals())) + return __startup_macsec + + @pytest.fixture(scope="module") + def shutdown_macsec(self, macsec_duthost, ctrl_links, macsec_profile): + def __shutdown_macsec(): + profile = macsec_profile + cleanup_macsec_configuration(macsec_duthost, ctrl_links, profile['name']) + return __shutdown_macsec + + @pytest.fixture(scope="module", autouse=True) + def macsec_setup(self, startup_macsec, shutdown_macsec, macsec_feature): + ''' + setup macsec links + ''' + startup_macsec() + yield + shutdown_macsec() + + @pytest.fixture(scope="module") + def macsec_nbrhosts(self, ctrl_links): + return {nbr["name"]: nbr for nbr in list(ctrl_links.values())} + + @pytest.fixture(scope="module") + def ctrl_links(self, macsec_duthost, tbinfo, nbrhosts): + + if not nbrhosts: + topo_name = tbinfo['topo']['name'] + pytest.skip("None of neighbors on topology {}".format(topo_name)) + + ctrl_nbr_names = self.get_ctrl_nbr_names(macsec_duthost, nbrhosts, tbinfo) + logger.info("Controlled links {}".format(ctrl_nbr_names)) + nbrhosts = {name: nbrhosts[name] for name in ctrl_nbr_names} + return self.find_links_from_nbr(macsec_duthost, tbinfo, nbrhosts) + + @pytest.fixture(scope="module") + def unctrl_links(self, macsec_duthost, tbinfo, nbrhosts, ctrl_links): + unctrl_nbr_names = set(nbrhosts.keys()) + for _, nbr in ctrl_links.items(): + if nbr["name"] in unctrl_nbr_names: + unctrl_nbr_names.remove(nbr["name"]) + + logger.info("Uncontrolled links {}".format(unctrl_nbr_names)) + nbrhosts = {name: nbrhosts[name] for name in unctrl_nbr_names} + return self.find_links_from_nbr(macsec_duthost, tbinfo, nbrhosts) + + @pytest.fixture(scope="module") + def downstream_links(self, macsec_duthost, tbinfo, nbrhosts): + links = collections.defaultdict(dict) + + def filter(interface, neighbor, mg_facts, tbinfo): + if self.downstream_neighbor(tbinfo, neighbor): + port = mg_facts["minigraph_neighbors"][interface]["port"] + if interface not in mg_facts["minigraph_ptf_indices"]: + logger.info("Interface {} not in minigraph_ptf_indices".format(interface)) + return + links[interface] = { + "name": neighbor["name"], + "ptf_port_id": mg_facts["minigraph_ptf_indices"][interface], + "port": port + } + self.find_links(macsec_duthost, tbinfo, filter) + return links + + @pytest.fixture(scope="module") + def upstream_links(self, macsec_duthost, tbinfo, nbrhosts): + links = collections.defaultdict(dict) + + def filter(interface, neighbor, mg_facts, tbinfo): + if self.upstream_neighbor(tbinfo, neighbor): + for item in mg_facts["minigraph_bgp"]: + if item["name"] == neighbor["name"]: + if isinstance(ip_address(item["addr"]), IPv4Address): + # The address of neighbor device + local_ipv4_addr = item["addr"] + # The address of DUT + peer_ipv4_addr = item["peer_addr"] + break + if interface not in mg_facts["minigraph_ptf_indices"]: + logger.info("Interface {} not in minigraph_ptf_indices".format(interface)) + return + port = mg_facts["minigraph_neighbors"][interface]["port"] + links[interface] = { + "name": neighbor["name"], + "ptf_port_id": mg_facts["minigraph_ptf_indices"][interface], + "local_ipv4_addr": local_ipv4_addr, + "peer_ipv4_addr": peer_ipv4_addr, + "port": port, + "host": nbrhosts[neighbor["name"]]["host"] + } + self.find_links(macsec_duthost, tbinfo, filter) + return links + + def find_links(self, duthost, tbinfo, filter): + + mg_facts = duthost.get_extended_minigraph_facts(tbinfo) + for interface, neighbor in mg_facts["minigraph_neighbors"].items(): + filter(interface, neighbor, mg_facts, tbinfo) + + def is_interface_portchannel_member(self, pc, interface): + for pc_name, elements in list(pc.items()): + if interface in elements['members']: + return True + return False + + def find_links_from_nbr(self, duthost, tbinfo, nbrhosts): + links = collections.defaultdict(dict) + def filter(interface, neighbor, mg_facts, tbinfo): + if neighbor["name"] not in list(nbrhosts.keys()): + return + port = mg_facts["minigraph_neighbors"][interface]["port"] + + links[interface] = { + "name": neighbor["name"], + "host": nbrhosts[neighbor["name"]]["host"], + "port": port, + "dut_name": duthost.hostname + } + self.find_links(duthost, tbinfo, filter) + return links + +class MacsecPluginT0(MacsecPlugin): + """ + Pytest macsec plugin + """ + + + def __init__(self): + super(MacsecPluginT0, self).__init__() + + def get_ctrl_nbr_names(self, macsec_duthost, nbrhosts, tbinfo): + ctrl_nbr_names = natsort.natsorted(nbrhosts.keys())[:2] + return ctrl_nbr_names + + def downstream_neighbor(self,tbinfo, neighbor): + if (tbinfo["topo"]["type"] == "t0" and "Server" in neighbor["name"]): + return True + return False + + def upstream_neighbor(self,tbinfo, neighbor): + if (tbinfo["topo"]["type"] == "t0" and "T1" in neighbor["name"]): + return True + return False + +class MacsecPluginT2(MacsecPlugin): + """ + Pytest macsec plugin + """ + + + def __init__(self): + super(MacsecPluginT2, self).__init__() + + def get_ctrl_nbr_names(self, macsec_duthost, nbrhosts, tbinfo): + mg_facts = macsec_duthost.get_extended_minigraph_facts(tbinfo) + ctrl_nbr_names = mg_facts['macsec_neighbors'] + return ctrl_nbr_names + + def downstream_neighbor(self,tbinfo, neighbor): + if ("t2" in tbinfo["topo"]["type"] and "T1" in neighbor["name"]): + return True + return False + + def upstream_neighbor(self,tbinfo, neighbor): + if ("t2" in tbinfo["topo"]["type"] and "T3" in neighbor["name"]): + return True + return False diff --git a/tests/macsec/macsec_config_helper.py b/tests/common/macsec/macsec_config_helper.py similarity index 97% rename from tests/macsec/macsec_config_helper.py rename to tests/common/macsec/macsec_config_helper.py index 87e74afbb76..ffec635677a 100644 --- a/tests/macsec/macsec_config_helper.py +++ b/tests/common/macsec/macsec_config_helper.py @@ -1,8 +1,8 @@ import logging import time -from .macsec_helper import get_mka_session, getns_prefix, wait_all_complete, submit_async_task -from .macsec_platform_helper import global_cmd, find_portchannel_from_member, get_portchannel +from tests.common.macsec.macsec_helper import get_mka_session, getns_prefix, wait_all_complete, submit_async_task +from tests.common.macsec.macsec_platform_helper import global_cmd, find_portchannel_from_member, get_portchannel from tests.common.devices.eos import EosHost from tests.common.utilities import wait_until diff --git a/tests/macsec/macsec_helper.py b/tests/common/macsec/macsec_helper.py similarity index 95% rename from tests/macsec/macsec_helper.py rename to tests/common/macsec/macsec_helper.py index da13721f417..b00b2058eb6 100644 --- a/tests/macsec/macsec_helper.py +++ b/tests/common/macsec/macsec_helper.py @@ -15,7 +15,7 @@ import scapy.all as scapy import scapy.contrib.macsec as scapy_macsec -from .macsec_platform_helper import sonic_db_cli +from tests.common.macsec.macsec_platform_helper import sonic_db_cli from tests.common.devices.eos import EosHost __all__ = [ @@ -192,7 +192,8 @@ def get_mka_session(host): ''' Here is an output example of `ip macsec show` admin@vlab-01:~$ ip macsec show - 130: macsec_eth29: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off + 130: macsec_eth29: protect on validate strict sc off sa off encrypt + on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 52540041303f0001 on SA 0 0: PN 1041, state on, SSCI 16777216, key 0ecddfe0f462491c13400dbf7433465d @@ -200,7 +201,8 @@ def get_mka_session(host): RXSC: 525400b5be690001, state on 0: PN 1041, state on, SSCI 16777216, key 0ecddfe0f462491c13400dbf7433465d 3: PN 0, state on, SSCI 16777216, key 0ecddfe0f462491c13400dbf7433465d - 131: macsec_eth30: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off + 131: macsec_eth30: protect on validate strict sc off sa off encrypt + on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 52540041303f0001 on SA 0 0: PN 1041, state on, key daa8169cde2fe1e238aaa83672e40279 @@ -438,14 +440,16 @@ def macsec_dp_poll(test, device_number=0, port_number=None, timeout=None, exp_pk ret = __origin_dp_poll( test, device_number=device_number, port_number=port_number, timeout=timeout, exp_pkt=None) timeout -= time.time() - start_time - # Since we call __origin_dp_poll with exp_pkt=None, it should only ever fail if no packets are received at all. In this case, continue normally + # Since we call __origin_dp_poll with exp_pkt=None, it should only ever fail if no packets are received at all. + # In this case, continue normally # until we exceed the timeout value provided to macsec_dp_poll. if isinstance(ret, test.dataplane.PollFailure): if timeout <= 0: break else: continue - # The device number of PTF host is 0, if the target port isn't a injected port(belong to ptf host), Don't need to do MACsec further. + # The device number of PTF host is 0, if the target port isn't a injected port(belong to ptf host), + # Don't need to do MACsec further. if ret.device != 0 or exp_pkt is None: return ret pkt = scapy.Ether(ret.packet) @@ -454,17 +458,22 @@ def macsec_dp_poll(test, device_number=0, port_number=None, timeout=None, exp_pk if ptf.dataplane.match_exp_pkt(exp_pkt, pkt): return ret else: - macsec_info = load_macsec_info(test.duthost, find_portname_from_ptf_id(test.mg_facts, ret.port), force_reload[ret.port]) + macsec_info = load_macsec_info(test.duthost, find_portname_from_ptf_id(test.mg_facts, ret.port), + force_reload[ret.port]) if macsec_info: encrypt, send_sci, xpn_en, sci, an, sak, ssci, salt = macsec_info force_reload[ret.port] = False pkt, decap_success = decap_macsec_pkt(pkt, sci, an, sak, encrypt, send_sci, 0, xpn_en, ssci, salt) if decap_success and ptf.dataplane.match_exp_pkt(exp_pkt, pkt): return ret - # Normally, if __origin_dp_poll returns a PollFailure, the PollFailure object will contain a list of recently received packets - # to help with debugging. However, since we call __origin_dp_poll multiple times, only the packets from the most recent call is retained. - # If we don't find a matching packet (either with or without MACsec decoding), we need to manually store the packet we received. - # Later if we return a PollFailure, we can provide the received packets to emulate the behavior of __origin_dp_poll. + # Normally, if __origin_dp_poll returns a PollFailure, + # the PollFailure object will contain a list of recently received packets + # to help with debugging. However, since we call __origin_dp_poll multiple times, + # only the packets from the most recent call is retained. + # If we don't find a matching packet (either with or without MACsec decoding), + # we need to manually store the packet we received. + # Later if we return a PollFailure, + # we can provide the received packets to emulate the behavior of __origin_dp_poll. recent_packets.append(pkt) packet_count += 1 if timeout <= 0: diff --git a/tests/macsec/macsec_platform_helper.py b/tests/common/macsec/macsec_platform_helper.py similarity index 100% rename from tests/macsec/macsec_platform_helper.py rename to tests/common/macsec/macsec_platform_helper.py diff --git a/tests/macsec/profile.json b/tests/common/macsec/profile.json similarity index 100% rename from tests/macsec/profile.json rename to tests/common/macsec/profile.json diff --git a/tests/conftest.py b/tests/conftest.py index f0531bb5ba0..4885d240aaa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -69,7 +69,7 @@ from tests.common.plugins.ptfadapter.dummy_testutils import DummyTestUtils try: - from tests.macsec import MacsecPluginT2, MacsecPluginT0 + from tests.common.macsec import MacsecPluginT2, MacsecPluginT0 except ImportError as e: logging.error(e) diff --git a/tests/macsec/__init__.py b/tests/macsec/__init__.py index 234c61c8485..e69de29bb2d 100644 --- a/tests/macsec/__init__.py +++ b/tests/macsec/__init__.py @@ -1,266 +0,0 @@ -import collections -import json -import logging -import os -import sys -from ipaddress import ip_address, IPv4Address - -import natsort -import pytest - -if sys.version_info.major > 2: - from pathlib import Path - sys.path.insert(0, str(Path(__file__).parent)) - -from .macsec_config_helper import enable_macsec_feature -from .macsec_config_helper import disable_macsec_feature -from .macsec_config_helper import setup_macsec_configuration -from .macsec_config_helper import cleanup_macsec_configuration -# flake8: noqa: F401 -from tests.common.plugins.sanity_check import sanity_check - -logger = logging.getLogger(__name__) - - -class MacsecPlugin(object): - """ - Pytest macsec plugin - """ - - def __init__(self): - with open(os.path.dirname(__file__) + '/profile.json') as f: - self.macsec_profiles = json.load(f) - for k, v in list(self.macsec_profiles.items()): - self.macsec_profiles[k]["name"] = k - # Set default value - if "rekey_period" not in v: - self.macsec_profiles[k]["rekey_period"] = 0 - - def _generate_macsec_profile(self, metafunc): - value = metafunc.config.getoption("macsec_profile") - if value == 'all': - return natsort.natsorted(list(self.macsec_profiles.keys())) - return [x for x in value.split(',') if x in self.macsec_profiles] - - def pytest_generate_tests(self, metafunc): - if 'macsec_profile' in metafunc.fixturenames: - profiles = self._generate_macsec_profile(metafunc) - assert profiles, "Specify valid macsec profile!" - metafunc.parametrize('macsec_profile', - [self.macsec_profiles[x] for x in profiles], - ids=profiles, - scope="module") - - def get_ctrl_nbr_names(self, macsec_duthost, nbrhosts, tbinfo): - return NotImplementedError() - - def downstream_neighbor(self,tbinfo, neighbor): - return NotImplementedError() - - def upstream_neighbor(self,tbinfo, neighbor): - return NotImplementedError() - - @pytest.fixture(scope="module") - def start_macsec_service(self, macsec_duthost, macsec_nbrhosts): - def __start_macsec_service(): - enable_macsec_feature(macsec_duthost, macsec_nbrhosts) - return __start_macsec_service - - @pytest.fixture(scope="module") - def stop_macsec_service(self, macsec_duthost, macsec_nbrhosts): - def __stop_macsec_service(): - disable_macsec_feature(macsec_duthost, macsec_nbrhosts) - return __stop_macsec_service - - @pytest.fixture(scope="module") - def macsec_feature(self, start_macsec_service, stop_macsec_service): - start_macsec_service() - yield - stop_macsec_service() - - @pytest.fixture(scope="module") - def startup_macsec(self, request, macsec_duthost, ctrl_links, macsec_profile, tbinfo): - topo_name = tbinfo['topo']['name'] - def __startup_macsec(): - profile = macsec_profile - if request.config.getoption("neighbor_type") == "eos": - if macsec_duthost.facts["asic_type"] == "vs" and profile['send_sci'] == "false": - # On EOS, portchannel mac is not same as the member port mac (being as SCI), - # then src mac is not equal to SCI in its sending packet. The receiver of vSONIC - # will drop it for macsec kernel module does not correctly handle it. - pytest.skip( - "macsec on dut vsonic, neighbor eos, send_sci false") - if 't2' not in topo_name: - cleanup_macsec_configuration(macsec_duthost, ctrl_links, profile['name']) - setup_macsec_configuration(macsec_duthost, ctrl_links, - profile['name'], profile['priority'], profile['cipher_suite'], - profile['primary_cak'], profile['primary_ckn'], profile['policy'], - profile['send_sci'], profile['rekey_period']) - logger.info( - "Setup MACsec configuration with arguments:\n{}".format(locals())) - return __startup_macsec - - @pytest.fixture(scope="module") - def shutdown_macsec(self, macsec_duthost, ctrl_links, macsec_profile): - def __shutdown_macsec(): - profile = macsec_profile - cleanup_macsec_configuration(macsec_duthost, ctrl_links, profile['name']) - return __shutdown_macsec - - @pytest.fixture(scope="module", autouse=True) - def macsec_setup(self, startup_macsec, shutdown_macsec, macsec_feature): - ''' - setup macsec links - ''' - startup_macsec() - yield - shutdown_macsec() - - @pytest.fixture(scope="module") - def macsec_nbrhosts(self, ctrl_links): - return {nbr["name"]: nbr for nbr in list(ctrl_links.values())} - - @pytest.fixture(scope="module") - def ctrl_links(self, macsec_duthost, tbinfo, nbrhosts): - - if not nbrhosts: - topo_name = tbinfo['topo']['name'] - pytest.skip("None of neighbors on topology {}".format(topo_name)) - - ctrl_nbr_names = self.get_ctrl_nbr_names(macsec_duthost, nbrhosts, tbinfo) - logger.info("Controlled links {}".format(ctrl_nbr_names)) - nbrhosts = {name: nbrhosts[name] for name in ctrl_nbr_names} - return self.find_links_from_nbr(macsec_duthost, tbinfo, nbrhosts) - - @pytest.fixture(scope="module") - def unctrl_links(self, macsec_duthost, tbinfo, nbrhosts, ctrl_links): - unctrl_nbr_names = set(nbrhosts.keys()) - for _, nbr in ctrl_links.items(): - if nbr["name"] in unctrl_nbr_names: - unctrl_nbr_names.remove(nbr["name"]) - - logger.info("Uncontrolled links {}".format(unctrl_nbr_names)) - nbrhosts = {name: nbrhosts[name] for name in unctrl_nbr_names} - return self.find_links_from_nbr(macsec_duthost, tbinfo, nbrhosts) - - @pytest.fixture(scope="module") - def downstream_links(self, macsec_duthost, tbinfo, nbrhosts): - links = collections.defaultdict(dict) - - def filter(interface, neighbor, mg_facts, tbinfo): - if self.downstream_neighbor(tbinfo, neighbor): - port = mg_facts["minigraph_neighbors"][interface]["port"] - if interface not in mg_facts["minigraph_ptf_indices"]: - logger.info("Interface {} not in minigraph_ptf_indices".format(interface)) - return - links[interface] = { - "name": neighbor["name"], - "ptf_port_id": mg_facts["minigraph_ptf_indices"][interface], - "port": port - } - self.find_links(macsec_duthost, tbinfo, filter) - return links - - @pytest.fixture(scope="module") - def upstream_links(self, macsec_duthost, tbinfo, nbrhosts): - links = collections.defaultdict(dict) - - def filter(interface, neighbor, mg_facts, tbinfo): - if self.upstream_neighbor(tbinfo, neighbor): - for item in mg_facts["minigraph_bgp"]: - if item["name"] == neighbor["name"]: - if isinstance(ip_address(item["addr"]), IPv4Address): - # The address of neighbor device - local_ipv4_addr = item["addr"] - # The address of DUT - peer_ipv4_addr = item["peer_addr"] - break - if interface not in mg_facts["minigraph_ptf_indices"]: - logger.info("Interface {} not in minigraph_ptf_indices".format(interface)) - return - port = mg_facts["minigraph_neighbors"][interface]["port"] - links[interface] = { - "name": neighbor["name"], - "ptf_port_id": mg_facts["minigraph_ptf_indices"][interface], - "local_ipv4_addr": local_ipv4_addr, - "peer_ipv4_addr": peer_ipv4_addr, - "port": port, - "host": nbrhosts[neighbor["name"]]["host"] - } - self.find_links(macsec_duthost, tbinfo, filter) - return links - - def find_links(self, duthost, tbinfo, filter): - - mg_facts = duthost.get_extended_minigraph_facts(tbinfo) - for interface, neighbor in mg_facts["minigraph_neighbors"].items(): - filter(interface, neighbor, mg_facts, tbinfo) - - def is_interface_portchannel_member(self, pc, interface): - for pc_name, elements in list(pc.items()): - if interface in elements['members']: - return True - return False - - def find_links_from_nbr(self, duthost, tbinfo, nbrhosts): - links = collections.defaultdict(dict) - def filter(interface, neighbor, mg_facts, tbinfo): - if neighbor["name"] not in list(nbrhosts.keys()): - return - port = mg_facts["minigraph_neighbors"][interface]["port"] - - links[interface] = { - "name": neighbor["name"], - "host": nbrhosts[neighbor["name"]]["host"], - "port": port, - "dut_name": duthost.hostname - } - self.find_links(duthost, tbinfo, filter) - return links - -class MacsecPluginT0(MacsecPlugin): - """ - Pytest macsec plugin - """ - - - def __init__(self): - super(MacsecPluginT0, self).__init__() - - def get_ctrl_nbr_names(self, macsec_duthost, nbrhosts, tbinfo): - ctrl_nbr_names = natsort.natsorted(nbrhosts.keys())[:2] - return ctrl_nbr_names - - def downstream_neighbor(self,tbinfo, neighbor): - if (tbinfo["topo"]["type"] == "t0" and "Server" in neighbor["name"]): - return True - return False - - def upstream_neighbor(self,tbinfo, neighbor): - if (tbinfo["topo"]["type"] == "t0" and "T1" in neighbor["name"]): - return True - return False - -class MacsecPluginT2(MacsecPlugin): - """ - Pytest macsec plugin - """ - - - def __init__(self): - super(MacsecPluginT2, self).__init__() - - def get_ctrl_nbr_names(self, macsec_duthost, nbrhosts, tbinfo): - mg_facts = macsec_duthost.get_extended_minigraph_facts(tbinfo) - ctrl_nbr_names = mg_facts['macsec_neighbors'] - return ctrl_nbr_names - - def downstream_neighbor(self,tbinfo, neighbor): - if ("t2" in tbinfo["topo"]["type"] and "T1" in neighbor["name"]): - return True - return False - - def upstream_neighbor(self,tbinfo, neighbor): - if ("t2" in tbinfo["topo"]["type"] and "T3" in neighbor["name"]): - return True - return False diff --git a/tests/macsec/conftest.py b/tests/macsec/conftest.py index 352887c41d3..d7b1bc6b2a6 100644 --- a/tests/macsec/conftest.py +++ b/tests/macsec/conftest.py @@ -1,6 +1,6 @@ import pytest -from .macsec_helper import check_appl_db +from tests.common.macsec.macsec_helper import check_appl_db from tests.common.utilities import wait_until diff --git a/tests/macsec/test_controlplane.py b/tests/macsec/test_controlplane.py index 61ffb58e02b..ad140df323c 100644 --- a/tests/macsec/test_controlplane.py +++ b/tests/macsec/test_controlplane.py @@ -5,9 +5,9 @@ from tests.common.utilities import wait_until from tests.common.devices.eos import EosHost -from .macsec_helper import check_wpa_supplicant_process, check_appl_db, check_mka_session,\ +from tests.common.macsec.macsec_helper import check_wpa_supplicant_process, check_appl_db, check_mka_session,\ get_mka_session, get_sci, get_appl_db, get_ipnetns_prefix -from .macsec_platform_helper import get_platform, get_macsec_ifname +from tests.common.macsec.macsec_platform_helper import get_platform, get_macsec_ifname logger = logging.getLogger(__name__) diff --git a/tests/macsec/test_dataplane.py b/tests/macsec/test_dataplane.py index b70eac40ae9..a6d5bd6e2ff 100644 --- a/tests/macsec/test_dataplane.py +++ b/tests/macsec/test_dataplane.py @@ -7,9 +7,9 @@ from collections import Counter from tests.common.devices.eos import EosHost -from .macsec_helper import create_pkt, create_exp_pkt, check_macsec_pkt,\ +from tests.common.macsec.macsec_helper import create_pkt, create_exp_pkt, check_macsec_pkt,\ get_ipnetns_prefix, get_macsec_sa_name, get_macsec_counters -from .macsec_platform_helper import get_portchannel, find_portchannel_from_member +from tests.common.macsec.macsec_platform_helper import get_portchannel, find_portchannel_from_member logger = logging.getLogger(__name__) diff --git a/tests/macsec/test_deployment.py b/tests/macsec/test_deployment.py index 58b3278ff02..ce1dfb2c245 100644 --- a/tests/macsec/test_deployment.py +++ b/tests/macsec/test_deployment.py @@ -3,7 +3,7 @@ from tests.common.utilities import wait_until from tests.common import config_reload -from .macsec_helper import check_appl_db +from tests.common.macsec.macsec_helper import check_appl_db logger = logging.getLogger(__name__) pytestmark = [ diff --git a/tests/macsec/test_docker_restart.py b/tests/macsec/test_docker_restart.py index a4fa0bd6664..eda0c32278c 100644 --- a/tests/macsec/test_docker_restart.py +++ b/tests/macsec/test_docker_restart.py @@ -2,7 +2,7 @@ import logging from tests.common.utilities import wait_until -from .macsec_helper import check_appl_db +from tests.common.macsec.macsec_helper import check_appl_db logger = logging.getLogger(__name__) diff --git a/tests/macsec/test_fault_handling.py b/tests/macsec/test_fault_handling.py index 53c19007e9c..ffd2c23b0b4 100644 --- a/tests/macsec/test_fault_handling.py +++ b/tests/macsec/test_fault_handling.py @@ -4,9 +4,10 @@ from tests.common.utilities import wait_until from tests.common.devices.eos import EosHost -from .macsec_helper import get_appl_db -from .macsec_config_helper import disable_macsec_port, enable_macsec_port, delete_macsec_profile, set_macsec_profile -from .macsec_platform_helper import get_eth_ifname, find_portchannel_from_member, get_portchannel +from tests.common.macsec.macsec_helper import get_appl_db +from tests.common.macsec.macsec_config_helper import disable_macsec_port, \ + enable_macsec_port, delete_macsec_profile, set_macsec_profile +from tests.common.macsec.macsec_platform_helper import get_eth_ifname, find_portchannel_from_member, get_portchannel logger = logging.getLogger(__name__) diff --git a/tests/macsec/test_interop_protocol.py b/tests/macsec/test_interop_protocol.py index 78bfd23657d..5351cea9261 100644 --- a/tests/macsec/test_interop_protocol.py +++ b/tests/macsec/test_interop_protocol.py @@ -3,9 +3,10 @@ import ipaddress from tests.common.utilities import wait_until -from .macsec_helper import getns_prefix -from .macsec_config_helper import disable_macsec_port, enable_macsec_port -from .macsec_platform_helper import find_portchannel_from_member, get_portchannel, get_lldp_list, sonic_db_cli +from tests.common.macsec.macsec_helper import getns_prefix +from tests.common.macsec.macsec_config_helper import disable_macsec_port, enable_macsec_port +from tests.common.macsec.macsec_platform_helper import find_portchannel_from_member, \ + get_portchannel, get_lldp_list, sonic_db_cli from tests.common.helpers.snmp_helpers import get_snmp_output logger = logging.getLogger(__name__) diff --git a/tests/macsec/test_interop_wan_isis.py b/tests/macsec/test_interop_wan_isis.py index 6e6e80527bc..ab0530aa708 100644 --- a/tests/macsec/test_interop_wan_isis.py +++ b/tests/macsec/test_interop_wan_isis.py @@ -3,9 +3,9 @@ from tests.common.utilities import wait_until from tests.common.helpers.assertions import pytest_assert -from .macsec_platform_helper import get_portchannel -from .macsec_platform_helper import find_portchannel_from_member -from .macsec_config_helper import enable_macsec_port, disable_macsec_port +from tests.common.macsec.macsec_platform_helper import get_portchannel +from tests.common.macsec.macsec_platform_helper import find_portchannel_from_member +from tests.common.macsec.macsec_config_helper import enable_macsec_port, disable_macsec_port logger = logging.getLogger(__name__) From 0f11ff3feaf2cf900bd68f32e4ed6b15a584fefe Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:31:00 +0800 Subject: [PATCH 196/221] Add a new checker to check cross-feature dependency. (#15559) What is the motivation for this PR? We introduced a new approach to PR testing called Impacted area based PR testing. In this model, the scope of PR testing is determined by the specific areas of the code that are impacted by the changes, allowing for more focused and efficient testing. This means, we need to establish clear boundaries between different sections of code and minimize dependencies as much as possible. In the tests directory of the sonic-mgmt repository, we have categorized scripts into two main groups: shared scripts and feature-specific scripts. Shared scripts provide common utilities or functionality used across multiple features, while feature-specific scripts are tied to particular features and their corresponding logic. However, the previous codebase contained a significant number of cross-feature dependencies, where scripts from one feature directly referenced or relied on scripts from another. To address this issue and align with our new testing model, we manually reviewed the existing code and removed all cross-feature references. But we need a mechanism to check future modifications and new code to prevent reintroducing these issues. In this PR, we introduce a new checker to identify any cross-feature dependencies. At this stage, since some cross-feature dependencies remain in the code, this checker is configured to flag these dependencies without causing the entire test to fail. Once all current dependencies are fully removed, any reintroduced cross-feature dependencies detected by this checker will result in a test failure. How did you do it? In this PR, we introduce a new checker to identify any cross-feature dependencies. At this stage, since some cross-feature dependencies remain in the code, this checker is configured to flag these dependencies without causing the entire test to fail. Once all current dependencies are fully removed, any reintroduced cross-feature dependencies detected by this checker will result in a test failure. How did you verify/test it? --- .azure-pipelines/dependency-check.yml | 8 + .azure-pipelines/dependency_check/README.md | 108 +++++++++ .azure-pipelines/dependency_check/__init__.py | 0 .../dependency_check/dependency_check.py | 218 ++++++++++++++++++ azure-pipelines.yml | 9 + 5 files changed, 343 insertions(+) create mode 100644 .azure-pipelines/dependency-check.yml create mode 100644 .azure-pipelines/dependency_check/README.md create mode 100644 .azure-pipelines/dependency_check/__init__.py create mode 100644 .azure-pipelines/dependency_check/dependency_check.py diff --git a/.azure-pipelines/dependency-check.yml b/.azure-pipelines/dependency-check.yml new file mode 100644 index 00000000000..ea9161927c3 --- /dev/null +++ b/.azure-pipelines/dependency-check.yml @@ -0,0 +1,8 @@ +steps: +- script: | + set -x + + pip3 install natsort + + python3 ./.azure-pipelines/dependency_check/dependency_check.py tests + displayName: "Dependency Check" diff --git a/.azure-pipelines/dependency_check/README.md b/.azure-pipelines/dependency_check/README.md new file mode 100644 index 00000000000..a5f8731a08f --- /dev/null +++ b/.azure-pipelines/dependency_check/README.md @@ -0,0 +1,108 @@ +## Background +We introduced a new approach to PR testing called _Impacted area based PR testing_. \ +In this model, the scope of PR testing is determined by the specific areas of the code that are impacted by the changes, +allowing for more focused and efficient testing. +This means, we need to establish clear boundaries between different sections of code +and minimize dependencies as much as possible. + +We can consider the test scripts in this way: +``` +sonic-mgmgt + | + | - tests + | + | - common ---------- shared + | - arp -----| + | - ecmp | --- features + | - vlan | + | - ...... -----| +``` +Within the tests directory in sonic-mgmt, we categorize scripts into two sections: shared and features. +Scripts in the common folder fall under the shared section and can be utilized across different folders. +In contrast, scripts in other folders belong to the features section, representing specific functionalities such as arp, ecmp, and vlan, +and are intended for use within their respective folders. + +However, the previous code had numerous cross-feature dependencies. +To achieve the above goal, we have removed the cross-feature references from the existing code. +But we need a mechanism to check future modifications and new code to prevent reintroducing these issues. + + +## Design +The _ast_ module helps python applications to process trees of the python abstract syntax grammar. +This module produces a tree of objects, where each object is an instance of a class that inherits from _ast.AST_. +There are two classes related to the imports: + +#### ast.Import + - An import statement such as `import x as a,y` + - _names_ is a list of alias nodes. +``` + Import(names=[ + alias(name='x', + asname='a') + ]), + Import(names=[ + alias(name='y', + asname=None) + ]), +``` +#### ast.ImportFrom + - Represents `from x import y,z`. + - _module_ is a raw string of the ‘from’ name, without any leading dots, or None for statements such as `from . import foo.` + - _level_ is an integer holding the level of the relative import (0 means absolute import) +``` +ImportFrom( + module='x', + names=[ + alias(name='y', asname=None), + alias(name='z', asname=None)], + level=0) +``` + +To achieve our goal, we need to follow these steps. + + Gather all scripts to be analyzed + + Identify all imported modules in each script along with their import paths + + Compare each imported path with its corresponding script path + +### Gather all scripts to be analyzed +To collect all scripts for analysis, +we can use `os.walk` to gather every script within the specified path + +### Identify all imported modules in each script along with their import paths +To identify all imported modules, +we can use the _ast_ module, as mentioned above, to analyze each collected script and obtain its abstract syntax tree. +Then, using the _ast.ImportFrom_ and _ast.Import_ classes, we can extract the imported modules from each script. + + +Here are the steps and configuration methods for Python to search for module paths: ++ The current script's directory or the directory from which the Python interpreter is started. ++ Standard library path: Contains the standard library modules from the Python installation directory. ++ Third-party library path: For example, the site-packages directory, where third-party libraries installed via pip and other tools are stored. ++ Environment variable path: Custom directories can be added to sys.path via the PYTHONPATH environment variable. + +As paths of project is not included in the sys path, we need to add them into sys path first. + ++ `importlib.util.find_spec` is a function in Python that is used to find the specification of a module. + The specification contains details about the module, such as its location (file path), loader, and other attributes. + It can find the path of standard library, third-party libraries and custom modules which are imported with no hierarchy. + + For statement like `import math`, `from tests.common.plugins.allure_wrapper import allure_step_wrapper`, `from gnmi_utils import apply_gnmi_file`, + we can use `importlib.util.find_spec` to get their imported path. ++ For hierarchy imported, we can calculate the abs path using the current file path and level to navigate up to the corresponding directory. + +### Compare each imported path with its corresponding script path +We will focus only on imported paths that start with `sonic-mgmt/tests`. +Paths imported from other folders within `sonic-mgmt` are treated as common locations. + +For paths beginning with `sonic-mgmt/tests`, there are three special cases: ++ sonic-mgmt/tests/common ++ sonic-mgmt/tests/ptf_runner.py ++ sonic-mgmt/tests/conftest.py +which are also considered as common paths. + +For all other paths, we will compare each imported path to the path of the corresponding script based on the following principles: ++ The first-level folders under `sonic-mgmt/tests` (e.g., arp, bgp) are considered feature folders. ++ If both the imported module and the script are in the same feature folder, there is no cross-feature dependency. ++ If they are in different feature folders, it indicates a cross-feature dependency, causing the check to fail. + + +We will add this check as a step in `Pre_test` in PR test. diff --git a/.azure-pipelines/dependency_check/__init__.py b/.azure-pipelines/dependency_check/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/.azure-pipelines/dependency_check/dependency_check.py b/.azure-pipelines/dependency_check/dependency_check.py new file mode 100644 index 00000000000..17c24a2b35b --- /dev/null +++ b/.azure-pipelines/dependency_check/dependency_check.py @@ -0,0 +1,218 @@ +import ast +import sys +import os +import importlib.util +from natsort import natsorted +from contextlib import contextmanager + + +def collect_all_scripts(): + """ + Recursively find all files ending with ".py" under the folder "tests" + Note: The full path and name of files are stored in a list named "files" + + Returns: + A list of files ending with ".py" under the folder "tests" + """ + location = sys.argv[1] + files = [] + for root, dirs, file in os.walk(location): + for f in file: + if f.endswith(".py"): + files.append(os.path.join(root, f)) + files = natsorted(files) + return files + + +@contextmanager +def set_sys_path(file_path): + """ + Add all the paths related to the file into sys path + + Args: + file_path (list): A list of files ending with ".py" under the folder "tests" + Returns: + None + """ + original_sys_path = sys.path.copy() + try: + current_dir = os.path.abspath(os.path.dirname(file_path)) + while current_dir != os.path.dirname(current_dir): + if current_dir.endswith("/tests"): + sys.path.append(os.path.join(current_dir, "common")) + + sys.path.append(current_dir) + current_dir = os.path.dirname(current_dir) + yield + finally: + sys.path = original_sys_path + + +def get_module_path(imported_module, level=0, file_path=""): + """ + Get the abs path of the imported module + + Args: + imported_module (string): The imported module imported in the script. + level (int): The import level that generated by ast. + file_path (string): The path of a test script. + Returns: + string/None: The absolute path of the imported module or None + """ + try: + if level == 0: + # Level 0 means an absolute import. + # This means that the import statement is intended to refer directly + # to the module or package path as specified without any relative hierarchy. + # So we can get the module path using "importlib.util.find_spec" + spec = importlib.util.find_spec(imported_module) + if spec and spec.origin: + return spec.origin + if level == 1: + # Level 1 means the import is relative to the current package level, + # so the module path shares the same dirname with the file. + # To save time, we don't need to check such import module. + return None + else: + # For level which is higher than 1, + # the number represents how many levels up in the package hierarchy the import should go. + # Based on the current file path and the specified level, we can navigate up to the corresponding directory + # and then combine the module name with the upper-level path to form an absolute path + base_dir = os.path.abspath(file_path) + for _ in range(level): + base_dir = os.path.dirname(base_dir) + return os.path.join(base_dir, *imported_module.split(".")) + except ModuleNotFoundError: + return None + + +def get_imported_modules(files): + """ + Get all imported modules in each file. + + Args: + files (list): A list of files ending with ".py" under the folder "tests" + Returns: + dict: All imported modules in test scripts. The output formatted as below + { + '../tests/acl/custom_acl_table/test_custom_acl_table.py': [ + { + 'type': 'from_import', + 'module': 'ptf.mask', + 'module_path': '/usr/local/lib/python3.8/dist-packages/ptf/mask.py', + 'alias': 'Mask', + 'asname': None + }, + { + 'type': 'from_import', + 'module': 'tests.common.fixtures.ptfhost_utils', + 'module_path': '/data/sonic-mgmt/tests/common/fixtures/ptfhost_utils.py', + 'alias': 'skip_traffic_test', + 'asname': None + } + ], + '../tests/bgp/test_bgp_session_flap.py': [ + { + 'type': 'from_import', + 'module': 'tests.common.utilities', + 'module_path': '/data/sonic-mgmt/tests/common/utilities.py', + 'alias': 'InterruptableThread', + 'asname': None + } + ] + } + """ + imported_modules_in_files = {} + for file_path in files: + # For each file, we need to add its related path into sys path + with set_sys_path(file_path): + # We use ast to analyse the file as an abstract syntax tree, + # and get all imported modules using class `ast.Import` and `ast.ImportFrom` + with open(file_path, "r", encoding="utf-8") as file: + tree = ast.parse(file.read(), filename=file_path) + imported_modules_in_files[file_path] = [] + for node in ast.walk(tree): + # Check for `import` statements + if isinstance(node, ast.Import): + for entry in node.names: + imported_modules_in_files[file_path].append({ + "type": "import", + "module": entry.name, + "module_path": get_module_path(entry.name), + "asname": entry.asname + }) + # Check for `from ... import ...` statements + if isinstance(node, ast.ImportFrom): + for entry in node.names: + imported_modules_in_files[file_path].append({ + "type": "from_import", + "module": node.module, + "module_path": get_module_path(node.module, node.level, file_path), + "alias": entry.name, + "asname": entry.asname + }) + return imported_modules_in_files + + +def get_feature_path(path): + """ + For our repo, we can consider the folders like "acl", "bgp" as feature folders. + In this function, we will retrieve the path of the top-level feature directories. + In other words, we will retrieve the absolute paths of the first-level folders under `sonic-mgmt/tests` + + Args: + path (string): The path of a file or an import module + Returns: + string/None: The absolute feature path or None + """ + if path is None: + return None + + file_path = os.path.abspath(path) + target_path = "tests" + index = file_path.find(target_path) + + if index != -1: + project_path = file_path[:index + len(target_path)] + else: + return None + + feature = file_path[len(project_path) + 1:].split("/")[0] + return os.path.join(project_path, feature) + + +def check_cross_dependency(imports_in_script): + """ + Check if there are cross-feature dependency in each file. + + Args: + imports_in_script (dict): All imported modules in test scripts. + Returns: + bool: True is there are cross-feature dependencies and False is there is no cross-feature dependencies + """ + cross_dependency = False + for file_path, imported_modules in imports_in_script.items(): + file_feature_path = get_feature_path(file_path) + for imported_module in imported_modules: + imported_module_feature_path = get_feature_path(imported_module["module_path"]) + if imported_module_feature_path is not None: + project_path = os.path.dirname(file_feature_path) + # Import from these paths are allowed. + if imported_module_feature_path not in [os.path.join(project_path, "common"), + os.path.join(project_path, "ptf_runner.py"), + os.path.join(project_path, "conftest.py"), + file_feature_path]: + print("There is a cross-feature dependence. File: {}, import module: {}" + .format(file_path, imported_module["module"])) + cross_dependency = True + return cross_dependency + + +if __name__ == '__main__': + files = collect_all_scripts() + imported_modules_in_files = get_imported_modules(files) + cross_dependency = check_cross_dependency(imported_modules_in_files) + if cross_dependency: + print("\033[31mThere are cross-feature dependencies, which is not allowed in our repo\033[0m") + print("\033[31mTo resolve this issue, please move the shared function to common place, " + "such as 'tests/common'\033[0m") diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1256f817404..76cacd39c1d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -43,6 +43,15 @@ stages: parameters: MGMT_BRANCH: "" + - job: dependency_check + displayName: "Dependency Check" + timeoutInMinutes: 10 + continueOnError: true + pool: sonic-common + steps: + - template: .azure-pipelines/dependency-check.yml + + - stage: Test dependsOn: Pre_test condition: and(succeeded(), in(dependencies.Pre_test.result, 'Succeeded')) From 28f0f7a60b75a95ad94bb02f5035fc957e90c2fd Mon Sep 17 00:00:00 2001 From: ShiyanWangMS Date: Wed, 20 Nov 2024 11:40:24 +0800 Subject: [PATCH 197/221] Ignore test_bgp_prefix.py::test_bgp_prefix_tc1_suite for Cisco 8122 backend compute ai deployment (#15622) * init commit * revise --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index b6c9edab036..51de4527a66 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -793,6 +793,12 @@ generic_config_updater: conditions: - "'t2' in topo_name" +generic_config_updater/test_bgp_prefix.py::test_bgp_prefix_tc1_suite[empty]: + skip: + reason: "Cisco 8122 backend compute ai platform is not supported." + conditions: + - "platform in ['x86_64-8122_64eh_o-r0', 'x86_64-8122_64ehf_o-r0']" + generic_config_updater/test_dhcp_relay.py: skip: reason: "Need to skip for platform x86_64-8111_32eh_o-r0 or backend topology / generic_config_updater is not a supported feature for T2" From 142d8ec68b5278fb7b6407ee1a7a185d3aa30aca Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:03:17 +0800 Subject: [PATCH 198/221] Revert "Update j2cli to jinjanator. (#15600)" (#15636) This reverts commit 174c6bf76535d1022f7a652daa251d605a5b3d21. --- ansible/setup-management-network.sh | 8 ++++---- docs/testbed/README.testbed.Setup.md | 2 +- docs/testbed/README.testbed.VsSetup.md | 2 +- setup-container.sh | 12 +++--------- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/ansible/setup-management-network.sh b/ansible/setup-management-network.sh index fd2eae5892b..3347d216b6d 100755 --- a/ansible/setup-management-network.sh +++ b/ansible/setup-management-network.sh @@ -33,10 +33,10 @@ echo "Refreshing apt package lists..." apt-get update echo -echo "STEP 1: Checking for jinjanator package..." -if ! command -v jinjanate; then - echo "jinjanator not found, installing jinjanator" - cmd="install --user jinjanator==24.4.0" +echo "STEP 1: Checking for j2cli package..." +if ! command -v j2; then + echo "j2cli not found, installing j2cli" + cmd="install --user j2cli==0.3.10" if ! command -v pip &> /dev/null; then pip3 $cmd else diff --git a/docs/testbed/README.testbed.Setup.md b/docs/testbed/README.testbed.Setup.md index c6dcf6431fb..f26f162befa 100644 --- a/docs/testbed/README.testbed.Setup.md +++ b/docs/testbed/README.testbed.Setup.md @@ -20,7 +20,7 @@ This document describes the steps to setup the testbed and deploy a topology. ``` - Install Python prerequisites ``` - sudo pip3 install jinjanator + sudo pip3 install j2cli ``` - Install Docker (all credits to https://docs.docker.com/engine/install/ubuntu/ ) ``` diff --git a/docs/testbed/README.testbed.VsSetup.md b/docs/testbed/README.testbed.VsSetup.md index daa38c6fbca..f6eea3fab0e 100644 --- a/docs/testbed/README.testbed.VsSetup.md +++ b/docs/testbed/README.testbed.VsSetup.md @@ -22,7 +22,7 @@ First, we need to prepare the host where we will be configuring the virtual test ``` sudo apt install python python-pip openssh-server # v0.3.10 Jinja2 is required, lower version may cause uncompatible issue - sudo pip install jinjanate==24.4.0 + sudo pip install j2cli==0.3.10 ``` 3. Run the host setup script to install required packages and initialize the management bridge network diff --git a/setup-container.sh b/setup-container.sh index 5318aa806e9..90bae4ef4f8 100755 --- a/setup-container.sh +++ b/setup-container.sh @@ -275,7 +275,7 @@ ROOT_PASS=${ROOT_PASS} EOF log_info "generate a Dockerfile: ${TMP_DIR}/Dockerfile" - jinjanate -o "${TMP_DIR}/Dockerfile" "${TMP_DIR}/Dockerfile.j2" "${TMP_DIR}/data.env" || \ + j2 -o "${TMP_DIR}/Dockerfile" "${TMP_DIR}/Dockerfile.j2" "${TMP_DIR}/data.env" || \ log_error "failed to generate a Dockerfile: ${TMP_DIR}/Dockerfile" log_info "building docker image from ${TMP_DIR}: ${LOCAL_IMAGE} ..." @@ -445,14 +445,8 @@ if docker ps -a --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then fi fi -if ! which jinjanate &> /dev/null; then - echo "jinjanator not found, installing jinjanator" - cmd="install --user jinjanator==24.4.0" - if ! command -v pip &> /dev/null; then - pip3 $cmd - else - pip $cmd - fi +if ! which j2 &> /dev/null; then + exit_failure "missing Jinja2 templates support: make sure j2cli package is installed" fi pull_sonic_mgmt_docker_image From 71793e7f1282889f0d2b3a38b8084f9ed1e4d4cc Mon Sep 17 00:00:00 2001 From: vkjammala-arista <152394203+vkjammala-arista@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:58:13 +0530 Subject: [PATCH 199/221] [sonic-mgmt] Correct conditional_mark for testcase "test_standby_tor_downstream_loopback_route_readded" (#15534) What is the motivation for this PR? dualtor/test_orchagent_standby_tor_downstream.py::test_standby_tor_downstream_loopback_route_readded was being skipped earlier with reason This testcase is designed for single tor testbed with mock dualtor config. This has started running recently after infra changes done for conditional_mark through #14395. How did you do it? Updated conditional_mark to skip this test for dualtor topologies (to be in consistent with earlier behaviour as the test was getting skipped earlier). How did you verify/test it? With the above change verified that test is getting skipped on dualtor topologies. --- .../plugins/conditional_mark/tests_mark_conditions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 51de4527a66..cd5255da248 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -477,9 +477,9 @@ dualtor/test_orchagent_standby_tor_downstream.py::test_standby_tor_downstream_bg dualtor/test_orchagent_standby_tor_downstream.py::test_standby_tor_downstream_loopback_route_readded: skip: - reason: "This testcase is designed for single tor testbed with mock dualtor config and dualtor." + reason: "This testcase is designed for single tor testbed with mock dualtor config." conditions: - - "(topo_type not in ['t0'])" + - "(topo_type not in ['t0']) or ('dualtor' in topo_name)" dualtor/test_orchagent_standby_tor_downstream.py::test_standby_tor_downstream_t1_link_recovered: skip: From 7136df6b9502dac594c2cc7ad9cb049c480fa1cb Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Wed, 20 Nov 2024 18:30:34 +0800 Subject: [PATCH 200/221] [arp] add conntrack table test for incomplete neighbor (#14747) What is the motivation for this PR? Need test to test conntrack table size when there is neighbor in incomplete state. How did you do it? Create neighbor in incomplete state, ping to create icmpv6 packets, and check conntrack table size. How did you verify/test it? Run test --- tests/arp/test_stress_arp.py | 120 ++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 17 deletions(-) diff --git a/tests/arp/test_stress_arp.py b/tests/arp/test_stress_arp.py index c6dcd250261..dcd1afb4e07 100644 --- a/tests/arp/test_stress_arp.py +++ b/tests/arp/test_stress_arp.py @@ -1,6 +1,7 @@ import logging import time import pytest +import random from .arp_utils import MacToInt, IntToMac, get_crm_resources, fdb_cleanup, \ clear_dut_arp_cache, get_fdb_dynamic_mac_count import ptf.testutils as testutils @@ -11,9 +12,12 @@ from tests.common.utilities import wait_until, increment_ipv6_addr from tests.common.errors import RunAnsibleModuleFail + ARP_BASE_IP = "172.16.0.1/16" ARP_SRC_MAC = "00:00:01:02:03:04" ENTRIES_NUMBERS = 12000 +TEST_CONNTRACK_TIMEOUT = 300 +TEST_INCOMPLETE_NEIGHBOR_CNT = 10 logger = logging.getLogger(__name__) @@ -95,15 +99,15 @@ def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, if normalized_level is None: normalized_level = "debug" asic_type = duthost.facts['asic_type'] - ipv4_avaliable = get_crm_resources(duthost, "ipv4_neighbor", "available") - fdb_avaliable = get_crm_resources(duthost, "fdb_entry", "available") - pytest_assert(ipv4_avaliable > 0 and fdb_avaliable > 0, "Entries have been filled") + ipv4_available = get_crm_resources(duthost, "ipv4_neighbor", "available") + fdb_available = get_crm_resources(duthost, "fdb_entry", "available") + pytest_assert(ipv4_available > 0 and fdb_available > 0, "Entries have been filled") - arp_avaliable = min(min(ipv4_avaliable, fdb_avaliable), ENTRIES_NUMBERS) + arp_available = min(min(ipv4_available, fdb_available), ENTRIES_NUMBERS) pytest_require(garp_enabled, 'Gratuitous ARP not enabled for this device') ptf_intf_ipv4_hosts = genrate_ipv4_ip() - ptf_intf_ipv4_hosts = ptf_intf_ipv4_hosts[1:arp_avaliable + 1] + ptf_intf_ipv4_hosts = ptf_intf_ipv4_hosts[1:arp_available + 1] _, _, intf1_index, _, = intfs_for_test loop_times = LOOP_TIMES_LEVEL_MAP[normalized_level] @@ -116,9 +120,9 @@ def test_ipv4_arp(duthost, garp_enabled, ip_and_intf_info, intfs_for_test, # There is a certain probability of hash collision, we set the percentage as 1% here # The entries we add will not exceed 10000, so the number we tolerate is 100 logger.debug("Expected route number: {}, real route number {}" - .format(arp_avaliable, get_fdb_dynamic_mac_count(duthost))) + .format(arp_available, get_fdb_dynamic_mac_count(duthost))) pytest_assert(wait_until(20, 1, 0, - lambda: abs(arp_avaliable - get_fdb_dynamic_mac_count(duthost)) < 250), + lambda: abs(arp_available - get_fdb_dynamic_mac_count(duthost)) < 250), "ARP Table Add failed") finally: try: @@ -147,6 +151,7 @@ def generate_global_addr(mac): return ipv6 +# generate neighbor solicitation packet for test def ipv6_packets_for_test(ip_and_intf_info, fake_src_mac, fake_src_addr): _, _, src_addr_v6, _, _ = ip_and_intf_info fake_src_mac = fake_src_mac @@ -163,14 +168,14 @@ def ipv6_packets_for_test(ip_and_intf_info, fake_src_mac, fake_src_addr): return ns_pkt -def add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_avaliable): - for entry in range(0, nd_avaliable): +def add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_available): + for entry in range(0, nd_available): nd_entry_mac = IntToMac(MacToInt(ARP_SRC_MAC) + entry) fake_src_addr = generate_global_addr(nd_entry_mac) ns_pkt = ipv6_packets_for_test(ip_and_intf_info, nd_entry_mac, fake_src_addr) testutils.send_packet(ptfadapter, ptf_intf_index, ns_pkt) - logger.info("Sending {} ipv6 neighbor entries".format(nd_avaliable)) + logger.info("Sending {} ipv6 neighbor entries".format(nd_available)) def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, @@ -185,23 +190,23 @@ def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, normalized_level = "debug" asic_type = duthost.facts['asic_type'] loop_times = LOOP_TIMES_LEVEL_MAP[normalized_level] - ipv6_avaliable = get_crm_resources(duthost, "ipv6_neighbor", "available") - fdb_avaliable = get_crm_resources(duthost, "fdb_entry", "available") - pytest_assert(ipv6_avaliable > 0 and fdb_avaliable > 0, "Entries have been filled") + ipv6_available = get_crm_resources(duthost, "ipv6_neighbor", "available") + fdb_available = get_crm_resources(duthost, "fdb_entry", "available") + pytest_assert(ipv6_available > 0 and fdb_available > 0, "Entries have been filled") - nd_avaliable = min(min(ipv6_avaliable, fdb_avaliable), ENTRIES_NUMBERS) + nd_available = min(min(ipv6_available, fdb_available), ENTRIES_NUMBERS) while loop_times > 0: loop_times -= 1 try: - add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_avaliable) + add_nd(ptfadapter, ip_and_intf_info, ptf_intf_index, nd_available) if asic_type != 'vs': # There is a certain probability of hash collision, we set the percentage as 1% here # The entries we add will not exceed 10000, so the number we tolerate is 100 logger.debug("Expected route number: {}, real route number {}" - .format(nd_avaliable, get_fdb_dynamic_mac_count(duthost))) + .format(nd_available, get_fdb_dynamic_mac_count(duthost))) pytest_assert(wait_until(20, 1, 0, - lambda: abs(nd_avaliable - get_fdb_dynamic_mac_count(duthost)) < 250), + lambda: abs(nd_available - get_fdb_dynamic_mac_count(duthost)) < 250), "Neighbor Table Add failed") finally: try: @@ -214,3 +219,84 @@ def test_ipv6_nd(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, raise e # Wait for 10 seconds before starting next loop time.sleep(10) + + +def send_ipv6_echo_request(ptfadapter, dut_mac, ip_and_intf_info, ptf_intf_index, nd_available, tgt_cnt): + for i in range(tgt_cnt): + entry = random.randrange(0, nd_available) + nd_entry_mac = IntToMac(MacToInt(ARP_SRC_MAC) + entry) + fake_src_addr = generate_global_addr(nd_entry_mac) + _, _, src_addr_v6, _, _ = ip_and_intf_info + tgt_addr = increment_ipv6_addr(src_addr_v6) + er_pkt = testutils.simple_icmpv6_packet(eth_dst=dut_mac, + eth_src=nd_entry_mac, + ipv6_src=fake_src_addr, + ipv6_dst=tgt_addr, + icmp_type=128, + ) + identifier = random.randint(10000, 50000) + er_pkt.load = identifier.to_bytes(2, "big") + b"D" * 40 + testutils.send_packet(ptfadapter, ptf_intf_index, er_pkt) + + +def test_ipv6_nd_incomplete(duthost, ptfhost, config_facts, tbinfo, ip_and_intf_info, + ptfadapter, get_function_completeness_level, proxy_arp_enabled): + _, _, ptf_intf_ipv6_addr, _, ptf_intf_index = ip_and_intf_info + ptf_intf_ipv6_addr = increment_ipv6_addr(ptf_intf_ipv6_addr) + pytest_require(proxy_arp_enabled, 'Proxy ARP not enabled for all VLANs') + pytest_require(ptf_intf_ipv6_addr is not None, 'No IPv6 VLAN address configured on device') + + ipv6_available = get_crm_resources(duthost, "ipv6_neighbor", "available") + fdb_available = get_crm_resources(duthost, "fdb_entry", "available") + pytest_assert(ipv6_available > 0 and fdb_available > 0, "Entries have been filled") + + nd_available = min(min(ipv6_available, fdb_available), ENTRIES_NUMBERS) + tgt_incomplete_neighbor_cnt = min(nd_available, TEST_INCOMPLETE_NEIGHBOR_CNT) + + max_conntrack = int(duthost.command("cat /proc/sys/net/netfilter/nf_conntrack_max")["stdout"]) + logger.info("nf_conntrack_max: {}".format(max_conntrack)) + # we test a small portion of max_conntrack to see the increase + tgt_conntrack_cnt = int(max_conntrack * 0.1) + + conntrack_cnt_pre = int(duthost.command("cat /proc/sys/net/netfilter/nf_conntrack_count")["stdout"]) + logger.info("nf_conntrack_count pre test: {}".format(conntrack_cnt_pre)) + + pytest_assert("[UNREPLIED]" not in duthost.command("sudo conntrack -f ipv6 -L dying")["stdout"], + "unreplied icmpv6 requests ended up in the dying list before test is run") + + orig_conntrack_icmpv6_timeout = int(duthost.command("cat /proc/sys/net/netfilter/" + "nf_conntrack_icmpv6_timeout")["stdout"]) + logger.info("original nf_conntrack_icmpv6_timeout: {}".format(orig_conntrack_icmpv6_timeout)) + + try: + clear_dut_arp_cache(duthost) + + duthost.command("conntrack -F") + + duthost.shell("echo {} > /proc/sys/net/netfilter/nf_conntrack_icmpv6_timeout" + .format(TEST_CONNTRACK_TIMEOUT)) + logger.info("setting nf_conntrack_icmpv6_timeout to {}".format(TEST_CONNTRACK_TIMEOUT)) + + send_ipv6_echo_request(ptfadapter, duthost.facts["router_mac"], ip_and_intf_info, + ptf_intf_index, tgt_incomplete_neighbor_cnt, tgt_conntrack_cnt) + + conntrack_cnt_post = int(duthost.command("cat /proc/sys/net/netfilter/nf_conntrack_count")["stdout"]) + logger.info("nf_conntrack_count post test: {}".format(conntrack_cnt_post)) + + pytest_assert((conntrack_cnt_post - conntrack_cnt_pre) < tgt_conntrack_cnt * 0.1, + "{} echo requests cause large increase in conntrack entries".format(tgt_conntrack_cnt)) + + pytest_assert("[UNREPLIED]" not in duthost.command("conntrack -f ipv6 -L dying")["stdout"], + "unreplied icmpv6 requests ended up in the dying list") + + logger.info("neighbors in INCOMPLETE state: {}" + .format(duthost.command("ip -6 neigh")["stdout"].count("INCOMPLETE"))) + + finally: + duthost.shell("echo {} > /proc/sys/net/netfilter/nf_conntrack_icmpv6_timeout" + .format(orig_conntrack_icmpv6_timeout)) + logger.info("setting nf_conntrack_icmpv6_timeout back to {}".format(orig_conntrack_icmpv6_timeout)) + + duthost.command("conntrack -F") + + clear_dut_arp_cache(duthost) From f803ac22ab22be8084ed64d4ad76bd8618d08c45 Mon Sep 17 00:00:00 2001 From: Vivek Verma <137406113+vivekverma-arista@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:14:31 +0530 Subject: [PATCH 201/221] Fix routes/test_route_perf.py (#15620) Description of PR Summary: Fixes #323 Approach What is the motivation for this PR? Regression due to #15452 How did you do it? Added missing quotes to the command. How did you verify/test it? Ran route/test_route_perf.py on Arista 7260CX3 platform with dualtor topology. co-authorized by: jianquanye@microsoft.com --- tests/route/test_route_perf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/route/test_route_perf.py b/tests/route/test_route_perf.py index 3488792e9d8..d54f46d95ca 100644 --- a/tests/route/test_route_perf.py +++ b/tests/route/test_route_perf.py @@ -65,7 +65,7 @@ def check_config(duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_rand_ if (asic == "broadcom"): broadcom_cmd = "bcmcmd -n " + str(asic_id) if duthost.is_multi_asic else "bcmcmd" - alpm_cmd = "{} {}".format(broadcom_cmd, "conf show l3_alpm_enable") + alpm_cmd = "{} {}".format(broadcom_cmd, '"conf show l3_alpm_enable"') alpm_enable = duthost.command(alpm_cmd)["stdout_lines"][2].strip() logger.info("Checking config: {}".format(alpm_enable)) pytest_assert(alpm_enable == "l3_alpm_enable=2", "l3_alpm_enable is not set for route scaling") From f994b052db6bae9b484797aa403fde8b230775c2 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Wed, 20 Nov 2024 02:48:50 -0800 Subject: [PATCH 202/221] Fixing service-restart testcases. (#15560) Description of PR Summary: The pfcwd_basic service-restart cases keep failing due to: sonic-net/sonic-buildimage#20637 The ask is not to restart swss multiple times without doing a config reload in between. So in this PR: we are doing config-reload for every iteration of the test The swss restart is done only once in one DUT. The asic is randomly picked, and the swss of that ASIC is restarted instead of doing the restart for all asics. Also added checks to make sure the services, interfaces and bgp are up before proceding with the ixia traffic. Approach What is the motivation for this PR? The issue: sonic-net/sonic-buildimage#20637 How did you do it? Pls see the description. How did you verify/test it? Ran it on my TB. =========================================================================================================================== PASSES =========================================================================================================================== ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-True-swss] _____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-False-swss] ____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-True-swss] _____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-False-swss] ____________________________________________________________________________________ ----------------------------------------------------------------------------- generated xml file: /run_logs/ixia/restart-service/2024-11-14-00-05-11/tr_2024-11-14-00-05-11.xml ------------------------------------------------------------------------------ INFO:root:Can not get Allure report URL. Please check logs ------------------------------------------------------------------------------------------------------------------- live log sessionfinish ------------------------------------------------------------------------------------------------------------------- 01:31:34 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ================================================================================================================== short test summary info =================================================================================================================== PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-True-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-False-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-True-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-False-swss] ========================================================================================================= 4 passed, 7 warnings in 5180.68s (1:26:20) ========================================================================================================= sonic@ixia-sonic-mgmt-whitebox:/data/tests$ -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================================================================================================================== PASSES =========================================================================================================================== ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-True-swss] _____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-False-swss] ____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-True-swss] _____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-False-swss] ____________________________________________________________________________________ ---------------------------------------------------------------------------- generated xml file: /run_logs/ixia/restart-service-2/2024-11-14-02-47-47/tr_2024-11-14-02-47-47.xml ----------------------------------------------------------------------------- INFO:root:Can not get Allure report URL. Please check logs ------------------------------------------------------------------------------------------------------------------- live log sessionfinish ------------------------------------------------------------------------------------------------------------------- 04:14:03 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ================================================================================================================== short test summary info =================================================================================================================== PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-True-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info0-False-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-True-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_multi_lossless_prio_restart_service[multidut_port_info1-False-swss] ========================================================================================================= 4 passed, 7 warnings in 5173.22s (1:26:13) ========================================================================================================= sonic@ixia-sonic-mgmt-whitebox:/data/tests$ =========================================================================================================================== PASSES =========================================================================================================================== ____________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info0-True-swss] ____________________________________________________________________________________ ___________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info0-False-swss] ____________________________________________________________________________________ ____________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info1-True-swss] ____________________________________________________________________________________ ___________________________________________________________________________________ test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info1-False-swss] ____________________________________________________________________________________ ---------------------------------------------------------------------------- generated xml file: /run_logs/ixia/restart-service-2/2024-11-14-06-39-15/tr_2024-11-14-06-39-15.xml ----------------------------------------------------------------------------- INFO:root:Can not get Allure report URL. Please check logs ------------------------------------------------------------------------------------------------------------------- live log sessionfinish ------------------------------------------------------------------------------------------------------------------- 08:10:42 __init__.pytest_terminal_summary L0067 INFO | Can not get Allure report URL. Please check logs ================================================================================================================== short test summary info =================================================================================================================== PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info0-True-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info0-False-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info1-True-swss] PASSED snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py::test_pfcwd_basic_single_lossless_prio_service_restart[multidut_port_info1-False-swss] ========================================================================================================= 4 passed, 7 warnings in 5484.86s (1:31:24) ========================================================================================================= sonic@ixia-sonic-mgmt-whitebox:/data/tests$ co-authorized by: jianquanye@microsoft.com --- .../test_multidut_pfcwd_basic_with_snappi.py | 63 +++++++++++++++---- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py index daf00e18751..9c09f674b45 100644 --- a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py +++ b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py @@ -1,6 +1,7 @@ import pytest import random import logging +import time import re from collections import defaultdict from tests.common.helpers.assertions import pytest_require, pytest_assert # noqa: F401 @@ -13,6 +14,8 @@ from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, lossless_prio_list # noqa F401 from tests.common.reboot import reboot # noqa: F401 from tests.common.utilities import wait_until # noqa: F401 +from tests.common.config_reload import config_reload +from tests.common.platform.interface_utils import check_interface_status_of_up_ports from tests.snappi_tests.multidut.pfcwd.files.pfcwd_multidut_basic_helper import run_pfcwd_basic_test from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.snappi_tests.files.helper import skip_pfcwd_test, reboot_duts, \ @@ -29,6 +32,26 @@ def number_of_tx_rx_ports(): yield (1, 1) +@pytest.fixture(autouse=False) +def save_restore_config(setup_ports_and_dut): + testbed_config, port_config_list, snappi_ports = setup_ports_and_dut + timestamp = time.time() + dest = f'~/{timestamp}' + + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): + duthost.shell(f"sudo mkdir {dest}; sudo cp /etc/sonic/config*.json {dest}") + duthost.shell("sudo config save -y") + + yield + + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): + duthost.shell(f"sudo cp {dest}/config_db*json /etc/sonic/") + duthost.shell("sudo config save -y") + + for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): + config_reload(duthost) + + @pytest.mark.parametrize("trigger_pfcwd", [True, False]) def test_pfcwd_basic_single_lossless_prio(snappi_api, # noqa: F811 conn_graph_facts, # noqa: F811 @@ -221,7 +244,8 @@ def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, prio_dscp_map, # noqa: F811 restart_service, trigger_pfcwd, - setup_ports_and_dut): # noqa: F811 + setup_ports_and_dut, # noqa: F811 + save_restore_config): """ Verify PFC watchdog basic test works on a single lossless priority after various service restarts @@ -251,6 +275,7 @@ def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, logger.info('Port dictionary:{}'.format(ports_dict)) for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") # Record current state of critical services. duthost.critical_services_fully_started() @@ -264,6 +289,11 @@ def test_pfcwd_basic_single_lossless_prio_service_restart(snappi_api, logger.info("Wait until the system is stable") pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), "Not all critical services are fully started") + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, check_interface_status_of_up_ports, duthost), + "Not all interfaces are up.") + pytest_assert(wait_until( + WAIT_TIME, INTERVAL, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established")) + else: for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): logger.info("Issuing a restart of service {} on the dut {}".format(restart_service, duthost.hostname)) @@ -300,7 +330,8 @@ def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, prio_dscp_map, # noqa F811 restart_service, setup_ports_and_dut, # noqa: F811 - trigger_pfcwd): + trigger_pfcwd, + save_restore_config): """ Verify PFC watchdog basic test works on multiple lossless priorities after various service restarts @@ -330,16 +361,26 @@ def test_pfcwd_basic_multi_lossless_prio_restart_service(snappi_api, logger.info('Port dictionary:{}'.format(ports_dict)) for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): + up_bgp_neighbors = duthost.get_bgp_neighbors_per_asic("established") + # Record current state of critical services. + duthost.critical_services_fully_started() + asic_list = ports_dict[duthost.hostname] - for asic in asic_list: - asic_id = re.match(r"(asic)(\d+)", asic).group(2) - proc = 'swss@' + asic_id - logger.info("Issuing a restart of service {} on the dut {}".format(proc, duthost.hostname)) - duthost.command("sudo systemctl reset-failed {}".format(proc)) - duthost.command("sudo systemctl restart {}".format(proc)) - logger.info("Wait until the system is stable") - pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), - "Not all critical services are fully started") + asic = random.sample(asic_list, 1)[0] + asic_id = re.match(r"(asic)(\d+)", asic).group(2) + proc = 'swss@' + asic_id + + logger.info("Issuing a restart of service {} on the dut {}".format(proc, duthost.hostname)) + duthost.command("sudo systemctl reset-failed {}".format(proc)) + duthost.command("sudo systemctl restart {}".format(proc)) + logger.info("Wait until the system is stable") + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, duthost.critical_services_fully_started), + "Not all critical services are fully started") + pytest_assert(wait_until(WAIT_TIME, INTERVAL, 0, check_interface_status_of_up_ports, duthost), + "Not all interfaces are up.") + pytest_assert(wait_until( + WAIT_TIME, INTERVAL, 0, duthost.check_bgp_session_state_all_asics, up_bgp_neighbors, "established")) + else: for duthost in list(set([snappi_ports[0]['duthost'], snappi_ports[1]['duthost']])): logger.info("Issuing a restart of service {} on the dut {}".format(restart_service, duthost.hostname)) From ea31b61aa4f686df8db4c8a770b2627f18b9fb88 Mon Sep 17 00:00:00 2001 From: Abdel Baig <137210298+abdbaig@users.noreply.github.com> Date: Wed, 20 Nov 2024 18:36:52 -0500 Subject: [PATCH 203/221] Handle p bit properly in bfd_responder (#15167) * handle p bit properly in bfd_responder * add missing flags and fix comment * add extra blank line --- ansible/roles/test/files/helpers/bfd_responder.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ansible/roles/test/files/helpers/bfd_responder.py b/ansible/roles/test/files/helpers/bfd_responder.py index fce30d0b0dc..774393dce42 100644 --- a/ansible/roles/test/files/helpers/bfd_responder.py +++ b/ansible/roles/test/files/helpers/bfd_responder.py @@ -14,6 +14,8 @@ IPv4 = '4' IPv6 = '6' +BFD_FLAG_P_BIT = 5 +BFD_FLAG_F_BIT = 4 def get_if(iff, cmd): @@ -86,13 +88,17 @@ def __init__(self, sessions): def action(self, interface): data = interface.recv() - mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state = self.extract_bfd_info( + mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state, bfd_flags = self.extract_bfd_info( data) if ip_dst not in self.sessions: return session = self.sessions[ip_dst] if bfd_state == 3: + # Respond with F bit if P bit is set + if (bfd_flags & (1 << BFD_FLAG_P_BIT)): + session["pkt"].payload.payload.payload.load.flags = (1 << BFD_FLAG_F_BIT) interface.send(session["pkt"]) + session["pkt"].payload.payload.payload.load.flags = 0 return if bfd_state == 2: @@ -101,6 +107,7 @@ def action(self, interface): bfd_pkt_init = self.craft_bfd_packet( session, data, mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, 2) bfd_pkt_init.payload.payload.chksum = None + bfd_pkt_init.payload.payload.payload.load.flags = 0 interface.send(bfd_pkt_init) bfd_pkt_init.payload.payload.payload.load.sta = 3 bfd_pkt_init.payload.payload.chksum = None @@ -120,10 +127,11 @@ def extract_bfd_info(self, data): bfdpkt = BFD(ether.payload.payload.payload.load) bfd_remote_disc = bfdpkt.my_discriminator bfd_state = bfdpkt.sta + bfd_flags = bfdpkt.flags if ip_priority != self.bfd_default_ip_priority: raise RuntimeError("Received BFD packet with incorrect priority value: {}".format(ip_priority)) logging.debug('BFD packet info: sip {}, dip {}, priority {}'.format(ip_src, ip_dst, ip_priority)) - return mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state + return mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state, bfd_flags def craft_bfd_packet(self, session, data, mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state): ethpart = scapy2.Ether(data) From 5976622f329480f48e12c0b44055fa3135b441fb Mon Sep 17 00:00:00 2001 From: Chenyang Wang <49756587+cyw233@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:44:19 +1100 Subject: [PATCH 204/221] fix: return all BGP neighbors for config reload (#15634) --- tests/common/config_reload.py | 2 +- tests/common/devices/multi_asic.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/common/config_reload.py b/tests/common/config_reload.py index 0b0fe7c2768..b6e2542bece 100644 --- a/tests/common/config_reload.py +++ b/tests/common/config_reload.py @@ -215,7 +215,7 @@ def _config_reload_cmd_wrapper(cmd, executable): time.sleep(wait) if wait_for_bgp: - bgp_neighbors = sonic_host.get_bgp_neighbors_per_asic() + bgp_neighbors = sonic_host.get_bgp_neighbors_per_asic(state="all") pytest_assert( wait_until(wait + 120, 10, 0, sonic_host.check_bgp_session_state_all_asics, bgp_neighbors), "Not all bgp sessions are established after config reload", diff --git a/tests/common/devices/multi_asic.py b/tests/common/devices/multi_asic.py index 6f541c201af..d879e468481 100644 --- a/tests/common/devices/multi_asic.py +++ b/tests/common/devices/multi_asic.py @@ -549,7 +549,8 @@ def get_bgp_neighbors_per_asic(self, state="established"): Get a diction of BGP neighbor states Args: - state: BGP session state, return neighbor IP of sessions that match this state + state: BGP session state, return neighbor IP of sessions that match this state. If state is "all", + return all neighbors regardless of state. Returns: dictionary {namespace: { (neighbor_ip : info_dict)* }} """ @@ -557,9 +558,10 @@ def get_bgp_neighbors_per_asic(self, state="established"): for asic in self.asics: bgp_neigh[asic.namespace] = {} bgp_info = asic.bgp_facts()["ansible_facts"]["bgp_neighbors"] - for k, v in list(bgp_info.items()): - if v["state"] != state: - bgp_info.pop(k) + if state != "all": + for k, v in list(bgp_info.items()): + if v["state"] != state: + bgp_info.pop(k) bgp_neigh[asic.namespace].update(bgp_info) return bgp_neigh @@ -598,7 +600,7 @@ def check_bgp_session_state_all_asics(self, bgp_neighbors, state="established"): """ for asic in self.asics: if asic.namespace in bgp_neighbors: - neigh_ips = [k.lower() for k, v in list(bgp_neighbors[asic.namespace].items()) if v["state"] == state] + neigh_ips = [k.lower() for k, v in list(bgp_neighbors[asic.namespace].items())] if not asic.check_bgp_session_state(neigh_ips, state): return False return True From 5b9020237214db2a4d78637fb37110850a03910b Mon Sep 17 00:00:00 2001 From: Hua Liu <58683130+liuh-80@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:48:55 +0800 Subject: [PATCH 205/221] Test IPV6 after all other test (#15583) Test test_ro_user_ipv6 after all other tests. Why I did it When IPV6 test case failed on some IPV6 not stable device, some other test also will failed. How I did it Test test_ro_user_ipv6 after all other tests. How to verify it Pass all test case. Description for the changelog Test test_ro_user_ipv6 after all other tests. --- tests/tacacs/test_ro_user.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/tacacs/test_ro_user.py b/tests/tacacs/test_ro_user.py index 847ee573100..1def4711877 100644 --- a/tests/tacacs/test_ro_user.py +++ b/tests/tacacs/test_ro_user.py @@ -81,18 +81,6 @@ def test_ro_user(localhost, duthosts, enum_rand_one_per_hwsku_hostname, tacacs_c check_output(res, 'test', 'remote_user') -def test_ro_user_ipv6(localhost, ptfhost, duthosts, enum_rand_one_per_hwsku_hostname, tacacs_creds, check_tacacs_v6): - duthost = duthosts[enum_rand_one_per_hwsku_hostname] - dutip = duthost.mgmt_ip - - res = ssh_remote_run_retry(localhost, dutip, ptfhost, - tacacs_creds['tacacs_ro_user'], - tacacs_creds['tacacs_ro_user_passwd'], - "cat /etc/passwd") - - check_output(res, 'testadmin', 'remote_user_su') - - def test_ro_user_allowed_command(localhost, duthosts, enum_rand_one_per_hwsku_hostname, tacacs_creds, check_tacacs): duthost = duthosts[enum_rand_one_per_hwsku_hostname] dutip = duthost.mgmt_ip @@ -214,3 +202,15 @@ def test_ro_user_banned_command(localhost, duthosts, enum_rand_one_per_hwsku_hos banned = ssh_remote_ban_run(localhost, dutip, tacacs_creds['tacacs_ro_user'], tacacs_creds['tacacs_ro_user_passwd'], command) pytest_assert(banned, "command '{}' authorized".format(command)) + + +def test_ro_user_ipv6(localhost, ptfhost, duthosts, enum_rand_one_per_hwsku_hostname, tacacs_creds, check_tacacs_v6): + duthost = duthosts[enum_rand_one_per_hwsku_hostname] + dutip = duthost.mgmt_ip + + res = ssh_remote_run_retry(localhost, dutip, ptfhost, + tacacs_creds['tacacs_ro_user'], + tacacs_creds['tacacs_ro_user_passwd'], + "cat /etc/passwd") + + check_output(res, 'testadmin', 'remote_user_su') From 1f2e6d6547cedf31e0b3a1ea157e0bbc727a13d2 Mon Sep 17 00:00:00 2001 From: Wenda Chu <32250288+w1nda@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:19:13 +0800 Subject: [PATCH 206/221] add topo_t0-isolated-u254d2, topo_t0-isolated-u510d2, topo_t1-isolated-u2d254, topo_t1-isolated-u2d510 topo (#15355) Add four topologies: t0 role with 254 uplinks and 2 downlinks t0 role with 510 uplinks and 2 downlinks t1 role with 2 uplinks and 254 downlinks t1 role with 2 uplinks and 510 downlinks --- ansible/vars/topo_t0-isolated-u254d2.yml | 5370 ++++++++++ ansible/vars/topo_t0-isolated-u510d2.yml | 10746 +++++++++++++++++++ ansible/vars/topo_t1-isolated-u2d254.yaml | 5650 ++++++++++ ansible/vars/topo_t1-isolated-u2d510.yaml | 11282 ++++++++++++++++++++ 4 files changed, 33048 insertions(+) create mode 100644 ansible/vars/topo_t0-isolated-u254d2.yml create mode 100644 ansible/vars/topo_t0-isolated-u510d2.yml create mode 100644 ansible/vars/topo_t1-isolated-u2d254.yaml create mode 100644 ansible/vars/topo_t1-isolated-u2d510.yaml diff --git a/ansible/vars/topo_t0-isolated-u254d2.yml b/ansible/vars/topo_t0-isolated-u254d2.yml new file mode 100644 index 00000000000..14f6e7c767e --- /dev/null +++ b/ansible/vars/topo_t0-isolated-u254d2.yml @@ -0,0 +1,5370 @@ +topology: + host_interfaces: + - 0 + - 1 + VMs: + ARISTA01T1: + vlans: + - 2 + vm_offset: 0 + ARISTA02T1: + vlans: + - 3 + vm_offset: 1 + ARISTA03T1: + vlans: + - 4 + vm_offset: 2 + ARISTA04T1: + vlans: + - 5 + vm_offset: 3 + ARISTA05T1: + vlans: + - 6 + vm_offset: 4 + ARISTA06T1: + vlans: + - 7 + vm_offset: 5 + ARISTA07T1: + vlans: + - 8 + vm_offset: 6 + ARISTA08T1: + vlans: + - 9 + vm_offset: 7 + ARISTA09T1: + vlans: + - 10 + vm_offset: 8 + ARISTA10T1: + vlans: + - 11 + vm_offset: 9 + ARISTA11T1: + vlans: + - 12 + vm_offset: 10 + ARISTA12T1: + vlans: + - 13 + vm_offset: 11 + ARISTA13T1: + vlans: + - 14 + vm_offset: 12 + ARISTA14T1: + vlans: + - 15 + vm_offset: 13 + ARISTA15T1: + vlans: + - 16 + vm_offset: 14 + ARISTA16T1: + vlans: + - 17 + vm_offset: 15 + ARISTA17T1: + vlans: + - 18 + vm_offset: 16 + ARISTA18T1: + vlans: + - 19 + vm_offset: 17 + ARISTA19T1: + vlans: + - 20 + vm_offset: 18 + ARISTA20T1: + vlans: + - 21 + vm_offset: 19 + ARISTA21T1: + vlans: + - 22 + vm_offset: 20 + ARISTA22T1: + vlans: + - 23 + vm_offset: 21 + ARISTA23T1: + vlans: + - 24 + vm_offset: 22 + ARISTA24T1: + vlans: + - 25 + vm_offset: 23 + ARISTA25T1: + vlans: + - 26 + vm_offset: 24 + ARISTA26T1: + vlans: + - 27 + vm_offset: 25 + ARISTA27T1: + vlans: + - 28 + vm_offset: 26 + ARISTA28T1: + vlans: + - 29 + vm_offset: 27 + ARISTA29T1: + vlans: + - 30 + vm_offset: 28 + ARISTA30T1: + vlans: + - 31 + vm_offset: 29 + ARISTA31T1: + vlans: + - 32 + vm_offset: 30 + ARISTA32T1: + vlans: + - 33 + vm_offset: 31 + ARISTA33T1: + vlans: + - 34 + vm_offset: 32 + ARISTA34T1: + vlans: + - 35 + vm_offset: 33 + ARISTA35T1: + vlans: + - 36 + vm_offset: 34 + ARISTA36T1: + vlans: + - 37 + vm_offset: 35 + ARISTA37T1: + vlans: + - 38 + vm_offset: 36 + ARISTA38T1: + vlans: + - 39 + vm_offset: 37 + ARISTA39T1: + vlans: + - 40 + vm_offset: 38 + ARISTA40T1: + vlans: + - 41 + vm_offset: 39 + ARISTA41T1: + vlans: + - 42 + vm_offset: 40 + ARISTA42T1: + vlans: + - 43 + vm_offset: 41 + ARISTA43T1: + vlans: + - 44 + vm_offset: 42 + ARISTA44T1: + vlans: + - 45 + vm_offset: 43 + ARISTA45T1: + vlans: + - 46 + vm_offset: 44 + ARISTA46T1: + vlans: + - 47 + vm_offset: 45 + ARISTA47T1: + vlans: + - 48 + vm_offset: 46 + ARISTA48T1: + vlans: + - 49 + vm_offset: 47 + ARISTA49T1: + vlans: + - 50 + vm_offset: 48 + ARISTA50T1: + vlans: + - 51 + vm_offset: 49 + ARISTA51T1: + vlans: + - 52 + vm_offset: 50 + ARISTA52T1: + vlans: + - 53 + vm_offset: 51 + ARISTA53T1: + vlans: + - 54 + vm_offset: 52 + ARISTA54T1: + vlans: + - 55 + vm_offset: 53 + ARISTA55T1: + vlans: + - 56 + vm_offset: 54 + ARISTA56T1: + vlans: + - 57 + vm_offset: 55 + ARISTA57T1: + vlans: + - 58 + vm_offset: 56 + ARISTA58T1: + vlans: + - 59 + vm_offset: 57 + ARISTA59T1: + vlans: + - 60 + vm_offset: 58 + ARISTA60T1: + vlans: + - 61 + vm_offset: 59 + ARISTA61T1: + vlans: + - 62 + vm_offset: 60 + ARISTA62T1: + vlans: + - 63 + vm_offset: 61 + ARISTA63T1: + vlans: + - 64 + vm_offset: 62 + ARISTA64T1: + vlans: + - 65 + vm_offset: 63 + ARISTA65T1: + vlans: + - 66 + vm_offset: 64 + ARISTA66T1: + vlans: + - 67 + vm_offset: 65 + ARISTA67T1: + vlans: + - 68 + vm_offset: 66 + ARISTA68T1: + vlans: + - 69 + vm_offset: 67 + ARISTA69T1: + vlans: + - 70 + vm_offset: 68 + ARISTA70T1: + vlans: + - 71 + vm_offset: 69 + ARISTA71T1: + vlans: + - 72 + vm_offset: 70 + ARISTA72T1: + vlans: + - 73 + vm_offset: 71 + ARISTA73T1: + vlans: + - 74 + vm_offset: 72 + ARISTA74T1: + vlans: + - 75 + vm_offset: 73 + ARISTA75T1: + vlans: + - 76 + vm_offset: 74 + ARISTA76T1: + vlans: + - 77 + vm_offset: 75 + ARISTA77T1: + vlans: + - 78 + vm_offset: 76 + ARISTA78T1: + vlans: + - 79 + vm_offset: 77 + ARISTA79T1: + vlans: + - 80 + vm_offset: 78 + ARISTA80T1: + vlans: + - 81 + vm_offset: 79 + ARISTA81T1: + vlans: + - 82 + vm_offset: 80 + ARISTA82T1: + vlans: + - 83 + vm_offset: 81 + ARISTA83T1: + vlans: + - 84 + vm_offset: 82 + ARISTA84T1: + vlans: + - 85 + vm_offset: 83 + ARISTA85T1: + vlans: + - 86 + vm_offset: 84 + ARISTA86T1: + vlans: + - 87 + vm_offset: 85 + ARISTA87T1: + vlans: + - 88 + vm_offset: 86 + ARISTA88T1: + vlans: + - 89 + vm_offset: 87 + ARISTA89T1: + vlans: + - 90 + vm_offset: 88 + ARISTA90T1: + vlans: + - 91 + vm_offset: 89 + ARISTA91T1: + vlans: + - 92 + vm_offset: 90 + ARISTA92T1: + vlans: + - 93 + vm_offset: 91 + ARISTA93T1: + vlans: + - 94 + vm_offset: 92 + ARISTA94T1: + vlans: + - 95 + vm_offset: 93 + ARISTA95T1: + vlans: + - 96 + vm_offset: 94 + ARISTA96T1: + vlans: + - 97 + vm_offset: 95 + ARISTA97T1: + vlans: + - 98 + vm_offset: 96 + ARISTA98T1: + vlans: + - 99 + vm_offset: 97 + ARISTA99T1: + vlans: + - 100 + vm_offset: 98 + ARISTA100T1: + vlans: + - 101 + vm_offset: 99 + ARISTA101T1: + vlans: + - 102 + vm_offset: 100 + ARISTA102T1: + vlans: + - 103 + vm_offset: 101 + ARISTA103T1: + vlans: + - 104 + vm_offset: 102 + ARISTA104T1: + vlans: + - 105 + vm_offset: 103 + ARISTA105T1: + vlans: + - 106 + vm_offset: 104 + ARISTA106T1: + vlans: + - 107 + vm_offset: 105 + ARISTA107T1: + vlans: + - 108 + vm_offset: 106 + ARISTA108T1: + vlans: + - 109 + vm_offset: 107 + ARISTA109T1: + vlans: + - 110 + vm_offset: 108 + ARISTA110T1: + vlans: + - 111 + vm_offset: 109 + ARISTA111T1: + vlans: + - 112 + vm_offset: 110 + ARISTA112T1: + vlans: + - 113 + vm_offset: 111 + ARISTA113T1: + vlans: + - 114 + vm_offset: 112 + ARISTA114T1: + vlans: + - 115 + vm_offset: 113 + ARISTA115T1: + vlans: + - 116 + vm_offset: 114 + ARISTA116T1: + vlans: + - 117 + vm_offset: 115 + ARISTA117T1: + vlans: + - 118 + vm_offset: 116 + ARISTA118T1: + vlans: + - 119 + vm_offset: 117 + ARISTA119T1: + vlans: + - 120 + vm_offset: 118 + ARISTA120T1: + vlans: + - 121 + vm_offset: 119 + ARISTA121T1: + vlans: + - 122 + vm_offset: 120 + ARISTA122T1: + vlans: + - 123 + vm_offset: 121 + ARISTA123T1: + vlans: + - 124 + vm_offset: 122 + ARISTA124T1: + vlans: + - 125 + vm_offset: 123 + ARISTA125T1: + vlans: + - 126 + vm_offset: 124 + ARISTA126T1: + vlans: + - 127 + vm_offset: 125 + ARISTA127T1: + vlans: + - 128 + vm_offset: 126 + ARISTA128T1: + vlans: + - 129 + vm_offset: 127 + ARISTA129T1: + vlans: + - 130 + vm_offset: 128 + ARISTA130T1: + vlans: + - 131 + vm_offset: 129 + ARISTA131T1: + vlans: + - 132 + vm_offset: 130 + ARISTA132T1: + vlans: + - 133 + vm_offset: 131 + ARISTA133T1: + vlans: + - 134 + vm_offset: 132 + ARISTA134T1: + vlans: + - 135 + vm_offset: 133 + ARISTA135T1: + vlans: + - 136 + vm_offset: 134 + ARISTA136T1: + vlans: + - 137 + vm_offset: 135 + ARISTA137T1: + vlans: + - 138 + vm_offset: 136 + ARISTA138T1: + vlans: + - 139 + vm_offset: 137 + ARISTA139T1: + vlans: + - 140 + vm_offset: 138 + ARISTA140T1: + vlans: + - 141 + vm_offset: 139 + ARISTA141T1: + vlans: + - 142 + vm_offset: 140 + ARISTA142T1: + vlans: + - 143 + vm_offset: 141 + ARISTA143T1: + vlans: + - 144 + vm_offset: 142 + ARISTA144T1: + vlans: + - 145 + vm_offset: 143 + ARISTA145T1: + vlans: + - 146 + vm_offset: 144 + ARISTA146T1: + vlans: + - 147 + vm_offset: 145 + ARISTA147T1: + vlans: + - 148 + vm_offset: 146 + ARISTA148T1: + vlans: + - 149 + vm_offset: 147 + ARISTA149T1: + vlans: + - 150 + vm_offset: 148 + ARISTA150T1: + vlans: + - 151 + vm_offset: 149 + ARISTA151T1: + vlans: + - 152 + vm_offset: 150 + ARISTA152T1: + vlans: + - 153 + vm_offset: 151 + ARISTA153T1: + vlans: + - 154 + vm_offset: 152 + ARISTA154T1: + vlans: + - 155 + vm_offset: 153 + ARISTA155T1: + vlans: + - 156 + vm_offset: 154 + ARISTA156T1: + vlans: + - 157 + vm_offset: 155 + ARISTA157T1: + vlans: + - 158 + vm_offset: 156 + ARISTA158T1: + vlans: + - 159 + vm_offset: 157 + ARISTA159T1: + vlans: + - 160 + vm_offset: 158 + ARISTA160T1: + vlans: + - 161 + vm_offset: 159 + ARISTA161T1: + vlans: + - 162 + vm_offset: 160 + ARISTA162T1: + vlans: + - 163 + vm_offset: 161 + ARISTA163T1: + vlans: + - 164 + vm_offset: 162 + ARISTA164T1: + vlans: + - 165 + vm_offset: 163 + ARISTA165T1: + vlans: + - 166 + vm_offset: 164 + ARISTA166T1: + vlans: + - 167 + vm_offset: 165 + ARISTA167T1: + vlans: + - 168 + vm_offset: 166 + ARISTA168T1: + vlans: + - 169 + vm_offset: 167 + ARISTA169T1: + vlans: + - 170 + vm_offset: 168 + ARISTA170T1: + vlans: + - 171 + vm_offset: 169 + ARISTA171T1: + vlans: + - 172 + vm_offset: 170 + ARISTA172T1: + vlans: + - 173 + vm_offset: 171 + ARISTA173T1: + vlans: + - 174 + vm_offset: 172 + ARISTA174T1: + vlans: + - 175 + vm_offset: 173 + ARISTA175T1: + vlans: + - 176 + vm_offset: 174 + ARISTA176T1: + vlans: + - 177 + vm_offset: 175 + ARISTA177T1: + vlans: + - 178 + vm_offset: 176 + ARISTA178T1: + vlans: + - 179 + vm_offset: 177 + ARISTA179T1: + vlans: + - 180 + vm_offset: 178 + ARISTA180T1: + vlans: + - 181 + vm_offset: 179 + ARISTA181T1: + vlans: + - 182 + vm_offset: 180 + ARISTA182T1: + vlans: + - 183 + vm_offset: 181 + ARISTA183T1: + vlans: + - 184 + vm_offset: 182 + ARISTA184T1: + vlans: + - 185 + vm_offset: 183 + ARISTA185T1: + vlans: + - 186 + vm_offset: 184 + ARISTA186T1: + vlans: + - 187 + vm_offset: 185 + ARISTA187T1: + vlans: + - 188 + vm_offset: 186 + ARISTA188T1: + vlans: + - 189 + vm_offset: 187 + ARISTA189T1: + vlans: + - 190 + vm_offset: 188 + ARISTA190T1: + vlans: + - 191 + vm_offset: 189 + ARISTA191T1: + vlans: + - 192 + vm_offset: 190 + ARISTA192T1: + vlans: + - 193 + vm_offset: 191 + ARISTA193T1: + vlans: + - 194 + vm_offset: 192 + ARISTA194T1: + vlans: + - 195 + vm_offset: 193 + ARISTA195T1: + vlans: + - 196 + vm_offset: 194 + ARISTA196T1: + vlans: + - 197 + vm_offset: 195 + ARISTA197T1: + vlans: + - 198 + vm_offset: 196 + ARISTA198T1: + vlans: + - 199 + vm_offset: 197 + ARISTA199T1: + vlans: + - 200 + vm_offset: 198 + ARISTA200T1: + vlans: + - 201 + vm_offset: 199 + ARISTA201T1: + vlans: + - 202 + vm_offset: 200 + ARISTA202T1: + vlans: + - 203 + vm_offset: 201 + ARISTA203T1: + vlans: + - 204 + vm_offset: 202 + ARISTA204T1: + vlans: + - 205 + vm_offset: 203 + ARISTA205T1: + vlans: + - 206 + vm_offset: 204 + ARISTA206T1: + vlans: + - 207 + vm_offset: 205 + ARISTA207T1: + vlans: + - 208 + vm_offset: 206 + ARISTA208T1: + vlans: + - 209 + vm_offset: 207 + ARISTA209T1: + vlans: + - 210 + vm_offset: 208 + ARISTA210T1: + vlans: + - 211 + vm_offset: 209 + ARISTA211T1: + vlans: + - 212 + vm_offset: 210 + ARISTA212T1: + vlans: + - 213 + vm_offset: 211 + ARISTA213T1: + vlans: + - 214 + vm_offset: 212 + ARISTA214T1: + vlans: + - 215 + vm_offset: 213 + ARISTA215T1: + vlans: + - 216 + vm_offset: 214 + ARISTA216T1: + vlans: + - 217 + vm_offset: 215 + ARISTA217T1: + vlans: + - 218 + vm_offset: 216 + ARISTA218T1: + vlans: + - 219 + vm_offset: 217 + ARISTA219T1: + vlans: + - 220 + vm_offset: 218 + ARISTA220T1: + vlans: + - 221 + vm_offset: 219 + ARISTA221T1: + vlans: + - 222 + vm_offset: 220 + ARISTA222T1: + vlans: + - 223 + vm_offset: 221 + ARISTA223T1: + vlans: + - 224 + vm_offset: 222 + ARISTA224T1: + vlans: + - 225 + vm_offset: 223 + ARISTA225T1: + vlans: + - 226 + vm_offset: 224 + ARISTA226T1: + vlans: + - 227 + vm_offset: 225 + ARISTA227T1: + vlans: + - 228 + vm_offset: 226 + ARISTA228T1: + vlans: + - 229 + vm_offset: 227 + ARISTA229T1: + vlans: + - 230 + vm_offset: 228 + ARISTA230T1: + vlans: + - 231 + vm_offset: 229 + ARISTA231T1: + vlans: + - 232 + vm_offset: 230 + ARISTA232T1: + vlans: + - 233 + vm_offset: 231 + ARISTA233T1: + vlans: + - 234 + vm_offset: 232 + ARISTA234T1: + vlans: + - 235 + vm_offset: 233 + ARISTA235T1: + vlans: + - 236 + vm_offset: 234 + ARISTA236T1: + vlans: + - 237 + vm_offset: 235 + ARISTA237T1: + vlans: + - 238 + vm_offset: 236 + ARISTA238T1: + vlans: + - 239 + vm_offset: 237 + ARISTA239T1: + vlans: + - 240 + vm_offset: 238 + ARISTA240T1: + vlans: + - 241 + vm_offset: 239 + ARISTA241T1: + vlans: + - 242 + vm_offset: 240 + ARISTA242T1: + vlans: + - 243 + vm_offset: 241 + ARISTA243T1: + vlans: + - 244 + vm_offset: 242 + ARISTA244T1: + vlans: + - 245 + vm_offset: 243 + ARISTA245T1: + vlans: + - 246 + vm_offset: 244 + ARISTA246T1: + vlans: + - 247 + vm_offset: 245 + ARISTA247T1: + vlans: + - 248 + vm_offset: 246 + ARISTA248T1: + vlans: + - 249 + vm_offset: 247 + ARISTA249T1: + vlans: + - 250 + vm_offset: 248 + ARISTA250T1: + vlans: + - 251 + vm_offset: 249 + ARISTA251T1: + vlans: + - 252 + vm_offset: 250 + ARISTA252T1: + vlans: + - 253 + vm_offset: 251 + ARISTA253T1: + vlans: + - 254 + vm_offset: 252 + ARISTA254T1: + vlans: + - 255 + vm_offset: 253 + DUT: + vlan_configs: + default_vlan_config: one_vlan_per_intf + one_vlan_per_intf: + Vlan1000: + id: 1000 + intfs: [0] + prefix_v6: fc00:c:c:0001::/64 + tag: 1000 + Vlan1001: + id: 1001 + intfs: [1] + prefix_v6: fc00:c:c:0002::/64 + tag: 1001 + +configuration_properties: + common: + dut_asn: 4200000000 + dut_type: ToRRouter + swrole: leaf + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine_asn: 4200200000 + leaf_asn_start: 4200100000 + tor_asn_start: 4200000000 + failure_rate: 0 + nhipv6: FC0A::FF + +configuration: + ARISTA01T1: + properties: + - common + bgp: + router-id: 0.12.0.3 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3::1/128 + Ethernet1: + ipv6: fc00:a::a/126 + bp_interface: + ipv6: fc00:b::3/64 + + ARISTA02T1: + properties: + - common + bgp: + router-id: 0.12.0.4 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d + interfaces: + Loopback0: + ipv6: fc00:c:c:4::1/128 + Ethernet1: + ipv6: fc00:a::e/126 + bp_interface: + ipv6: fc00:b::4/64 + + ARISTA03T1: + properties: + - common + bgp: + router-id: 0.12.0.5 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::11 + interfaces: + Loopback0: + ipv6: fc00:c:c:5::1/128 + Ethernet1: + ipv6: fc00:a::12/126 + bp_interface: + ipv6: fc00:b::5/64 + + ARISTA04T1: + properties: + - common + bgp: + router-id: 0.12.0.6 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::15 + interfaces: + Loopback0: + ipv6: fc00:c:c:6::1/128 + Ethernet1: + ipv6: fc00:a::16/126 + bp_interface: + ipv6: fc00:b::6/64 + + ARISTA05T1: + properties: + - common + bgp: + router-id: 0.12.0.7 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::19 + interfaces: + Loopback0: + ipv6: fc00:c:c:7::1/128 + Ethernet1: + ipv6: fc00:a::1a/126 + bp_interface: + ipv6: fc00:b::7/64 + + ARISTA06T1: + properties: + - common + bgp: + router-id: 0.12.0.8 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d + interfaces: + Loopback0: + ipv6: fc00:c:c:8::1/128 + Ethernet1: + ipv6: fc00:a::1e/126 + bp_interface: + ipv6: fc00:b::8/64 + + ARISTA07T1: + properties: + - common + bgp: + router-id: 0.12.0.9 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::21 + interfaces: + Loopback0: + ipv6: fc00:c:c:9::1/128 + Ethernet1: + ipv6: fc00:a::22/126 + bp_interface: + ipv6: fc00:b::9/64 + + ARISTA08T1: + properties: + - common + bgp: + router-id: 0.12.0.10 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::25 + interfaces: + Loopback0: + ipv6: fc00:c:c:a::1/128 + Ethernet1: + ipv6: fc00:a::26/126 + bp_interface: + ipv6: fc00:b::a/64 + + ARISTA09T1: + properties: + - common + bgp: + router-id: 0.12.0.11 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::29 + interfaces: + Loopback0: + ipv6: fc00:c:c:b::1/128 + Ethernet1: + ipv6: fc00:a::2a/126 + bp_interface: + ipv6: fc00:b::b/64 + + ARISTA10T1: + properties: + - common + bgp: + router-id: 0.12.0.12 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d + interfaces: + Loopback0: + ipv6: fc00:c:c:c::1/128 + Ethernet1: + ipv6: fc00:a::2e/126 + bp_interface: + ipv6: fc00:b::c/64 + + ARISTA11T1: + properties: + - common + bgp: + router-id: 0.12.0.13 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::31 + interfaces: + Loopback0: + ipv6: fc00:c:c:d::1/128 + Ethernet1: + ipv6: fc00:a::32/126 + bp_interface: + ipv6: fc00:b::d/64 + + ARISTA12T1: + properties: + - common + bgp: + router-id: 0.12.0.14 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::35 + interfaces: + Loopback0: + ipv6: fc00:c:c:e::1/128 + Ethernet1: + ipv6: fc00:a::36/126 + bp_interface: + ipv6: fc00:b::e/64 + + ARISTA13T1: + properties: + - common + bgp: + router-id: 0.12.0.15 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::39 + interfaces: + Loopback0: + ipv6: fc00:c:c:f::1/128 + Ethernet1: + ipv6: fc00:a::3a/126 + bp_interface: + ipv6: fc00:b::f/64 + + ARISTA14T1: + properties: + - common + bgp: + router-id: 0.12.0.16 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d + interfaces: + Loopback0: + ipv6: fc00:c:c:10::1/128 + Ethernet1: + ipv6: fc00:a::3e/126 + bp_interface: + ipv6: fc00:b::10/64 + + ARISTA15T1: + properties: + - common + bgp: + router-id: 0.12.0.17 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::41 + interfaces: + Loopback0: + ipv6: fc00:c:c:11::1/128 + Ethernet1: + ipv6: fc00:a::42/126 + bp_interface: + ipv6: fc00:b::11/64 + + ARISTA16T1: + properties: + - common + bgp: + router-id: 0.12.0.18 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::45 + interfaces: + Loopback0: + ipv6: fc00:c:c:12::1/128 + Ethernet1: + ipv6: fc00:a::46/126 + bp_interface: + ipv6: fc00:b::12/64 + + ARISTA17T1: + properties: + - common + bgp: + router-id: 0.12.0.19 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::49 + interfaces: + Loopback0: + ipv6: fc00:c:c:13::1/128 + Ethernet1: + ipv6: fc00:a::4a/126 + bp_interface: + ipv6: fc00:b::13/64 + + ARISTA18T1: + properties: + - common + bgp: + router-id: 0.12.0.20 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4d + interfaces: + Loopback0: + ipv6: fc00:c:c:14::1/128 + Ethernet1: + ipv6: fc00:a::4e/126 + bp_interface: + ipv6: fc00:b::14/64 + + ARISTA19T1: + properties: + - common + bgp: + router-id: 0.12.0.21 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::51 + interfaces: + Loopback0: + ipv6: fc00:c:c:15::1/128 + Ethernet1: + ipv6: fc00:a::52/126 + bp_interface: + ipv6: fc00:b::15/64 + + ARISTA20T1: + properties: + - common + bgp: + router-id: 0.12.0.22 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::55 + interfaces: + Loopback0: + ipv6: fc00:c:c:16::1/128 + Ethernet1: + ipv6: fc00:a::56/126 + bp_interface: + ipv6: fc00:b::16/64 + + ARISTA21T1: + properties: + - common + bgp: + router-id: 0.12.0.23 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::59 + interfaces: + Loopback0: + ipv6: fc00:c:c:17::1/128 + Ethernet1: + ipv6: fc00:a::5a/126 + bp_interface: + ipv6: fc00:b::17/64 + + ARISTA22T1: + properties: + - common + bgp: + router-id: 0.12.0.24 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5d + interfaces: + Loopback0: + ipv6: fc00:c:c:18::1/128 + Ethernet1: + ipv6: fc00:a::5e/126 + bp_interface: + ipv6: fc00:b::18/64 + + ARISTA23T1: + properties: + - common + bgp: + router-id: 0.12.0.25 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::61 + interfaces: + Loopback0: + ipv6: fc00:c:c:19::1/128 + Ethernet1: + ipv6: fc00:a::62/126 + bp_interface: + ipv6: fc00:b::19/64 + + ARISTA24T1: + properties: + - common + bgp: + router-id: 0.12.0.26 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::65 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a::1/128 + Ethernet1: + ipv6: fc00:a::66/126 + bp_interface: + ipv6: fc00:b::1a/64 + + ARISTA25T1: + properties: + - common + bgp: + router-id: 0.12.0.27 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::69 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b::1/128 + Ethernet1: + ipv6: fc00:a::6a/126 + bp_interface: + ipv6: fc00:b::1b/64 + + ARISTA26T1: + properties: + - common + bgp: + router-id: 0.12.0.28 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c::1/128 + Ethernet1: + ipv6: fc00:a::6e/126 + bp_interface: + ipv6: fc00:b::1c/64 + + ARISTA27T1: + properties: + - common + bgp: + router-id: 0.12.0.29 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::71 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d::1/128 + Ethernet1: + ipv6: fc00:a::72/126 + bp_interface: + ipv6: fc00:b::1d/64 + + ARISTA28T1: + properties: + - common + bgp: + router-id: 0.12.0.30 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::75 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e::1/128 + Ethernet1: + ipv6: fc00:a::76/126 + bp_interface: + ipv6: fc00:b::1e/64 + + ARISTA29T1: + properties: + - common + bgp: + router-id: 0.12.0.31 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::79 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f::1/128 + Ethernet1: + ipv6: fc00:a::7a/126 + bp_interface: + ipv6: fc00:b::1f/64 + + ARISTA30T1: + properties: + - common + bgp: + router-id: 0.12.0.32 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7d + interfaces: + Loopback0: + ipv6: fc00:c:c:20::1/128 + Ethernet1: + ipv6: fc00:a::7e/126 + bp_interface: + ipv6: fc00:b::20/64 + + ARISTA31T1: + properties: + - common + bgp: + router-id: 0.12.0.33 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::81 + interfaces: + Loopback0: + ipv6: fc00:c:c:21::1/128 + Ethernet1: + ipv6: fc00:a::82/126 + bp_interface: + ipv6: fc00:b::21/64 + + ARISTA32T1: + properties: + - common + bgp: + router-id: 0.12.0.34 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::85 + interfaces: + Loopback0: + ipv6: fc00:c:c:22::1/128 + Ethernet1: + ipv6: fc00:a::86/126 + bp_interface: + ipv6: fc00:b::22/64 + + ARISTA33T1: + properties: + - common + bgp: + router-id: 0.12.0.35 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::89 + interfaces: + Loopback0: + ipv6: fc00:c:c:23::1/128 + Ethernet1: + ipv6: fc00:a::8a/126 + bp_interface: + ipv6: fc00:b::23/64 + + ARISTA34T1: + properties: + - common + bgp: + router-id: 0.12.0.36 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::8d + interfaces: + Loopback0: + ipv6: fc00:c:c:24::1/128 + Ethernet1: + ipv6: fc00:a::8e/126 + bp_interface: + ipv6: fc00:b::24/64 + + ARISTA35T1: + properties: + - common + bgp: + router-id: 0.12.0.37 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::91 + interfaces: + Loopback0: + ipv6: fc00:c:c:25::1/128 + Ethernet1: + ipv6: fc00:a::92/126 + bp_interface: + ipv6: fc00:b::25/64 + + ARISTA36T1: + properties: + - common + bgp: + router-id: 0.12.0.38 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::95 + interfaces: + Loopback0: + ipv6: fc00:c:c:26::1/128 + Ethernet1: + ipv6: fc00:a::96/126 + bp_interface: + ipv6: fc00:b::26/64 + + ARISTA37T1: + properties: + - common + bgp: + router-id: 0.12.0.39 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::99 + interfaces: + Loopback0: + ipv6: fc00:c:c:27::1/128 + Ethernet1: + ipv6: fc00:a::9a/126 + bp_interface: + ipv6: fc00:b::27/64 + + ARISTA38T1: + properties: + - common + bgp: + router-id: 0.12.0.40 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::9d + interfaces: + Loopback0: + ipv6: fc00:c:c:28::1/128 + Ethernet1: + ipv6: fc00:a::9e/126 + bp_interface: + ipv6: fc00:b::28/64 + + ARISTA39T1: + properties: + - common + bgp: + router-id: 0.12.0.41 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:29::1/128 + Ethernet1: + ipv6: fc00:a::a2/126 + bp_interface: + ipv6: fc00:b::29/64 + + ARISTA40T1: + properties: + - common + bgp: + router-id: 0.12.0.42 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2a::1/128 + Ethernet1: + ipv6: fc00:a::a6/126 + bp_interface: + ipv6: fc00:b::2a/64 + + ARISTA41T1: + properties: + - common + bgp: + router-id: 0.12.0.43 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2b::1/128 + Ethernet1: + ipv6: fc00:a::aa/126 + bp_interface: + ipv6: fc00:b::2b/64 + + ARISTA42T1: + properties: + - common + bgp: + router-id: 0.12.0.44 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::ad + interfaces: + Loopback0: + ipv6: fc00:c:c:2c::1/128 + Ethernet1: + ipv6: fc00:a::ae/126 + bp_interface: + ipv6: fc00:b::2c/64 + + ARISTA43T1: + properties: + - common + bgp: + router-id: 0.12.0.45 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:2d::1/128 + Ethernet1: + ipv6: fc00:a::b2/126 + bp_interface: + ipv6: fc00:b::2d/64 + + ARISTA44T1: + properties: + - common + bgp: + router-id: 0.12.0.46 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2e::1/128 + Ethernet1: + ipv6: fc00:a::b6/126 + bp_interface: + ipv6: fc00:b::2e/64 + + ARISTA45T1: + properties: + - common + bgp: + router-id: 0.12.0.47 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2f::1/128 + Ethernet1: + ipv6: fc00:a::ba/126 + bp_interface: + ipv6: fc00:b::2f/64 + + ARISTA46T1: + properties: + - common + bgp: + router-id: 0.12.0.48 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::bd + interfaces: + Loopback0: + ipv6: fc00:c:c:30::1/128 + Ethernet1: + ipv6: fc00:a::be/126 + bp_interface: + ipv6: fc00:b::30/64 + + ARISTA47T1: + properties: + - common + bgp: + router-id: 0.12.0.49 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:31::1/128 + Ethernet1: + ipv6: fc00:a::c2/126 + bp_interface: + ipv6: fc00:b::31/64 + + ARISTA48T1: + properties: + - common + bgp: + router-id: 0.12.0.50 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:32::1/128 + Ethernet1: + ipv6: fc00:a::c6/126 + bp_interface: + ipv6: fc00:b::32/64 + + ARISTA49T1: + properties: + - common + bgp: + router-id: 0.12.0.51 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:33::1/128 + Ethernet1: + ipv6: fc00:a::ca/126 + bp_interface: + ipv6: fc00:b::33/64 + + ARISTA50T1: + properties: + - common + bgp: + router-id: 0.12.0.52 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::cd + interfaces: + Loopback0: + ipv6: fc00:c:c:34::1/128 + Ethernet1: + ipv6: fc00:a::ce/126 + bp_interface: + ipv6: fc00:b::34/64 + + ARISTA51T1: + properties: + - common + bgp: + router-id: 0.12.0.53 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:35::1/128 + Ethernet1: + ipv6: fc00:a::d2/126 + bp_interface: + ipv6: fc00:b::35/64 + + ARISTA52T1: + properties: + - common + bgp: + router-id: 0.12.0.54 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:36::1/128 + Ethernet1: + ipv6: fc00:a::d6/126 + bp_interface: + ipv6: fc00:b::36/64 + + ARISTA53T1: + properties: + - common + bgp: + router-id: 0.12.0.55 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:37::1/128 + Ethernet1: + ipv6: fc00:a::da/126 + bp_interface: + ipv6: fc00:b::37/64 + + ARISTA54T1: + properties: + - common + bgp: + router-id: 0.12.0.56 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::dd + interfaces: + Loopback0: + ipv6: fc00:c:c:38::1/128 + Ethernet1: + ipv6: fc00:a::de/126 + bp_interface: + ipv6: fc00:b::38/64 + + ARISTA55T1: + properties: + - common + bgp: + router-id: 0.12.0.57 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:39::1/128 + Ethernet1: + ipv6: fc00:a::e2/126 + bp_interface: + ipv6: fc00:b::39/64 + + ARISTA56T1: + properties: + - common + bgp: + router-id: 0.12.0.58 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3a::1/128 + Ethernet1: + ipv6: fc00:a::e6/126 + bp_interface: + ipv6: fc00:b::3a/64 + + ARISTA57T1: + properties: + - common + bgp: + router-id: 0.12.0.59 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3b::1/128 + Ethernet1: + ipv6: fc00:a::ea/126 + bp_interface: + ipv6: fc00:b::3b/64 + + ARISTA58T1: + properties: + - common + bgp: + router-id: 0.12.0.60 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::ed + interfaces: + Loopback0: + ipv6: fc00:c:c:3c::1/128 + Ethernet1: + ipv6: fc00:a::ee/126 + bp_interface: + ipv6: fc00:b::3c/64 + + ARISTA59T1: + properties: + - common + bgp: + router-id: 0.12.0.61 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:3d::1/128 + Ethernet1: + ipv6: fc00:a::f2/126 + bp_interface: + ipv6: fc00:b::3d/64 + + ARISTA60T1: + properties: + - common + bgp: + router-id: 0.12.0.62 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3e::1/128 + Ethernet1: + ipv6: fc00:a::f6/126 + bp_interface: + ipv6: fc00:b::3e/64 + + ARISTA61T1: + properties: + - common + bgp: + router-id: 0.12.0.63 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3f::1/128 + Ethernet1: + ipv6: fc00:a::fa/126 + bp_interface: + ipv6: fc00:b::3f/64 + + ARISTA62T1: + properties: + - common + bgp: + router-id: 0.12.0.64 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::fd + interfaces: + Loopback0: + ipv6: fc00:c:c:40::1/128 + Ethernet1: + ipv6: fc00:a::fe/126 + bp_interface: + ipv6: fc00:b::40/64 + + ARISTA63T1: + properties: + - common + bgp: + router-id: 0.12.0.65 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::101 + interfaces: + Loopback0: + ipv6: fc00:c:c:41::1/128 + Ethernet1: + ipv6: fc00:a::102/126 + bp_interface: + ipv6: fc00:b::41/64 + + ARISTA64T1: + properties: + - common + bgp: + router-id: 0.12.0.66 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::105 + interfaces: + Loopback0: + ipv6: fc00:c:c:42::1/128 + Ethernet1: + ipv6: fc00:a::106/126 + bp_interface: + ipv6: fc00:b::42/64 + + ARISTA65T1: + properties: + - common + bgp: + router-id: 0.12.0.67 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::109 + interfaces: + Loopback0: + ipv6: fc00:c:c:43::1/128 + Ethernet1: + ipv6: fc00:a::10a/126 + bp_interface: + ipv6: fc00:b::43/64 + + ARISTA66T1: + properties: + - common + bgp: + router-id: 0.12.0.68 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::10d + interfaces: + Loopback0: + ipv6: fc00:c:c:44::1/128 + Ethernet1: + ipv6: fc00:a::10e/126 + bp_interface: + ipv6: fc00:b::44/64 + + ARISTA67T1: + properties: + - common + bgp: + router-id: 0.12.0.69 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::111 + interfaces: + Loopback0: + ipv6: fc00:c:c:45::1/128 + Ethernet1: + ipv6: fc00:a::112/126 + bp_interface: + ipv6: fc00:b::45/64 + + ARISTA68T1: + properties: + - common + bgp: + router-id: 0.12.0.70 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::115 + interfaces: + Loopback0: + ipv6: fc00:c:c:46::1/128 + Ethernet1: + ipv6: fc00:a::116/126 + bp_interface: + ipv6: fc00:b::46/64 + + ARISTA69T1: + properties: + - common + bgp: + router-id: 0.12.0.71 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::119 + interfaces: + Loopback0: + ipv6: fc00:c:c:47::1/128 + Ethernet1: + ipv6: fc00:a::11a/126 + bp_interface: + ipv6: fc00:b::47/64 + + ARISTA70T1: + properties: + - common + bgp: + router-id: 0.12.0.72 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::11d + interfaces: + Loopback0: + ipv6: fc00:c:c:48::1/128 + Ethernet1: + ipv6: fc00:a::11e/126 + bp_interface: + ipv6: fc00:b::48/64 + + ARISTA71T1: + properties: + - common + bgp: + router-id: 0.12.0.73 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::121 + interfaces: + Loopback0: + ipv6: fc00:c:c:49::1/128 + Ethernet1: + ipv6: fc00:a::122/126 + bp_interface: + ipv6: fc00:b::49/64 + + ARISTA72T1: + properties: + - common + bgp: + router-id: 0.12.0.74 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::125 + interfaces: + Loopback0: + ipv6: fc00:c:c:4a::1/128 + Ethernet1: + ipv6: fc00:a::126/126 + bp_interface: + ipv6: fc00:b::4a/64 + + ARISTA73T1: + properties: + - common + bgp: + router-id: 0.12.0.75 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::129 + interfaces: + Loopback0: + ipv6: fc00:c:c:4b::1/128 + Ethernet1: + ipv6: fc00:a::12a/126 + bp_interface: + ipv6: fc00:b::4b/64 + + ARISTA74T1: + properties: + - common + bgp: + router-id: 0.12.0.76 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::12d + interfaces: + Loopback0: + ipv6: fc00:c:c:4c::1/128 + Ethernet1: + ipv6: fc00:a::12e/126 + bp_interface: + ipv6: fc00:b::4c/64 + + ARISTA75T1: + properties: + - common + bgp: + router-id: 0.12.0.77 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::131 + interfaces: + Loopback0: + ipv6: fc00:c:c:4d::1/128 + Ethernet1: + ipv6: fc00:a::132/126 + bp_interface: + ipv6: fc00:b::4d/64 + + ARISTA76T1: + properties: + - common + bgp: + router-id: 0.12.0.78 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::135 + interfaces: + Loopback0: + ipv6: fc00:c:c:4e::1/128 + Ethernet1: + ipv6: fc00:a::136/126 + bp_interface: + ipv6: fc00:b::4e/64 + + ARISTA77T1: + properties: + - common + bgp: + router-id: 0.12.0.79 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::139 + interfaces: + Loopback0: + ipv6: fc00:c:c:4f::1/128 + Ethernet1: + ipv6: fc00:a::13a/126 + bp_interface: + ipv6: fc00:b::4f/64 + + ARISTA78T1: + properties: + - common + bgp: + router-id: 0.12.0.80 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::13d + interfaces: + Loopback0: + ipv6: fc00:c:c:50::1/128 + Ethernet1: + ipv6: fc00:a::13e/126 + bp_interface: + ipv6: fc00:b::50/64 + + ARISTA79T1: + properties: + - common + bgp: + router-id: 0.12.0.81 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::141 + interfaces: + Loopback0: + ipv6: fc00:c:c:51::1/128 + Ethernet1: + ipv6: fc00:a::142/126 + bp_interface: + ipv6: fc00:b::51/64 + + ARISTA80T1: + properties: + - common + bgp: + router-id: 0.12.0.82 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::145 + interfaces: + Loopback0: + ipv6: fc00:c:c:52::1/128 + Ethernet1: + ipv6: fc00:a::146/126 + bp_interface: + ipv6: fc00:b::52/64 + + ARISTA81T1: + properties: + - common + bgp: + router-id: 0.12.0.83 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::149 + interfaces: + Loopback0: + ipv6: fc00:c:c:53::1/128 + Ethernet1: + ipv6: fc00:a::14a/126 + bp_interface: + ipv6: fc00:b::53/64 + + ARISTA82T1: + properties: + - common + bgp: + router-id: 0.12.0.84 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::14d + interfaces: + Loopback0: + ipv6: fc00:c:c:54::1/128 + Ethernet1: + ipv6: fc00:a::14e/126 + bp_interface: + ipv6: fc00:b::54/64 + + ARISTA83T1: + properties: + - common + bgp: + router-id: 0.12.0.85 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::151 + interfaces: + Loopback0: + ipv6: fc00:c:c:55::1/128 + Ethernet1: + ipv6: fc00:a::152/126 + bp_interface: + ipv6: fc00:b::55/64 + + ARISTA84T1: + properties: + - common + bgp: + router-id: 0.12.0.86 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::155 + interfaces: + Loopback0: + ipv6: fc00:c:c:56::1/128 + Ethernet1: + ipv6: fc00:a::156/126 + bp_interface: + ipv6: fc00:b::56/64 + + ARISTA85T1: + properties: + - common + bgp: + router-id: 0.12.0.87 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::159 + interfaces: + Loopback0: + ipv6: fc00:c:c:57::1/128 + Ethernet1: + ipv6: fc00:a::15a/126 + bp_interface: + ipv6: fc00:b::57/64 + + ARISTA86T1: + properties: + - common + bgp: + router-id: 0.12.0.88 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::15d + interfaces: + Loopback0: + ipv6: fc00:c:c:58::1/128 + Ethernet1: + ipv6: fc00:a::15e/126 + bp_interface: + ipv6: fc00:b::58/64 + + ARISTA87T1: + properties: + - common + bgp: + router-id: 0.12.0.89 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::161 + interfaces: + Loopback0: + ipv6: fc00:c:c:59::1/128 + Ethernet1: + ipv6: fc00:a::162/126 + bp_interface: + ipv6: fc00:b::59/64 + + ARISTA88T1: + properties: + - common + bgp: + router-id: 0.12.0.90 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::165 + interfaces: + Loopback0: + ipv6: fc00:c:c:5a::1/128 + Ethernet1: + ipv6: fc00:a::166/126 + bp_interface: + ipv6: fc00:b::5a/64 + + ARISTA89T1: + properties: + - common + bgp: + router-id: 0.12.0.91 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::169 + interfaces: + Loopback0: + ipv6: fc00:c:c:5b::1/128 + Ethernet1: + ipv6: fc00:a::16a/126 + bp_interface: + ipv6: fc00:b::5b/64 + + ARISTA90T1: + properties: + - common + bgp: + router-id: 0.12.0.92 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::16d + interfaces: + Loopback0: + ipv6: fc00:c:c:5c::1/128 + Ethernet1: + ipv6: fc00:a::16e/126 + bp_interface: + ipv6: fc00:b::5c/64 + + ARISTA91T1: + properties: + - common + bgp: + router-id: 0.12.0.93 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::171 + interfaces: + Loopback0: + ipv6: fc00:c:c:5d::1/128 + Ethernet1: + ipv6: fc00:a::172/126 + bp_interface: + ipv6: fc00:b::5d/64 + + ARISTA92T1: + properties: + - common + bgp: + router-id: 0.12.0.94 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::175 + interfaces: + Loopback0: + ipv6: fc00:c:c:5e::1/128 + Ethernet1: + ipv6: fc00:a::176/126 + bp_interface: + ipv6: fc00:b::5e/64 + + ARISTA93T1: + properties: + - common + bgp: + router-id: 0.12.0.95 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::179 + interfaces: + Loopback0: + ipv6: fc00:c:c:5f::1/128 + Ethernet1: + ipv6: fc00:a::17a/126 + bp_interface: + ipv6: fc00:b::5f/64 + + ARISTA94T1: + properties: + - common + bgp: + router-id: 0.12.0.96 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::17d + interfaces: + Loopback0: + ipv6: fc00:c:c:60::1/128 + Ethernet1: + ipv6: fc00:a::17e/126 + bp_interface: + ipv6: fc00:b::60/64 + + ARISTA95T1: + properties: + - common + bgp: + router-id: 0.12.0.97 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::181 + interfaces: + Loopback0: + ipv6: fc00:c:c:61::1/128 + Ethernet1: + ipv6: fc00:a::182/126 + bp_interface: + ipv6: fc00:b::61/64 + + ARISTA96T1: + properties: + - common + bgp: + router-id: 0.12.0.98 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::185 + interfaces: + Loopback0: + ipv6: fc00:c:c:62::1/128 + Ethernet1: + ipv6: fc00:a::186/126 + bp_interface: + ipv6: fc00:b::62/64 + + ARISTA97T1: + properties: + - common + bgp: + router-id: 0.12.0.99 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::189 + interfaces: + Loopback0: + ipv6: fc00:c:c:63::1/128 + Ethernet1: + ipv6: fc00:a::18a/126 + bp_interface: + ipv6: fc00:b::63/64 + + ARISTA98T1: + properties: + - common + bgp: + router-id: 0.12.0.100 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::18d + interfaces: + Loopback0: + ipv6: fc00:c:c:64::1/128 + Ethernet1: + ipv6: fc00:a::18e/126 + bp_interface: + ipv6: fc00:b::64/64 + + ARISTA99T1: + properties: + - common + bgp: + router-id: 0.12.0.101 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::191 + interfaces: + Loopback0: + ipv6: fc00:c:c:65::1/128 + Ethernet1: + ipv6: fc00:a::192/126 + bp_interface: + ipv6: fc00:b::65/64 + + ARISTA100T1: + properties: + - common + bgp: + router-id: 0.12.0.102 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::195 + interfaces: + Loopback0: + ipv6: fc00:c:c:66::1/128 + Ethernet1: + ipv6: fc00:a::196/126 + bp_interface: + ipv6: fc00:b::66/64 + + ARISTA101T1: + properties: + - common + bgp: + router-id: 0.12.0.103 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::199 + interfaces: + Loopback0: + ipv6: fc00:c:c:67::1/128 + Ethernet1: + ipv6: fc00:a::19a/126 + bp_interface: + ipv6: fc00:b::67/64 + + ARISTA102T1: + properties: + - common + bgp: + router-id: 0.12.0.104 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::19d + interfaces: + Loopback0: + ipv6: fc00:c:c:68::1/128 + Ethernet1: + ipv6: fc00:a::19e/126 + bp_interface: + ipv6: fc00:b::68/64 + + ARISTA103T1: + properties: + - common + bgp: + router-id: 0.12.0.105 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:69::1/128 + Ethernet1: + ipv6: fc00:a::1a2/126 + bp_interface: + ipv6: fc00:b::69/64 + + ARISTA104T1: + properties: + - common + bgp: + router-id: 0.12.0.106 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6a::1/128 + Ethernet1: + ipv6: fc00:a::1a6/126 + bp_interface: + ipv6: fc00:b::6a/64 + + ARISTA105T1: + properties: + - common + bgp: + router-id: 0.12.0.107 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6b::1/128 + Ethernet1: + ipv6: fc00:a::1aa/126 + bp_interface: + ipv6: fc00:b::6b/64 + + ARISTA106T1: + properties: + - common + bgp: + router-id: 0.12.0.108 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1ad + interfaces: + Loopback0: + ipv6: fc00:c:c:6c::1/128 + Ethernet1: + ipv6: fc00:a::1ae/126 + bp_interface: + ipv6: fc00:b::6c/64 + + ARISTA107T1: + properties: + - common + bgp: + router-id: 0.12.0.109 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:6d::1/128 + Ethernet1: + ipv6: fc00:a::1b2/126 + bp_interface: + ipv6: fc00:b::6d/64 + + ARISTA108T1: + properties: + - common + bgp: + router-id: 0.12.0.110 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6e::1/128 + Ethernet1: + ipv6: fc00:a::1b6/126 + bp_interface: + ipv6: fc00:b::6e/64 + + ARISTA109T1: + properties: + - common + bgp: + router-id: 0.12.0.111 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6f::1/128 + Ethernet1: + ipv6: fc00:a::1ba/126 + bp_interface: + ipv6: fc00:b::6f/64 + + ARISTA110T1: + properties: + - common + bgp: + router-id: 0.12.0.112 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1bd + interfaces: + Loopback0: + ipv6: fc00:c:c:70::1/128 + Ethernet1: + ipv6: fc00:a::1be/126 + bp_interface: + ipv6: fc00:b::70/64 + + ARISTA111T1: + properties: + - common + bgp: + router-id: 0.12.0.113 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:71::1/128 + Ethernet1: + ipv6: fc00:a::1c2/126 + bp_interface: + ipv6: fc00:b::71/64 + + ARISTA112T1: + properties: + - common + bgp: + router-id: 0.12.0.114 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:72::1/128 + Ethernet1: + ipv6: fc00:a::1c6/126 + bp_interface: + ipv6: fc00:b::72/64 + + ARISTA113T1: + properties: + - common + bgp: + router-id: 0.12.0.115 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:73::1/128 + Ethernet1: + ipv6: fc00:a::1ca/126 + bp_interface: + ipv6: fc00:b::73/64 + + ARISTA114T1: + properties: + - common + bgp: + router-id: 0.12.0.116 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1cd + interfaces: + Loopback0: + ipv6: fc00:c:c:74::1/128 + Ethernet1: + ipv6: fc00:a::1ce/126 + bp_interface: + ipv6: fc00:b::74/64 + + ARISTA115T1: + properties: + - common + bgp: + router-id: 0.12.0.117 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:75::1/128 + Ethernet1: + ipv6: fc00:a::1d2/126 + bp_interface: + ipv6: fc00:b::75/64 + + ARISTA116T1: + properties: + - common + bgp: + router-id: 0.12.0.118 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:76::1/128 + Ethernet1: + ipv6: fc00:a::1d6/126 + bp_interface: + ipv6: fc00:b::76/64 + + ARISTA117T1: + properties: + - common + bgp: + router-id: 0.12.0.119 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:77::1/128 + Ethernet1: + ipv6: fc00:a::1da/126 + bp_interface: + ipv6: fc00:b::77/64 + + ARISTA118T1: + properties: + - common + bgp: + router-id: 0.12.0.120 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1dd + interfaces: + Loopback0: + ipv6: fc00:c:c:78::1/128 + Ethernet1: + ipv6: fc00:a::1de/126 + bp_interface: + ipv6: fc00:b::78/64 + + ARISTA119T1: + properties: + - common + bgp: + router-id: 0.12.0.121 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:79::1/128 + Ethernet1: + ipv6: fc00:a::1e2/126 + bp_interface: + ipv6: fc00:b::79/64 + + ARISTA120T1: + properties: + - common + bgp: + router-id: 0.12.0.122 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7a::1/128 + Ethernet1: + ipv6: fc00:a::1e6/126 + bp_interface: + ipv6: fc00:b::7a/64 + + ARISTA121T1: + properties: + - common + bgp: + router-id: 0.12.0.123 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7b::1/128 + Ethernet1: + ipv6: fc00:a::1ea/126 + bp_interface: + ipv6: fc00:b::7b/64 + + ARISTA122T1: + properties: + - common + bgp: + router-id: 0.12.0.124 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1ed + interfaces: + Loopback0: + ipv6: fc00:c:c:7c::1/128 + Ethernet1: + ipv6: fc00:a::1ee/126 + bp_interface: + ipv6: fc00:b::7c/64 + + ARISTA123T1: + properties: + - common + bgp: + router-id: 0.12.0.125 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:7d::1/128 + Ethernet1: + ipv6: fc00:a::1f2/126 + bp_interface: + ipv6: fc00:b::7d/64 + + ARISTA124T1: + properties: + - common + bgp: + router-id: 0.12.0.126 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7e::1/128 + Ethernet1: + ipv6: fc00:a::1f6/126 + bp_interface: + ipv6: fc00:b::7e/64 + + ARISTA125T1: + properties: + - common + bgp: + router-id: 0.12.0.127 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7f::1/128 + Ethernet1: + ipv6: fc00:a::1fa/126 + bp_interface: + ipv6: fc00:b::7f/64 + + ARISTA126T1: + properties: + - common + bgp: + router-id: 0.12.0.128 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1fd + interfaces: + Loopback0: + ipv6: fc00:c:c:80::1/128 + Ethernet1: + ipv6: fc00:a::1fe/126 + bp_interface: + ipv6: fc00:b::80/64 + + ARISTA127T1: + properties: + - common + bgp: + router-id: 0.12.0.129 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::201 + interfaces: + Loopback0: + ipv6: fc00:c:c:81::1/128 + Ethernet1: + ipv6: fc00:a::202/126 + bp_interface: + ipv6: fc00:b::81/64 + + ARISTA128T1: + properties: + - common + bgp: + router-id: 0.12.0.130 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::205 + interfaces: + Loopback0: + ipv6: fc00:c:c:82::1/128 + Ethernet1: + ipv6: fc00:a::206/126 + bp_interface: + ipv6: fc00:b::82/64 + + ARISTA129T1: + properties: + - common + bgp: + router-id: 0.12.0.131 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::209 + interfaces: + Loopback0: + ipv6: fc00:c:c:83::1/128 + Ethernet1: + ipv6: fc00:a::20a/126 + bp_interface: + ipv6: fc00:b::83/64 + + ARISTA130T1: + properties: + - common + bgp: + router-id: 0.12.0.132 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::20d + interfaces: + Loopback0: + ipv6: fc00:c:c:84::1/128 + Ethernet1: + ipv6: fc00:a::20e/126 + bp_interface: + ipv6: fc00:b::84/64 + + ARISTA131T1: + properties: + - common + bgp: + router-id: 0.12.0.133 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::211 + interfaces: + Loopback0: + ipv6: fc00:c:c:85::1/128 + Ethernet1: + ipv6: fc00:a::212/126 + bp_interface: + ipv6: fc00:b::85/64 + + ARISTA132T1: + properties: + - common + bgp: + router-id: 0.12.0.134 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::215 + interfaces: + Loopback0: + ipv6: fc00:c:c:86::1/128 + Ethernet1: + ipv6: fc00:a::216/126 + bp_interface: + ipv6: fc00:b::86/64 + + ARISTA133T1: + properties: + - common + bgp: + router-id: 0.12.0.135 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::219 + interfaces: + Loopback0: + ipv6: fc00:c:c:87::1/128 + Ethernet1: + ipv6: fc00:a::21a/126 + bp_interface: + ipv6: fc00:b::87/64 + + ARISTA134T1: + properties: + - common + bgp: + router-id: 0.12.0.136 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::21d + interfaces: + Loopback0: + ipv6: fc00:c:c:88::1/128 + Ethernet1: + ipv6: fc00:a::21e/126 + bp_interface: + ipv6: fc00:b::88/64 + + ARISTA135T1: + properties: + - common + bgp: + router-id: 0.12.0.137 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::221 + interfaces: + Loopback0: + ipv6: fc00:c:c:89::1/128 + Ethernet1: + ipv6: fc00:a::222/126 + bp_interface: + ipv6: fc00:b::89/64 + + ARISTA136T1: + properties: + - common + bgp: + router-id: 0.12.0.138 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::225 + interfaces: + Loopback0: + ipv6: fc00:c:c:8a::1/128 + Ethernet1: + ipv6: fc00:a::226/126 + bp_interface: + ipv6: fc00:b::8a/64 + + ARISTA137T1: + properties: + - common + bgp: + router-id: 0.12.0.139 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::229 + interfaces: + Loopback0: + ipv6: fc00:c:c:8b::1/128 + Ethernet1: + ipv6: fc00:a::22a/126 + bp_interface: + ipv6: fc00:b::8b/64 + + ARISTA138T1: + properties: + - common + bgp: + router-id: 0.12.0.140 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::22d + interfaces: + Loopback0: + ipv6: fc00:c:c:8c::1/128 + Ethernet1: + ipv6: fc00:a::22e/126 + bp_interface: + ipv6: fc00:b::8c/64 + + ARISTA139T1: + properties: + - common + bgp: + router-id: 0.12.0.141 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::231 + interfaces: + Loopback0: + ipv6: fc00:c:c:8d::1/128 + Ethernet1: + ipv6: fc00:a::232/126 + bp_interface: + ipv6: fc00:b::8d/64 + + ARISTA140T1: + properties: + - common + bgp: + router-id: 0.12.0.142 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::235 + interfaces: + Loopback0: + ipv6: fc00:c:c:8e::1/128 + Ethernet1: + ipv6: fc00:a::236/126 + bp_interface: + ipv6: fc00:b::8e/64 + + ARISTA141T1: + properties: + - common + bgp: + router-id: 0.12.0.143 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::239 + interfaces: + Loopback0: + ipv6: fc00:c:c:8f::1/128 + Ethernet1: + ipv6: fc00:a::23a/126 + bp_interface: + ipv6: fc00:b::8f/64 + + ARISTA142T1: + properties: + - common + bgp: + router-id: 0.12.0.144 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::23d + interfaces: + Loopback0: + ipv6: fc00:c:c:90::1/128 + Ethernet1: + ipv6: fc00:a::23e/126 + bp_interface: + ipv6: fc00:b::90/64 + + ARISTA143T1: + properties: + - common + bgp: + router-id: 0.12.0.145 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::241 + interfaces: + Loopback0: + ipv6: fc00:c:c:91::1/128 + Ethernet1: + ipv6: fc00:a::242/126 + bp_interface: + ipv6: fc00:b::91/64 + + ARISTA144T1: + properties: + - common + bgp: + router-id: 0.12.0.146 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::245 + interfaces: + Loopback0: + ipv6: fc00:c:c:92::1/128 + Ethernet1: + ipv6: fc00:a::246/126 + bp_interface: + ipv6: fc00:b::92/64 + + ARISTA145T1: + properties: + - common + bgp: + router-id: 0.12.0.147 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::249 + interfaces: + Loopback0: + ipv6: fc00:c:c:93::1/128 + Ethernet1: + ipv6: fc00:a::24a/126 + bp_interface: + ipv6: fc00:b::93/64 + + ARISTA146T1: + properties: + - common + bgp: + router-id: 0.12.0.148 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::24d + interfaces: + Loopback0: + ipv6: fc00:c:c:94::1/128 + Ethernet1: + ipv6: fc00:a::24e/126 + bp_interface: + ipv6: fc00:b::94/64 + + ARISTA147T1: + properties: + - common + bgp: + router-id: 0.12.0.149 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::251 + interfaces: + Loopback0: + ipv6: fc00:c:c:95::1/128 + Ethernet1: + ipv6: fc00:a::252/126 + bp_interface: + ipv6: fc00:b::95/64 + + ARISTA148T1: + properties: + - common + bgp: + router-id: 0.12.0.150 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::255 + interfaces: + Loopback0: + ipv6: fc00:c:c:96::1/128 + Ethernet1: + ipv6: fc00:a::256/126 + bp_interface: + ipv6: fc00:b::96/64 + + ARISTA149T1: + properties: + - common + bgp: + router-id: 0.12.0.151 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::259 + interfaces: + Loopback0: + ipv6: fc00:c:c:97::1/128 + Ethernet1: + ipv6: fc00:a::25a/126 + bp_interface: + ipv6: fc00:b::97/64 + + ARISTA150T1: + properties: + - common + bgp: + router-id: 0.12.0.152 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::25d + interfaces: + Loopback0: + ipv6: fc00:c:c:98::1/128 + Ethernet1: + ipv6: fc00:a::25e/126 + bp_interface: + ipv6: fc00:b::98/64 + + ARISTA151T1: + properties: + - common + bgp: + router-id: 0.12.0.153 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::261 + interfaces: + Loopback0: + ipv6: fc00:c:c:99::1/128 + Ethernet1: + ipv6: fc00:a::262/126 + bp_interface: + ipv6: fc00:b::99/64 + + ARISTA152T1: + properties: + - common + bgp: + router-id: 0.12.0.154 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::265 + interfaces: + Loopback0: + ipv6: fc00:c:c:9a::1/128 + Ethernet1: + ipv6: fc00:a::266/126 + bp_interface: + ipv6: fc00:b::9a/64 + + ARISTA153T1: + properties: + - common + bgp: + router-id: 0.12.0.155 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::269 + interfaces: + Loopback0: + ipv6: fc00:c:c:9b::1/128 + Ethernet1: + ipv6: fc00:a::26a/126 + bp_interface: + ipv6: fc00:b::9b/64 + + ARISTA154T1: + properties: + - common + bgp: + router-id: 0.12.0.156 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::26d + interfaces: + Loopback0: + ipv6: fc00:c:c:9c::1/128 + Ethernet1: + ipv6: fc00:a::26e/126 + bp_interface: + ipv6: fc00:b::9c/64 + + ARISTA155T1: + properties: + - common + bgp: + router-id: 0.12.0.157 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::271 + interfaces: + Loopback0: + ipv6: fc00:c:c:9d::1/128 + Ethernet1: + ipv6: fc00:a::272/126 + bp_interface: + ipv6: fc00:b::9d/64 + + ARISTA156T1: + properties: + - common + bgp: + router-id: 0.12.0.158 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::275 + interfaces: + Loopback0: + ipv6: fc00:c:c:9e::1/128 + Ethernet1: + ipv6: fc00:a::276/126 + bp_interface: + ipv6: fc00:b::9e/64 + + ARISTA157T1: + properties: + - common + bgp: + router-id: 0.12.0.159 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::279 + interfaces: + Loopback0: + ipv6: fc00:c:c:9f::1/128 + Ethernet1: + ipv6: fc00:a::27a/126 + bp_interface: + ipv6: fc00:b::9f/64 + + ARISTA158T1: + properties: + - common + bgp: + router-id: 0.12.0.160 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::27d + interfaces: + Loopback0: + ipv6: fc00:c:c:a0::1/128 + Ethernet1: + ipv6: fc00:a::27e/126 + bp_interface: + ipv6: fc00:b::a0/64 + + ARISTA159T1: + properties: + - common + bgp: + router-id: 0.12.0.161 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::281 + interfaces: + Loopback0: + ipv6: fc00:c:c:a1::1/128 + Ethernet1: + ipv6: fc00:a::282/126 + bp_interface: + ipv6: fc00:b::a1/64 + + ARISTA160T1: + properties: + - common + bgp: + router-id: 0.12.0.162 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::285 + interfaces: + Loopback0: + ipv6: fc00:c:c:a2::1/128 + Ethernet1: + ipv6: fc00:a::286/126 + bp_interface: + ipv6: fc00:b::a2/64 + + ARISTA161T1: + properties: + - common + bgp: + router-id: 0.12.0.163 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::289 + interfaces: + Loopback0: + ipv6: fc00:c:c:a3::1/128 + Ethernet1: + ipv6: fc00:a::28a/126 + bp_interface: + ipv6: fc00:b::a3/64 + + ARISTA162T1: + properties: + - common + bgp: + router-id: 0.12.0.164 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::28d + interfaces: + Loopback0: + ipv6: fc00:c:c:a4::1/128 + Ethernet1: + ipv6: fc00:a::28e/126 + bp_interface: + ipv6: fc00:b::a4/64 + + ARISTA163T1: + properties: + - common + bgp: + router-id: 0.12.0.165 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::291 + interfaces: + Loopback0: + ipv6: fc00:c:c:a5::1/128 + Ethernet1: + ipv6: fc00:a::292/126 + bp_interface: + ipv6: fc00:b::a5/64 + + ARISTA164T1: + properties: + - common + bgp: + router-id: 0.12.0.166 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::295 + interfaces: + Loopback0: + ipv6: fc00:c:c:a6::1/128 + Ethernet1: + ipv6: fc00:a::296/126 + bp_interface: + ipv6: fc00:b::a6/64 + + ARISTA165T1: + properties: + - common + bgp: + router-id: 0.12.0.167 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::299 + interfaces: + Loopback0: + ipv6: fc00:c:c:a7::1/128 + Ethernet1: + ipv6: fc00:a::29a/126 + bp_interface: + ipv6: fc00:b::a7/64 + + ARISTA166T1: + properties: + - common + bgp: + router-id: 0.12.0.168 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::29d + interfaces: + Loopback0: + ipv6: fc00:c:c:a8::1/128 + Ethernet1: + ipv6: fc00:a::29e/126 + bp_interface: + ipv6: fc00:b::a8/64 + + ARISTA167T1: + properties: + - common + bgp: + router-id: 0.12.0.169 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:a9::1/128 + Ethernet1: + ipv6: fc00:a::2a2/126 + bp_interface: + ipv6: fc00:b::a9/64 + + ARISTA168T1: + properties: + - common + bgp: + router-id: 0.12.0.170 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:aa::1/128 + Ethernet1: + ipv6: fc00:a::2a6/126 + bp_interface: + ipv6: fc00:b::aa/64 + + ARISTA169T1: + properties: + - common + bgp: + router-id: 0.12.0.171 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ab::1/128 + Ethernet1: + ipv6: fc00:a::2aa/126 + bp_interface: + ipv6: fc00:b::ab/64 + + ARISTA170T1: + properties: + - common + bgp: + router-id: 0.12.0.172 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ac::1/128 + Ethernet1: + ipv6: fc00:a::2ae/126 + bp_interface: + ipv6: fc00:b::ac/64 + + ARISTA171T1: + properties: + - common + bgp: + router-id: 0.12.0.173 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ad::1/128 + Ethernet1: + ipv6: fc00:a::2b2/126 + bp_interface: + ipv6: fc00:b::ad/64 + + ARISTA172T1: + properties: + - common + bgp: + router-id: 0.12.0.174 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ae::1/128 + Ethernet1: + ipv6: fc00:a::2b6/126 + bp_interface: + ipv6: fc00:b::ae/64 + + ARISTA173T1: + properties: + - common + bgp: + router-id: 0.12.0.175 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:af::1/128 + Ethernet1: + ipv6: fc00:a::2ba/126 + bp_interface: + ipv6: fc00:b::af/64 + + ARISTA174T1: + properties: + - common + bgp: + router-id: 0.12.0.176 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2bd + interfaces: + Loopback0: + ipv6: fc00:c:c:b0::1/128 + Ethernet1: + ipv6: fc00:a::2be/126 + bp_interface: + ipv6: fc00:b::b0/64 + + ARISTA175T1: + properties: + - common + bgp: + router-id: 0.12.0.177 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b1::1/128 + Ethernet1: + ipv6: fc00:a::2c2/126 + bp_interface: + ipv6: fc00:b::b1/64 + + ARISTA176T1: + properties: + - common + bgp: + router-id: 0.12.0.178 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b2::1/128 + Ethernet1: + ipv6: fc00:a::2c6/126 + bp_interface: + ipv6: fc00:b::b2/64 + + ARISTA177T1: + properties: + - common + bgp: + router-id: 0.12.0.179 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b3::1/128 + Ethernet1: + ipv6: fc00:a::2ca/126 + bp_interface: + ipv6: fc00:b::b3/64 + + ARISTA178T1: + properties: + - common + bgp: + router-id: 0.12.0.180 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2cd + interfaces: + Loopback0: + ipv6: fc00:c:c:b4::1/128 + Ethernet1: + ipv6: fc00:a::2ce/126 + bp_interface: + ipv6: fc00:b::b4/64 + + ARISTA179T1: + properties: + - common + bgp: + router-id: 0.12.0.181 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b5::1/128 + Ethernet1: + ipv6: fc00:a::2d2/126 + bp_interface: + ipv6: fc00:b::b5/64 + + ARISTA180T1: + properties: + - common + bgp: + router-id: 0.12.0.182 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b6::1/128 + Ethernet1: + ipv6: fc00:a::2d6/126 + bp_interface: + ipv6: fc00:b::b6/64 + + ARISTA181T1: + properties: + - common + bgp: + router-id: 0.12.0.183 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b7::1/128 + Ethernet1: + ipv6: fc00:a::2da/126 + bp_interface: + ipv6: fc00:b::b7/64 + + ARISTA182T1: + properties: + - common + bgp: + router-id: 0.12.0.184 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2dd + interfaces: + Loopback0: + ipv6: fc00:c:c:b8::1/128 + Ethernet1: + ipv6: fc00:a::2de/126 + bp_interface: + ipv6: fc00:b::b8/64 + + ARISTA183T1: + properties: + - common + bgp: + router-id: 0.12.0.185 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b9::1/128 + Ethernet1: + ipv6: fc00:a::2e2/126 + bp_interface: + ipv6: fc00:b::b9/64 + + ARISTA184T1: + properties: + - common + bgp: + router-id: 0.12.0.186 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ba::1/128 + Ethernet1: + ipv6: fc00:a::2e6/126 + bp_interface: + ipv6: fc00:b::ba/64 + + ARISTA185T1: + properties: + - common + bgp: + router-id: 0.12.0.187 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bb::1/128 + Ethernet1: + ipv6: fc00:a::2ea/126 + bp_interface: + ipv6: fc00:b::bb/64 + + ARISTA186T1: + properties: + - common + bgp: + router-id: 0.12.0.188 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2ed + interfaces: + Loopback0: + ipv6: fc00:c:c:bc::1/128 + Ethernet1: + ipv6: fc00:a::2ee/126 + bp_interface: + ipv6: fc00:b::bc/64 + + ARISTA187T1: + properties: + - common + bgp: + router-id: 0.12.0.189 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:bd::1/128 + Ethernet1: + ipv6: fc00:a::2f2/126 + bp_interface: + ipv6: fc00:b::bd/64 + + ARISTA188T1: + properties: + - common + bgp: + router-id: 0.12.0.190 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:be::1/128 + Ethernet1: + ipv6: fc00:a::2f6/126 + bp_interface: + ipv6: fc00:b::be/64 + + ARISTA189T1: + properties: + - common + bgp: + router-id: 0.12.0.191 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bf::1/128 + Ethernet1: + ipv6: fc00:a::2fa/126 + bp_interface: + ipv6: fc00:b::bf/64 + + ARISTA190T1: + properties: + - common + bgp: + router-id: 0.12.0.192 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2fd + interfaces: + Loopback0: + ipv6: fc00:c:c:c0::1/128 + Ethernet1: + ipv6: fc00:a::2fe/126 + bp_interface: + ipv6: fc00:b::c0/64 + + ARISTA191T1: + properties: + - common + bgp: + router-id: 0.12.0.193 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::301 + interfaces: + Loopback0: + ipv6: fc00:c:c:c1::1/128 + Ethernet1: + ipv6: fc00:a::302/126 + bp_interface: + ipv6: fc00:b::c1/64 + + ARISTA192T1: + properties: + - common + bgp: + router-id: 0.12.0.194 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::305 + interfaces: + Loopback0: + ipv6: fc00:c:c:c2::1/128 + Ethernet1: + ipv6: fc00:a::306/126 + bp_interface: + ipv6: fc00:b::c2/64 + + ARISTA193T1: + properties: + - common + bgp: + router-id: 0.12.0.195 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::309 + interfaces: + Loopback0: + ipv6: fc00:c:c:c3::1/128 + Ethernet1: + ipv6: fc00:a::30a/126 + bp_interface: + ipv6: fc00:b::c3/64 + + ARISTA194T1: + properties: + - common + bgp: + router-id: 0.12.0.196 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::30d + interfaces: + Loopback0: + ipv6: fc00:c:c:c4::1/128 + Ethernet1: + ipv6: fc00:a::30e/126 + bp_interface: + ipv6: fc00:b::c4/64 + + ARISTA195T1: + properties: + - common + bgp: + router-id: 0.12.0.197 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::311 + interfaces: + Loopback0: + ipv6: fc00:c:c:c5::1/128 + Ethernet1: + ipv6: fc00:a::312/126 + bp_interface: + ipv6: fc00:b::c5/64 + + ARISTA196T1: + properties: + - common + bgp: + router-id: 0.12.0.198 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::315 + interfaces: + Loopback0: + ipv6: fc00:c:c:c6::1/128 + Ethernet1: + ipv6: fc00:a::316/126 + bp_interface: + ipv6: fc00:b::c6/64 + + ARISTA197T1: + properties: + - common + bgp: + router-id: 0.12.0.199 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::319 + interfaces: + Loopback0: + ipv6: fc00:c:c:c7::1/128 + Ethernet1: + ipv6: fc00:a::31a/126 + bp_interface: + ipv6: fc00:b::c7/64 + + ARISTA198T1: + properties: + - common + bgp: + router-id: 0.12.0.200 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::31d + interfaces: + Loopback0: + ipv6: fc00:c:c:c8::1/128 + Ethernet1: + ipv6: fc00:a::31e/126 + bp_interface: + ipv6: fc00:b::c8/64 + + ARISTA199T1: + properties: + - common + bgp: + router-id: 0.12.0.201 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::321 + interfaces: + Loopback0: + ipv6: fc00:c:c:c9::1/128 + Ethernet1: + ipv6: fc00:a::322/126 + bp_interface: + ipv6: fc00:b::c9/64 + + ARISTA200T1: + properties: + - common + bgp: + router-id: 0.12.0.202 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::325 + interfaces: + Loopback0: + ipv6: fc00:c:c:ca::1/128 + Ethernet1: + ipv6: fc00:a::326/126 + bp_interface: + ipv6: fc00:b::ca/64 + + ARISTA201T1: + properties: + - common + bgp: + router-id: 0.12.0.203 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::329 + interfaces: + Loopback0: + ipv6: fc00:c:c:cb::1/128 + Ethernet1: + ipv6: fc00:a::32a/126 + bp_interface: + ipv6: fc00:b::cb/64 + + ARISTA202T1: + properties: + - common + bgp: + router-id: 0.12.0.204 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::32d + interfaces: + Loopback0: + ipv6: fc00:c:c:cc::1/128 + Ethernet1: + ipv6: fc00:a::32e/126 + bp_interface: + ipv6: fc00:b::cc/64 + + ARISTA203T1: + properties: + - common + bgp: + router-id: 0.12.0.205 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::331 + interfaces: + Loopback0: + ipv6: fc00:c:c:cd::1/128 + Ethernet1: + ipv6: fc00:a::332/126 + bp_interface: + ipv6: fc00:b::cd/64 + + ARISTA204T1: + properties: + - common + bgp: + router-id: 0.12.0.206 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::335 + interfaces: + Loopback0: + ipv6: fc00:c:c:ce::1/128 + Ethernet1: + ipv6: fc00:a::336/126 + bp_interface: + ipv6: fc00:b::ce/64 + + ARISTA205T1: + properties: + - common + bgp: + router-id: 0.12.0.207 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::339 + interfaces: + Loopback0: + ipv6: fc00:c:c:cf::1/128 + Ethernet1: + ipv6: fc00:a::33a/126 + bp_interface: + ipv6: fc00:b::cf/64 + + ARISTA206T1: + properties: + - common + bgp: + router-id: 0.12.0.208 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::33d + interfaces: + Loopback0: + ipv6: fc00:c:c:d0::1/128 + Ethernet1: + ipv6: fc00:a::33e/126 + bp_interface: + ipv6: fc00:b::d0/64 + + ARISTA207T1: + properties: + - common + bgp: + router-id: 0.12.0.209 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::341 + interfaces: + Loopback0: + ipv6: fc00:c:c:d1::1/128 + Ethernet1: + ipv6: fc00:a::342/126 + bp_interface: + ipv6: fc00:b::d1/64 + + ARISTA208T1: + properties: + - common + bgp: + router-id: 0.12.0.210 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::345 + interfaces: + Loopback0: + ipv6: fc00:c:c:d2::1/128 + Ethernet1: + ipv6: fc00:a::346/126 + bp_interface: + ipv6: fc00:b::d2/64 + + ARISTA209T1: + properties: + - common + bgp: + router-id: 0.12.0.211 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::349 + interfaces: + Loopback0: + ipv6: fc00:c:c:d3::1/128 + Ethernet1: + ipv6: fc00:a::34a/126 + bp_interface: + ipv6: fc00:b::d3/64 + + ARISTA210T1: + properties: + - common + bgp: + router-id: 0.12.0.212 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::34d + interfaces: + Loopback0: + ipv6: fc00:c:c:d4::1/128 + Ethernet1: + ipv6: fc00:a::34e/126 + bp_interface: + ipv6: fc00:b::d4/64 + + ARISTA211T1: + properties: + - common + bgp: + router-id: 0.12.0.213 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::351 + interfaces: + Loopback0: + ipv6: fc00:c:c:d5::1/128 + Ethernet1: + ipv6: fc00:a::352/126 + bp_interface: + ipv6: fc00:b::d5/64 + + ARISTA212T1: + properties: + - common + bgp: + router-id: 0.12.0.214 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::355 + interfaces: + Loopback0: + ipv6: fc00:c:c:d6::1/128 + Ethernet1: + ipv6: fc00:a::356/126 + bp_interface: + ipv6: fc00:b::d6/64 + + ARISTA213T1: + properties: + - common + bgp: + router-id: 0.12.0.215 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::359 + interfaces: + Loopback0: + ipv6: fc00:c:c:d7::1/128 + Ethernet1: + ipv6: fc00:a::35a/126 + bp_interface: + ipv6: fc00:b::d7/64 + + ARISTA214T1: + properties: + - common + bgp: + router-id: 0.12.0.216 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::35d + interfaces: + Loopback0: + ipv6: fc00:c:c:d8::1/128 + Ethernet1: + ipv6: fc00:a::35e/126 + bp_interface: + ipv6: fc00:b::d8/64 + + ARISTA215T1: + properties: + - common + bgp: + router-id: 0.12.0.217 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::361 + interfaces: + Loopback0: + ipv6: fc00:c:c:d9::1/128 + Ethernet1: + ipv6: fc00:a::362/126 + bp_interface: + ipv6: fc00:b::d9/64 + + ARISTA216T1: + properties: + - common + bgp: + router-id: 0.12.0.218 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::365 + interfaces: + Loopback0: + ipv6: fc00:c:c:da::1/128 + Ethernet1: + ipv6: fc00:a::366/126 + bp_interface: + ipv6: fc00:b::da/64 + + ARISTA217T1: + properties: + - common + bgp: + router-id: 0.12.0.219 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::369 + interfaces: + Loopback0: + ipv6: fc00:c:c:db::1/128 + Ethernet1: + ipv6: fc00:a::36a/126 + bp_interface: + ipv6: fc00:b::db/64 + + ARISTA218T1: + properties: + - common + bgp: + router-id: 0.12.0.220 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::36d + interfaces: + Loopback0: + ipv6: fc00:c:c:dc::1/128 + Ethernet1: + ipv6: fc00:a::36e/126 + bp_interface: + ipv6: fc00:b::dc/64 + + ARISTA219T1: + properties: + - common + bgp: + router-id: 0.12.0.221 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::371 + interfaces: + Loopback0: + ipv6: fc00:c:c:dd::1/128 + Ethernet1: + ipv6: fc00:a::372/126 + bp_interface: + ipv6: fc00:b::dd/64 + + ARISTA220T1: + properties: + - common + bgp: + router-id: 0.12.0.222 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::375 + interfaces: + Loopback0: + ipv6: fc00:c:c:de::1/128 + Ethernet1: + ipv6: fc00:a::376/126 + bp_interface: + ipv6: fc00:b::de/64 + + ARISTA221T1: + properties: + - common + bgp: + router-id: 0.12.0.223 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::379 + interfaces: + Loopback0: + ipv6: fc00:c:c:df::1/128 + Ethernet1: + ipv6: fc00:a::37a/126 + bp_interface: + ipv6: fc00:b::df/64 + + ARISTA222T1: + properties: + - common + bgp: + router-id: 0.12.0.224 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::37d + interfaces: + Loopback0: + ipv6: fc00:c:c:e0::1/128 + Ethernet1: + ipv6: fc00:a::37e/126 + bp_interface: + ipv6: fc00:b::e0/64 + + ARISTA223T1: + properties: + - common + bgp: + router-id: 0.12.0.225 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::381 + interfaces: + Loopback0: + ipv6: fc00:c:c:e1::1/128 + Ethernet1: + ipv6: fc00:a::382/126 + bp_interface: + ipv6: fc00:b::e1/64 + + ARISTA224T1: + properties: + - common + bgp: + router-id: 0.12.0.226 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::385 + interfaces: + Loopback0: + ipv6: fc00:c:c:e2::1/128 + Ethernet1: + ipv6: fc00:a::386/126 + bp_interface: + ipv6: fc00:b::e2/64 + + ARISTA225T1: + properties: + - common + bgp: + router-id: 0.12.0.227 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::389 + interfaces: + Loopback0: + ipv6: fc00:c:c:e3::1/128 + Ethernet1: + ipv6: fc00:a::38a/126 + bp_interface: + ipv6: fc00:b::e3/64 + + ARISTA226T1: + properties: + - common + bgp: + router-id: 0.12.0.228 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::38d + interfaces: + Loopback0: + ipv6: fc00:c:c:e4::1/128 + Ethernet1: + ipv6: fc00:a::38e/126 + bp_interface: + ipv6: fc00:b::e4/64 + + ARISTA227T1: + properties: + - common + bgp: + router-id: 0.12.0.229 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::391 + interfaces: + Loopback0: + ipv6: fc00:c:c:e5::1/128 + Ethernet1: + ipv6: fc00:a::392/126 + bp_interface: + ipv6: fc00:b::e5/64 + + ARISTA228T1: + properties: + - common + bgp: + router-id: 0.12.0.230 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::395 + interfaces: + Loopback0: + ipv6: fc00:c:c:e6::1/128 + Ethernet1: + ipv6: fc00:a::396/126 + bp_interface: + ipv6: fc00:b::e6/64 + + ARISTA229T1: + properties: + - common + bgp: + router-id: 0.12.0.231 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::399 + interfaces: + Loopback0: + ipv6: fc00:c:c:e7::1/128 + Ethernet1: + ipv6: fc00:a::39a/126 + bp_interface: + ipv6: fc00:b::e7/64 + + ARISTA230T1: + properties: + - common + bgp: + router-id: 0.12.0.232 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::39d + interfaces: + Loopback0: + ipv6: fc00:c:c:e8::1/128 + Ethernet1: + ipv6: fc00:a::39e/126 + bp_interface: + ipv6: fc00:b::e8/64 + + ARISTA231T1: + properties: + - common + bgp: + router-id: 0.12.0.233 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:e9::1/128 + Ethernet1: + ipv6: fc00:a::3a2/126 + bp_interface: + ipv6: fc00:b::e9/64 + + ARISTA232T1: + properties: + - common + bgp: + router-id: 0.12.0.234 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ea::1/128 + Ethernet1: + ipv6: fc00:a::3a6/126 + bp_interface: + ipv6: fc00:b::ea/64 + + ARISTA233T1: + properties: + - common + bgp: + router-id: 0.12.0.235 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:eb::1/128 + Ethernet1: + ipv6: fc00:a::3aa/126 + bp_interface: + ipv6: fc00:b::eb/64 + + ARISTA234T1: + properties: + - common + bgp: + router-id: 0.12.0.236 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ec::1/128 + Ethernet1: + ipv6: fc00:a::3ae/126 + bp_interface: + ipv6: fc00:b::ec/64 + + ARISTA235T1: + properties: + - common + bgp: + router-id: 0.12.0.237 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ed::1/128 + Ethernet1: + ipv6: fc00:a::3b2/126 + bp_interface: + ipv6: fc00:b::ed/64 + + ARISTA236T1: + properties: + - common + bgp: + router-id: 0.12.0.238 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ee::1/128 + Ethernet1: + ipv6: fc00:a::3b6/126 + bp_interface: + ipv6: fc00:b::ee/64 + + ARISTA237T1: + properties: + - common + bgp: + router-id: 0.12.0.239 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ef::1/128 + Ethernet1: + ipv6: fc00:a::3ba/126 + bp_interface: + ipv6: fc00:b::ef/64 + + ARISTA238T1: + properties: + - common + bgp: + router-id: 0.12.0.240 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3bd + interfaces: + Loopback0: + ipv6: fc00:c:c:f0::1/128 + Ethernet1: + ipv6: fc00:a::3be/126 + bp_interface: + ipv6: fc00:b::f0/64 + + ARISTA239T1: + properties: + - common + bgp: + router-id: 0.12.0.241 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f1::1/128 + Ethernet1: + ipv6: fc00:a::3c2/126 + bp_interface: + ipv6: fc00:b::f1/64 + + ARISTA240T1: + properties: + - common + bgp: + router-id: 0.12.0.242 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f2::1/128 + Ethernet1: + ipv6: fc00:a::3c6/126 + bp_interface: + ipv6: fc00:b::f2/64 + + ARISTA241T1: + properties: + - common + bgp: + router-id: 0.12.0.243 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f3::1/128 + Ethernet1: + ipv6: fc00:a::3ca/126 + bp_interface: + ipv6: fc00:b::f3/64 + + ARISTA242T1: + properties: + - common + bgp: + router-id: 0.12.0.244 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3cd + interfaces: + Loopback0: + ipv6: fc00:c:c:f4::1/128 + Ethernet1: + ipv6: fc00:a::3ce/126 + bp_interface: + ipv6: fc00:b::f4/64 + + ARISTA243T1: + properties: + - common + bgp: + router-id: 0.12.0.245 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f5::1/128 + Ethernet1: + ipv6: fc00:a::3d2/126 + bp_interface: + ipv6: fc00:b::f5/64 + + ARISTA244T1: + properties: + - common + bgp: + router-id: 0.12.0.246 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f6::1/128 + Ethernet1: + ipv6: fc00:a::3d6/126 + bp_interface: + ipv6: fc00:b::f6/64 + + ARISTA245T1: + properties: + - common + bgp: + router-id: 0.12.0.247 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f7::1/128 + Ethernet1: + ipv6: fc00:a::3da/126 + bp_interface: + ipv6: fc00:b::f7/64 + + ARISTA246T1: + properties: + - common + bgp: + router-id: 0.12.0.248 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3dd + interfaces: + Loopback0: + ipv6: fc00:c:c:f8::1/128 + Ethernet1: + ipv6: fc00:a::3de/126 + bp_interface: + ipv6: fc00:b::f8/64 + + ARISTA247T1: + properties: + - common + bgp: + router-id: 0.12.0.249 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f9::1/128 + Ethernet1: + ipv6: fc00:a::3e2/126 + bp_interface: + ipv6: fc00:b::f9/64 + + ARISTA248T1: + properties: + - common + bgp: + router-id: 0.12.0.250 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fa::1/128 + Ethernet1: + ipv6: fc00:a::3e6/126 + bp_interface: + ipv6: fc00:b::fa/64 + + ARISTA249T1: + properties: + - common + bgp: + router-id: 0.12.0.251 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:fb::1/128 + Ethernet1: + ipv6: fc00:a::3ea/126 + bp_interface: + ipv6: fc00:b::fb/64 + + ARISTA250T1: + properties: + - common + bgp: + router-id: 0.12.0.252 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3ed + interfaces: + Loopback0: + ipv6: fc00:c:c:fc::1/128 + Ethernet1: + ipv6: fc00:a::3ee/126 + bp_interface: + ipv6: fc00:b::fc/64 + + ARISTA251T1: + properties: + - common + bgp: + router-id: 0.12.0.253 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:fd::1/128 + Ethernet1: + ipv6: fc00:a::3f2/126 + bp_interface: + ipv6: fc00:b::fd/64 + + ARISTA252T1: + properties: + - common + bgp: + router-id: 0.12.0.254 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fe::1/128 + Ethernet1: + ipv6: fc00:a::3f6/126 + bp_interface: + ipv6: fc00:b::fe/64 + + ARISTA253T1: + properties: + - common + bgp: + router-id: 0.12.0.255 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ff::1/128 + Ethernet1: + ipv6: fc00:a::3fa/126 + bp_interface: + ipv6: fc00:b::ff/64 + + ARISTA254T1: + properties: + - common + bgp: + router-id: 0.12.1.0 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3fd + interfaces: + Loopback0: + ipv6: fc00:c:c:100::1/128 + Ethernet1: + ipv6: fc00:a::3fe/126 + bp_interface: + ipv6: fc00:b::100/64 diff --git a/ansible/vars/topo_t0-isolated-u510d2.yml b/ansible/vars/topo_t0-isolated-u510d2.yml new file mode 100644 index 00000000000..ebd4e49d896 --- /dev/null +++ b/ansible/vars/topo_t0-isolated-u510d2.yml @@ -0,0 +1,10746 @@ +topology: + host_interfaces: + - 0 + - 1 + VMs: + ARISTA01T1: + vlans: + - 2 + vm_offset: 0 + ARISTA02T1: + vlans: + - 3 + vm_offset: 1 + ARISTA03T1: + vlans: + - 4 + vm_offset: 2 + ARISTA04T1: + vlans: + - 5 + vm_offset: 3 + ARISTA05T1: + vlans: + - 6 + vm_offset: 4 + ARISTA06T1: + vlans: + - 7 + vm_offset: 5 + ARISTA07T1: + vlans: + - 8 + vm_offset: 6 + ARISTA08T1: + vlans: + - 9 + vm_offset: 7 + ARISTA09T1: + vlans: + - 10 + vm_offset: 8 + ARISTA10T1: + vlans: + - 11 + vm_offset: 9 + ARISTA11T1: + vlans: + - 12 + vm_offset: 10 + ARISTA12T1: + vlans: + - 13 + vm_offset: 11 + ARISTA13T1: + vlans: + - 14 + vm_offset: 12 + ARISTA14T1: + vlans: + - 15 + vm_offset: 13 + ARISTA15T1: + vlans: + - 16 + vm_offset: 14 + ARISTA16T1: + vlans: + - 17 + vm_offset: 15 + ARISTA17T1: + vlans: + - 18 + vm_offset: 16 + ARISTA18T1: + vlans: + - 19 + vm_offset: 17 + ARISTA19T1: + vlans: + - 20 + vm_offset: 18 + ARISTA20T1: + vlans: + - 21 + vm_offset: 19 + ARISTA21T1: + vlans: + - 22 + vm_offset: 20 + ARISTA22T1: + vlans: + - 23 + vm_offset: 21 + ARISTA23T1: + vlans: + - 24 + vm_offset: 22 + ARISTA24T1: + vlans: + - 25 + vm_offset: 23 + ARISTA25T1: + vlans: + - 26 + vm_offset: 24 + ARISTA26T1: + vlans: + - 27 + vm_offset: 25 + ARISTA27T1: + vlans: + - 28 + vm_offset: 26 + ARISTA28T1: + vlans: + - 29 + vm_offset: 27 + ARISTA29T1: + vlans: + - 30 + vm_offset: 28 + ARISTA30T1: + vlans: + - 31 + vm_offset: 29 + ARISTA31T1: + vlans: + - 32 + vm_offset: 30 + ARISTA32T1: + vlans: + - 33 + vm_offset: 31 + ARISTA33T1: + vlans: + - 34 + vm_offset: 32 + ARISTA34T1: + vlans: + - 35 + vm_offset: 33 + ARISTA35T1: + vlans: + - 36 + vm_offset: 34 + ARISTA36T1: + vlans: + - 37 + vm_offset: 35 + ARISTA37T1: + vlans: + - 38 + vm_offset: 36 + ARISTA38T1: + vlans: + - 39 + vm_offset: 37 + ARISTA39T1: + vlans: + - 40 + vm_offset: 38 + ARISTA40T1: + vlans: + - 41 + vm_offset: 39 + ARISTA41T1: + vlans: + - 42 + vm_offset: 40 + ARISTA42T1: + vlans: + - 43 + vm_offset: 41 + ARISTA43T1: + vlans: + - 44 + vm_offset: 42 + ARISTA44T1: + vlans: + - 45 + vm_offset: 43 + ARISTA45T1: + vlans: + - 46 + vm_offset: 44 + ARISTA46T1: + vlans: + - 47 + vm_offset: 45 + ARISTA47T1: + vlans: + - 48 + vm_offset: 46 + ARISTA48T1: + vlans: + - 49 + vm_offset: 47 + ARISTA49T1: + vlans: + - 50 + vm_offset: 48 + ARISTA50T1: + vlans: + - 51 + vm_offset: 49 + ARISTA51T1: + vlans: + - 52 + vm_offset: 50 + ARISTA52T1: + vlans: + - 53 + vm_offset: 51 + ARISTA53T1: + vlans: + - 54 + vm_offset: 52 + ARISTA54T1: + vlans: + - 55 + vm_offset: 53 + ARISTA55T1: + vlans: + - 56 + vm_offset: 54 + ARISTA56T1: + vlans: + - 57 + vm_offset: 55 + ARISTA57T1: + vlans: + - 58 + vm_offset: 56 + ARISTA58T1: + vlans: + - 59 + vm_offset: 57 + ARISTA59T1: + vlans: + - 60 + vm_offset: 58 + ARISTA60T1: + vlans: + - 61 + vm_offset: 59 + ARISTA61T1: + vlans: + - 62 + vm_offset: 60 + ARISTA62T1: + vlans: + - 63 + vm_offset: 61 + ARISTA63T1: + vlans: + - 64 + vm_offset: 62 + ARISTA64T1: + vlans: + - 65 + vm_offset: 63 + ARISTA65T1: + vlans: + - 66 + vm_offset: 64 + ARISTA66T1: + vlans: + - 67 + vm_offset: 65 + ARISTA67T1: + vlans: + - 68 + vm_offset: 66 + ARISTA68T1: + vlans: + - 69 + vm_offset: 67 + ARISTA69T1: + vlans: + - 70 + vm_offset: 68 + ARISTA70T1: + vlans: + - 71 + vm_offset: 69 + ARISTA71T1: + vlans: + - 72 + vm_offset: 70 + ARISTA72T1: + vlans: + - 73 + vm_offset: 71 + ARISTA73T1: + vlans: + - 74 + vm_offset: 72 + ARISTA74T1: + vlans: + - 75 + vm_offset: 73 + ARISTA75T1: + vlans: + - 76 + vm_offset: 74 + ARISTA76T1: + vlans: + - 77 + vm_offset: 75 + ARISTA77T1: + vlans: + - 78 + vm_offset: 76 + ARISTA78T1: + vlans: + - 79 + vm_offset: 77 + ARISTA79T1: + vlans: + - 80 + vm_offset: 78 + ARISTA80T1: + vlans: + - 81 + vm_offset: 79 + ARISTA81T1: + vlans: + - 82 + vm_offset: 80 + ARISTA82T1: + vlans: + - 83 + vm_offset: 81 + ARISTA83T1: + vlans: + - 84 + vm_offset: 82 + ARISTA84T1: + vlans: + - 85 + vm_offset: 83 + ARISTA85T1: + vlans: + - 86 + vm_offset: 84 + ARISTA86T1: + vlans: + - 87 + vm_offset: 85 + ARISTA87T1: + vlans: + - 88 + vm_offset: 86 + ARISTA88T1: + vlans: + - 89 + vm_offset: 87 + ARISTA89T1: + vlans: + - 90 + vm_offset: 88 + ARISTA90T1: + vlans: + - 91 + vm_offset: 89 + ARISTA91T1: + vlans: + - 92 + vm_offset: 90 + ARISTA92T1: + vlans: + - 93 + vm_offset: 91 + ARISTA93T1: + vlans: + - 94 + vm_offset: 92 + ARISTA94T1: + vlans: + - 95 + vm_offset: 93 + ARISTA95T1: + vlans: + - 96 + vm_offset: 94 + ARISTA96T1: + vlans: + - 97 + vm_offset: 95 + ARISTA97T1: + vlans: + - 98 + vm_offset: 96 + ARISTA98T1: + vlans: + - 99 + vm_offset: 97 + ARISTA99T1: + vlans: + - 100 + vm_offset: 98 + ARISTA100T1: + vlans: + - 101 + vm_offset: 99 + ARISTA101T1: + vlans: + - 102 + vm_offset: 100 + ARISTA102T1: + vlans: + - 103 + vm_offset: 101 + ARISTA103T1: + vlans: + - 104 + vm_offset: 102 + ARISTA104T1: + vlans: + - 105 + vm_offset: 103 + ARISTA105T1: + vlans: + - 106 + vm_offset: 104 + ARISTA106T1: + vlans: + - 107 + vm_offset: 105 + ARISTA107T1: + vlans: + - 108 + vm_offset: 106 + ARISTA108T1: + vlans: + - 109 + vm_offset: 107 + ARISTA109T1: + vlans: + - 110 + vm_offset: 108 + ARISTA110T1: + vlans: + - 111 + vm_offset: 109 + ARISTA111T1: + vlans: + - 112 + vm_offset: 110 + ARISTA112T1: + vlans: + - 113 + vm_offset: 111 + ARISTA113T1: + vlans: + - 114 + vm_offset: 112 + ARISTA114T1: + vlans: + - 115 + vm_offset: 113 + ARISTA115T1: + vlans: + - 116 + vm_offset: 114 + ARISTA116T1: + vlans: + - 117 + vm_offset: 115 + ARISTA117T1: + vlans: + - 118 + vm_offset: 116 + ARISTA118T1: + vlans: + - 119 + vm_offset: 117 + ARISTA119T1: + vlans: + - 120 + vm_offset: 118 + ARISTA120T1: + vlans: + - 121 + vm_offset: 119 + ARISTA121T1: + vlans: + - 122 + vm_offset: 120 + ARISTA122T1: + vlans: + - 123 + vm_offset: 121 + ARISTA123T1: + vlans: + - 124 + vm_offset: 122 + ARISTA124T1: + vlans: + - 125 + vm_offset: 123 + ARISTA125T1: + vlans: + - 126 + vm_offset: 124 + ARISTA126T1: + vlans: + - 127 + vm_offset: 125 + ARISTA127T1: + vlans: + - 128 + vm_offset: 126 + ARISTA128T1: + vlans: + - 129 + vm_offset: 127 + ARISTA129T1: + vlans: + - 130 + vm_offset: 128 + ARISTA130T1: + vlans: + - 131 + vm_offset: 129 + ARISTA131T1: + vlans: + - 132 + vm_offset: 130 + ARISTA132T1: + vlans: + - 133 + vm_offset: 131 + ARISTA133T1: + vlans: + - 134 + vm_offset: 132 + ARISTA134T1: + vlans: + - 135 + vm_offset: 133 + ARISTA135T1: + vlans: + - 136 + vm_offset: 134 + ARISTA136T1: + vlans: + - 137 + vm_offset: 135 + ARISTA137T1: + vlans: + - 138 + vm_offset: 136 + ARISTA138T1: + vlans: + - 139 + vm_offset: 137 + ARISTA139T1: + vlans: + - 140 + vm_offset: 138 + ARISTA140T1: + vlans: + - 141 + vm_offset: 139 + ARISTA141T1: + vlans: + - 142 + vm_offset: 140 + ARISTA142T1: + vlans: + - 143 + vm_offset: 141 + ARISTA143T1: + vlans: + - 144 + vm_offset: 142 + ARISTA144T1: + vlans: + - 145 + vm_offset: 143 + ARISTA145T1: + vlans: + - 146 + vm_offset: 144 + ARISTA146T1: + vlans: + - 147 + vm_offset: 145 + ARISTA147T1: + vlans: + - 148 + vm_offset: 146 + ARISTA148T1: + vlans: + - 149 + vm_offset: 147 + ARISTA149T1: + vlans: + - 150 + vm_offset: 148 + ARISTA150T1: + vlans: + - 151 + vm_offset: 149 + ARISTA151T1: + vlans: + - 152 + vm_offset: 150 + ARISTA152T1: + vlans: + - 153 + vm_offset: 151 + ARISTA153T1: + vlans: + - 154 + vm_offset: 152 + ARISTA154T1: + vlans: + - 155 + vm_offset: 153 + ARISTA155T1: + vlans: + - 156 + vm_offset: 154 + ARISTA156T1: + vlans: + - 157 + vm_offset: 155 + ARISTA157T1: + vlans: + - 158 + vm_offset: 156 + ARISTA158T1: + vlans: + - 159 + vm_offset: 157 + ARISTA159T1: + vlans: + - 160 + vm_offset: 158 + ARISTA160T1: + vlans: + - 161 + vm_offset: 159 + ARISTA161T1: + vlans: + - 162 + vm_offset: 160 + ARISTA162T1: + vlans: + - 163 + vm_offset: 161 + ARISTA163T1: + vlans: + - 164 + vm_offset: 162 + ARISTA164T1: + vlans: + - 165 + vm_offset: 163 + ARISTA165T1: + vlans: + - 166 + vm_offset: 164 + ARISTA166T1: + vlans: + - 167 + vm_offset: 165 + ARISTA167T1: + vlans: + - 168 + vm_offset: 166 + ARISTA168T1: + vlans: + - 169 + vm_offset: 167 + ARISTA169T1: + vlans: + - 170 + vm_offset: 168 + ARISTA170T1: + vlans: + - 171 + vm_offset: 169 + ARISTA171T1: + vlans: + - 172 + vm_offset: 170 + ARISTA172T1: + vlans: + - 173 + vm_offset: 171 + ARISTA173T1: + vlans: + - 174 + vm_offset: 172 + ARISTA174T1: + vlans: + - 175 + vm_offset: 173 + ARISTA175T1: + vlans: + - 176 + vm_offset: 174 + ARISTA176T1: + vlans: + - 177 + vm_offset: 175 + ARISTA177T1: + vlans: + - 178 + vm_offset: 176 + ARISTA178T1: + vlans: + - 179 + vm_offset: 177 + ARISTA179T1: + vlans: + - 180 + vm_offset: 178 + ARISTA180T1: + vlans: + - 181 + vm_offset: 179 + ARISTA181T1: + vlans: + - 182 + vm_offset: 180 + ARISTA182T1: + vlans: + - 183 + vm_offset: 181 + ARISTA183T1: + vlans: + - 184 + vm_offset: 182 + ARISTA184T1: + vlans: + - 185 + vm_offset: 183 + ARISTA185T1: + vlans: + - 186 + vm_offset: 184 + ARISTA186T1: + vlans: + - 187 + vm_offset: 185 + ARISTA187T1: + vlans: + - 188 + vm_offset: 186 + ARISTA188T1: + vlans: + - 189 + vm_offset: 187 + ARISTA189T1: + vlans: + - 190 + vm_offset: 188 + ARISTA190T1: + vlans: + - 191 + vm_offset: 189 + ARISTA191T1: + vlans: + - 192 + vm_offset: 190 + ARISTA192T1: + vlans: + - 193 + vm_offset: 191 + ARISTA193T1: + vlans: + - 194 + vm_offset: 192 + ARISTA194T1: + vlans: + - 195 + vm_offset: 193 + ARISTA195T1: + vlans: + - 196 + vm_offset: 194 + ARISTA196T1: + vlans: + - 197 + vm_offset: 195 + ARISTA197T1: + vlans: + - 198 + vm_offset: 196 + ARISTA198T1: + vlans: + - 199 + vm_offset: 197 + ARISTA199T1: + vlans: + - 200 + vm_offset: 198 + ARISTA200T1: + vlans: + - 201 + vm_offset: 199 + ARISTA201T1: + vlans: + - 202 + vm_offset: 200 + ARISTA202T1: + vlans: + - 203 + vm_offset: 201 + ARISTA203T1: + vlans: + - 204 + vm_offset: 202 + ARISTA204T1: + vlans: + - 205 + vm_offset: 203 + ARISTA205T1: + vlans: + - 206 + vm_offset: 204 + ARISTA206T1: + vlans: + - 207 + vm_offset: 205 + ARISTA207T1: + vlans: + - 208 + vm_offset: 206 + ARISTA208T1: + vlans: + - 209 + vm_offset: 207 + ARISTA209T1: + vlans: + - 210 + vm_offset: 208 + ARISTA210T1: + vlans: + - 211 + vm_offset: 209 + ARISTA211T1: + vlans: + - 212 + vm_offset: 210 + ARISTA212T1: + vlans: + - 213 + vm_offset: 211 + ARISTA213T1: + vlans: + - 214 + vm_offset: 212 + ARISTA214T1: + vlans: + - 215 + vm_offset: 213 + ARISTA215T1: + vlans: + - 216 + vm_offset: 214 + ARISTA216T1: + vlans: + - 217 + vm_offset: 215 + ARISTA217T1: + vlans: + - 218 + vm_offset: 216 + ARISTA218T1: + vlans: + - 219 + vm_offset: 217 + ARISTA219T1: + vlans: + - 220 + vm_offset: 218 + ARISTA220T1: + vlans: + - 221 + vm_offset: 219 + ARISTA221T1: + vlans: + - 222 + vm_offset: 220 + ARISTA222T1: + vlans: + - 223 + vm_offset: 221 + ARISTA223T1: + vlans: + - 224 + vm_offset: 222 + ARISTA224T1: + vlans: + - 225 + vm_offset: 223 + ARISTA225T1: + vlans: + - 226 + vm_offset: 224 + ARISTA226T1: + vlans: + - 227 + vm_offset: 225 + ARISTA227T1: + vlans: + - 228 + vm_offset: 226 + ARISTA228T1: + vlans: + - 229 + vm_offset: 227 + ARISTA229T1: + vlans: + - 230 + vm_offset: 228 + ARISTA230T1: + vlans: + - 231 + vm_offset: 229 + ARISTA231T1: + vlans: + - 232 + vm_offset: 230 + ARISTA232T1: + vlans: + - 233 + vm_offset: 231 + ARISTA233T1: + vlans: + - 234 + vm_offset: 232 + ARISTA234T1: + vlans: + - 235 + vm_offset: 233 + ARISTA235T1: + vlans: + - 236 + vm_offset: 234 + ARISTA236T1: + vlans: + - 237 + vm_offset: 235 + ARISTA237T1: + vlans: + - 238 + vm_offset: 236 + ARISTA238T1: + vlans: + - 239 + vm_offset: 237 + ARISTA239T1: + vlans: + - 240 + vm_offset: 238 + ARISTA240T1: + vlans: + - 241 + vm_offset: 239 + ARISTA241T1: + vlans: + - 242 + vm_offset: 240 + ARISTA242T1: + vlans: + - 243 + vm_offset: 241 + ARISTA243T1: + vlans: + - 244 + vm_offset: 242 + ARISTA244T1: + vlans: + - 245 + vm_offset: 243 + ARISTA245T1: + vlans: + - 246 + vm_offset: 244 + ARISTA246T1: + vlans: + - 247 + vm_offset: 245 + ARISTA247T1: + vlans: + - 248 + vm_offset: 246 + ARISTA248T1: + vlans: + - 249 + vm_offset: 247 + ARISTA249T1: + vlans: + - 250 + vm_offset: 248 + ARISTA250T1: + vlans: + - 251 + vm_offset: 249 + ARISTA251T1: + vlans: + - 252 + vm_offset: 250 + ARISTA252T1: + vlans: + - 253 + vm_offset: 251 + ARISTA253T1: + vlans: + - 254 + vm_offset: 252 + ARISTA254T1: + vlans: + - 255 + vm_offset: 253 + ARISTA255T1: + vlans: + - 256 + vm_offset: 254 + ARISTA256T1: + vlans: + - 257 + vm_offset: 255 + ARISTA257T1: + vlans: + - 258 + vm_offset: 256 + ARISTA258T1: + vlans: + - 259 + vm_offset: 257 + ARISTA259T1: + vlans: + - 260 + vm_offset: 258 + ARISTA260T1: + vlans: + - 261 + vm_offset: 259 + ARISTA261T1: + vlans: + - 262 + vm_offset: 260 + ARISTA262T1: + vlans: + - 263 + vm_offset: 261 + ARISTA263T1: + vlans: + - 264 + vm_offset: 262 + ARISTA264T1: + vlans: + - 265 + vm_offset: 263 + ARISTA265T1: + vlans: + - 266 + vm_offset: 264 + ARISTA266T1: + vlans: + - 267 + vm_offset: 265 + ARISTA267T1: + vlans: + - 268 + vm_offset: 266 + ARISTA268T1: + vlans: + - 269 + vm_offset: 267 + ARISTA269T1: + vlans: + - 270 + vm_offset: 268 + ARISTA270T1: + vlans: + - 271 + vm_offset: 269 + ARISTA271T1: + vlans: + - 272 + vm_offset: 270 + ARISTA272T1: + vlans: + - 273 + vm_offset: 271 + ARISTA273T1: + vlans: + - 274 + vm_offset: 272 + ARISTA274T1: + vlans: + - 275 + vm_offset: 273 + ARISTA275T1: + vlans: + - 276 + vm_offset: 274 + ARISTA276T1: + vlans: + - 277 + vm_offset: 275 + ARISTA277T1: + vlans: + - 278 + vm_offset: 276 + ARISTA278T1: + vlans: + - 279 + vm_offset: 277 + ARISTA279T1: + vlans: + - 280 + vm_offset: 278 + ARISTA280T1: + vlans: + - 281 + vm_offset: 279 + ARISTA281T1: + vlans: + - 282 + vm_offset: 280 + ARISTA282T1: + vlans: + - 283 + vm_offset: 281 + ARISTA283T1: + vlans: + - 284 + vm_offset: 282 + ARISTA284T1: + vlans: + - 285 + vm_offset: 283 + ARISTA285T1: + vlans: + - 286 + vm_offset: 284 + ARISTA286T1: + vlans: + - 287 + vm_offset: 285 + ARISTA287T1: + vlans: + - 288 + vm_offset: 286 + ARISTA288T1: + vlans: + - 289 + vm_offset: 287 + ARISTA289T1: + vlans: + - 290 + vm_offset: 288 + ARISTA290T1: + vlans: + - 291 + vm_offset: 289 + ARISTA291T1: + vlans: + - 292 + vm_offset: 290 + ARISTA292T1: + vlans: + - 293 + vm_offset: 291 + ARISTA293T1: + vlans: + - 294 + vm_offset: 292 + ARISTA294T1: + vlans: + - 295 + vm_offset: 293 + ARISTA295T1: + vlans: + - 296 + vm_offset: 294 + ARISTA296T1: + vlans: + - 297 + vm_offset: 295 + ARISTA297T1: + vlans: + - 298 + vm_offset: 296 + ARISTA298T1: + vlans: + - 299 + vm_offset: 297 + ARISTA299T1: + vlans: + - 300 + vm_offset: 298 + ARISTA300T1: + vlans: + - 301 + vm_offset: 299 + ARISTA301T1: + vlans: + - 302 + vm_offset: 300 + ARISTA302T1: + vlans: + - 303 + vm_offset: 301 + ARISTA303T1: + vlans: + - 304 + vm_offset: 302 + ARISTA304T1: + vlans: + - 305 + vm_offset: 303 + ARISTA305T1: + vlans: + - 306 + vm_offset: 304 + ARISTA306T1: + vlans: + - 307 + vm_offset: 305 + ARISTA307T1: + vlans: + - 308 + vm_offset: 306 + ARISTA308T1: + vlans: + - 309 + vm_offset: 307 + ARISTA309T1: + vlans: + - 310 + vm_offset: 308 + ARISTA310T1: + vlans: + - 311 + vm_offset: 309 + ARISTA311T1: + vlans: + - 312 + vm_offset: 310 + ARISTA312T1: + vlans: + - 313 + vm_offset: 311 + ARISTA313T1: + vlans: + - 314 + vm_offset: 312 + ARISTA314T1: + vlans: + - 315 + vm_offset: 313 + ARISTA315T1: + vlans: + - 316 + vm_offset: 314 + ARISTA316T1: + vlans: + - 317 + vm_offset: 315 + ARISTA317T1: + vlans: + - 318 + vm_offset: 316 + ARISTA318T1: + vlans: + - 319 + vm_offset: 317 + ARISTA319T1: + vlans: + - 320 + vm_offset: 318 + ARISTA320T1: + vlans: + - 321 + vm_offset: 319 + ARISTA321T1: + vlans: + - 322 + vm_offset: 320 + ARISTA322T1: + vlans: + - 323 + vm_offset: 321 + ARISTA323T1: + vlans: + - 324 + vm_offset: 322 + ARISTA324T1: + vlans: + - 325 + vm_offset: 323 + ARISTA325T1: + vlans: + - 326 + vm_offset: 324 + ARISTA326T1: + vlans: + - 327 + vm_offset: 325 + ARISTA327T1: + vlans: + - 328 + vm_offset: 326 + ARISTA328T1: + vlans: + - 329 + vm_offset: 327 + ARISTA329T1: + vlans: + - 330 + vm_offset: 328 + ARISTA330T1: + vlans: + - 331 + vm_offset: 329 + ARISTA331T1: + vlans: + - 332 + vm_offset: 330 + ARISTA332T1: + vlans: + - 333 + vm_offset: 331 + ARISTA333T1: + vlans: + - 334 + vm_offset: 332 + ARISTA334T1: + vlans: + - 335 + vm_offset: 333 + ARISTA335T1: + vlans: + - 336 + vm_offset: 334 + ARISTA336T1: + vlans: + - 337 + vm_offset: 335 + ARISTA337T1: + vlans: + - 338 + vm_offset: 336 + ARISTA338T1: + vlans: + - 339 + vm_offset: 337 + ARISTA339T1: + vlans: + - 340 + vm_offset: 338 + ARISTA340T1: + vlans: + - 341 + vm_offset: 339 + ARISTA341T1: + vlans: + - 342 + vm_offset: 340 + ARISTA342T1: + vlans: + - 343 + vm_offset: 341 + ARISTA343T1: + vlans: + - 344 + vm_offset: 342 + ARISTA344T1: + vlans: + - 345 + vm_offset: 343 + ARISTA345T1: + vlans: + - 346 + vm_offset: 344 + ARISTA346T1: + vlans: + - 347 + vm_offset: 345 + ARISTA347T1: + vlans: + - 348 + vm_offset: 346 + ARISTA348T1: + vlans: + - 349 + vm_offset: 347 + ARISTA349T1: + vlans: + - 350 + vm_offset: 348 + ARISTA350T1: + vlans: + - 351 + vm_offset: 349 + ARISTA351T1: + vlans: + - 352 + vm_offset: 350 + ARISTA352T1: + vlans: + - 353 + vm_offset: 351 + ARISTA353T1: + vlans: + - 354 + vm_offset: 352 + ARISTA354T1: + vlans: + - 355 + vm_offset: 353 + ARISTA355T1: + vlans: + - 356 + vm_offset: 354 + ARISTA356T1: + vlans: + - 357 + vm_offset: 355 + ARISTA357T1: + vlans: + - 358 + vm_offset: 356 + ARISTA358T1: + vlans: + - 359 + vm_offset: 357 + ARISTA359T1: + vlans: + - 360 + vm_offset: 358 + ARISTA360T1: + vlans: + - 361 + vm_offset: 359 + ARISTA361T1: + vlans: + - 362 + vm_offset: 360 + ARISTA362T1: + vlans: + - 363 + vm_offset: 361 + ARISTA363T1: + vlans: + - 364 + vm_offset: 362 + ARISTA364T1: + vlans: + - 365 + vm_offset: 363 + ARISTA365T1: + vlans: + - 366 + vm_offset: 364 + ARISTA366T1: + vlans: + - 367 + vm_offset: 365 + ARISTA367T1: + vlans: + - 368 + vm_offset: 366 + ARISTA368T1: + vlans: + - 369 + vm_offset: 367 + ARISTA369T1: + vlans: + - 370 + vm_offset: 368 + ARISTA370T1: + vlans: + - 371 + vm_offset: 369 + ARISTA371T1: + vlans: + - 372 + vm_offset: 370 + ARISTA372T1: + vlans: + - 373 + vm_offset: 371 + ARISTA373T1: + vlans: + - 374 + vm_offset: 372 + ARISTA374T1: + vlans: + - 375 + vm_offset: 373 + ARISTA375T1: + vlans: + - 376 + vm_offset: 374 + ARISTA376T1: + vlans: + - 377 + vm_offset: 375 + ARISTA377T1: + vlans: + - 378 + vm_offset: 376 + ARISTA378T1: + vlans: + - 379 + vm_offset: 377 + ARISTA379T1: + vlans: + - 380 + vm_offset: 378 + ARISTA380T1: + vlans: + - 381 + vm_offset: 379 + ARISTA381T1: + vlans: + - 382 + vm_offset: 380 + ARISTA382T1: + vlans: + - 383 + vm_offset: 381 + ARISTA383T1: + vlans: + - 384 + vm_offset: 382 + ARISTA384T1: + vlans: + - 385 + vm_offset: 383 + ARISTA385T1: + vlans: + - 386 + vm_offset: 384 + ARISTA386T1: + vlans: + - 387 + vm_offset: 385 + ARISTA387T1: + vlans: + - 388 + vm_offset: 386 + ARISTA388T1: + vlans: + - 389 + vm_offset: 387 + ARISTA389T1: + vlans: + - 390 + vm_offset: 388 + ARISTA390T1: + vlans: + - 391 + vm_offset: 389 + ARISTA391T1: + vlans: + - 392 + vm_offset: 390 + ARISTA392T1: + vlans: + - 393 + vm_offset: 391 + ARISTA393T1: + vlans: + - 394 + vm_offset: 392 + ARISTA394T1: + vlans: + - 395 + vm_offset: 393 + ARISTA395T1: + vlans: + - 396 + vm_offset: 394 + ARISTA396T1: + vlans: + - 397 + vm_offset: 395 + ARISTA397T1: + vlans: + - 398 + vm_offset: 396 + ARISTA398T1: + vlans: + - 399 + vm_offset: 397 + ARISTA399T1: + vlans: + - 400 + vm_offset: 398 + ARISTA400T1: + vlans: + - 401 + vm_offset: 399 + ARISTA401T1: + vlans: + - 402 + vm_offset: 400 + ARISTA402T1: + vlans: + - 403 + vm_offset: 401 + ARISTA403T1: + vlans: + - 404 + vm_offset: 402 + ARISTA404T1: + vlans: + - 405 + vm_offset: 403 + ARISTA405T1: + vlans: + - 406 + vm_offset: 404 + ARISTA406T1: + vlans: + - 407 + vm_offset: 405 + ARISTA407T1: + vlans: + - 408 + vm_offset: 406 + ARISTA408T1: + vlans: + - 409 + vm_offset: 407 + ARISTA409T1: + vlans: + - 410 + vm_offset: 408 + ARISTA410T1: + vlans: + - 411 + vm_offset: 409 + ARISTA411T1: + vlans: + - 412 + vm_offset: 410 + ARISTA412T1: + vlans: + - 413 + vm_offset: 411 + ARISTA413T1: + vlans: + - 414 + vm_offset: 412 + ARISTA414T1: + vlans: + - 415 + vm_offset: 413 + ARISTA415T1: + vlans: + - 416 + vm_offset: 414 + ARISTA416T1: + vlans: + - 417 + vm_offset: 415 + ARISTA417T1: + vlans: + - 418 + vm_offset: 416 + ARISTA418T1: + vlans: + - 419 + vm_offset: 417 + ARISTA419T1: + vlans: + - 420 + vm_offset: 418 + ARISTA420T1: + vlans: + - 421 + vm_offset: 419 + ARISTA421T1: + vlans: + - 422 + vm_offset: 420 + ARISTA422T1: + vlans: + - 423 + vm_offset: 421 + ARISTA423T1: + vlans: + - 424 + vm_offset: 422 + ARISTA424T1: + vlans: + - 425 + vm_offset: 423 + ARISTA425T1: + vlans: + - 426 + vm_offset: 424 + ARISTA426T1: + vlans: + - 427 + vm_offset: 425 + ARISTA427T1: + vlans: + - 428 + vm_offset: 426 + ARISTA428T1: + vlans: + - 429 + vm_offset: 427 + ARISTA429T1: + vlans: + - 430 + vm_offset: 428 + ARISTA430T1: + vlans: + - 431 + vm_offset: 429 + ARISTA431T1: + vlans: + - 432 + vm_offset: 430 + ARISTA432T1: + vlans: + - 433 + vm_offset: 431 + ARISTA433T1: + vlans: + - 434 + vm_offset: 432 + ARISTA434T1: + vlans: + - 435 + vm_offset: 433 + ARISTA435T1: + vlans: + - 436 + vm_offset: 434 + ARISTA436T1: + vlans: + - 437 + vm_offset: 435 + ARISTA437T1: + vlans: + - 438 + vm_offset: 436 + ARISTA438T1: + vlans: + - 439 + vm_offset: 437 + ARISTA439T1: + vlans: + - 440 + vm_offset: 438 + ARISTA440T1: + vlans: + - 441 + vm_offset: 439 + ARISTA441T1: + vlans: + - 442 + vm_offset: 440 + ARISTA442T1: + vlans: + - 443 + vm_offset: 441 + ARISTA443T1: + vlans: + - 444 + vm_offset: 442 + ARISTA444T1: + vlans: + - 445 + vm_offset: 443 + ARISTA445T1: + vlans: + - 446 + vm_offset: 444 + ARISTA446T1: + vlans: + - 447 + vm_offset: 445 + ARISTA447T1: + vlans: + - 448 + vm_offset: 446 + ARISTA448T1: + vlans: + - 449 + vm_offset: 447 + ARISTA449T1: + vlans: + - 450 + vm_offset: 448 + ARISTA450T1: + vlans: + - 451 + vm_offset: 449 + ARISTA451T1: + vlans: + - 452 + vm_offset: 450 + ARISTA452T1: + vlans: + - 453 + vm_offset: 451 + ARISTA453T1: + vlans: + - 454 + vm_offset: 452 + ARISTA454T1: + vlans: + - 455 + vm_offset: 453 + ARISTA455T1: + vlans: + - 456 + vm_offset: 454 + ARISTA456T1: + vlans: + - 457 + vm_offset: 455 + ARISTA457T1: + vlans: + - 458 + vm_offset: 456 + ARISTA458T1: + vlans: + - 459 + vm_offset: 457 + ARISTA459T1: + vlans: + - 460 + vm_offset: 458 + ARISTA460T1: + vlans: + - 461 + vm_offset: 459 + ARISTA461T1: + vlans: + - 462 + vm_offset: 460 + ARISTA462T1: + vlans: + - 463 + vm_offset: 461 + ARISTA463T1: + vlans: + - 464 + vm_offset: 462 + ARISTA464T1: + vlans: + - 465 + vm_offset: 463 + ARISTA465T1: + vlans: + - 466 + vm_offset: 464 + ARISTA466T1: + vlans: + - 467 + vm_offset: 465 + ARISTA467T1: + vlans: + - 468 + vm_offset: 466 + ARISTA468T1: + vlans: + - 469 + vm_offset: 467 + ARISTA469T1: + vlans: + - 470 + vm_offset: 468 + ARISTA470T1: + vlans: + - 471 + vm_offset: 469 + ARISTA471T1: + vlans: + - 472 + vm_offset: 470 + ARISTA472T1: + vlans: + - 473 + vm_offset: 471 + ARISTA473T1: + vlans: + - 474 + vm_offset: 472 + ARISTA474T1: + vlans: + - 475 + vm_offset: 473 + ARISTA475T1: + vlans: + - 476 + vm_offset: 474 + ARISTA476T1: + vlans: + - 477 + vm_offset: 475 + ARISTA477T1: + vlans: + - 478 + vm_offset: 476 + ARISTA478T1: + vlans: + - 479 + vm_offset: 477 + ARISTA479T1: + vlans: + - 480 + vm_offset: 478 + ARISTA480T1: + vlans: + - 481 + vm_offset: 479 + ARISTA481T1: + vlans: + - 482 + vm_offset: 480 + ARISTA482T1: + vlans: + - 483 + vm_offset: 481 + ARISTA483T1: + vlans: + - 484 + vm_offset: 482 + ARISTA484T1: + vlans: + - 485 + vm_offset: 483 + ARISTA485T1: + vlans: + - 486 + vm_offset: 484 + ARISTA486T1: + vlans: + - 487 + vm_offset: 485 + ARISTA487T1: + vlans: + - 488 + vm_offset: 486 + ARISTA488T1: + vlans: + - 489 + vm_offset: 487 + ARISTA489T1: + vlans: + - 490 + vm_offset: 488 + ARISTA490T1: + vlans: + - 491 + vm_offset: 489 + ARISTA491T1: + vlans: + - 492 + vm_offset: 490 + ARISTA492T1: + vlans: + - 493 + vm_offset: 491 + ARISTA493T1: + vlans: + - 494 + vm_offset: 492 + ARISTA494T1: + vlans: + - 495 + vm_offset: 493 + ARISTA495T1: + vlans: + - 496 + vm_offset: 494 + ARISTA496T1: + vlans: + - 497 + vm_offset: 495 + ARISTA497T1: + vlans: + - 498 + vm_offset: 496 + ARISTA498T1: + vlans: + - 499 + vm_offset: 497 + ARISTA499T1: + vlans: + - 500 + vm_offset: 498 + ARISTA500T1: + vlans: + - 501 + vm_offset: 499 + ARISTA501T1: + vlans: + - 502 + vm_offset: 500 + ARISTA502T1: + vlans: + - 503 + vm_offset: 501 + ARISTA503T1: + vlans: + - 504 + vm_offset: 502 + ARISTA504T1: + vlans: + - 505 + vm_offset: 503 + ARISTA505T1: + vlans: + - 506 + vm_offset: 504 + ARISTA506T1: + vlans: + - 507 + vm_offset: 505 + ARISTA507T1: + vlans: + - 508 + vm_offset: 506 + ARISTA508T1: + vlans: + - 509 + vm_offset: 507 + ARISTA509T1: + vlans: + - 510 + vm_offset: 508 + ARISTA510T1: + vlans: + - 511 + vm_offset: 509 + DUT: + vlan_configs: + default_vlan_config: one_vlan_per_intf + one_vlan_per_intf: + Vlan1000: + id: 1000 + intfs: [0] + prefix_v6: fc00:c:c:0001::/64 + tag: 1000 + Vlan1001: + id: 1001 + intfs: [1] + prefix_v6: fc00:c:c:0002::/64 + tag: 1001 + +configuration_properties: + common: + dut_asn: 4200000000 + dut_type: ToRRouter + swrole: leaf + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + spine_asn: 4200200000 + leaf_asn_start: 4200100000 + tor_asn_start: 4200000000 + failure_rate: 0 + nhipv6: FC0A::FF + +configuration: + ARISTA01T1: + properties: + - common + bgp: + router-id: 0.12.0.3 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3::1/128 + Ethernet1: + ipv6: fc00:a::a/126 + bp_interface: + ipv6: fc00:b::3/64 + + ARISTA02T1: + properties: + - common + bgp: + router-id: 0.12.0.4 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d + interfaces: + Loopback0: + ipv6: fc00:c:c:4::1/128 + Ethernet1: + ipv6: fc00:a::e/126 + bp_interface: + ipv6: fc00:b::4/64 + + ARISTA03T1: + properties: + - common + bgp: + router-id: 0.12.0.5 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::11 + interfaces: + Loopback0: + ipv6: fc00:c:c:5::1/128 + Ethernet1: + ipv6: fc00:a::12/126 + bp_interface: + ipv6: fc00:b::5/64 + + ARISTA04T1: + properties: + - common + bgp: + router-id: 0.12.0.6 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::15 + interfaces: + Loopback0: + ipv6: fc00:c:c:6::1/128 + Ethernet1: + ipv6: fc00:a::16/126 + bp_interface: + ipv6: fc00:b::6/64 + + ARISTA05T1: + properties: + - common + bgp: + router-id: 0.12.0.7 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::19 + interfaces: + Loopback0: + ipv6: fc00:c:c:7::1/128 + Ethernet1: + ipv6: fc00:a::1a/126 + bp_interface: + ipv6: fc00:b::7/64 + + ARISTA06T1: + properties: + - common + bgp: + router-id: 0.12.0.8 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d + interfaces: + Loopback0: + ipv6: fc00:c:c:8::1/128 + Ethernet1: + ipv6: fc00:a::1e/126 + bp_interface: + ipv6: fc00:b::8/64 + + ARISTA07T1: + properties: + - common + bgp: + router-id: 0.12.0.9 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::21 + interfaces: + Loopback0: + ipv6: fc00:c:c:9::1/128 + Ethernet1: + ipv6: fc00:a::22/126 + bp_interface: + ipv6: fc00:b::9/64 + + ARISTA08T1: + properties: + - common + bgp: + router-id: 0.12.0.10 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::25 + interfaces: + Loopback0: + ipv6: fc00:c:c:a::1/128 + Ethernet1: + ipv6: fc00:a::26/126 + bp_interface: + ipv6: fc00:b::a/64 + + ARISTA09T1: + properties: + - common + bgp: + router-id: 0.12.0.11 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::29 + interfaces: + Loopback0: + ipv6: fc00:c:c:b::1/128 + Ethernet1: + ipv6: fc00:a::2a/126 + bp_interface: + ipv6: fc00:b::b/64 + + ARISTA10T1: + properties: + - common + bgp: + router-id: 0.12.0.12 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d + interfaces: + Loopback0: + ipv6: fc00:c:c:c::1/128 + Ethernet1: + ipv6: fc00:a::2e/126 + bp_interface: + ipv6: fc00:b::c/64 + + ARISTA11T1: + properties: + - common + bgp: + router-id: 0.12.0.13 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::31 + interfaces: + Loopback0: + ipv6: fc00:c:c:d::1/128 + Ethernet1: + ipv6: fc00:a::32/126 + bp_interface: + ipv6: fc00:b::d/64 + + ARISTA12T1: + properties: + - common + bgp: + router-id: 0.12.0.14 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::35 + interfaces: + Loopback0: + ipv6: fc00:c:c:e::1/128 + Ethernet1: + ipv6: fc00:a::36/126 + bp_interface: + ipv6: fc00:b::e/64 + + ARISTA13T1: + properties: + - common + bgp: + router-id: 0.12.0.15 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::39 + interfaces: + Loopback0: + ipv6: fc00:c:c:f::1/128 + Ethernet1: + ipv6: fc00:a::3a/126 + bp_interface: + ipv6: fc00:b::f/64 + + ARISTA14T1: + properties: + - common + bgp: + router-id: 0.12.0.16 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d + interfaces: + Loopback0: + ipv6: fc00:c:c:10::1/128 + Ethernet1: + ipv6: fc00:a::3e/126 + bp_interface: + ipv6: fc00:b::10/64 + + ARISTA15T1: + properties: + - common + bgp: + router-id: 0.12.0.17 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::41 + interfaces: + Loopback0: + ipv6: fc00:c:c:11::1/128 + Ethernet1: + ipv6: fc00:a::42/126 + bp_interface: + ipv6: fc00:b::11/64 + + ARISTA16T1: + properties: + - common + bgp: + router-id: 0.12.0.18 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::45 + interfaces: + Loopback0: + ipv6: fc00:c:c:12::1/128 + Ethernet1: + ipv6: fc00:a::46/126 + bp_interface: + ipv6: fc00:b::12/64 + + ARISTA17T1: + properties: + - common + bgp: + router-id: 0.12.0.19 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::49 + interfaces: + Loopback0: + ipv6: fc00:c:c:13::1/128 + Ethernet1: + ipv6: fc00:a::4a/126 + bp_interface: + ipv6: fc00:b::13/64 + + ARISTA18T1: + properties: + - common + bgp: + router-id: 0.12.0.20 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4d + interfaces: + Loopback0: + ipv6: fc00:c:c:14::1/128 + Ethernet1: + ipv6: fc00:a::4e/126 + bp_interface: + ipv6: fc00:b::14/64 + + ARISTA19T1: + properties: + - common + bgp: + router-id: 0.12.0.21 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::51 + interfaces: + Loopback0: + ipv6: fc00:c:c:15::1/128 + Ethernet1: + ipv6: fc00:a::52/126 + bp_interface: + ipv6: fc00:b::15/64 + + ARISTA20T1: + properties: + - common + bgp: + router-id: 0.12.0.22 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::55 + interfaces: + Loopback0: + ipv6: fc00:c:c:16::1/128 + Ethernet1: + ipv6: fc00:a::56/126 + bp_interface: + ipv6: fc00:b::16/64 + + ARISTA21T1: + properties: + - common + bgp: + router-id: 0.12.0.23 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::59 + interfaces: + Loopback0: + ipv6: fc00:c:c:17::1/128 + Ethernet1: + ipv6: fc00:a::5a/126 + bp_interface: + ipv6: fc00:b::17/64 + + ARISTA22T1: + properties: + - common + bgp: + router-id: 0.12.0.24 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5d + interfaces: + Loopback0: + ipv6: fc00:c:c:18::1/128 + Ethernet1: + ipv6: fc00:a::5e/126 + bp_interface: + ipv6: fc00:b::18/64 + + ARISTA23T1: + properties: + - common + bgp: + router-id: 0.12.0.25 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::61 + interfaces: + Loopback0: + ipv6: fc00:c:c:19::1/128 + Ethernet1: + ipv6: fc00:a::62/126 + bp_interface: + ipv6: fc00:b::19/64 + + ARISTA24T1: + properties: + - common + bgp: + router-id: 0.12.0.26 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::65 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a::1/128 + Ethernet1: + ipv6: fc00:a::66/126 + bp_interface: + ipv6: fc00:b::1a/64 + + ARISTA25T1: + properties: + - common + bgp: + router-id: 0.12.0.27 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::69 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b::1/128 + Ethernet1: + ipv6: fc00:a::6a/126 + bp_interface: + ipv6: fc00:b::1b/64 + + ARISTA26T1: + properties: + - common + bgp: + router-id: 0.12.0.28 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c::1/128 + Ethernet1: + ipv6: fc00:a::6e/126 + bp_interface: + ipv6: fc00:b::1c/64 + + ARISTA27T1: + properties: + - common + bgp: + router-id: 0.12.0.29 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::71 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d::1/128 + Ethernet1: + ipv6: fc00:a::72/126 + bp_interface: + ipv6: fc00:b::1d/64 + + ARISTA28T1: + properties: + - common + bgp: + router-id: 0.12.0.30 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::75 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e::1/128 + Ethernet1: + ipv6: fc00:a::76/126 + bp_interface: + ipv6: fc00:b::1e/64 + + ARISTA29T1: + properties: + - common + bgp: + router-id: 0.12.0.31 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::79 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f::1/128 + Ethernet1: + ipv6: fc00:a::7a/126 + bp_interface: + ipv6: fc00:b::1f/64 + + ARISTA30T1: + properties: + - common + bgp: + router-id: 0.12.0.32 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7d + interfaces: + Loopback0: + ipv6: fc00:c:c:20::1/128 + Ethernet1: + ipv6: fc00:a::7e/126 + bp_interface: + ipv6: fc00:b::20/64 + + ARISTA31T1: + properties: + - common + bgp: + router-id: 0.12.0.33 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::81 + interfaces: + Loopback0: + ipv6: fc00:c:c:21::1/128 + Ethernet1: + ipv6: fc00:a::82/126 + bp_interface: + ipv6: fc00:b::21/64 + + ARISTA32T1: + properties: + - common + bgp: + router-id: 0.12.0.34 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::85 + interfaces: + Loopback0: + ipv6: fc00:c:c:22::1/128 + Ethernet1: + ipv6: fc00:a::86/126 + bp_interface: + ipv6: fc00:b::22/64 + + ARISTA33T1: + properties: + - common + bgp: + router-id: 0.12.0.35 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::89 + interfaces: + Loopback0: + ipv6: fc00:c:c:23::1/128 + Ethernet1: + ipv6: fc00:a::8a/126 + bp_interface: + ipv6: fc00:b::23/64 + + ARISTA34T1: + properties: + - common + bgp: + router-id: 0.12.0.36 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::8d + interfaces: + Loopback0: + ipv6: fc00:c:c:24::1/128 + Ethernet1: + ipv6: fc00:a::8e/126 + bp_interface: + ipv6: fc00:b::24/64 + + ARISTA35T1: + properties: + - common + bgp: + router-id: 0.12.0.37 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::91 + interfaces: + Loopback0: + ipv6: fc00:c:c:25::1/128 + Ethernet1: + ipv6: fc00:a::92/126 + bp_interface: + ipv6: fc00:b::25/64 + + ARISTA36T1: + properties: + - common + bgp: + router-id: 0.12.0.38 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::95 + interfaces: + Loopback0: + ipv6: fc00:c:c:26::1/128 + Ethernet1: + ipv6: fc00:a::96/126 + bp_interface: + ipv6: fc00:b::26/64 + + ARISTA37T1: + properties: + - common + bgp: + router-id: 0.12.0.39 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::99 + interfaces: + Loopback0: + ipv6: fc00:c:c:27::1/128 + Ethernet1: + ipv6: fc00:a::9a/126 + bp_interface: + ipv6: fc00:b::27/64 + + ARISTA38T1: + properties: + - common + bgp: + router-id: 0.12.0.40 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::9d + interfaces: + Loopback0: + ipv6: fc00:c:c:28::1/128 + Ethernet1: + ipv6: fc00:a::9e/126 + bp_interface: + ipv6: fc00:b::28/64 + + ARISTA39T1: + properties: + - common + bgp: + router-id: 0.12.0.41 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:29::1/128 + Ethernet1: + ipv6: fc00:a::a2/126 + bp_interface: + ipv6: fc00:b::29/64 + + ARISTA40T1: + properties: + - common + bgp: + router-id: 0.12.0.42 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2a::1/128 + Ethernet1: + ipv6: fc00:a::a6/126 + bp_interface: + ipv6: fc00:b::2a/64 + + ARISTA41T1: + properties: + - common + bgp: + router-id: 0.12.0.43 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2b::1/128 + Ethernet1: + ipv6: fc00:a::aa/126 + bp_interface: + ipv6: fc00:b::2b/64 + + ARISTA42T1: + properties: + - common + bgp: + router-id: 0.12.0.44 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::ad + interfaces: + Loopback0: + ipv6: fc00:c:c:2c::1/128 + Ethernet1: + ipv6: fc00:a::ae/126 + bp_interface: + ipv6: fc00:b::2c/64 + + ARISTA43T1: + properties: + - common + bgp: + router-id: 0.12.0.45 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:2d::1/128 + Ethernet1: + ipv6: fc00:a::b2/126 + bp_interface: + ipv6: fc00:b::2d/64 + + ARISTA44T1: + properties: + - common + bgp: + router-id: 0.12.0.46 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2e::1/128 + Ethernet1: + ipv6: fc00:a::b6/126 + bp_interface: + ipv6: fc00:b::2e/64 + + ARISTA45T1: + properties: + - common + bgp: + router-id: 0.12.0.47 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2f::1/128 + Ethernet1: + ipv6: fc00:a::ba/126 + bp_interface: + ipv6: fc00:b::2f/64 + + ARISTA46T1: + properties: + - common + bgp: + router-id: 0.12.0.48 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::bd + interfaces: + Loopback0: + ipv6: fc00:c:c:30::1/128 + Ethernet1: + ipv6: fc00:a::be/126 + bp_interface: + ipv6: fc00:b::30/64 + + ARISTA47T1: + properties: + - common + bgp: + router-id: 0.12.0.49 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:31::1/128 + Ethernet1: + ipv6: fc00:a::c2/126 + bp_interface: + ipv6: fc00:b::31/64 + + ARISTA48T1: + properties: + - common + bgp: + router-id: 0.12.0.50 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:32::1/128 + Ethernet1: + ipv6: fc00:a::c6/126 + bp_interface: + ipv6: fc00:b::32/64 + + ARISTA49T1: + properties: + - common + bgp: + router-id: 0.12.0.51 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:33::1/128 + Ethernet1: + ipv6: fc00:a::ca/126 + bp_interface: + ipv6: fc00:b::33/64 + + ARISTA50T1: + properties: + - common + bgp: + router-id: 0.12.0.52 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::cd + interfaces: + Loopback0: + ipv6: fc00:c:c:34::1/128 + Ethernet1: + ipv6: fc00:a::ce/126 + bp_interface: + ipv6: fc00:b::34/64 + + ARISTA51T1: + properties: + - common + bgp: + router-id: 0.12.0.53 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:35::1/128 + Ethernet1: + ipv6: fc00:a::d2/126 + bp_interface: + ipv6: fc00:b::35/64 + + ARISTA52T1: + properties: + - common + bgp: + router-id: 0.12.0.54 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:36::1/128 + Ethernet1: + ipv6: fc00:a::d6/126 + bp_interface: + ipv6: fc00:b::36/64 + + ARISTA53T1: + properties: + - common + bgp: + router-id: 0.12.0.55 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:37::1/128 + Ethernet1: + ipv6: fc00:a::da/126 + bp_interface: + ipv6: fc00:b::37/64 + + ARISTA54T1: + properties: + - common + bgp: + router-id: 0.12.0.56 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::dd + interfaces: + Loopback0: + ipv6: fc00:c:c:38::1/128 + Ethernet1: + ipv6: fc00:a::de/126 + bp_interface: + ipv6: fc00:b::38/64 + + ARISTA55T1: + properties: + - common + bgp: + router-id: 0.12.0.57 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:39::1/128 + Ethernet1: + ipv6: fc00:a::e2/126 + bp_interface: + ipv6: fc00:b::39/64 + + ARISTA56T1: + properties: + - common + bgp: + router-id: 0.12.0.58 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3a::1/128 + Ethernet1: + ipv6: fc00:a::e6/126 + bp_interface: + ipv6: fc00:b::3a/64 + + ARISTA57T1: + properties: + - common + bgp: + router-id: 0.12.0.59 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3b::1/128 + Ethernet1: + ipv6: fc00:a::ea/126 + bp_interface: + ipv6: fc00:b::3b/64 + + ARISTA58T1: + properties: + - common + bgp: + router-id: 0.12.0.60 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::ed + interfaces: + Loopback0: + ipv6: fc00:c:c:3c::1/128 + Ethernet1: + ipv6: fc00:a::ee/126 + bp_interface: + ipv6: fc00:b::3c/64 + + ARISTA59T1: + properties: + - common + bgp: + router-id: 0.12.0.61 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:3d::1/128 + Ethernet1: + ipv6: fc00:a::f2/126 + bp_interface: + ipv6: fc00:b::3d/64 + + ARISTA60T1: + properties: + - common + bgp: + router-id: 0.12.0.62 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3e::1/128 + Ethernet1: + ipv6: fc00:a::f6/126 + bp_interface: + ipv6: fc00:b::3e/64 + + ARISTA61T1: + properties: + - common + bgp: + router-id: 0.12.0.63 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3f::1/128 + Ethernet1: + ipv6: fc00:a::fa/126 + bp_interface: + ipv6: fc00:b::3f/64 + + ARISTA62T1: + properties: + - common + bgp: + router-id: 0.12.0.64 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::fd + interfaces: + Loopback0: + ipv6: fc00:c:c:40::1/128 + Ethernet1: + ipv6: fc00:a::fe/126 + bp_interface: + ipv6: fc00:b::40/64 + + ARISTA63T1: + properties: + - common + bgp: + router-id: 0.12.0.65 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::101 + interfaces: + Loopback0: + ipv6: fc00:c:c:41::1/128 + Ethernet1: + ipv6: fc00:a::102/126 + bp_interface: + ipv6: fc00:b::41/64 + + ARISTA64T1: + properties: + - common + bgp: + router-id: 0.12.0.66 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::105 + interfaces: + Loopback0: + ipv6: fc00:c:c:42::1/128 + Ethernet1: + ipv6: fc00:a::106/126 + bp_interface: + ipv6: fc00:b::42/64 + + ARISTA65T1: + properties: + - common + bgp: + router-id: 0.12.0.67 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::109 + interfaces: + Loopback0: + ipv6: fc00:c:c:43::1/128 + Ethernet1: + ipv6: fc00:a::10a/126 + bp_interface: + ipv6: fc00:b::43/64 + + ARISTA66T1: + properties: + - common + bgp: + router-id: 0.12.0.68 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::10d + interfaces: + Loopback0: + ipv6: fc00:c:c:44::1/128 + Ethernet1: + ipv6: fc00:a::10e/126 + bp_interface: + ipv6: fc00:b::44/64 + + ARISTA67T1: + properties: + - common + bgp: + router-id: 0.12.0.69 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::111 + interfaces: + Loopback0: + ipv6: fc00:c:c:45::1/128 + Ethernet1: + ipv6: fc00:a::112/126 + bp_interface: + ipv6: fc00:b::45/64 + + ARISTA68T1: + properties: + - common + bgp: + router-id: 0.12.0.70 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::115 + interfaces: + Loopback0: + ipv6: fc00:c:c:46::1/128 + Ethernet1: + ipv6: fc00:a::116/126 + bp_interface: + ipv6: fc00:b::46/64 + + ARISTA69T1: + properties: + - common + bgp: + router-id: 0.12.0.71 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::119 + interfaces: + Loopback0: + ipv6: fc00:c:c:47::1/128 + Ethernet1: + ipv6: fc00:a::11a/126 + bp_interface: + ipv6: fc00:b::47/64 + + ARISTA70T1: + properties: + - common + bgp: + router-id: 0.12.0.72 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::11d + interfaces: + Loopback0: + ipv6: fc00:c:c:48::1/128 + Ethernet1: + ipv6: fc00:a::11e/126 + bp_interface: + ipv6: fc00:b::48/64 + + ARISTA71T1: + properties: + - common + bgp: + router-id: 0.12.0.73 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::121 + interfaces: + Loopback0: + ipv6: fc00:c:c:49::1/128 + Ethernet1: + ipv6: fc00:a::122/126 + bp_interface: + ipv6: fc00:b::49/64 + + ARISTA72T1: + properties: + - common + bgp: + router-id: 0.12.0.74 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::125 + interfaces: + Loopback0: + ipv6: fc00:c:c:4a::1/128 + Ethernet1: + ipv6: fc00:a::126/126 + bp_interface: + ipv6: fc00:b::4a/64 + + ARISTA73T1: + properties: + - common + bgp: + router-id: 0.12.0.75 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::129 + interfaces: + Loopback0: + ipv6: fc00:c:c:4b::1/128 + Ethernet1: + ipv6: fc00:a::12a/126 + bp_interface: + ipv6: fc00:b::4b/64 + + ARISTA74T1: + properties: + - common + bgp: + router-id: 0.12.0.76 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::12d + interfaces: + Loopback0: + ipv6: fc00:c:c:4c::1/128 + Ethernet1: + ipv6: fc00:a::12e/126 + bp_interface: + ipv6: fc00:b::4c/64 + + ARISTA75T1: + properties: + - common + bgp: + router-id: 0.12.0.77 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::131 + interfaces: + Loopback0: + ipv6: fc00:c:c:4d::1/128 + Ethernet1: + ipv6: fc00:a::132/126 + bp_interface: + ipv6: fc00:b::4d/64 + + ARISTA76T1: + properties: + - common + bgp: + router-id: 0.12.0.78 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::135 + interfaces: + Loopback0: + ipv6: fc00:c:c:4e::1/128 + Ethernet1: + ipv6: fc00:a::136/126 + bp_interface: + ipv6: fc00:b::4e/64 + + ARISTA77T1: + properties: + - common + bgp: + router-id: 0.12.0.79 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::139 + interfaces: + Loopback0: + ipv6: fc00:c:c:4f::1/128 + Ethernet1: + ipv6: fc00:a::13a/126 + bp_interface: + ipv6: fc00:b::4f/64 + + ARISTA78T1: + properties: + - common + bgp: + router-id: 0.12.0.80 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::13d + interfaces: + Loopback0: + ipv6: fc00:c:c:50::1/128 + Ethernet1: + ipv6: fc00:a::13e/126 + bp_interface: + ipv6: fc00:b::50/64 + + ARISTA79T1: + properties: + - common + bgp: + router-id: 0.12.0.81 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::141 + interfaces: + Loopback0: + ipv6: fc00:c:c:51::1/128 + Ethernet1: + ipv6: fc00:a::142/126 + bp_interface: + ipv6: fc00:b::51/64 + + ARISTA80T1: + properties: + - common + bgp: + router-id: 0.12.0.82 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::145 + interfaces: + Loopback0: + ipv6: fc00:c:c:52::1/128 + Ethernet1: + ipv6: fc00:a::146/126 + bp_interface: + ipv6: fc00:b::52/64 + + ARISTA81T1: + properties: + - common + bgp: + router-id: 0.12.0.83 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::149 + interfaces: + Loopback0: + ipv6: fc00:c:c:53::1/128 + Ethernet1: + ipv6: fc00:a::14a/126 + bp_interface: + ipv6: fc00:b::53/64 + + ARISTA82T1: + properties: + - common + bgp: + router-id: 0.12.0.84 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::14d + interfaces: + Loopback0: + ipv6: fc00:c:c:54::1/128 + Ethernet1: + ipv6: fc00:a::14e/126 + bp_interface: + ipv6: fc00:b::54/64 + + ARISTA83T1: + properties: + - common + bgp: + router-id: 0.12.0.85 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::151 + interfaces: + Loopback0: + ipv6: fc00:c:c:55::1/128 + Ethernet1: + ipv6: fc00:a::152/126 + bp_interface: + ipv6: fc00:b::55/64 + + ARISTA84T1: + properties: + - common + bgp: + router-id: 0.12.0.86 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::155 + interfaces: + Loopback0: + ipv6: fc00:c:c:56::1/128 + Ethernet1: + ipv6: fc00:a::156/126 + bp_interface: + ipv6: fc00:b::56/64 + + ARISTA85T1: + properties: + - common + bgp: + router-id: 0.12.0.87 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::159 + interfaces: + Loopback0: + ipv6: fc00:c:c:57::1/128 + Ethernet1: + ipv6: fc00:a::15a/126 + bp_interface: + ipv6: fc00:b::57/64 + + ARISTA86T1: + properties: + - common + bgp: + router-id: 0.12.0.88 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::15d + interfaces: + Loopback0: + ipv6: fc00:c:c:58::1/128 + Ethernet1: + ipv6: fc00:a::15e/126 + bp_interface: + ipv6: fc00:b::58/64 + + ARISTA87T1: + properties: + - common + bgp: + router-id: 0.12.0.89 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::161 + interfaces: + Loopback0: + ipv6: fc00:c:c:59::1/128 + Ethernet1: + ipv6: fc00:a::162/126 + bp_interface: + ipv6: fc00:b::59/64 + + ARISTA88T1: + properties: + - common + bgp: + router-id: 0.12.0.90 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::165 + interfaces: + Loopback0: + ipv6: fc00:c:c:5a::1/128 + Ethernet1: + ipv6: fc00:a::166/126 + bp_interface: + ipv6: fc00:b::5a/64 + + ARISTA89T1: + properties: + - common + bgp: + router-id: 0.12.0.91 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::169 + interfaces: + Loopback0: + ipv6: fc00:c:c:5b::1/128 + Ethernet1: + ipv6: fc00:a::16a/126 + bp_interface: + ipv6: fc00:b::5b/64 + + ARISTA90T1: + properties: + - common + bgp: + router-id: 0.12.0.92 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::16d + interfaces: + Loopback0: + ipv6: fc00:c:c:5c::1/128 + Ethernet1: + ipv6: fc00:a::16e/126 + bp_interface: + ipv6: fc00:b::5c/64 + + ARISTA91T1: + properties: + - common + bgp: + router-id: 0.12.0.93 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::171 + interfaces: + Loopback0: + ipv6: fc00:c:c:5d::1/128 + Ethernet1: + ipv6: fc00:a::172/126 + bp_interface: + ipv6: fc00:b::5d/64 + + ARISTA92T1: + properties: + - common + bgp: + router-id: 0.12.0.94 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::175 + interfaces: + Loopback0: + ipv6: fc00:c:c:5e::1/128 + Ethernet1: + ipv6: fc00:a::176/126 + bp_interface: + ipv6: fc00:b::5e/64 + + ARISTA93T1: + properties: + - common + bgp: + router-id: 0.12.0.95 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::179 + interfaces: + Loopback0: + ipv6: fc00:c:c:5f::1/128 + Ethernet1: + ipv6: fc00:a::17a/126 + bp_interface: + ipv6: fc00:b::5f/64 + + ARISTA94T1: + properties: + - common + bgp: + router-id: 0.12.0.96 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::17d + interfaces: + Loopback0: + ipv6: fc00:c:c:60::1/128 + Ethernet1: + ipv6: fc00:a::17e/126 + bp_interface: + ipv6: fc00:b::60/64 + + ARISTA95T1: + properties: + - common + bgp: + router-id: 0.12.0.97 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::181 + interfaces: + Loopback0: + ipv6: fc00:c:c:61::1/128 + Ethernet1: + ipv6: fc00:a::182/126 + bp_interface: + ipv6: fc00:b::61/64 + + ARISTA96T1: + properties: + - common + bgp: + router-id: 0.12.0.98 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::185 + interfaces: + Loopback0: + ipv6: fc00:c:c:62::1/128 + Ethernet1: + ipv6: fc00:a::186/126 + bp_interface: + ipv6: fc00:b::62/64 + + ARISTA97T1: + properties: + - common + bgp: + router-id: 0.12.0.99 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::189 + interfaces: + Loopback0: + ipv6: fc00:c:c:63::1/128 + Ethernet1: + ipv6: fc00:a::18a/126 + bp_interface: + ipv6: fc00:b::63/64 + + ARISTA98T1: + properties: + - common + bgp: + router-id: 0.12.0.100 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::18d + interfaces: + Loopback0: + ipv6: fc00:c:c:64::1/128 + Ethernet1: + ipv6: fc00:a::18e/126 + bp_interface: + ipv6: fc00:b::64/64 + + ARISTA99T1: + properties: + - common + bgp: + router-id: 0.12.0.101 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::191 + interfaces: + Loopback0: + ipv6: fc00:c:c:65::1/128 + Ethernet1: + ipv6: fc00:a::192/126 + bp_interface: + ipv6: fc00:b::65/64 + + ARISTA100T1: + properties: + - common + bgp: + router-id: 0.12.0.102 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::195 + interfaces: + Loopback0: + ipv6: fc00:c:c:66::1/128 + Ethernet1: + ipv6: fc00:a::196/126 + bp_interface: + ipv6: fc00:b::66/64 + + ARISTA101T1: + properties: + - common + bgp: + router-id: 0.12.0.103 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::199 + interfaces: + Loopback0: + ipv6: fc00:c:c:67::1/128 + Ethernet1: + ipv6: fc00:a::19a/126 + bp_interface: + ipv6: fc00:b::67/64 + + ARISTA102T1: + properties: + - common + bgp: + router-id: 0.12.0.104 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::19d + interfaces: + Loopback0: + ipv6: fc00:c:c:68::1/128 + Ethernet1: + ipv6: fc00:a::19e/126 + bp_interface: + ipv6: fc00:b::68/64 + + ARISTA103T1: + properties: + - common + bgp: + router-id: 0.12.0.105 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:69::1/128 + Ethernet1: + ipv6: fc00:a::1a2/126 + bp_interface: + ipv6: fc00:b::69/64 + + ARISTA104T1: + properties: + - common + bgp: + router-id: 0.12.0.106 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6a::1/128 + Ethernet1: + ipv6: fc00:a::1a6/126 + bp_interface: + ipv6: fc00:b::6a/64 + + ARISTA105T1: + properties: + - common + bgp: + router-id: 0.12.0.107 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6b::1/128 + Ethernet1: + ipv6: fc00:a::1aa/126 + bp_interface: + ipv6: fc00:b::6b/64 + + ARISTA106T1: + properties: + - common + bgp: + router-id: 0.12.0.108 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1ad + interfaces: + Loopback0: + ipv6: fc00:c:c:6c::1/128 + Ethernet1: + ipv6: fc00:a::1ae/126 + bp_interface: + ipv6: fc00:b::6c/64 + + ARISTA107T1: + properties: + - common + bgp: + router-id: 0.12.0.109 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:6d::1/128 + Ethernet1: + ipv6: fc00:a::1b2/126 + bp_interface: + ipv6: fc00:b::6d/64 + + ARISTA108T1: + properties: + - common + bgp: + router-id: 0.12.0.110 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6e::1/128 + Ethernet1: + ipv6: fc00:a::1b6/126 + bp_interface: + ipv6: fc00:b::6e/64 + + ARISTA109T1: + properties: + - common + bgp: + router-id: 0.12.0.111 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6f::1/128 + Ethernet1: + ipv6: fc00:a::1ba/126 + bp_interface: + ipv6: fc00:b::6f/64 + + ARISTA110T1: + properties: + - common + bgp: + router-id: 0.12.0.112 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1bd + interfaces: + Loopback0: + ipv6: fc00:c:c:70::1/128 + Ethernet1: + ipv6: fc00:a::1be/126 + bp_interface: + ipv6: fc00:b::70/64 + + ARISTA111T1: + properties: + - common + bgp: + router-id: 0.12.0.113 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:71::1/128 + Ethernet1: + ipv6: fc00:a::1c2/126 + bp_interface: + ipv6: fc00:b::71/64 + + ARISTA112T1: + properties: + - common + bgp: + router-id: 0.12.0.114 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:72::1/128 + Ethernet1: + ipv6: fc00:a::1c6/126 + bp_interface: + ipv6: fc00:b::72/64 + + ARISTA113T1: + properties: + - common + bgp: + router-id: 0.12.0.115 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:73::1/128 + Ethernet1: + ipv6: fc00:a::1ca/126 + bp_interface: + ipv6: fc00:b::73/64 + + ARISTA114T1: + properties: + - common + bgp: + router-id: 0.12.0.116 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1cd + interfaces: + Loopback0: + ipv6: fc00:c:c:74::1/128 + Ethernet1: + ipv6: fc00:a::1ce/126 + bp_interface: + ipv6: fc00:b::74/64 + + ARISTA115T1: + properties: + - common + bgp: + router-id: 0.12.0.117 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:75::1/128 + Ethernet1: + ipv6: fc00:a::1d2/126 + bp_interface: + ipv6: fc00:b::75/64 + + ARISTA116T1: + properties: + - common + bgp: + router-id: 0.12.0.118 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:76::1/128 + Ethernet1: + ipv6: fc00:a::1d6/126 + bp_interface: + ipv6: fc00:b::76/64 + + ARISTA117T1: + properties: + - common + bgp: + router-id: 0.12.0.119 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:77::1/128 + Ethernet1: + ipv6: fc00:a::1da/126 + bp_interface: + ipv6: fc00:b::77/64 + + ARISTA118T1: + properties: + - common + bgp: + router-id: 0.12.0.120 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1dd + interfaces: + Loopback0: + ipv6: fc00:c:c:78::1/128 + Ethernet1: + ipv6: fc00:a::1de/126 + bp_interface: + ipv6: fc00:b::78/64 + + ARISTA119T1: + properties: + - common + bgp: + router-id: 0.12.0.121 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:79::1/128 + Ethernet1: + ipv6: fc00:a::1e2/126 + bp_interface: + ipv6: fc00:b::79/64 + + ARISTA120T1: + properties: + - common + bgp: + router-id: 0.12.0.122 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7a::1/128 + Ethernet1: + ipv6: fc00:a::1e6/126 + bp_interface: + ipv6: fc00:b::7a/64 + + ARISTA121T1: + properties: + - common + bgp: + router-id: 0.12.0.123 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7b::1/128 + Ethernet1: + ipv6: fc00:a::1ea/126 + bp_interface: + ipv6: fc00:b::7b/64 + + ARISTA122T1: + properties: + - common + bgp: + router-id: 0.12.0.124 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1ed + interfaces: + Loopback0: + ipv6: fc00:c:c:7c::1/128 + Ethernet1: + ipv6: fc00:a::1ee/126 + bp_interface: + ipv6: fc00:b::7c/64 + + ARISTA123T1: + properties: + - common + bgp: + router-id: 0.12.0.125 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:7d::1/128 + Ethernet1: + ipv6: fc00:a::1f2/126 + bp_interface: + ipv6: fc00:b::7d/64 + + ARISTA124T1: + properties: + - common + bgp: + router-id: 0.12.0.126 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7e::1/128 + Ethernet1: + ipv6: fc00:a::1f6/126 + bp_interface: + ipv6: fc00:b::7e/64 + + ARISTA125T1: + properties: + - common + bgp: + router-id: 0.12.0.127 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7f::1/128 + Ethernet1: + ipv6: fc00:a::1fa/126 + bp_interface: + ipv6: fc00:b::7f/64 + + ARISTA126T1: + properties: + - common + bgp: + router-id: 0.12.0.128 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::1fd + interfaces: + Loopback0: + ipv6: fc00:c:c:80::1/128 + Ethernet1: + ipv6: fc00:a::1fe/126 + bp_interface: + ipv6: fc00:b::80/64 + + ARISTA127T1: + properties: + - common + bgp: + router-id: 0.12.0.129 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::201 + interfaces: + Loopback0: + ipv6: fc00:c:c:81::1/128 + Ethernet1: + ipv6: fc00:a::202/126 + bp_interface: + ipv6: fc00:b::81/64 + + ARISTA128T1: + properties: + - common + bgp: + router-id: 0.12.0.130 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::205 + interfaces: + Loopback0: + ipv6: fc00:c:c:82::1/128 + Ethernet1: + ipv6: fc00:a::206/126 + bp_interface: + ipv6: fc00:b::82/64 + + ARISTA129T1: + properties: + - common + bgp: + router-id: 0.12.0.131 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::209 + interfaces: + Loopback0: + ipv6: fc00:c:c:83::1/128 + Ethernet1: + ipv6: fc00:a::20a/126 + bp_interface: + ipv6: fc00:b::83/64 + + ARISTA130T1: + properties: + - common + bgp: + router-id: 0.12.0.132 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::20d + interfaces: + Loopback0: + ipv6: fc00:c:c:84::1/128 + Ethernet1: + ipv6: fc00:a::20e/126 + bp_interface: + ipv6: fc00:b::84/64 + + ARISTA131T1: + properties: + - common + bgp: + router-id: 0.12.0.133 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::211 + interfaces: + Loopback0: + ipv6: fc00:c:c:85::1/128 + Ethernet1: + ipv6: fc00:a::212/126 + bp_interface: + ipv6: fc00:b::85/64 + + ARISTA132T1: + properties: + - common + bgp: + router-id: 0.12.0.134 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::215 + interfaces: + Loopback0: + ipv6: fc00:c:c:86::1/128 + Ethernet1: + ipv6: fc00:a::216/126 + bp_interface: + ipv6: fc00:b::86/64 + + ARISTA133T1: + properties: + - common + bgp: + router-id: 0.12.0.135 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::219 + interfaces: + Loopback0: + ipv6: fc00:c:c:87::1/128 + Ethernet1: + ipv6: fc00:a::21a/126 + bp_interface: + ipv6: fc00:b::87/64 + + ARISTA134T1: + properties: + - common + bgp: + router-id: 0.12.0.136 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::21d + interfaces: + Loopback0: + ipv6: fc00:c:c:88::1/128 + Ethernet1: + ipv6: fc00:a::21e/126 + bp_interface: + ipv6: fc00:b::88/64 + + ARISTA135T1: + properties: + - common + bgp: + router-id: 0.12.0.137 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::221 + interfaces: + Loopback0: + ipv6: fc00:c:c:89::1/128 + Ethernet1: + ipv6: fc00:a::222/126 + bp_interface: + ipv6: fc00:b::89/64 + + ARISTA136T1: + properties: + - common + bgp: + router-id: 0.12.0.138 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::225 + interfaces: + Loopback0: + ipv6: fc00:c:c:8a::1/128 + Ethernet1: + ipv6: fc00:a::226/126 + bp_interface: + ipv6: fc00:b::8a/64 + + ARISTA137T1: + properties: + - common + bgp: + router-id: 0.12.0.139 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::229 + interfaces: + Loopback0: + ipv6: fc00:c:c:8b::1/128 + Ethernet1: + ipv6: fc00:a::22a/126 + bp_interface: + ipv6: fc00:b::8b/64 + + ARISTA138T1: + properties: + - common + bgp: + router-id: 0.12.0.140 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::22d + interfaces: + Loopback0: + ipv6: fc00:c:c:8c::1/128 + Ethernet1: + ipv6: fc00:a::22e/126 + bp_interface: + ipv6: fc00:b::8c/64 + + ARISTA139T1: + properties: + - common + bgp: + router-id: 0.12.0.141 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::231 + interfaces: + Loopback0: + ipv6: fc00:c:c:8d::1/128 + Ethernet1: + ipv6: fc00:a::232/126 + bp_interface: + ipv6: fc00:b::8d/64 + + ARISTA140T1: + properties: + - common + bgp: + router-id: 0.12.0.142 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::235 + interfaces: + Loopback0: + ipv6: fc00:c:c:8e::1/128 + Ethernet1: + ipv6: fc00:a::236/126 + bp_interface: + ipv6: fc00:b::8e/64 + + ARISTA141T1: + properties: + - common + bgp: + router-id: 0.12.0.143 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::239 + interfaces: + Loopback0: + ipv6: fc00:c:c:8f::1/128 + Ethernet1: + ipv6: fc00:a::23a/126 + bp_interface: + ipv6: fc00:b::8f/64 + + ARISTA142T1: + properties: + - common + bgp: + router-id: 0.12.0.144 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::23d + interfaces: + Loopback0: + ipv6: fc00:c:c:90::1/128 + Ethernet1: + ipv6: fc00:a::23e/126 + bp_interface: + ipv6: fc00:b::90/64 + + ARISTA143T1: + properties: + - common + bgp: + router-id: 0.12.0.145 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::241 + interfaces: + Loopback0: + ipv6: fc00:c:c:91::1/128 + Ethernet1: + ipv6: fc00:a::242/126 + bp_interface: + ipv6: fc00:b::91/64 + + ARISTA144T1: + properties: + - common + bgp: + router-id: 0.12.0.146 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::245 + interfaces: + Loopback0: + ipv6: fc00:c:c:92::1/128 + Ethernet1: + ipv6: fc00:a::246/126 + bp_interface: + ipv6: fc00:b::92/64 + + ARISTA145T1: + properties: + - common + bgp: + router-id: 0.12.0.147 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::249 + interfaces: + Loopback0: + ipv6: fc00:c:c:93::1/128 + Ethernet1: + ipv6: fc00:a::24a/126 + bp_interface: + ipv6: fc00:b::93/64 + + ARISTA146T1: + properties: + - common + bgp: + router-id: 0.12.0.148 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::24d + interfaces: + Loopback0: + ipv6: fc00:c:c:94::1/128 + Ethernet1: + ipv6: fc00:a::24e/126 + bp_interface: + ipv6: fc00:b::94/64 + + ARISTA147T1: + properties: + - common + bgp: + router-id: 0.12.0.149 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::251 + interfaces: + Loopback0: + ipv6: fc00:c:c:95::1/128 + Ethernet1: + ipv6: fc00:a::252/126 + bp_interface: + ipv6: fc00:b::95/64 + + ARISTA148T1: + properties: + - common + bgp: + router-id: 0.12.0.150 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::255 + interfaces: + Loopback0: + ipv6: fc00:c:c:96::1/128 + Ethernet1: + ipv6: fc00:a::256/126 + bp_interface: + ipv6: fc00:b::96/64 + + ARISTA149T1: + properties: + - common + bgp: + router-id: 0.12.0.151 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::259 + interfaces: + Loopback0: + ipv6: fc00:c:c:97::1/128 + Ethernet1: + ipv6: fc00:a::25a/126 + bp_interface: + ipv6: fc00:b::97/64 + + ARISTA150T1: + properties: + - common + bgp: + router-id: 0.12.0.152 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::25d + interfaces: + Loopback0: + ipv6: fc00:c:c:98::1/128 + Ethernet1: + ipv6: fc00:a::25e/126 + bp_interface: + ipv6: fc00:b::98/64 + + ARISTA151T1: + properties: + - common + bgp: + router-id: 0.12.0.153 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::261 + interfaces: + Loopback0: + ipv6: fc00:c:c:99::1/128 + Ethernet1: + ipv6: fc00:a::262/126 + bp_interface: + ipv6: fc00:b::99/64 + + ARISTA152T1: + properties: + - common + bgp: + router-id: 0.12.0.154 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::265 + interfaces: + Loopback0: + ipv6: fc00:c:c:9a::1/128 + Ethernet1: + ipv6: fc00:a::266/126 + bp_interface: + ipv6: fc00:b::9a/64 + + ARISTA153T1: + properties: + - common + bgp: + router-id: 0.12.0.155 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::269 + interfaces: + Loopback0: + ipv6: fc00:c:c:9b::1/128 + Ethernet1: + ipv6: fc00:a::26a/126 + bp_interface: + ipv6: fc00:b::9b/64 + + ARISTA154T1: + properties: + - common + bgp: + router-id: 0.12.0.156 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::26d + interfaces: + Loopback0: + ipv6: fc00:c:c:9c::1/128 + Ethernet1: + ipv6: fc00:a::26e/126 + bp_interface: + ipv6: fc00:b::9c/64 + + ARISTA155T1: + properties: + - common + bgp: + router-id: 0.12.0.157 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::271 + interfaces: + Loopback0: + ipv6: fc00:c:c:9d::1/128 + Ethernet1: + ipv6: fc00:a::272/126 + bp_interface: + ipv6: fc00:b::9d/64 + + ARISTA156T1: + properties: + - common + bgp: + router-id: 0.12.0.158 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::275 + interfaces: + Loopback0: + ipv6: fc00:c:c:9e::1/128 + Ethernet1: + ipv6: fc00:a::276/126 + bp_interface: + ipv6: fc00:b::9e/64 + + ARISTA157T1: + properties: + - common + bgp: + router-id: 0.12.0.159 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::279 + interfaces: + Loopback0: + ipv6: fc00:c:c:9f::1/128 + Ethernet1: + ipv6: fc00:a::27a/126 + bp_interface: + ipv6: fc00:b::9f/64 + + ARISTA158T1: + properties: + - common + bgp: + router-id: 0.12.0.160 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::27d + interfaces: + Loopback0: + ipv6: fc00:c:c:a0::1/128 + Ethernet1: + ipv6: fc00:a::27e/126 + bp_interface: + ipv6: fc00:b::a0/64 + + ARISTA159T1: + properties: + - common + bgp: + router-id: 0.12.0.161 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::281 + interfaces: + Loopback0: + ipv6: fc00:c:c:a1::1/128 + Ethernet1: + ipv6: fc00:a::282/126 + bp_interface: + ipv6: fc00:b::a1/64 + + ARISTA160T1: + properties: + - common + bgp: + router-id: 0.12.0.162 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::285 + interfaces: + Loopback0: + ipv6: fc00:c:c:a2::1/128 + Ethernet1: + ipv6: fc00:a::286/126 + bp_interface: + ipv6: fc00:b::a2/64 + + ARISTA161T1: + properties: + - common + bgp: + router-id: 0.12.0.163 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::289 + interfaces: + Loopback0: + ipv6: fc00:c:c:a3::1/128 + Ethernet1: + ipv6: fc00:a::28a/126 + bp_interface: + ipv6: fc00:b::a3/64 + + ARISTA162T1: + properties: + - common + bgp: + router-id: 0.12.0.164 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::28d + interfaces: + Loopback0: + ipv6: fc00:c:c:a4::1/128 + Ethernet1: + ipv6: fc00:a::28e/126 + bp_interface: + ipv6: fc00:b::a4/64 + + ARISTA163T1: + properties: + - common + bgp: + router-id: 0.12.0.165 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::291 + interfaces: + Loopback0: + ipv6: fc00:c:c:a5::1/128 + Ethernet1: + ipv6: fc00:a::292/126 + bp_interface: + ipv6: fc00:b::a5/64 + + ARISTA164T1: + properties: + - common + bgp: + router-id: 0.12.0.166 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::295 + interfaces: + Loopback0: + ipv6: fc00:c:c:a6::1/128 + Ethernet1: + ipv6: fc00:a::296/126 + bp_interface: + ipv6: fc00:b::a6/64 + + ARISTA165T1: + properties: + - common + bgp: + router-id: 0.12.0.167 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::299 + interfaces: + Loopback0: + ipv6: fc00:c:c:a7::1/128 + Ethernet1: + ipv6: fc00:a::29a/126 + bp_interface: + ipv6: fc00:b::a7/64 + + ARISTA166T1: + properties: + - common + bgp: + router-id: 0.12.0.168 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::29d + interfaces: + Loopback0: + ipv6: fc00:c:c:a8::1/128 + Ethernet1: + ipv6: fc00:a::29e/126 + bp_interface: + ipv6: fc00:b::a8/64 + + ARISTA167T1: + properties: + - common + bgp: + router-id: 0.12.0.169 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:a9::1/128 + Ethernet1: + ipv6: fc00:a::2a2/126 + bp_interface: + ipv6: fc00:b::a9/64 + + ARISTA168T1: + properties: + - common + bgp: + router-id: 0.12.0.170 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:aa::1/128 + Ethernet1: + ipv6: fc00:a::2a6/126 + bp_interface: + ipv6: fc00:b::aa/64 + + ARISTA169T1: + properties: + - common + bgp: + router-id: 0.12.0.171 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ab::1/128 + Ethernet1: + ipv6: fc00:a::2aa/126 + bp_interface: + ipv6: fc00:b::ab/64 + + ARISTA170T1: + properties: + - common + bgp: + router-id: 0.12.0.172 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ac::1/128 + Ethernet1: + ipv6: fc00:a::2ae/126 + bp_interface: + ipv6: fc00:b::ac/64 + + ARISTA171T1: + properties: + - common + bgp: + router-id: 0.12.0.173 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ad::1/128 + Ethernet1: + ipv6: fc00:a::2b2/126 + bp_interface: + ipv6: fc00:b::ad/64 + + ARISTA172T1: + properties: + - common + bgp: + router-id: 0.12.0.174 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ae::1/128 + Ethernet1: + ipv6: fc00:a::2b6/126 + bp_interface: + ipv6: fc00:b::ae/64 + + ARISTA173T1: + properties: + - common + bgp: + router-id: 0.12.0.175 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:af::1/128 + Ethernet1: + ipv6: fc00:a::2ba/126 + bp_interface: + ipv6: fc00:b::af/64 + + ARISTA174T1: + properties: + - common + bgp: + router-id: 0.12.0.176 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2bd + interfaces: + Loopback0: + ipv6: fc00:c:c:b0::1/128 + Ethernet1: + ipv6: fc00:a::2be/126 + bp_interface: + ipv6: fc00:b::b0/64 + + ARISTA175T1: + properties: + - common + bgp: + router-id: 0.12.0.177 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b1::1/128 + Ethernet1: + ipv6: fc00:a::2c2/126 + bp_interface: + ipv6: fc00:b::b1/64 + + ARISTA176T1: + properties: + - common + bgp: + router-id: 0.12.0.178 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b2::1/128 + Ethernet1: + ipv6: fc00:a::2c6/126 + bp_interface: + ipv6: fc00:b::b2/64 + + ARISTA177T1: + properties: + - common + bgp: + router-id: 0.12.0.179 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b3::1/128 + Ethernet1: + ipv6: fc00:a::2ca/126 + bp_interface: + ipv6: fc00:b::b3/64 + + ARISTA178T1: + properties: + - common + bgp: + router-id: 0.12.0.180 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2cd + interfaces: + Loopback0: + ipv6: fc00:c:c:b4::1/128 + Ethernet1: + ipv6: fc00:a::2ce/126 + bp_interface: + ipv6: fc00:b::b4/64 + + ARISTA179T1: + properties: + - common + bgp: + router-id: 0.12.0.181 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b5::1/128 + Ethernet1: + ipv6: fc00:a::2d2/126 + bp_interface: + ipv6: fc00:b::b5/64 + + ARISTA180T1: + properties: + - common + bgp: + router-id: 0.12.0.182 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b6::1/128 + Ethernet1: + ipv6: fc00:a::2d6/126 + bp_interface: + ipv6: fc00:b::b6/64 + + ARISTA181T1: + properties: + - common + bgp: + router-id: 0.12.0.183 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b7::1/128 + Ethernet1: + ipv6: fc00:a::2da/126 + bp_interface: + ipv6: fc00:b::b7/64 + + ARISTA182T1: + properties: + - common + bgp: + router-id: 0.12.0.184 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2dd + interfaces: + Loopback0: + ipv6: fc00:c:c:b8::1/128 + Ethernet1: + ipv6: fc00:a::2de/126 + bp_interface: + ipv6: fc00:b::b8/64 + + ARISTA183T1: + properties: + - common + bgp: + router-id: 0.12.0.185 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b9::1/128 + Ethernet1: + ipv6: fc00:a::2e2/126 + bp_interface: + ipv6: fc00:b::b9/64 + + ARISTA184T1: + properties: + - common + bgp: + router-id: 0.12.0.186 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ba::1/128 + Ethernet1: + ipv6: fc00:a::2e6/126 + bp_interface: + ipv6: fc00:b::ba/64 + + ARISTA185T1: + properties: + - common + bgp: + router-id: 0.12.0.187 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bb::1/128 + Ethernet1: + ipv6: fc00:a::2ea/126 + bp_interface: + ipv6: fc00:b::bb/64 + + ARISTA186T1: + properties: + - common + bgp: + router-id: 0.12.0.188 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2ed + interfaces: + Loopback0: + ipv6: fc00:c:c:bc::1/128 + Ethernet1: + ipv6: fc00:a::2ee/126 + bp_interface: + ipv6: fc00:b::bc/64 + + ARISTA187T1: + properties: + - common + bgp: + router-id: 0.12.0.189 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:bd::1/128 + Ethernet1: + ipv6: fc00:a::2f2/126 + bp_interface: + ipv6: fc00:b::bd/64 + + ARISTA188T1: + properties: + - common + bgp: + router-id: 0.12.0.190 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:be::1/128 + Ethernet1: + ipv6: fc00:a::2f6/126 + bp_interface: + ipv6: fc00:b::be/64 + + ARISTA189T1: + properties: + - common + bgp: + router-id: 0.12.0.191 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bf::1/128 + Ethernet1: + ipv6: fc00:a::2fa/126 + bp_interface: + ipv6: fc00:b::bf/64 + + ARISTA190T1: + properties: + - common + bgp: + router-id: 0.12.0.192 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::2fd + interfaces: + Loopback0: + ipv6: fc00:c:c:c0::1/128 + Ethernet1: + ipv6: fc00:a::2fe/126 + bp_interface: + ipv6: fc00:b::c0/64 + + ARISTA191T1: + properties: + - common + bgp: + router-id: 0.12.0.193 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::301 + interfaces: + Loopback0: + ipv6: fc00:c:c:c1::1/128 + Ethernet1: + ipv6: fc00:a::302/126 + bp_interface: + ipv6: fc00:b::c1/64 + + ARISTA192T1: + properties: + - common + bgp: + router-id: 0.12.0.194 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::305 + interfaces: + Loopback0: + ipv6: fc00:c:c:c2::1/128 + Ethernet1: + ipv6: fc00:a::306/126 + bp_interface: + ipv6: fc00:b::c2/64 + + ARISTA193T1: + properties: + - common + bgp: + router-id: 0.12.0.195 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::309 + interfaces: + Loopback0: + ipv6: fc00:c:c:c3::1/128 + Ethernet1: + ipv6: fc00:a::30a/126 + bp_interface: + ipv6: fc00:b::c3/64 + + ARISTA194T1: + properties: + - common + bgp: + router-id: 0.12.0.196 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::30d + interfaces: + Loopback0: + ipv6: fc00:c:c:c4::1/128 + Ethernet1: + ipv6: fc00:a::30e/126 + bp_interface: + ipv6: fc00:b::c4/64 + + ARISTA195T1: + properties: + - common + bgp: + router-id: 0.12.0.197 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::311 + interfaces: + Loopback0: + ipv6: fc00:c:c:c5::1/128 + Ethernet1: + ipv6: fc00:a::312/126 + bp_interface: + ipv6: fc00:b::c5/64 + + ARISTA196T1: + properties: + - common + bgp: + router-id: 0.12.0.198 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::315 + interfaces: + Loopback0: + ipv6: fc00:c:c:c6::1/128 + Ethernet1: + ipv6: fc00:a::316/126 + bp_interface: + ipv6: fc00:b::c6/64 + + ARISTA197T1: + properties: + - common + bgp: + router-id: 0.12.0.199 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::319 + interfaces: + Loopback0: + ipv6: fc00:c:c:c7::1/128 + Ethernet1: + ipv6: fc00:a::31a/126 + bp_interface: + ipv6: fc00:b::c7/64 + + ARISTA198T1: + properties: + - common + bgp: + router-id: 0.12.0.200 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::31d + interfaces: + Loopback0: + ipv6: fc00:c:c:c8::1/128 + Ethernet1: + ipv6: fc00:a::31e/126 + bp_interface: + ipv6: fc00:b::c8/64 + + ARISTA199T1: + properties: + - common + bgp: + router-id: 0.12.0.201 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::321 + interfaces: + Loopback0: + ipv6: fc00:c:c:c9::1/128 + Ethernet1: + ipv6: fc00:a::322/126 + bp_interface: + ipv6: fc00:b::c9/64 + + ARISTA200T1: + properties: + - common + bgp: + router-id: 0.12.0.202 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::325 + interfaces: + Loopback0: + ipv6: fc00:c:c:ca::1/128 + Ethernet1: + ipv6: fc00:a::326/126 + bp_interface: + ipv6: fc00:b::ca/64 + + ARISTA201T1: + properties: + - common + bgp: + router-id: 0.12.0.203 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::329 + interfaces: + Loopback0: + ipv6: fc00:c:c:cb::1/128 + Ethernet1: + ipv6: fc00:a::32a/126 + bp_interface: + ipv6: fc00:b::cb/64 + + ARISTA202T1: + properties: + - common + bgp: + router-id: 0.12.0.204 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::32d + interfaces: + Loopback0: + ipv6: fc00:c:c:cc::1/128 + Ethernet1: + ipv6: fc00:a::32e/126 + bp_interface: + ipv6: fc00:b::cc/64 + + ARISTA203T1: + properties: + - common + bgp: + router-id: 0.12.0.205 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::331 + interfaces: + Loopback0: + ipv6: fc00:c:c:cd::1/128 + Ethernet1: + ipv6: fc00:a::332/126 + bp_interface: + ipv6: fc00:b::cd/64 + + ARISTA204T1: + properties: + - common + bgp: + router-id: 0.12.0.206 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::335 + interfaces: + Loopback0: + ipv6: fc00:c:c:ce::1/128 + Ethernet1: + ipv6: fc00:a::336/126 + bp_interface: + ipv6: fc00:b::ce/64 + + ARISTA205T1: + properties: + - common + bgp: + router-id: 0.12.0.207 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::339 + interfaces: + Loopback0: + ipv6: fc00:c:c:cf::1/128 + Ethernet1: + ipv6: fc00:a::33a/126 + bp_interface: + ipv6: fc00:b::cf/64 + + ARISTA206T1: + properties: + - common + bgp: + router-id: 0.12.0.208 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::33d + interfaces: + Loopback0: + ipv6: fc00:c:c:d0::1/128 + Ethernet1: + ipv6: fc00:a::33e/126 + bp_interface: + ipv6: fc00:b::d0/64 + + ARISTA207T1: + properties: + - common + bgp: + router-id: 0.12.0.209 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::341 + interfaces: + Loopback0: + ipv6: fc00:c:c:d1::1/128 + Ethernet1: + ipv6: fc00:a::342/126 + bp_interface: + ipv6: fc00:b::d1/64 + + ARISTA208T1: + properties: + - common + bgp: + router-id: 0.12.0.210 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::345 + interfaces: + Loopback0: + ipv6: fc00:c:c:d2::1/128 + Ethernet1: + ipv6: fc00:a::346/126 + bp_interface: + ipv6: fc00:b::d2/64 + + ARISTA209T1: + properties: + - common + bgp: + router-id: 0.12.0.211 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::349 + interfaces: + Loopback0: + ipv6: fc00:c:c:d3::1/128 + Ethernet1: + ipv6: fc00:a::34a/126 + bp_interface: + ipv6: fc00:b::d3/64 + + ARISTA210T1: + properties: + - common + bgp: + router-id: 0.12.0.212 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::34d + interfaces: + Loopback0: + ipv6: fc00:c:c:d4::1/128 + Ethernet1: + ipv6: fc00:a::34e/126 + bp_interface: + ipv6: fc00:b::d4/64 + + ARISTA211T1: + properties: + - common + bgp: + router-id: 0.12.0.213 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::351 + interfaces: + Loopback0: + ipv6: fc00:c:c:d5::1/128 + Ethernet1: + ipv6: fc00:a::352/126 + bp_interface: + ipv6: fc00:b::d5/64 + + ARISTA212T1: + properties: + - common + bgp: + router-id: 0.12.0.214 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::355 + interfaces: + Loopback0: + ipv6: fc00:c:c:d6::1/128 + Ethernet1: + ipv6: fc00:a::356/126 + bp_interface: + ipv6: fc00:b::d6/64 + + ARISTA213T1: + properties: + - common + bgp: + router-id: 0.12.0.215 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::359 + interfaces: + Loopback0: + ipv6: fc00:c:c:d7::1/128 + Ethernet1: + ipv6: fc00:a::35a/126 + bp_interface: + ipv6: fc00:b::d7/64 + + ARISTA214T1: + properties: + - common + bgp: + router-id: 0.12.0.216 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::35d + interfaces: + Loopback0: + ipv6: fc00:c:c:d8::1/128 + Ethernet1: + ipv6: fc00:a::35e/126 + bp_interface: + ipv6: fc00:b::d8/64 + + ARISTA215T1: + properties: + - common + bgp: + router-id: 0.12.0.217 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::361 + interfaces: + Loopback0: + ipv6: fc00:c:c:d9::1/128 + Ethernet1: + ipv6: fc00:a::362/126 + bp_interface: + ipv6: fc00:b::d9/64 + + ARISTA216T1: + properties: + - common + bgp: + router-id: 0.12.0.218 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::365 + interfaces: + Loopback0: + ipv6: fc00:c:c:da::1/128 + Ethernet1: + ipv6: fc00:a::366/126 + bp_interface: + ipv6: fc00:b::da/64 + + ARISTA217T1: + properties: + - common + bgp: + router-id: 0.12.0.219 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::369 + interfaces: + Loopback0: + ipv6: fc00:c:c:db::1/128 + Ethernet1: + ipv6: fc00:a::36a/126 + bp_interface: + ipv6: fc00:b::db/64 + + ARISTA218T1: + properties: + - common + bgp: + router-id: 0.12.0.220 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::36d + interfaces: + Loopback0: + ipv6: fc00:c:c:dc::1/128 + Ethernet1: + ipv6: fc00:a::36e/126 + bp_interface: + ipv6: fc00:b::dc/64 + + ARISTA219T1: + properties: + - common + bgp: + router-id: 0.12.0.221 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::371 + interfaces: + Loopback0: + ipv6: fc00:c:c:dd::1/128 + Ethernet1: + ipv6: fc00:a::372/126 + bp_interface: + ipv6: fc00:b::dd/64 + + ARISTA220T1: + properties: + - common + bgp: + router-id: 0.12.0.222 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::375 + interfaces: + Loopback0: + ipv6: fc00:c:c:de::1/128 + Ethernet1: + ipv6: fc00:a::376/126 + bp_interface: + ipv6: fc00:b::de/64 + + ARISTA221T1: + properties: + - common + bgp: + router-id: 0.12.0.223 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::379 + interfaces: + Loopback0: + ipv6: fc00:c:c:df::1/128 + Ethernet1: + ipv6: fc00:a::37a/126 + bp_interface: + ipv6: fc00:b::df/64 + + ARISTA222T1: + properties: + - common + bgp: + router-id: 0.12.0.224 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::37d + interfaces: + Loopback0: + ipv6: fc00:c:c:e0::1/128 + Ethernet1: + ipv6: fc00:a::37e/126 + bp_interface: + ipv6: fc00:b::e0/64 + + ARISTA223T1: + properties: + - common + bgp: + router-id: 0.12.0.225 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::381 + interfaces: + Loopback0: + ipv6: fc00:c:c:e1::1/128 + Ethernet1: + ipv6: fc00:a::382/126 + bp_interface: + ipv6: fc00:b::e1/64 + + ARISTA224T1: + properties: + - common + bgp: + router-id: 0.12.0.226 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::385 + interfaces: + Loopback0: + ipv6: fc00:c:c:e2::1/128 + Ethernet1: + ipv6: fc00:a::386/126 + bp_interface: + ipv6: fc00:b::e2/64 + + ARISTA225T1: + properties: + - common + bgp: + router-id: 0.12.0.227 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::389 + interfaces: + Loopback0: + ipv6: fc00:c:c:e3::1/128 + Ethernet1: + ipv6: fc00:a::38a/126 + bp_interface: + ipv6: fc00:b::e3/64 + + ARISTA226T1: + properties: + - common + bgp: + router-id: 0.12.0.228 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::38d + interfaces: + Loopback0: + ipv6: fc00:c:c:e4::1/128 + Ethernet1: + ipv6: fc00:a::38e/126 + bp_interface: + ipv6: fc00:b::e4/64 + + ARISTA227T1: + properties: + - common + bgp: + router-id: 0.12.0.229 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::391 + interfaces: + Loopback0: + ipv6: fc00:c:c:e5::1/128 + Ethernet1: + ipv6: fc00:a::392/126 + bp_interface: + ipv6: fc00:b::e5/64 + + ARISTA228T1: + properties: + - common + bgp: + router-id: 0.12.0.230 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::395 + interfaces: + Loopback0: + ipv6: fc00:c:c:e6::1/128 + Ethernet1: + ipv6: fc00:a::396/126 + bp_interface: + ipv6: fc00:b::e6/64 + + ARISTA229T1: + properties: + - common + bgp: + router-id: 0.12.0.231 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::399 + interfaces: + Loopback0: + ipv6: fc00:c:c:e7::1/128 + Ethernet1: + ipv6: fc00:a::39a/126 + bp_interface: + ipv6: fc00:b::e7/64 + + ARISTA230T1: + properties: + - common + bgp: + router-id: 0.12.0.232 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::39d + interfaces: + Loopback0: + ipv6: fc00:c:c:e8::1/128 + Ethernet1: + ipv6: fc00:a::39e/126 + bp_interface: + ipv6: fc00:b::e8/64 + + ARISTA231T1: + properties: + - common + bgp: + router-id: 0.12.0.233 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:e9::1/128 + Ethernet1: + ipv6: fc00:a::3a2/126 + bp_interface: + ipv6: fc00:b::e9/64 + + ARISTA232T1: + properties: + - common + bgp: + router-id: 0.12.0.234 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ea::1/128 + Ethernet1: + ipv6: fc00:a::3a6/126 + bp_interface: + ipv6: fc00:b::ea/64 + + ARISTA233T1: + properties: + - common + bgp: + router-id: 0.12.0.235 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:eb::1/128 + Ethernet1: + ipv6: fc00:a::3aa/126 + bp_interface: + ipv6: fc00:b::eb/64 + + ARISTA234T1: + properties: + - common + bgp: + router-id: 0.12.0.236 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ec::1/128 + Ethernet1: + ipv6: fc00:a::3ae/126 + bp_interface: + ipv6: fc00:b::ec/64 + + ARISTA235T1: + properties: + - common + bgp: + router-id: 0.12.0.237 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ed::1/128 + Ethernet1: + ipv6: fc00:a::3b2/126 + bp_interface: + ipv6: fc00:b::ed/64 + + ARISTA236T1: + properties: + - common + bgp: + router-id: 0.12.0.238 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ee::1/128 + Ethernet1: + ipv6: fc00:a::3b6/126 + bp_interface: + ipv6: fc00:b::ee/64 + + ARISTA237T1: + properties: + - common + bgp: + router-id: 0.12.0.239 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ef::1/128 + Ethernet1: + ipv6: fc00:a::3ba/126 + bp_interface: + ipv6: fc00:b::ef/64 + + ARISTA238T1: + properties: + - common + bgp: + router-id: 0.12.0.240 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3bd + interfaces: + Loopback0: + ipv6: fc00:c:c:f0::1/128 + Ethernet1: + ipv6: fc00:a::3be/126 + bp_interface: + ipv6: fc00:b::f0/64 + + ARISTA239T1: + properties: + - common + bgp: + router-id: 0.12.0.241 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f1::1/128 + Ethernet1: + ipv6: fc00:a::3c2/126 + bp_interface: + ipv6: fc00:b::f1/64 + + ARISTA240T1: + properties: + - common + bgp: + router-id: 0.12.0.242 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f2::1/128 + Ethernet1: + ipv6: fc00:a::3c6/126 + bp_interface: + ipv6: fc00:b::f2/64 + + ARISTA241T1: + properties: + - common + bgp: + router-id: 0.12.0.243 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f3::1/128 + Ethernet1: + ipv6: fc00:a::3ca/126 + bp_interface: + ipv6: fc00:b::f3/64 + + ARISTA242T1: + properties: + - common + bgp: + router-id: 0.12.0.244 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3cd + interfaces: + Loopback0: + ipv6: fc00:c:c:f4::1/128 + Ethernet1: + ipv6: fc00:a::3ce/126 + bp_interface: + ipv6: fc00:b::f4/64 + + ARISTA243T1: + properties: + - common + bgp: + router-id: 0.12.0.245 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f5::1/128 + Ethernet1: + ipv6: fc00:a::3d2/126 + bp_interface: + ipv6: fc00:b::f5/64 + + ARISTA244T1: + properties: + - common + bgp: + router-id: 0.12.0.246 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f6::1/128 + Ethernet1: + ipv6: fc00:a::3d6/126 + bp_interface: + ipv6: fc00:b::f6/64 + + ARISTA245T1: + properties: + - common + bgp: + router-id: 0.12.0.247 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f7::1/128 + Ethernet1: + ipv6: fc00:a::3da/126 + bp_interface: + ipv6: fc00:b::f7/64 + + ARISTA246T1: + properties: + - common + bgp: + router-id: 0.12.0.248 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3dd + interfaces: + Loopback0: + ipv6: fc00:c:c:f8::1/128 + Ethernet1: + ipv6: fc00:a::3de/126 + bp_interface: + ipv6: fc00:b::f8/64 + + ARISTA247T1: + properties: + - common + bgp: + router-id: 0.12.0.249 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f9::1/128 + Ethernet1: + ipv6: fc00:a::3e2/126 + bp_interface: + ipv6: fc00:b::f9/64 + + ARISTA248T1: + properties: + - common + bgp: + router-id: 0.12.0.250 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fa::1/128 + Ethernet1: + ipv6: fc00:a::3e6/126 + bp_interface: + ipv6: fc00:b::fa/64 + + ARISTA249T1: + properties: + - common + bgp: + router-id: 0.12.0.251 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:fb::1/128 + Ethernet1: + ipv6: fc00:a::3ea/126 + bp_interface: + ipv6: fc00:b::fb/64 + + ARISTA250T1: + properties: + - common + bgp: + router-id: 0.12.0.252 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3ed + interfaces: + Loopback0: + ipv6: fc00:c:c:fc::1/128 + Ethernet1: + ipv6: fc00:a::3ee/126 + bp_interface: + ipv6: fc00:b::fc/64 + + ARISTA251T1: + properties: + - common + bgp: + router-id: 0.12.0.253 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:fd::1/128 + Ethernet1: + ipv6: fc00:a::3f2/126 + bp_interface: + ipv6: fc00:b::fd/64 + + ARISTA252T1: + properties: + - common + bgp: + router-id: 0.12.0.254 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fe::1/128 + Ethernet1: + ipv6: fc00:a::3f6/126 + bp_interface: + ipv6: fc00:b::fe/64 + + ARISTA253T1: + properties: + - common + bgp: + router-id: 0.12.0.255 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ff::1/128 + Ethernet1: + ipv6: fc00:a::3fa/126 + bp_interface: + ipv6: fc00:b::ff/64 + + ARISTA254T1: + properties: + - common + bgp: + router-id: 0.12.1.0 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::3fd + interfaces: + Loopback0: + ipv6: fc00:c:c:100::1/128 + Ethernet1: + ipv6: fc00:a::3fe/126 + bp_interface: + ipv6: fc00:b::100/64 + + ARISTA255T1: + properties: + - common + bgp: + router-id: 0.12.1.1 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::401 + interfaces: + Loopback0: + ipv6: fc00:c:c:101::1/128 + Ethernet1: + ipv6: fc00:a::402/126 + bp_interface: + ipv6: fc00:b::101/64 + + ARISTA256T1: + properties: + - common + bgp: + router-id: 0.12.1.2 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::405 + interfaces: + Loopback0: + ipv6: fc00:c:c:102::1/128 + Ethernet1: + ipv6: fc00:a::406/126 + bp_interface: + ipv6: fc00:b::102/64 + + ARISTA257T1: + properties: + - common + bgp: + router-id: 0.12.1.3 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::409 + interfaces: + Loopback0: + ipv6: fc00:c:c:103::1/128 + Ethernet1: + ipv6: fc00:a::40a/126 + bp_interface: + ipv6: fc00:b::103/64 + + ARISTA258T1: + properties: + - common + bgp: + router-id: 0.12.1.4 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::40d + interfaces: + Loopback0: + ipv6: fc00:c:c:104::1/128 + Ethernet1: + ipv6: fc00:a::40e/126 + bp_interface: + ipv6: fc00:b::104/64 + + ARISTA259T1: + properties: + - common + bgp: + router-id: 0.12.1.5 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::411 + interfaces: + Loopback0: + ipv6: fc00:c:c:105::1/128 + Ethernet1: + ipv6: fc00:a::412/126 + bp_interface: + ipv6: fc00:b::105/64 + + ARISTA260T1: + properties: + - common + bgp: + router-id: 0.12.1.6 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::415 + interfaces: + Loopback0: + ipv6: fc00:c:c:106::1/128 + Ethernet1: + ipv6: fc00:a::416/126 + bp_interface: + ipv6: fc00:b::106/64 + + ARISTA261T1: + properties: + - common + bgp: + router-id: 0.12.1.7 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::419 + interfaces: + Loopback0: + ipv6: fc00:c:c:107::1/128 + Ethernet1: + ipv6: fc00:a::41a/126 + bp_interface: + ipv6: fc00:b::107/64 + + ARISTA262T1: + properties: + - common + bgp: + router-id: 0.12.1.8 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::41d + interfaces: + Loopback0: + ipv6: fc00:c:c:108::1/128 + Ethernet1: + ipv6: fc00:a::41e/126 + bp_interface: + ipv6: fc00:b::108/64 + + ARISTA263T1: + properties: + - common + bgp: + router-id: 0.12.1.9 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::421 + interfaces: + Loopback0: + ipv6: fc00:c:c:109::1/128 + Ethernet1: + ipv6: fc00:a::422/126 + bp_interface: + ipv6: fc00:b::109/64 + + ARISTA264T1: + properties: + - common + bgp: + router-id: 0.12.1.10 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::425 + interfaces: + Loopback0: + ipv6: fc00:c:c:10a::1/128 + Ethernet1: + ipv6: fc00:a::426/126 + bp_interface: + ipv6: fc00:b::10a/64 + + ARISTA265T1: + properties: + - common + bgp: + router-id: 0.12.1.11 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::429 + interfaces: + Loopback0: + ipv6: fc00:c:c:10b::1/128 + Ethernet1: + ipv6: fc00:a::42a/126 + bp_interface: + ipv6: fc00:b::10b/64 + + ARISTA266T1: + properties: + - common + bgp: + router-id: 0.12.1.12 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::42d + interfaces: + Loopback0: + ipv6: fc00:c:c:10c::1/128 + Ethernet1: + ipv6: fc00:a::42e/126 + bp_interface: + ipv6: fc00:b::10c/64 + + ARISTA267T1: + properties: + - common + bgp: + router-id: 0.12.1.13 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::431 + interfaces: + Loopback0: + ipv6: fc00:c:c:10d::1/128 + Ethernet1: + ipv6: fc00:a::432/126 + bp_interface: + ipv6: fc00:b::10d/64 + + ARISTA268T1: + properties: + - common + bgp: + router-id: 0.12.1.14 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::435 + interfaces: + Loopback0: + ipv6: fc00:c:c:10e::1/128 + Ethernet1: + ipv6: fc00:a::436/126 + bp_interface: + ipv6: fc00:b::10e/64 + + ARISTA269T1: + properties: + - common + bgp: + router-id: 0.12.1.15 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::439 + interfaces: + Loopback0: + ipv6: fc00:c:c:10f::1/128 + Ethernet1: + ipv6: fc00:a::43a/126 + bp_interface: + ipv6: fc00:b::10f/64 + + ARISTA270T1: + properties: + - common + bgp: + router-id: 0.12.1.16 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::43d + interfaces: + Loopback0: + ipv6: fc00:c:c:110::1/128 + Ethernet1: + ipv6: fc00:a::43e/126 + bp_interface: + ipv6: fc00:b::110/64 + + ARISTA271T1: + properties: + - common + bgp: + router-id: 0.12.1.17 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::441 + interfaces: + Loopback0: + ipv6: fc00:c:c:111::1/128 + Ethernet1: + ipv6: fc00:a::442/126 + bp_interface: + ipv6: fc00:b::111/64 + + ARISTA272T1: + properties: + - common + bgp: + router-id: 0.12.1.18 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::445 + interfaces: + Loopback0: + ipv6: fc00:c:c:112::1/128 + Ethernet1: + ipv6: fc00:a::446/126 + bp_interface: + ipv6: fc00:b::112/64 + + ARISTA273T1: + properties: + - common + bgp: + router-id: 0.12.1.19 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::449 + interfaces: + Loopback0: + ipv6: fc00:c:c:113::1/128 + Ethernet1: + ipv6: fc00:a::44a/126 + bp_interface: + ipv6: fc00:b::113/64 + + ARISTA274T1: + properties: + - common + bgp: + router-id: 0.12.1.20 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::44d + interfaces: + Loopback0: + ipv6: fc00:c:c:114::1/128 + Ethernet1: + ipv6: fc00:a::44e/126 + bp_interface: + ipv6: fc00:b::114/64 + + ARISTA275T1: + properties: + - common + bgp: + router-id: 0.12.1.21 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::451 + interfaces: + Loopback0: + ipv6: fc00:c:c:115::1/128 + Ethernet1: + ipv6: fc00:a::452/126 + bp_interface: + ipv6: fc00:b::115/64 + + ARISTA276T1: + properties: + - common + bgp: + router-id: 0.12.1.22 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::455 + interfaces: + Loopback0: + ipv6: fc00:c:c:116::1/128 + Ethernet1: + ipv6: fc00:a::456/126 + bp_interface: + ipv6: fc00:b::116/64 + + ARISTA277T1: + properties: + - common + bgp: + router-id: 0.12.1.23 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::459 + interfaces: + Loopback0: + ipv6: fc00:c:c:117::1/128 + Ethernet1: + ipv6: fc00:a::45a/126 + bp_interface: + ipv6: fc00:b::117/64 + + ARISTA278T1: + properties: + - common + bgp: + router-id: 0.12.1.24 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::45d + interfaces: + Loopback0: + ipv6: fc00:c:c:118::1/128 + Ethernet1: + ipv6: fc00:a::45e/126 + bp_interface: + ipv6: fc00:b::118/64 + + ARISTA279T1: + properties: + - common + bgp: + router-id: 0.12.1.25 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::461 + interfaces: + Loopback0: + ipv6: fc00:c:c:119::1/128 + Ethernet1: + ipv6: fc00:a::462/126 + bp_interface: + ipv6: fc00:b::119/64 + + ARISTA280T1: + properties: + - common + bgp: + router-id: 0.12.1.26 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::465 + interfaces: + Loopback0: + ipv6: fc00:c:c:11a::1/128 + Ethernet1: + ipv6: fc00:a::466/126 + bp_interface: + ipv6: fc00:b::11a/64 + + ARISTA281T1: + properties: + - common + bgp: + router-id: 0.12.1.27 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::469 + interfaces: + Loopback0: + ipv6: fc00:c:c:11b::1/128 + Ethernet1: + ipv6: fc00:a::46a/126 + bp_interface: + ipv6: fc00:b::11b/64 + + ARISTA282T1: + properties: + - common + bgp: + router-id: 0.12.1.28 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::46d + interfaces: + Loopback0: + ipv6: fc00:c:c:11c::1/128 + Ethernet1: + ipv6: fc00:a::46e/126 + bp_interface: + ipv6: fc00:b::11c/64 + + ARISTA283T1: + properties: + - common + bgp: + router-id: 0.12.1.29 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::471 + interfaces: + Loopback0: + ipv6: fc00:c:c:11d::1/128 + Ethernet1: + ipv6: fc00:a::472/126 + bp_interface: + ipv6: fc00:b::11d/64 + + ARISTA284T1: + properties: + - common + bgp: + router-id: 0.12.1.30 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::475 + interfaces: + Loopback0: + ipv6: fc00:c:c:11e::1/128 + Ethernet1: + ipv6: fc00:a::476/126 + bp_interface: + ipv6: fc00:b::11e/64 + + ARISTA285T1: + properties: + - common + bgp: + router-id: 0.12.1.31 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::479 + interfaces: + Loopback0: + ipv6: fc00:c:c:11f::1/128 + Ethernet1: + ipv6: fc00:a::47a/126 + bp_interface: + ipv6: fc00:b::11f/64 + + ARISTA286T1: + properties: + - common + bgp: + router-id: 0.12.1.32 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::47d + interfaces: + Loopback0: + ipv6: fc00:c:c:120::1/128 + Ethernet1: + ipv6: fc00:a::47e/126 + bp_interface: + ipv6: fc00:b::120/64 + + ARISTA287T1: + properties: + - common + bgp: + router-id: 0.12.1.33 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::481 + interfaces: + Loopback0: + ipv6: fc00:c:c:121::1/128 + Ethernet1: + ipv6: fc00:a::482/126 + bp_interface: + ipv6: fc00:b::121/64 + + ARISTA288T1: + properties: + - common + bgp: + router-id: 0.12.1.34 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::485 + interfaces: + Loopback0: + ipv6: fc00:c:c:122::1/128 + Ethernet1: + ipv6: fc00:a::486/126 + bp_interface: + ipv6: fc00:b::122/64 + + ARISTA289T1: + properties: + - common + bgp: + router-id: 0.12.1.35 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::489 + interfaces: + Loopback0: + ipv6: fc00:c:c:123::1/128 + Ethernet1: + ipv6: fc00:a::48a/126 + bp_interface: + ipv6: fc00:b::123/64 + + ARISTA290T1: + properties: + - common + bgp: + router-id: 0.12.1.36 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::48d + interfaces: + Loopback0: + ipv6: fc00:c:c:124::1/128 + Ethernet1: + ipv6: fc00:a::48e/126 + bp_interface: + ipv6: fc00:b::124/64 + + ARISTA291T1: + properties: + - common + bgp: + router-id: 0.12.1.37 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::491 + interfaces: + Loopback0: + ipv6: fc00:c:c:125::1/128 + Ethernet1: + ipv6: fc00:a::492/126 + bp_interface: + ipv6: fc00:b::125/64 + + ARISTA292T1: + properties: + - common + bgp: + router-id: 0.12.1.38 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::495 + interfaces: + Loopback0: + ipv6: fc00:c:c:126::1/128 + Ethernet1: + ipv6: fc00:a::496/126 + bp_interface: + ipv6: fc00:b::126/64 + + ARISTA293T1: + properties: + - common + bgp: + router-id: 0.12.1.39 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::499 + interfaces: + Loopback0: + ipv6: fc00:c:c:127::1/128 + Ethernet1: + ipv6: fc00:a::49a/126 + bp_interface: + ipv6: fc00:b::127/64 + + ARISTA294T1: + properties: + - common + bgp: + router-id: 0.12.1.40 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::49d + interfaces: + Loopback0: + ipv6: fc00:c:c:128::1/128 + Ethernet1: + ipv6: fc00:a::49e/126 + bp_interface: + ipv6: fc00:b::128/64 + + ARISTA295T1: + properties: + - common + bgp: + router-id: 0.12.1.41 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:129::1/128 + Ethernet1: + ipv6: fc00:a::4a2/126 + bp_interface: + ipv6: fc00:b::129/64 + + ARISTA296T1: + properties: + - common + bgp: + router-id: 0.12.1.42 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:12a::1/128 + Ethernet1: + ipv6: fc00:a::4a6/126 + bp_interface: + ipv6: fc00:b::12a/64 + + ARISTA297T1: + properties: + - common + bgp: + router-id: 0.12.1.43 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:12b::1/128 + Ethernet1: + ipv6: fc00:a::4aa/126 + bp_interface: + ipv6: fc00:b::12b/64 + + ARISTA298T1: + properties: + - common + bgp: + router-id: 0.12.1.44 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4ad + interfaces: + Loopback0: + ipv6: fc00:c:c:12c::1/128 + Ethernet1: + ipv6: fc00:a::4ae/126 + bp_interface: + ipv6: fc00:b::12c/64 + + ARISTA299T1: + properties: + - common + bgp: + router-id: 0.12.1.45 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:12d::1/128 + Ethernet1: + ipv6: fc00:a::4b2/126 + bp_interface: + ipv6: fc00:b::12d/64 + + ARISTA300T1: + properties: + - common + bgp: + router-id: 0.12.1.46 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:12e::1/128 + Ethernet1: + ipv6: fc00:a::4b6/126 + bp_interface: + ipv6: fc00:b::12e/64 + + ARISTA301T1: + properties: + - common + bgp: + router-id: 0.12.1.47 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:12f::1/128 + Ethernet1: + ipv6: fc00:a::4ba/126 + bp_interface: + ipv6: fc00:b::12f/64 + + ARISTA302T1: + properties: + - common + bgp: + router-id: 0.12.1.48 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4bd + interfaces: + Loopback0: + ipv6: fc00:c:c:130::1/128 + Ethernet1: + ipv6: fc00:a::4be/126 + bp_interface: + ipv6: fc00:b::130/64 + + ARISTA303T1: + properties: + - common + bgp: + router-id: 0.12.1.49 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:131::1/128 + Ethernet1: + ipv6: fc00:a::4c2/126 + bp_interface: + ipv6: fc00:b::131/64 + + ARISTA304T1: + properties: + - common + bgp: + router-id: 0.12.1.50 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:132::1/128 + Ethernet1: + ipv6: fc00:a::4c6/126 + bp_interface: + ipv6: fc00:b::132/64 + + ARISTA305T1: + properties: + - common + bgp: + router-id: 0.12.1.51 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:133::1/128 + Ethernet1: + ipv6: fc00:a::4ca/126 + bp_interface: + ipv6: fc00:b::133/64 + + ARISTA306T1: + properties: + - common + bgp: + router-id: 0.12.1.52 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4cd + interfaces: + Loopback0: + ipv6: fc00:c:c:134::1/128 + Ethernet1: + ipv6: fc00:a::4ce/126 + bp_interface: + ipv6: fc00:b::134/64 + + ARISTA307T1: + properties: + - common + bgp: + router-id: 0.12.1.53 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:135::1/128 + Ethernet1: + ipv6: fc00:a::4d2/126 + bp_interface: + ipv6: fc00:b::135/64 + + ARISTA308T1: + properties: + - common + bgp: + router-id: 0.12.1.54 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:136::1/128 + Ethernet1: + ipv6: fc00:a::4d6/126 + bp_interface: + ipv6: fc00:b::136/64 + + ARISTA309T1: + properties: + - common + bgp: + router-id: 0.12.1.55 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:137::1/128 + Ethernet1: + ipv6: fc00:a::4da/126 + bp_interface: + ipv6: fc00:b::137/64 + + ARISTA310T1: + properties: + - common + bgp: + router-id: 0.12.1.56 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4dd + interfaces: + Loopback0: + ipv6: fc00:c:c:138::1/128 + Ethernet1: + ipv6: fc00:a::4de/126 + bp_interface: + ipv6: fc00:b::138/64 + + ARISTA311T1: + properties: + - common + bgp: + router-id: 0.12.1.57 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:139::1/128 + Ethernet1: + ipv6: fc00:a::4e2/126 + bp_interface: + ipv6: fc00:b::139/64 + + ARISTA312T1: + properties: + - common + bgp: + router-id: 0.12.1.58 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:13a::1/128 + Ethernet1: + ipv6: fc00:a::4e6/126 + bp_interface: + ipv6: fc00:b::13a/64 + + ARISTA313T1: + properties: + - common + bgp: + router-id: 0.12.1.59 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:13b::1/128 + Ethernet1: + ipv6: fc00:a::4ea/126 + bp_interface: + ipv6: fc00:b::13b/64 + + ARISTA314T1: + properties: + - common + bgp: + router-id: 0.12.1.60 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4ed + interfaces: + Loopback0: + ipv6: fc00:c:c:13c::1/128 + Ethernet1: + ipv6: fc00:a::4ee/126 + bp_interface: + ipv6: fc00:b::13c/64 + + ARISTA315T1: + properties: + - common + bgp: + router-id: 0.12.1.61 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:13d::1/128 + Ethernet1: + ipv6: fc00:a::4f2/126 + bp_interface: + ipv6: fc00:b::13d/64 + + ARISTA316T1: + properties: + - common + bgp: + router-id: 0.12.1.62 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:13e::1/128 + Ethernet1: + ipv6: fc00:a::4f6/126 + bp_interface: + ipv6: fc00:b::13e/64 + + ARISTA317T1: + properties: + - common + bgp: + router-id: 0.12.1.63 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:13f::1/128 + Ethernet1: + ipv6: fc00:a::4fa/126 + bp_interface: + ipv6: fc00:b::13f/64 + + ARISTA318T1: + properties: + - common + bgp: + router-id: 0.12.1.64 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::4fd + interfaces: + Loopback0: + ipv6: fc00:c:c:140::1/128 + Ethernet1: + ipv6: fc00:a::4fe/126 + bp_interface: + ipv6: fc00:b::140/64 + + ARISTA319T1: + properties: + - common + bgp: + router-id: 0.12.1.65 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::501 + interfaces: + Loopback0: + ipv6: fc00:c:c:141::1/128 + Ethernet1: + ipv6: fc00:a::502/126 + bp_interface: + ipv6: fc00:b::141/64 + + ARISTA320T1: + properties: + - common + bgp: + router-id: 0.12.1.66 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::505 + interfaces: + Loopback0: + ipv6: fc00:c:c:142::1/128 + Ethernet1: + ipv6: fc00:a::506/126 + bp_interface: + ipv6: fc00:b::142/64 + + ARISTA321T1: + properties: + - common + bgp: + router-id: 0.12.1.67 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::509 + interfaces: + Loopback0: + ipv6: fc00:c:c:143::1/128 + Ethernet1: + ipv6: fc00:a::50a/126 + bp_interface: + ipv6: fc00:b::143/64 + + ARISTA322T1: + properties: + - common + bgp: + router-id: 0.12.1.68 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::50d + interfaces: + Loopback0: + ipv6: fc00:c:c:144::1/128 + Ethernet1: + ipv6: fc00:a::50e/126 + bp_interface: + ipv6: fc00:b::144/64 + + ARISTA323T1: + properties: + - common + bgp: + router-id: 0.12.1.69 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::511 + interfaces: + Loopback0: + ipv6: fc00:c:c:145::1/128 + Ethernet1: + ipv6: fc00:a::512/126 + bp_interface: + ipv6: fc00:b::145/64 + + ARISTA324T1: + properties: + - common + bgp: + router-id: 0.12.1.70 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::515 + interfaces: + Loopback0: + ipv6: fc00:c:c:146::1/128 + Ethernet1: + ipv6: fc00:a::516/126 + bp_interface: + ipv6: fc00:b::146/64 + + ARISTA325T1: + properties: + - common + bgp: + router-id: 0.12.1.71 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::519 + interfaces: + Loopback0: + ipv6: fc00:c:c:147::1/128 + Ethernet1: + ipv6: fc00:a::51a/126 + bp_interface: + ipv6: fc00:b::147/64 + + ARISTA326T1: + properties: + - common + bgp: + router-id: 0.12.1.72 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::51d + interfaces: + Loopback0: + ipv6: fc00:c:c:148::1/128 + Ethernet1: + ipv6: fc00:a::51e/126 + bp_interface: + ipv6: fc00:b::148/64 + + ARISTA327T1: + properties: + - common + bgp: + router-id: 0.12.1.73 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::521 + interfaces: + Loopback0: + ipv6: fc00:c:c:149::1/128 + Ethernet1: + ipv6: fc00:a::522/126 + bp_interface: + ipv6: fc00:b::149/64 + + ARISTA328T1: + properties: + - common + bgp: + router-id: 0.12.1.74 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::525 + interfaces: + Loopback0: + ipv6: fc00:c:c:14a::1/128 + Ethernet1: + ipv6: fc00:a::526/126 + bp_interface: + ipv6: fc00:b::14a/64 + + ARISTA329T1: + properties: + - common + bgp: + router-id: 0.12.1.75 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::529 + interfaces: + Loopback0: + ipv6: fc00:c:c:14b::1/128 + Ethernet1: + ipv6: fc00:a::52a/126 + bp_interface: + ipv6: fc00:b::14b/64 + + ARISTA330T1: + properties: + - common + bgp: + router-id: 0.12.1.76 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::52d + interfaces: + Loopback0: + ipv6: fc00:c:c:14c::1/128 + Ethernet1: + ipv6: fc00:a::52e/126 + bp_interface: + ipv6: fc00:b::14c/64 + + ARISTA331T1: + properties: + - common + bgp: + router-id: 0.12.1.77 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::531 + interfaces: + Loopback0: + ipv6: fc00:c:c:14d::1/128 + Ethernet1: + ipv6: fc00:a::532/126 + bp_interface: + ipv6: fc00:b::14d/64 + + ARISTA332T1: + properties: + - common + bgp: + router-id: 0.12.1.78 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::535 + interfaces: + Loopback0: + ipv6: fc00:c:c:14e::1/128 + Ethernet1: + ipv6: fc00:a::536/126 + bp_interface: + ipv6: fc00:b::14e/64 + + ARISTA333T1: + properties: + - common + bgp: + router-id: 0.12.1.79 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::539 + interfaces: + Loopback0: + ipv6: fc00:c:c:14f::1/128 + Ethernet1: + ipv6: fc00:a::53a/126 + bp_interface: + ipv6: fc00:b::14f/64 + + ARISTA334T1: + properties: + - common + bgp: + router-id: 0.12.1.80 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::53d + interfaces: + Loopback0: + ipv6: fc00:c:c:150::1/128 + Ethernet1: + ipv6: fc00:a::53e/126 + bp_interface: + ipv6: fc00:b::150/64 + + ARISTA335T1: + properties: + - common + bgp: + router-id: 0.12.1.81 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::541 + interfaces: + Loopback0: + ipv6: fc00:c:c:151::1/128 + Ethernet1: + ipv6: fc00:a::542/126 + bp_interface: + ipv6: fc00:b::151/64 + + ARISTA336T1: + properties: + - common + bgp: + router-id: 0.12.1.82 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::545 + interfaces: + Loopback0: + ipv6: fc00:c:c:152::1/128 + Ethernet1: + ipv6: fc00:a::546/126 + bp_interface: + ipv6: fc00:b::152/64 + + ARISTA337T1: + properties: + - common + bgp: + router-id: 0.12.1.83 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::549 + interfaces: + Loopback0: + ipv6: fc00:c:c:153::1/128 + Ethernet1: + ipv6: fc00:a::54a/126 + bp_interface: + ipv6: fc00:b::153/64 + + ARISTA338T1: + properties: + - common + bgp: + router-id: 0.12.1.84 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::54d + interfaces: + Loopback0: + ipv6: fc00:c:c:154::1/128 + Ethernet1: + ipv6: fc00:a::54e/126 + bp_interface: + ipv6: fc00:b::154/64 + + ARISTA339T1: + properties: + - common + bgp: + router-id: 0.12.1.85 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::551 + interfaces: + Loopback0: + ipv6: fc00:c:c:155::1/128 + Ethernet1: + ipv6: fc00:a::552/126 + bp_interface: + ipv6: fc00:b::155/64 + + ARISTA340T1: + properties: + - common + bgp: + router-id: 0.12.1.86 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::555 + interfaces: + Loopback0: + ipv6: fc00:c:c:156::1/128 + Ethernet1: + ipv6: fc00:a::556/126 + bp_interface: + ipv6: fc00:b::156/64 + + ARISTA341T1: + properties: + - common + bgp: + router-id: 0.12.1.87 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::559 + interfaces: + Loopback0: + ipv6: fc00:c:c:157::1/128 + Ethernet1: + ipv6: fc00:a::55a/126 + bp_interface: + ipv6: fc00:b::157/64 + + ARISTA342T1: + properties: + - common + bgp: + router-id: 0.12.1.88 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::55d + interfaces: + Loopback0: + ipv6: fc00:c:c:158::1/128 + Ethernet1: + ipv6: fc00:a::55e/126 + bp_interface: + ipv6: fc00:b::158/64 + + ARISTA343T1: + properties: + - common + bgp: + router-id: 0.12.1.89 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::561 + interfaces: + Loopback0: + ipv6: fc00:c:c:159::1/128 + Ethernet1: + ipv6: fc00:a::562/126 + bp_interface: + ipv6: fc00:b::159/64 + + ARISTA344T1: + properties: + - common + bgp: + router-id: 0.12.1.90 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::565 + interfaces: + Loopback0: + ipv6: fc00:c:c:15a::1/128 + Ethernet1: + ipv6: fc00:a::566/126 + bp_interface: + ipv6: fc00:b::15a/64 + + ARISTA345T1: + properties: + - common + bgp: + router-id: 0.12.1.91 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::569 + interfaces: + Loopback0: + ipv6: fc00:c:c:15b::1/128 + Ethernet1: + ipv6: fc00:a::56a/126 + bp_interface: + ipv6: fc00:b::15b/64 + + ARISTA346T1: + properties: + - common + bgp: + router-id: 0.12.1.92 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::56d + interfaces: + Loopback0: + ipv6: fc00:c:c:15c::1/128 + Ethernet1: + ipv6: fc00:a::56e/126 + bp_interface: + ipv6: fc00:b::15c/64 + + ARISTA347T1: + properties: + - common + bgp: + router-id: 0.12.1.93 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::571 + interfaces: + Loopback0: + ipv6: fc00:c:c:15d::1/128 + Ethernet1: + ipv6: fc00:a::572/126 + bp_interface: + ipv6: fc00:b::15d/64 + + ARISTA348T1: + properties: + - common + bgp: + router-id: 0.12.1.94 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::575 + interfaces: + Loopback0: + ipv6: fc00:c:c:15e::1/128 + Ethernet1: + ipv6: fc00:a::576/126 + bp_interface: + ipv6: fc00:b::15e/64 + + ARISTA349T1: + properties: + - common + bgp: + router-id: 0.12.1.95 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::579 + interfaces: + Loopback0: + ipv6: fc00:c:c:15f::1/128 + Ethernet1: + ipv6: fc00:a::57a/126 + bp_interface: + ipv6: fc00:b::15f/64 + + ARISTA350T1: + properties: + - common + bgp: + router-id: 0.12.1.96 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::57d + interfaces: + Loopback0: + ipv6: fc00:c:c:160::1/128 + Ethernet1: + ipv6: fc00:a::57e/126 + bp_interface: + ipv6: fc00:b::160/64 + + ARISTA351T1: + properties: + - common + bgp: + router-id: 0.12.1.97 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::581 + interfaces: + Loopback0: + ipv6: fc00:c:c:161::1/128 + Ethernet1: + ipv6: fc00:a::582/126 + bp_interface: + ipv6: fc00:b::161/64 + + ARISTA352T1: + properties: + - common + bgp: + router-id: 0.12.1.98 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::585 + interfaces: + Loopback0: + ipv6: fc00:c:c:162::1/128 + Ethernet1: + ipv6: fc00:a::586/126 + bp_interface: + ipv6: fc00:b::162/64 + + ARISTA353T1: + properties: + - common + bgp: + router-id: 0.12.1.99 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::589 + interfaces: + Loopback0: + ipv6: fc00:c:c:163::1/128 + Ethernet1: + ipv6: fc00:a::58a/126 + bp_interface: + ipv6: fc00:b::163/64 + + ARISTA354T1: + properties: + - common + bgp: + router-id: 0.12.1.100 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::58d + interfaces: + Loopback0: + ipv6: fc00:c:c:164::1/128 + Ethernet1: + ipv6: fc00:a::58e/126 + bp_interface: + ipv6: fc00:b::164/64 + + ARISTA355T1: + properties: + - common + bgp: + router-id: 0.12.1.101 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::591 + interfaces: + Loopback0: + ipv6: fc00:c:c:165::1/128 + Ethernet1: + ipv6: fc00:a::592/126 + bp_interface: + ipv6: fc00:b::165/64 + + ARISTA356T1: + properties: + - common + bgp: + router-id: 0.12.1.102 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::595 + interfaces: + Loopback0: + ipv6: fc00:c:c:166::1/128 + Ethernet1: + ipv6: fc00:a::596/126 + bp_interface: + ipv6: fc00:b::166/64 + + ARISTA357T1: + properties: + - common + bgp: + router-id: 0.12.1.103 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::599 + interfaces: + Loopback0: + ipv6: fc00:c:c:167::1/128 + Ethernet1: + ipv6: fc00:a::59a/126 + bp_interface: + ipv6: fc00:b::167/64 + + ARISTA358T1: + properties: + - common + bgp: + router-id: 0.12.1.104 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::59d + interfaces: + Loopback0: + ipv6: fc00:c:c:168::1/128 + Ethernet1: + ipv6: fc00:a::59e/126 + bp_interface: + ipv6: fc00:b::168/64 + + ARISTA359T1: + properties: + - common + bgp: + router-id: 0.12.1.105 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:169::1/128 + Ethernet1: + ipv6: fc00:a::5a2/126 + bp_interface: + ipv6: fc00:b::169/64 + + ARISTA360T1: + properties: + - common + bgp: + router-id: 0.12.1.106 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:16a::1/128 + Ethernet1: + ipv6: fc00:a::5a6/126 + bp_interface: + ipv6: fc00:b::16a/64 + + ARISTA361T1: + properties: + - common + bgp: + router-id: 0.12.1.107 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:16b::1/128 + Ethernet1: + ipv6: fc00:a::5aa/126 + bp_interface: + ipv6: fc00:b::16b/64 + + ARISTA362T1: + properties: + - common + bgp: + router-id: 0.12.1.108 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5ad + interfaces: + Loopback0: + ipv6: fc00:c:c:16c::1/128 + Ethernet1: + ipv6: fc00:a::5ae/126 + bp_interface: + ipv6: fc00:b::16c/64 + + ARISTA363T1: + properties: + - common + bgp: + router-id: 0.12.1.109 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:16d::1/128 + Ethernet1: + ipv6: fc00:a::5b2/126 + bp_interface: + ipv6: fc00:b::16d/64 + + ARISTA364T1: + properties: + - common + bgp: + router-id: 0.12.1.110 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:16e::1/128 + Ethernet1: + ipv6: fc00:a::5b6/126 + bp_interface: + ipv6: fc00:b::16e/64 + + ARISTA365T1: + properties: + - common + bgp: + router-id: 0.12.1.111 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:16f::1/128 + Ethernet1: + ipv6: fc00:a::5ba/126 + bp_interface: + ipv6: fc00:b::16f/64 + + ARISTA366T1: + properties: + - common + bgp: + router-id: 0.12.1.112 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5bd + interfaces: + Loopback0: + ipv6: fc00:c:c:170::1/128 + Ethernet1: + ipv6: fc00:a::5be/126 + bp_interface: + ipv6: fc00:b::170/64 + + ARISTA367T1: + properties: + - common + bgp: + router-id: 0.12.1.113 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:171::1/128 + Ethernet1: + ipv6: fc00:a::5c2/126 + bp_interface: + ipv6: fc00:b::171/64 + + ARISTA368T1: + properties: + - common + bgp: + router-id: 0.12.1.114 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:172::1/128 + Ethernet1: + ipv6: fc00:a::5c6/126 + bp_interface: + ipv6: fc00:b::172/64 + + ARISTA369T1: + properties: + - common + bgp: + router-id: 0.12.1.115 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:173::1/128 + Ethernet1: + ipv6: fc00:a::5ca/126 + bp_interface: + ipv6: fc00:b::173/64 + + ARISTA370T1: + properties: + - common + bgp: + router-id: 0.12.1.116 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5cd + interfaces: + Loopback0: + ipv6: fc00:c:c:174::1/128 + Ethernet1: + ipv6: fc00:a::5ce/126 + bp_interface: + ipv6: fc00:b::174/64 + + ARISTA371T1: + properties: + - common + bgp: + router-id: 0.12.1.117 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:175::1/128 + Ethernet1: + ipv6: fc00:a::5d2/126 + bp_interface: + ipv6: fc00:b::175/64 + + ARISTA372T1: + properties: + - common + bgp: + router-id: 0.12.1.118 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:176::1/128 + Ethernet1: + ipv6: fc00:a::5d6/126 + bp_interface: + ipv6: fc00:b::176/64 + + ARISTA373T1: + properties: + - common + bgp: + router-id: 0.12.1.119 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:177::1/128 + Ethernet1: + ipv6: fc00:a::5da/126 + bp_interface: + ipv6: fc00:b::177/64 + + ARISTA374T1: + properties: + - common + bgp: + router-id: 0.12.1.120 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5dd + interfaces: + Loopback0: + ipv6: fc00:c:c:178::1/128 + Ethernet1: + ipv6: fc00:a::5de/126 + bp_interface: + ipv6: fc00:b::178/64 + + ARISTA375T1: + properties: + - common + bgp: + router-id: 0.12.1.121 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:179::1/128 + Ethernet1: + ipv6: fc00:a::5e2/126 + bp_interface: + ipv6: fc00:b::179/64 + + ARISTA376T1: + properties: + - common + bgp: + router-id: 0.12.1.122 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:17a::1/128 + Ethernet1: + ipv6: fc00:a::5e6/126 + bp_interface: + ipv6: fc00:b::17a/64 + + ARISTA377T1: + properties: + - common + bgp: + router-id: 0.12.1.123 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:17b::1/128 + Ethernet1: + ipv6: fc00:a::5ea/126 + bp_interface: + ipv6: fc00:b::17b/64 + + ARISTA378T1: + properties: + - common + bgp: + router-id: 0.12.1.124 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5ed + interfaces: + Loopback0: + ipv6: fc00:c:c:17c::1/128 + Ethernet1: + ipv6: fc00:a::5ee/126 + bp_interface: + ipv6: fc00:b::17c/64 + + ARISTA379T1: + properties: + - common + bgp: + router-id: 0.12.1.125 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:17d::1/128 + Ethernet1: + ipv6: fc00:a::5f2/126 + bp_interface: + ipv6: fc00:b::17d/64 + + ARISTA380T1: + properties: + - common + bgp: + router-id: 0.12.1.126 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:17e::1/128 + Ethernet1: + ipv6: fc00:a::5f6/126 + bp_interface: + ipv6: fc00:b::17e/64 + + ARISTA381T1: + properties: + - common + bgp: + router-id: 0.12.1.127 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:17f::1/128 + Ethernet1: + ipv6: fc00:a::5fa/126 + bp_interface: + ipv6: fc00:b::17f/64 + + ARISTA382T1: + properties: + - common + bgp: + router-id: 0.12.1.128 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::5fd + interfaces: + Loopback0: + ipv6: fc00:c:c:180::1/128 + Ethernet1: + ipv6: fc00:a::5fe/126 + bp_interface: + ipv6: fc00:b::180/64 + + ARISTA383T1: + properties: + - common + bgp: + router-id: 0.12.1.129 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::601 + interfaces: + Loopback0: + ipv6: fc00:c:c:181::1/128 + Ethernet1: + ipv6: fc00:a::602/126 + bp_interface: + ipv6: fc00:b::181/64 + + ARISTA384T1: + properties: + - common + bgp: + router-id: 0.12.1.130 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::605 + interfaces: + Loopback0: + ipv6: fc00:c:c:182::1/128 + Ethernet1: + ipv6: fc00:a::606/126 + bp_interface: + ipv6: fc00:b::182/64 + + ARISTA385T1: + properties: + - common + bgp: + router-id: 0.12.1.131 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::609 + interfaces: + Loopback0: + ipv6: fc00:c:c:183::1/128 + Ethernet1: + ipv6: fc00:a::60a/126 + bp_interface: + ipv6: fc00:b::183/64 + + ARISTA386T1: + properties: + - common + bgp: + router-id: 0.12.1.132 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::60d + interfaces: + Loopback0: + ipv6: fc00:c:c:184::1/128 + Ethernet1: + ipv6: fc00:a::60e/126 + bp_interface: + ipv6: fc00:b::184/64 + + ARISTA387T1: + properties: + - common + bgp: + router-id: 0.12.1.133 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::611 + interfaces: + Loopback0: + ipv6: fc00:c:c:185::1/128 + Ethernet1: + ipv6: fc00:a::612/126 + bp_interface: + ipv6: fc00:b::185/64 + + ARISTA388T1: + properties: + - common + bgp: + router-id: 0.12.1.134 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::615 + interfaces: + Loopback0: + ipv6: fc00:c:c:186::1/128 + Ethernet1: + ipv6: fc00:a::616/126 + bp_interface: + ipv6: fc00:b::186/64 + + ARISTA389T1: + properties: + - common + bgp: + router-id: 0.12.1.135 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::619 + interfaces: + Loopback0: + ipv6: fc00:c:c:187::1/128 + Ethernet1: + ipv6: fc00:a::61a/126 + bp_interface: + ipv6: fc00:b::187/64 + + ARISTA390T1: + properties: + - common + bgp: + router-id: 0.12.1.136 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::61d + interfaces: + Loopback0: + ipv6: fc00:c:c:188::1/128 + Ethernet1: + ipv6: fc00:a::61e/126 + bp_interface: + ipv6: fc00:b::188/64 + + ARISTA391T1: + properties: + - common + bgp: + router-id: 0.12.1.137 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::621 + interfaces: + Loopback0: + ipv6: fc00:c:c:189::1/128 + Ethernet1: + ipv6: fc00:a::622/126 + bp_interface: + ipv6: fc00:b::189/64 + + ARISTA392T1: + properties: + - common + bgp: + router-id: 0.12.1.138 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::625 + interfaces: + Loopback0: + ipv6: fc00:c:c:18a::1/128 + Ethernet1: + ipv6: fc00:a::626/126 + bp_interface: + ipv6: fc00:b::18a/64 + + ARISTA393T1: + properties: + - common + bgp: + router-id: 0.12.1.139 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::629 + interfaces: + Loopback0: + ipv6: fc00:c:c:18b::1/128 + Ethernet1: + ipv6: fc00:a::62a/126 + bp_interface: + ipv6: fc00:b::18b/64 + + ARISTA394T1: + properties: + - common + bgp: + router-id: 0.12.1.140 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::62d + interfaces: + Loopback0: + ipv6: fc00:c:c:18c::1/128 + Ethernet1: + ipv6: fc00:a::62e/126 + bp_interface: + ipv6: fc00:b::18c/64 + + ARISTA395T1: + properties: + - common + bgp: + router-id: 0.12.1.141 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::631 + interfaces: + Loopback0: + ipv6: fc00:c:c:18d::1/128 + Ethernet1: + ipv6: fc00:a::632/126 + bp_interface: + ipv6: fc00:b::18d/64 + + ARISTA396T1: + properties: + - common + bgp: + router-id: 0.12.1.142 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::635 + interfaces: + Loopback0: + ipv6: fc00:c:c:18e::1/128 + Ethernet1: + ipv6: fc00:a::636/126 + bp_interface: + ipv6: fc00:b::18e/64 + + ARISTA397T1: + properties: + - common + bgp: + router-id: 0.12.1.143 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::639 + interfaces: + Loopback0: + ipv6: fc00:c:c:18f::1/128 + Ethernet1: + ipv6: fc00:a::63a/126 + bp_interface: + ipv6: fc00:b::18f/64 + + ARISTA398T1: + properties: + - common + bgp: + router-id: 0.12.1.144 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::63d + interfaces: + Loopback0: + ipv6: fc00:c:c:190::1/128 + Ethernet1: + ipv6: fc00:a::63e/126 + bp_interface: + ipv6: fc00:b::190/64 + + ARISTA399T1: + properties: + - common + bgp: + router-id: 0.12.1.145 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::641 + interfaces: + Loopback0: + ipv6: fc00:c:c:191::1/128 + Ethernet1: + ipv6: fc00:a::642/126 + bp_interface: + ipv6: fc00:b::191/64 + + ARISTA400T1: + properties: + - common + bgp: + router-id: 0.12.1.146 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::645 + interfaces: + Loopback0: + ipv6: fc00:c:c:192::1/128 + Ethernet1: + ipv6: fc00:a::646/126 + bp_interface: + ipv6: fc00:b::192/64 + + ARISTA401T1: + properties: + - common + bgp: + router-id: 0.12.1.147 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::649 + interfaces: + Loopback0: + ipv6: fc00:c:c:193::1/128 + Ethernet1: + ipv6: fc00:a::64a/126 + bp_interface: + ipv6: fc00:b::193/64 + + ARISTA402T1: + properties: + - common + bgp: + router-id: 0.12.1.148 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::64d + interfaces: + Loopback0: + ipv6: fc00:c:c:194::1/128 + Ethernet1: + ipv6: fc00:a::64e/126 + bp_interface: + ipv6: fc00:b::194/64 + + ARISTA403T1: + properties: + - common + bgp: + router-id: 0.12.1.149 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::651 + interfaces: + Loopback0: + ipv6: fc00:c:c:195::1/128 + Ethernet1: + ipv6: fc00:a::652/126 + bp_interface: + ipv6: fc00:b::195/64 + + ARISTA404T1: + properties: + - common + bgp: + router-id: 0.12.1.150 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::655 + interfaces: + Loopback0: + ipv6: fc00:c:c:196::1/128 + Ethernet1: + ipv6: fc00:a::656/126 + bp_interface: + ipv6: fc00:b::196/64 + + ARISTA405T1: + properties: + - common + bgp: + router-id: 0.12.1.151 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::659 + interfaces: + Loopback0: + ipv6: fc00:c:c:197::1/128 + Ethernet1: + ipv6: fc00:a::65a/126 + bp_interface: + ipv6: fc00:b::197/64 + + ARISTA406T1: + properties: + - common + bgp: + router-id: 0.12.1.152 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::65d + interfaces: + Loopback0: + ipv6: fc00:c:c:198::1/128 + Ethernet1: + ipv6: fc00:a::65e/126 + bp_interface: + ipv6: fc00:b::198/64 + + ARISTA407T1: + properties: + - common + bgp: + router-id: 0.12.1.153 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::661 + interfaces: + Loopback0: + ipv6: fc00:c:c:199::1/128 + Ethernet1: + ipv6: fc00:a::662/126 + bp_interface: + ipv6: fc00:b::199/64 + + ARISTA408T1: + properties: + - common + bgp: + router-id: 0.12.1.154 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::665 + interfaces: + Loopback0: + ipv6: fc00:c:c:19a::1/128 + Ethernet1: + ipv6: fc00:a::666/126 + bp_interface: + ipv6: fc00:b::19a/64 + + ARISTA409T1: + properties: + - common + bgp: + router-id: 0.12.1.155 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::669 + interfaces: + Loopback0: + ipv6: fc00:c:c:19b::1/128 + Ethernet1: + ipv6: fc00:a::66a/126 + bp_interface: + ipv6: fc00:b::19b/64 + + ARISTA410T1: + properties: + - common + bgp: + router-id: 0.12.1.156 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::66d + interfaces: + Loopback0: + ipv6: fc00:c:c:19c::1/128 + Ethernet1: + ipv6: fc00:a::66e/126 + bp_interface: + ipv6: fc00:b::19c/64 + + ARISTA411T1: + properties: + - common + bgp: + router-id: 0.12.1.157 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::671 + interfaces: + Loopback0: + ipv6: fc00:c:c:19d::1/128 + Ethernet1: + ipv6: fc00:a::672/126 + bp_interface: + ipv6: fc00:b::19d/64 + + ARISTA412T1: + properties: + - common + bgp: + router-id: 0.12.1.158 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::675 + interfaces: + Loopback0: + ipv6: fc00:c:c:19e::1/128 + Ethernet1: + ipv6: fc00:a::676/126 + bp_interface: + ipv6: fc00:b::19e/64 + + ARISTA413T1: + properties: + - common + bgp: + router-id: 0.12.1.159 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::679 + interfaces: + Loopback0: + ipv6: fc00:c:c:19f::1/128 + Ethernet1: + ipv6: fc00:a::67a/126 + bp_interface: + ipv6: fc00:b::19f/64 + + ARISTA414T1: + properties: + - common + bgp: + router-id: 0.12.1.160 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::67d + interfaces: + Loopback0: + ipv6: fc00:c:c:1a0::1/128 + Ethernet1: + ipv6: fc00:a::67e/126 + bp_interface: + ipv6: fc00:b::1a0/64 + + ARISTA415T1: + properties: + - common + bgp: + router-id: 0.12.1.161 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::681 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a1::1/128 + Ethernet1: + ipv6: fc00:a::682/126 + bp_interface: + ipv6: fc00:b::1a1/64 + + ARISTA416T1: + properties: + - common + bgp: + router-id: 0.12.1.162 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::685 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a2::1/128 + Ethernet1: + ipv6: fc00:a::686/126 + bp_interface: + ipv6: fc00:b::1a2/64 + + ARISTA417T1: + properties: + - common + bgp: + router-id: 0.12.1.163 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::689 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a3::1/128 + Ethernet1: + ipv6: fc00:a::68a/126 + bp_interface: + ipv6: fc00:b::1a3/64 + + ARISTA418T1: + properties: + - common + bgp: + router-id: 0.12.1.164 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::68d + interfaces: + Loopback0: + ipv6: fc00:c:c:1a4::1/128 + Ethernet1: + ipv6: fc00:a::68e/126 + bp_interface: + ipv6: fc00:b::1a4/64 + + ARISTA419T1: + properties: + - common + bgp: + router-id: 0.12.1.165 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::691 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a5::1/128 + Ethernet1: + ipv6: fc00:a::692/126 + bp_interface: + ipv6: fc00:b::1a5/64 + + ARISTA420T1: + properties: + - common + bgp: + router-id: 0.12.1.166 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::695 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a6::1/128 + Ethernet1: + ipv6: fc00:a::696/126 + bp_interface: + ipv6: fc00:b::1a6/64 + + ARISTA421T1: + properties: + - common + bgp: + router-id: 0.12.1.167 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::699 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a7::1/128 + Ethernet1: + ipv6: fc00:a::69a/126 + bp_interface: + ipv6: fc00:b::1a7/64 + + ARISTA422T1: + properties: + - common + bgp: + router-id: 0.12.1.168 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::69d + interfaces: + Loopback0: + ipv6: fc00:c:c:1a8::1/128 + Ethernet1: + ipv6: fc00:a::69e/126 + bp_interface: + ipv6: fc00:b::1a8/64 + + ARISTA423T1: + properties: + - common + bgp: + router-id: 0.12.1.169 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a9::1/128 + Ethernet1: + ipv6: fc00:a::6a2/126 + bp_interface: + ipv6: fc00:b::1a9/64 + + ARISTA424T1: + properties: + - common + bgp: + router-id: 0.12.1.170 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1aa::1/128 + Ethernet1: + ipv6: fc00:a::6a6/126 + bp_interface: + ipv6: fc00:b::1aa/64 + + ARISTA425T1: + properties: + - common + bgp: + router-id: 0.12.1.171 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ab::1/128 + Ethernet1: + ipv6: fc00:a::6aa/126 + bp_interface: + ipv6: fc00:b::1ab/64 + + ARISTA426T1: + properties: + - common + bgp: + router-id: 0.12.1.172 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6ad + interfaces: + Loopback0: + ipv6: fc00:c:c:1ac::1/128 + Ethernet1: + ipv6: fc00:a::6ae/126 + bp_interface: + ipv6: fc00:b::1ac/64 + + ARISTA427T1: + properties: + - common + bgp: + router-id: 0.12.1.173 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ad::1/128 + Ethernet1: + ipv6: fc00:a::6b2/126 + bp_interface: + ipv6: fc00:b::1ad/64 + + ARISTA428T1: + properties: + - common + bgp: + router-id: 0.12.1.174 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ae::1/128 + Ethernet1: + ipv6: fc00:a::6b6/126 + bp_interface: + ipv6: fc00:b::1ae/64 + + ARISTA429T1: + properties: + - common + bgp: + router-id: 0.12.1.175 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1af::1/128 + Ethernet1: + ipv6: fc00:a::6ba/126 + bp_interface: + ipv6: fc00:b::1af/64 + + ARISTA430T1: + properties: + - common + bgp: + router-id: 0.12.1.176 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6bd + interfaces: + Loopback0: + ipv6: fc00:c:c:1b0::1/128 + Ethernet1: + ipv6: fc00:a::6be/126 + bp_interface: + ipv6: fc00:b::1b0/64 + + ARISTA431T1: + properties: + - common + bgp: + router-id: 0.12.1.177 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b1::1/128 + Ethernet1: + ipv6: fc00:a::6c2/126 + bp_interface: + ipv6: fc00:b::1b1/64 + + ARISTA432T1: + properties: + - common + bgp: + router-id: 0.12.1.178 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b2::1/128 + Ethernet1: + ipv6: fc00:a::6c6/126 + bp_interface: + ipv6: fc00:b::1b2/64 + + ARISTA433T1: + properties: + - common + bgp: + router-id: 0.12.1.179 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b3::1/128 + Ethernet1: + ipv6: fc00:a::6ca/126 + bp_interface: + ipv6: fc00:b::1b3/64 + + ARISTA434T1: + properties: + - common + bgp: + router-id: 0.12.1.180 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6cd + interfaces: + Loopback0: + ipv6: fc00:c:c:1b4::1/128 + Ethernet1: + ipv6: fc00:a::6ce/126 + bp_interface: + ipv6: fc00:b::1b4/64 + + ARISTA435T1: + properties: + - common + bgp: + router-id: 0.12.1.181 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b5::1/128 + Ethernet1: + ipv6: fc00:a::6d2/126 + bp_interface: + ipv6: fc00:b::1b5/64 + + ARISTA436T1: + properties: + - common + bgp: + router-id: 0.12.1.182 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b6::1/128 + Ethernet1: + ipv6: fc00:a::6d6/126 + bp_interface: + ipv6: fc00:b::1b6/64 + + ARISTA437T1: + properties: + - common + bgp: + router-id: 0.12.1.183 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b7::1/128 + Ethernet1: + ipv6: fc00:a::6da/126 + bp_interface: + ipv6: fc00:b::1b7/64 + + ARISTA438T1: + properties: + - common + bgp: + router-id: 0.12.1.184 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6dd + interfaces: + Loopback0: + ipv6: fc00:c:c:1b8::1/128 + Ethernet1: + ipv6: fc00:a::6de/126 + bp_interface: + ipv6: fc00:b::1b8/64 + + ARISTA439T1: + properties: + - common + bgp: + router-id: 0.12.1.185 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b9::1/128 + Ethernet1: + ipv6: fc00:a::6e2/126 + bp_interface: + ipv6: fc00:b::1b9/64 + + ARISTA440T1: + properties: + - common + bgp: + router-id: 0.12.1.186 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ba::1/128 + Ethernet1: + ipv6: fc00:a::6e6/126 + bp_interface: + ipv6: fc00:b::1ba/64 + + ARISTA441T1: + properties: + - common + bgp: + router-id: 0.12.1.187 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1bb::1/128 + Ethernet1: + ipv6: fc00:a::6ea/126 + bp_interface: + ipv6: fc00:b::1bb/64 + + ARISTA442T1: + properties: + - common + bgp: + router-id: 0.12.1.188 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6ed + interfaces: + Loopback0: + ipv6: fc00:c:c:1bc::1/128 + Ethernet1: + ipv6: fc00:a::6ee/126 + bp_interface: + ipv6: fc00:b::1bc/64 + + ARISTA443T1: + properties: + - common + bgp: + router-id: 0.12.1.189 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1bd::1/128 + Ethernet1: + ipv6: fc00:a::6f2/126 + bp_interface: + ipv6: fc00:b::1bd/64 + + ARISTA444T1: + properties: + - common + bgp: + router-id: 0.12.1.190 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1be::1/128 + Ethernet1: + ipv6: fc00:a::6f6/126 + bp_interface: + ipv6: fc00:b::1be/64 + + ARISTA445T1: + properties: + - common + bgp: + router-id: 0.12.1.191 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1bf::1/128 + Ethernet1: + ipv6: fc00:a::6fa/126 + bp_interface: + ipv6: fc00:b::1bf/64 + + ARISTA446T1: + properties: + - common + bgp: + router-id: 0.12.1.192 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::6fd + interfaces: + Loopback0: + ipv6: fc00:c:c:1c0::1/128 + Ethernet1: + ipv6: fc00:a::6fe/126 + bp_interface: + ipv6: fc00:b::1c0/64 + + ARISTA447T1: + properties: + - common + bgp: + router-id: 0.12.1.193 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::701 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c1::1/128 + Ethernet1: + ipv6: fc00:a::702/126 + bp_interface: + ipv6: fc00:b::1c1/64 + + ARISTA448T1: + properties: + - common + bgp: + router-id: 0.12.1.194 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::705 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c2::1/128 + Ethernet1: + ipv6: fc00:a::706/126 + bp_interface: + ipv6: fc00:b::1c2/64 + + ARISTA449T1: + properties: + - common + bgp: + router-id: 0.12.1.195 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::709 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c3::1/128 + Ethernet1: + ipv6: fc00:a::70a/126 + bp_interface: + ipv6: fc00:b::1c3/64 + + ARISTA450T1: + properties: + - common + bgp: + router-id: 0.12.1.196 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::70d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c4::1/128 + Ethernet1: + ipv6: fc00:a::70e/126 + bp_interface: + ipv6: fc00:b::1c4/64 + + ARISTA451T1: + properties: + - common + bgp: + router-id: 0.12.1.197 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::711 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c5::1/128 + Ethernet1: + ipv6: fc00:a::712/126 + bp_interface: + ipv6: fc00:b::1c5/64 + + ARISTA452T1: + properties: + - common + bgp: + router-id: 0.12.1.198 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::715 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c6::1/128 + Ethernet1: + ipv6: fc00:a::716/126 + bp_interface: + ipv6: fc00:b::1c6/64 + + ARISTA453T1: + properties: + - common + bgp: + router-id: 0.12.1.199 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::719 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c7::1/128 + Ethernet1: + ipv6: fc00:a::71a/126 + bp_interface: + ipv6: fc00:b::1c7/64 + + ARISTA454T1: + properties: + - common + bgp: + router-id: 0.12.1.200 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::71d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c8::1/128 + Ethernet1: + ipv6: fc00:a::71e/126 + bp_interface: + ipv6: fc00:b::1c8/64 + + ARISTA455T1: + properties: + - common + bgp: + router-id: 0.12.1.201 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::721 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c9::1/128 + Ethernet1: + ipv6: fc00:a::722/126 + bp_interface: + ipv6: fc00:b::1c9/64 + + ARISTA456T1: + properties: + - common + bgp: + router-id: 0.12.1.202 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::725 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ca::1/128 + Ethernet1: + ipv6: fc00:a::726/126 + bp_interface: + ipv6: fc00:b::1ca/64 + + ARISTA457T1: + properties: + - common + bgp: + router-id: 0.12.1.203 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::729 + interfaces: + Loopback0: + ipv6: fc00:c:c:1cb::1/128 + Ethernet1: + ipv6: fc00:a::72a/126 + bp_interface: + ipv6: fc00:b::1cb/64 + + ARISTA458T1: + properties: + - common + bgp: + router-id: 0.12.1.204 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::72d + interfaces: + Loopback0: + ipv6: fc00:c:c:1cc::1/128 + Ethernet1: + ipv6: fc00:a::72e/126 + bp_interface: + ipv6: fc00:b::1cc/64 + + ARISTA459T1: + properties: + - common + bgp: + router-id: 0.12.1.205 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::731 + interfaces: + Loopback0: + ipv6: fc00:c:c:1cd::1/128 + Ethernet1: + ipv6: fc00:a::732/126 + bp_interface: + ipv6: fc00:b::1cd/64 + + ARISTA460T1: + properties: + - common + bgp: + router-id: 0.12.1.206 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::735 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ce::1/128 + Ethernet1: + ipv6: fc00:a::736/126 + bp_interface: + ipv6: fc00:b::1ce/64 + + ARISTA461T1: + properties: + - common + bgp: + router-id: 0.12.1.207 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::739 + interfaces: + Loopback0: + ipv6: fc00:c:c:1cf::1/128 + Ethernet1: + ipv6: fc00:a::73a/126 + bp_interface: + ipv6: fc00:b::1cf/64 + + ARISTA462T1: + properties: + - common + bgp: + router-id: 0.12.1.208 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::73d + interfaces: + Loopback0: + ipv6: fc00:c:c:1d0::1/128 + Ethernet1: + ipv6: fc00:a::73e/126 + bp_interface: + ipv6: fc00:b::1d0/64 + + ARISTA463T1: + properties: + - common + bgp: + router-id: 0.12.1.209 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::741 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d1::1/128 + Ethernet1: + ipv6: fc00:a::742/126 + bp_interface: + ipv6: fc00:b::1d1/64 + + ARISTA464T1: + properties: + - common + bgp: + router-id: 0.12.1.210 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::745 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d2::1/128 + Ethernet1: + ipv6: fc00:a::746/126 + bp_interface: + ipv6: fc00:b::1d2/64 + + ARISTA465T1: + properties: + - common + bgp: + router-id: 0.12.1.211 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::749 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d3::1/128 + Ethernet1: + ipv6: fc00:a::74a/126 + bp_interface: + ipv6: fc00:b::1d3/64 + + ARISTA466T1: + properties: + - common + bgp: + router-id: 0.12.1.212 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::74d + interfaces: + Loopback0: + ipv6: fc00:c:c:1d4::1/128 + Ethernet1: + ipv6: fc00:a::74e/126 + bp_interface: + ipv6: fc00:b::1d4/64 + + ARISTA467T1: + properties: + - common + bgp: + router-id: 0.12.1.213 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::751 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d5::1/128 + Ethernet1: + ipv6: fc00:a::752/126 + bp_interface: + ipv6: fc00:b::1d5/64 + + ARISTA468T1: + properties: + - common + bgp: + router-id: 0.12.1.214 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::755 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d6::1/128 + Ethernet1: + ipv6: fc00:a::756/126 + bp_interface: + ipv6: fc00:b::1d6/64 + + ARISTA469T1: + properties: + - common + bgp: + router-id: 0.12.1.215 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::759 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d7::1/128 + Ethernet1: + ipv6: fc00:a::75a/126 + bp_interface: + ipv6: fc00:b::1d7/64 + + ARISTA470T1: + properties: + - common + bgp: + router-id: 0.12.1.216 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::75d + interfaces: + Loopback0: + ipv6: fc00:c:c:1d8::1/128 + Ethernet1: + ipv6: fc00:a::75e/126 + bp_interface: + ipv6: fc00:b::1d8/64 + + ARISTA471T1: + properties: + - common + bgp: + router-id: 0.12.1.217 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::761 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d9::1/128 + Ethernet1: + ipv6: fc00:a::762/126 + bp_interface: + ipv6: fc00:b::1d9/64 + + ARISTA472T1: + properties: + - common + bgp: + router-id: 0.12.1.218 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::765 + interfaces: + Loopback0: + ipv6: fc00:c:c:1da::1/128 + Ethernet1: + ipv6: fc00:a::766/126 + bp_interface: + ipv6: fc00:b::1da/64 + + ARISTA473T1: + properties: + - common + bgp: + router-id: 0.12.1.219 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::769 + interfaces: + Loopback0: + ipv6: fc00:c:c:1db::1/128 + Ethernet1: + ipv6: fc00:a::76a/126 + bp_interface: + ipv6: fc00:b::1db/64 + + ARISTA474T1: + properties: + - common + bgp: + router-id: 0.12.1.220 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::76d + interfaces: + Loopback0: + ipv6: fc00:c:c:1dc::1/128 + Ethernet1: + ipv6: fc00:a::76e/126 + bp_interface: + ipv6: fc00:b::1dc/64 + + ARISTA475T1: + properties: + - common + bgp: + router-id: 0.12.1.221 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::771 + interfaces: + Loopback0: + ipv6: fc00:c:c:1dd::1/128 + Ethernet1: + ipv6: fc00:a::772/126 + bp_interface: + ipv6: fc00:b::1dd/64 + + ARISTA476T1: + properties: + - common + bgp: + router-id: 0.12.1.222 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::775 + interfaces: + Loopback0: + ipv6: fc00:c:c:1de::1/128 + Ethernet1: + ipv6: fc00:a::776/126 + bp_interface: + ipv6: fc00:b::1de/64 + + ARISTA477T1: + properties: + - common + bgp: + router-id: 0.12.1.223 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::779 + interfaces: + Loopback0: + ipv6: fc00:c:c:1df::1/128 + Ethernet1: + ipv6: fc00:a::77a/126 + bp_interface: + ipv6: fc00:b::1df/64 + + ARISTA478T1: + properties: + - common + bgp: + router-id: 0.12.1.224 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::77d + interfaces: + Loopback0: + ipv6: fc00:c:c:1e0::1/128 + Ethernet1: + ipv6: fc00:a::77e/126 + bp_interface: + ipv6: fc00:b::1e0/64 + + ARISTA479T1: + properties: + - common + bgp: + router-id: 0.12.1.225 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::781 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e1::1/128 + Ethernet1: + ipv6: fc00:a::782/126 + bp_interface: + ipv6: fc00:b::1e1/64 + + ARISTA480T1: + properties: + - common + bgp: + router-id: 0.12.1.226 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::785 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e2::1/128 + Ethernet1: + ipv6: fc00:a::786/126 + bp_interface: + ipv6: fc00:b::1e2/64 + + ARISTA481T1: + properties: + - common + bgp: + router-id: 0.12.1.227 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::789 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e3::1/128 + Ethernet1: + ipv6: fc00:a::78a/126 + bp_interface: + ipv6: fc00:b::1e3/64 + + ARISTA482T1: + properties: + - common + bgp: + router-id: 0.12.1.228 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::78d + interfaces: + Loopback0: + ipv6: fc00:c:c:1e4::1/128 + Ethernet1: + ipv6: fc00:a::78e/126 + bp_interface: + ipv6: fc00:b::1e4/64 + + ARISTA483T1: + properties: + - common + bgp: + router-id: 0.12.1.229 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::791 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e5::1/128 + Ethernet1: + ipv6: fc00:a::792/126 + bp_interface: + ipv6: fc00:b::1e5/64 + + ARISTA484T1: + properties: + - common + bgp: + router-id: 0.12.1.230 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::795 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e6::1/128 + Ethernet1: + ipv6: fc00:a::796/126 + bp_interface: + ipv6: fc00:b::1e6/64 + + ARISTA485T1: + properties: + - common + bgp: + router-id: 0.12.1.231 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::799 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e7::1/128 + Ethernet1: + ipv6: fc00:a::79a/126 + bp_interface: + ipv6: fc00:b::1e7/64 + + ARISTA486T1: + properties: + - common + bgp: + router-id: 0.12.1.232 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::79d + interfaces: + Loopback0: + ipv6: fc00:c:c:1e8::1/128 + Ethernet1: + ipv6: fc00:a::79e/126 + bp_interface: + ipv6: fc00:b::1e8/64 + + ARISTA487T1: + properties: + - common + bgp: + router-id: 0.12.1.233 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e9::1/128 + Ethernet1: + ipv6: fc00:a::7a2/126 + bp_interface: + ipv6: fc00:b::1e9/64 + + ARISTA488T1: + properties: + - common + bgp: + router-id: 0.12.1.234 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ea::1/128 + Ethernet1: + ipv6: fc00:a::7a6/126 + bp_interface: + ipv6: fc00:b::1ea/64 + + ARISTA489T1: + properties: + - common + bgp: + router-id: 0.12.1.235 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1eb::1/128 + Ethernet1: + ipv6: fc00:a::7aa/126 + bp_interface: + ipv6: fc00:b::1eb/64 + + ARISTA490T1: + properties: + - common + bgp: + router-id: 0.12.1.236 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7ad + interfaces: + Loopback0: + ipv6: fc00:c:c:1ec::1/128 + Ethernet1: + ipv6: fc00:a::7ae/126 + bp_interface: + ipv6: fc00:b::1ec/64 + + ARISTA491T1: + properties: + - common + bgp: + router-id: 0.12.1.237 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ed::1/128 + Ethernet1: + ipv6: fc00:a::7b2/126 + bp_interface: + ipv6: fc00:b::1ed/64 + + ARISTA492T1: + properties: + - common + bgp: + router-id: 0.12.1.238 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ee::1/128 + Ethernet1: + ipv6: fc00:a::7b6/126 + bp_interface: + ipv6: fc00:b::1ee/64 + + ARISTA493T1: + properties: + - common + bgp: + router-id: 0.12.1.239 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ef::1/128 + Ethernet1: + ipv6: fc00:a::7ba/126 + bp_interface: + ipv6: fc00:b::1ef/64 + + ARISTA494T1: + properties: + - common + bgp: + router-id: 0.12.1.240 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7bd + interfaces: + Loopback0: + ipv6: fc00:c:c:1f0::1/128 + Ethernet1: + ipv6: fc00:a::7be/126 + bp_interface: + ipv6: fc00:b::1f0/64 + + ARISTA495T1: + properties: + - common + bgp: + router-id: 0.12.1.241 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f1::1/128 + Ethernet1: + ipv6: fc00:a::7c2/126 + bp_interface: + ipv6: fc00:b::1f1/64 + + ARISTA496T1: + properties: + - common + bgp: + router-id: 0.12.1.242 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f2::1/128 + Ethernet1: + ipv6: fc00:a::7c6/126 + bp_interface: + ipv6: fc00:b::1f2/64 + + ARISTA497T1: + properties: + - common + bgp: + router-id: 0.12.1.243 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f3::1/128 + Ethernet1: + ipv6: fc00:a::7ca/126 + bp_interface: + ipv6: fc00:b::1f3/64 + + ARISTA498T1: + properties: + - common + bgp: + router-id: 0.12.1.244 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7cd + interfaces: + Loopback0: + ipv6: fc00:c:c:1f4::1/128 + Ethernet1: + ipv6: fc00:a::7ce/126 + bp_interface: + ipv6: fc00:b::1f4/64 + + ARISTA499T1: + properties: + - common + bgp: + router-id: 0.12.1.245 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f5::1/128 + Ethernet1: + ipv6: fc00:a::7d2/126 + bp_interface: + ipv6: fc00:b::1f5/64 + + ARISTA500T1: + properties: + - common + bgp: + router-id: 0.12.1.246 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f6::1/128 + Ethernet1: + ipv6: fc00:a::7d6/126 + bp_interface: + ipv6: fc00:b::1f6/64 + + ARISTA501T1: + properties: + - common + bgp: + router-id: 0.12.1.247 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f7::1/128 + Ethernet1: + ipv6: fc00:a::7da/126 + bp_interface: + ipv6: fc00:b::1f7/64 + + ARISTA502T1: + properties: + - common + bgp: + router-id: 0.12.1.248 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7dd + interfaces: + Loopback0: + ipv6: fc00:c:c:1f8::1/128 + Ethernet1: + ipv6: fc00:a::7de/126 + bp_interface: + ipv6: fc00:b::1f8/64 + + ARISTA503T1: + properties: + - common + bgp: + router-id: 0.12.1.249 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f9::1/128 + Ethernet1: + ipv6: fc00:a::7e2/126 + bp_interface: + ipv6: fc00:b::1f9/64 + + ARISTA504T1: + properties: + - common + bgp: + router-id: 0.12.1.250 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fa::1/128 + Ethernet1: + ipv6: fc00:a::7e6/126 + bp_interface: + ipv6: fc00:b::1fa/64 + + ARISTA505T1: + properties: + - common + bgp: + router-id: 0.12.1.251 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fb::1/128 + Ethernet1: + ipv6: fc00:a::7ea/126 + bp_interface: + ipv6: fc00:b::1fb/64 + + ARISTA506T1: + properties: + - common + bgp: + router-id: 0.12.1.252 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7ed + interfaces: + Loopback0: + ipv6: fc00:c:c:1fc::1/128 + Ethernet1: + ipv6: fc00:a::7ee/126 + bp_interface: + ipv6: fc00:b::1fc/64 + + ARISTA507T1: + properties: + - common + bgp: + router-id: 0.12.1.253 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fd::1/128 + Ethernet1: + ipv6: fc00:a::7f2/126 + bp_interface: + ipv6: fc00:b::1fd/64 + + ARISTA508T1: + properties: + - common + bgp: + router-id: 0.12.1.254 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fe::1/128 + Ethernet1: + ipv6: fc00:a::7f6/126 + bp_interface: + ipv6: fc00:b::1fe/64 + + ARISTA509T1: + properties: + - common + bgp: + router-id: 0.12.1.255 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ff::1/128 + Ethernet1: + ipv6: fc00:a::7fa/126 + bp_interface: + ipv6: fc00:b::1ff/64 + + ARISTA510T1: + properties: + - common + bgp: + router-id: 0.12.2.0 + asn: 4200100000 + peers: + 4200000000: + - fc00:a::7fd + interfaces: + Loopback0: + ipv6: fc00:c:c:200::1/128 + Ethernet1: + ipv6: fc00:a::7fe/126 + bp_interface: + ipv6: fc00:b::200/64 diff --git a/ansible/vars/topo_t1-isolated-u2d254.yaml b/ansible/vars/topo_t1-isolated-u2d254.yaml new file mode 100644 index 00000000000..47477a6ba03 --- /dev/null +++ b/ansible/vars/topo_t1-isolated-u2d254.yaml @@ -0,0 +1,5650 @@ +topology: + VMs: + ARISTA01T2: + vlans: + - 0 + vm_offset: 0 + ARISTA02T2: + vlans: + - 1 + vm_offset: 1 + ARISTA01T0: + vlans: + - 2 + vm_offset: 2 + ARISTA02T0: + vlans: + - 3 + vm_offset: 3 + ARISTA03T0: + vlans: + - 4 + vm_offset: 4 + ARISTA04T0: + vlans: + - 5 + vm_offset: 5 + ARISTA05T0: + vlans: + - 6 + vm_offset: 6 + ARISTA06T0: + vlans: + - 7 + vm_offset: 7 + ARISTA07T0: + vlans: + - 8 + vm_offset: 8 + ARISTA08T0: + vlans: + - 9 + vm_offset: 9 + ARISTA09T0: + vlans: + - 10 + vm_offset: 10 + ARISTA10T0: + vlans: + - 11 + vm_offset: 11 + ARISTA11T0: + vlans: + - 12 + vm_offset: 12 + ARISTA12T0: + vlans: + - 13 + vm_offset: 13 + ARISTA13T0: + vlans: + - 14 + vm_offset: 14 + ARISTA14T0: + vlans: + - 15 + vm_offset: 15 + ARISTA15T0: + vlans: + - 16 + vm_offset: 16 + ARISTA16T0: + vlans: + - 17 + vm_offset: 17 + ARISTA17T0: + vlans: + - 18 + vm_offset: 18 + ARISTA18T0: + vlans: + - 19 + vm_offset: 19 + ARISTA19T0: + vlans: + - 20 + vm_offset: 20 + ARISTA20T0: + vlans: + - 21 + vm_offset: 21 + ARISTA21T0: + vlans: + - 22 + vm_offset: 22 + ARISTA22T0: + vlans: + - 23 + vm_offset: 23 + ARISTA23T0: + vlans: + - 24 + vm_offset: 24 + ARISTA24T0: + vlans: + - 25 + vm_offset: 25 + ARISTA25T0: + vlans: + - 26 + vm_offset: 26 + ARISTA26T0: + vlans: + - 27 + vm_offset: 27 + ARISTA27T0: + vlans: + - 28 + vm_offset: 28 + ARISTA28T0: + vlans: + - 29 + vm_offset: 29 + ARISTA29T0: + vlans: + - 30 + vm_offset: 30 + ARISTA30T0: + vlans: + - 31 + vm_offset: 31 + ARISTA31T0: + vlans: + - 32 + vm_offset: 32 + ARISTA32T0: + vlans: + - 33 + vm_offset: 33 + ARISTA33T0: + vlans: + - 34 + vm_offset: 34 + ARISTA34T0: + vlans: + - 35 + vm_offset: 35 + ARISTA35T0: + vlans: + - 36 + vm_offset: 36 + ARISTA36T0: + vlans: + - 37 + vm_offset: 37 + ARISTA37T0: + vlans: + - 38 + vm_offset: 38 + ARISTA38T0: + vlans: + - 39 + vm_offset: 39 + ARISTA39T0: + vlans: + - 40 + vm_offset: 40 + ARISTA40T0: + vlans: + - 41 + vm_offset: 41 + ARISTA41T0: + vlans: + - 42 + vm_offset: 42 + ARISTA42T0: + vlans: + - 43 + vm_offset: 43 + ARISTA43T0: + vlans: + - 44 + vm_offset: 44 + ARISTA44T0: + vlans: + - 45 + vm_offset: 45 + ARISTA45T0: + vlans: + - 46 + vm_offset: 46 + ARISTA46T0: + vlans: + - 47 + vm_offset: 47 + ARISTA47T0: + vlans: + - 48 + vm_offset: 48 + ARISTA48T0: + vlans: + - 49 + vm_offset: 49 + ARISTA49T0: + vlans: + - 50 + vm_offset: 50 + ARISTA50T0: + vlans: + - 51 + vm_offset: 51 + ARISTA51T0: + vlans: + - 52 + vm_offset: 52 + ARISTA52T0: + vlans: + - 53 + vm_offset: 53 + ARISTA53T0: + vlans: + - 54 + vm_offset: 54 + ARISTA54T0: + vlans: + - 55 + vm_offset: 55 + ARISTA55T0: + vlans: + - 56 + vm_offset: 56 + ARISTA56T0: + vlans: + - 57 + vm_offset: 57 + ARISTA57T0: + vlans: + - 58 + vm_offset: 58 + ARISTA58T0: + vlans: + - 59 + vm_offset: 59 + ARISTA59T0: + vlans: + - 60 + vm_offset: 60 + ARISTA60T0: + vlans: + - 61 + vm_offset: 61 + ARISTA61T0: + vlans: + - 62 + vm_offset: 62 + ARISTA62T0: + vlans: + - 63 + vm_offset: 63 + ARISTA63T0: + vlans: + - 64 + vm_offset: 64 + ARISTA64T0: + vlans: + - 65 + vm_offset: 65 + ARISTA65T0: + vlans: + - 66 + vm_offset: 66 + ARISTA66T0: + vlans: + - 67 + vm_offset: 67 + ARISTA67T0: + vlans: + - 68 + vm_offset: 68 + ARISTA68T0: + vlans: + - 69 + vm_offset: 69 + ARISTA69T0: + vlans: + - 70 + vm_offset: 70 + ARISTA70T0: + vlans: + - 71 + vm_offset: 71 + ARISTA71T0: + vlans: + - 72 + vm_offset: 72 + ARISTA72T0: + vlans: + - 73 + vm_offset: 73 + ARISTA73T0: + vlans: + - 74 + vm_offset: 74 + ARISTA74T0: + vlans: + - 75 + vm_offset: 75 + ARISTA75T0: + vlans: + - 76 + vm_offset: 76 + ARISTA76T0: + vlans: + - 77 + vm_offset: 77 + ARISTA77T0: + vlans: + - 78 + vm_offset: 78 + ARISTA78T0: + vlans: + - 79 + vm_offset: 79 + ARISTA79T0: + vlans: + - 80 + vm_offset: 80 + ARISTA80T0: + vlans: + - 81 + vm_offset: 81 + ARISTA81T0: + vlans: + - 82 + vm_offset: 82 + ARISTA82T0: + vlans: + - 83 + vm_offset: 83 + ARISTA83T0: + vlans: + - 84 + vm_offset: 84 + ARISTA84T0: + vlans: + - 85 + vm_offset: 85 + ARISTA85T0: + vlans: + - 86 + vm_offset: 86 + ARISTA86T0: + vlans: + - 87 + vm_offset: 87 + ARISTA87T0: + vlans: + - 88 + vm_offset: 88 + ARISTA88T0: + vlans: + - 89 + vm_offset: 89 + ARISTA89T0: + vlans: + - 90 + vm_offset: 90 + ARISTA90T0: + vlans: + - 91 + vm_offset: 91 + ARISTA91T0: + vlans: + - 92 + vm_offset: 92 + ARISTA92T0: + vlans: + - 93 + vm_offset: 93 + ARISTA93T0: + vlans: + - 94 + vm_offset: 94 + ARISTA94T0: + vlans: + - 95 + vm_offset: 95 + ARISTA95T0: + vlans: + - 96 + vm_offset: 96 + ARISTA96T0: + vlans: + - 97 + vm_offset: 97 + ARISTA97T0: + vlans: + - 98 + vm_offset: 98 + ARISTA98T0: + vlans: + - 99 + vm_offset: 99 + ARISTA99T0: + vlans: + - 100 + vm_offset: 100 + ARISTA100T0: + vlans: + - 101 + vm_offset: 101 + ARISTA101T0: + vlans: + - 102 + vm_offset: 102 + ARISTA102T0: + vlans: + - 103 + vm_offset: 103 + ARISTA103T0: + vlans: + - 104 + vm_offset: 104 + ARISTA104T0: + vlans: + - 105 + vm_offset: 105 + ARISTA105T0: + vlans: + - 106 + vm_offset: 106 + ARISTA106T0: + vlans: + - 107 + vm_offset: 107 + ARISTA107T0: + vlans: + - 108 + vm_offset: 108 + ARISTA108T0: + vlans: + - 109 + vm_offset: 109 + ARISTA109T0: + vlans: + - 110 + vm_offset: 110 + ARISTA110T0: + vlans: + - 111 + vm_offset: 111 + ARISTA111T0: + vlans: + - 112 + vm_offset: 112 + ARISTA112T0: + vlans: + - 113 + vm_offset: 113 + ARISTA113T0: + vlans: + - 114 + vm_offset: 114 + ARISTA114T0: + vlans: + - 115 + vm_offset: 115 + ARISTA115T0: + vlans: + - 116 + vm_offset: 116 + ARISTA116T0: + vlans: + - 117 + vm_offset: 117 + ARISTA117T0: + vlans: + - 118 + vm_offset: 118 + ARISTA118T0: + vlans: + - 119 + vm_offset: 119 + ARISTA119T0: + vlans: + - 120 + vm_offset: 120 + ARISTA120T0: + vlans: + - 121 + vm_offset: 121 + ARISTA121T0: + vlans: + - 122 + vm_offset: 122 + ARISTA122T0: + vlans: + - 123 + vm_offset: 123 + ARISTA123T0: + vlans: + - 124 + vm_offset: 124 + ARISTA124T0: + vlans: + - 125 + vm_offset: 125 + ARISTA125T0: + vlans: + - 126 + vm_offset: 126 + ARISTA126T0: + vlans: + - 127 + vm_offset: 127 + ARISTA127T0: + vlans: + - 128 + vm_offset: 128 + ARISTA128T0: + vlans: + - 129 + vm_offset: 129 + ARISTA129T0: + vlans: + - 130 + vm_offset: 130 + ARISTA130T0: + vlans: + - 131 + vm_offset: 131 + ARISTA131T0: + vlans: + - 132 + vm_offset: 132 + ARISTA132T0: + vlans: + - 133 + vm_offset: 133 + ARISTA133T0: + vlans: + - 134 + vm_offset: 134 + ARISTA134T0: + vlans: + - 135 + vm_offset: 135 + ARISTA135T0: + vlans: + - 136 + vm_offset: 136 + ARISTA136T0: + vlans: + - 137 + vm_offset: 137 + ARISTA137T0: + vlans: + - 138 + vm_offset: 138 + ARISTA138T0: + vlans: + - 139 + vm_offset: 139 + ARISTA139T0: + vlans: + - 140 + vm_offset: 140 + ARISTA140T0: + vlans: + - 141 + vm_offset: 141 + ARISTA141T0: + vlans: + - 142 + vm_offset: 142 + ARISTA142T0: + vlans: + - 143 + vm_offset: 143 + ARISTA143T0: + vlans: + - 144 + vm_offset: 144 + ARISTA144T0: + vlans: + - 145 + vm_offset: 145 + ARISTA145T0: + vlans: + - 146 + vm_offset: 146 + ARISTA146T0: + vlans: + - 147 + vm_offset: 147 + ARISTA147T0: + vlans: + - 148 + vm_offset: 148 + ARISTA148T0: + vlans: + - 149 + vm_offset: 149 + ARISTA149T0: + vlans: + - 150 + vm_offset: 150 + ARISTA150T0: + vlans: + - 151 + vm_offset: 151 + ARISTA151T0: + vlans: + - 152 + vm_offset: 152 + ARISTA152T0: + vlans: + - 153 + vm_offset: 153 + ARISTA153T0: + vlans: + - 154 + vm_offset: 154 + ARISTA154T0: + vlans: + - 155 + vm_offset: 155 + ARISTA155T0: + vlans: + - 156 + vm_offset: 156 + ARISTA156T0: + vlans: + - 157 + vm_offset: 157 + ARISTA157T0: + vlans: + - 158 + vm_offset: 158 + ARISTA158T0: + vlans: + - 159 + vm_offset: 159 + ARISTA159T0: + vlans: + - 160 + vm_offset: 160 + ARISTA160T0: + vlans: + - 161 + vm_offset: 161 + ARISTA161T0: + vlans: + - 162 + vm_offset: 162 + ARISTA162T0: + vlans: + - 163 + vm_offset: 163 + ARISTA163T0: + vlans: + - 164 + vm_offset: 164 + ARISTA164T0: + vlans: + - 165 + vm_offset: 165 + ARISTA165T0: + vlans: + - 166 + vm_offset: 166 + ARISTA166T0: + vlans: + - 167 + vm_offset: 167 + ARISTA167T0: + vlans: + - 168 + vm_offset: 168 + ARISTA168T0: + vlans: + - 169 + vm_offset: 169 + ARISTA169T0: + vlans: + - 170 + vm_offset: 170 + ARISTA170T0: + vlans: + - 171 + vm_offset: 171 + ARISTA171T0: + vlans: + - 172 + vm_offset: 172 + ARISTA172T0: + vlans: + - 173 + vm_offset: 173 + ARISTA173T0: + vlans: + - 174 + vm_offset: 174 + ARISTA174T0: + vlans: + - 175 + vm_offset: 175 + ARISTA175T0: + vlans: + - 176 + vm_offset: 176 + ARISTA176T0: + vlans: + - 177 + vm_offset: 177 + ARISTA177T0: + vlans: + - 178 + vm_offset: 178 + ARISTA178T0: + vlans: + - 179 + vm_offset: 179 + ARISTA179T0: + vlans: + - 180 + vm_offset: 180 + ARISTA180T0: + vlans: + - 181 + vm_offset: 181 + ARISTA181T0: + vlans: + - 182 + vm_offset: 182 + ARISTA182T0: + vlans: + - 183 + vm_offset: 183 + ARISTA183T0: + vlans: + - 184 + vm_offset: 184 + ARISTA184T0: + vlans: + - 185 + vm_offset: 185 + ARISTA185T0: + vlans: + - 186 + vm_offset: 186 + ARISTA186T0: + vlans: + - 187 + vm_offset: 187 + ARISTA187T0: + vlans: + - 188 + vm_offset: 188 + ARISTA188T0: + vlans: + - 189 + vm_offset: 189 + ARISTA189T0: + vlans: + - 190 + vm_offset: 190 + ARISTA190T0: + vlans: + - 191 + vm_offset: 191 + ARISTA191T0: + vlans: + - 192 + vm_offset: 192 + ARISTA192T0: + vlans: + - 193 + vm_offset: 193 + ARISTA193T0: + vlans: + - 194 + vm_offset: 194 + ARISTA194T0: + vlans: + - 195 + vm_offset: 195 + ARISTA195T0: + vlans: + - 196 + vm_offset: 196 + ARISTA196T0: + vlans: + - 197 + vm_offset: 197 + ARISTA197T0: + vlans: + - 198 + vm_offset: 198 + ARISTA198T0: + vlans: + - 199 + vm_offset: 199 + ARISTA199T0: + vlans: + - 200 + vm_offset: 200 + ARISTA200T0: + vlans: + - 201 + vm_offset: 201 + ARISTA201T0: + vlans: + - 202 + vm_offset: 202 + ARISTA202T0: + vlans: + - 203 + vm_offset: 203 + ARISTA203T0: + vlans: + - 204 + vm_offset: 204 + ARISTA204T0: + vlans: + - 205 + vm_offset: 205 + ARISTA205T0: + vlans: + - 206 + vm_offset: 206 + ARISTA206T0: + vlans: + - 207 + vm_offset: 207 + ARISTA207T0: + vlans: + - 208 + vm_offset: 208 + ARISTA208T0: + vlans: + - 209 + vm_offset: 209 + ARISTA209T0: + vlans: + - 210 + vm_offset: 210 + ARISTA210T0: + vlans: + - 211 + vm_offset: 211 + ARISTA211T0: + vlans: + - 212 + vm_offset: 212 + ARISTA212T0: + vlans: + - 213 + vm_offset: 213 + ARISTA213T0: + vlans: + - 214 + vm_offset: 214 + ARISTA214T0: + vlans: + - 215 + vm_offset: 215 + ARISTA215T0: + vlans: + - 216 + vm_offset: 216 + ARISTA216T0: + vlans: + - 217 + vm_offset: 217 + ARISTA217T0: + vlans: + - 218 + vm_offset: 218 + ARISTA218T0: + vlans: + - 219 + vm_offset: 219 + ARISTA219T0: + vlans: + - 220 + vm_offset: 220 + ARISTA220T0: + vlans: + - 221 + vm_offset: 221 + ARISTA221T0: + vlans: + - 222 + vm_offset: 222 + ARISTA222T0: + vlans: + - 223 + vm_offset: 223 + ARISTA223T0: + vlans: + - 224 + vm_offset: 224 + ARISTA224T0: + vlans: + - 225 + vm_offset: 225 + ARISTA225T0: + vlans: + - 226 + vm_offset: 226 + ARISTA226T0: + vlans: + - 227 + vm_offset: 227 + ARISTA227T0: + vlans: + - 228 + vm_offset: 228 + ARISTA228T0: + vlans: + - 229 + vm_offset: 229 + ARISTA229T0: + vlans: + - 230 + vm_offset: 230 + ARISTA230T0: + vlans: + - 231 + vm_offset: 231 + ARISTA231T0: + vlans: + - 232 + vm_offset: 232 + ARISTA232T0: + vlans: + - 233 + vm_offset: 233 + ARISTA233T0: + vlans: + - 234 + vm_offset: 234 + ARISTA234T0: + vlans: + - 235 + vm_offset: 235 + ARISTA235T0: + vlans: + - 236 + vm_offset: 236 + ARISTA236T0: + vlans: + - 237 + vm_offset: 237 + ARISTA237T0: + vlans: + - 238 + vm_offset: 238 + ARISTA238T0: + vlans: + - 239 + vm_offset: 239 + ARISTA239T0: + vlans: + - 240 + vm_offset: 240 + ARISTA240T0: + vlans: + - 241 + vm_offset: 241 + ARISTA241T0: + vlans: + - 242 + vm_offset: 242 + ARISTA242T0: + vlans: + - 243 + vm_offset: 243 + ARISTA243T0: + vlans: + - 244 + vm_offset: 244 + ARISTA244T0: + vlans: + - 245 + vm_offset: 245 + ARISTA245T0: + vlans: + - 246 + vm_offset: 246 + ARISTA246T0: + vlans: + - 247 + vm_offset: 247 + ARISTA247T0: + vlans: + - 248 + vm_offset: 248 + ARISTA248T0: + vlans: + - 249 + vm_offset: 249 + ARISTA249T0: + vlans: + - 250 + vm_offset: 250 + ARISTA250T0: + vlans: + - 251 + vm_offset: 251 + ARISTA251T0: + vlans: + - 252 + vm_offset: 252 + ARISTA252T0: + vlans: + - 253 + vm_offset: 253 + ARISTA253T0: + vlans: + - 254 + vm_offset: 254 + ARISTA254T0: + vlans: + - 255 + vm_offset: 255 + +configuration_properties: + common: + dut_asn: 4200100000 + dut_type: LeafRouter + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + nhipv6: FC0A::FF + spine: + swrole: spine + tor: + swrole: tor + +configuration: + ARISTA01T2: + properties: + - common + - spine + bgp: + router-id: 0.12.0.1 + asn: 4200200000 + peers: + 4200100000: + - fc00:a::1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1::1/128 + Ethernet1: + ipv6: fc00:a::2/126 + bp_interface: + ipv6: fc00:b::1/64 + + ARISTA02T2: + properties: + - common + - spine + bgp: + router-id: 0.12.0.2 + asn: 4200200000 + peers: + 4200100000: + - fc00:a::5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2::1/128 + Ethernet1: + ipv6: fc00:a::6/126 + bp_interface: + ipv6: fc00:b::2/64 + + ARISTA01T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.3 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3::1/128 + Ethernet1: + ipv6: fc00:a::a/126 + bp_interface: + ipv6: fc00:b::3/64 + + ARISTA02T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.4 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d + interfaces: + Loopback0: + ipv6: fc00:c:c:4::1/128 + Ethernet1: + ipv6: fc00:a::e/126 + bp_interface: + ipv6: fc00:b::4/64 + + ARISTA03T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.5 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::11 + interfaces: + Loopback0: + ipv6: fc00:c:c:5::1/128 + Ethernet1: + ipv6: fc00:a::12/126 + bp_interface: + ipv6: fc00:b::5/64 + + ARISTA04T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.6 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::15 + interfaces: + Loopback0: + ipv6: fc00:c:c:6::1/128 + Ethernet1: + ipv6: fc00:a::16/126 + bp_interface: + ipv6: fc00:b::6/64 + + ARISTA05T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.7 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::19 + interfaces: + Loopback0: + ipv6: fc00:c:c:7::1/128 + Ethernet1: + ipv6: fc00:a::1a/126 + bp_interface: + ipv6: fc00:b::7/64 + + ARISTA06T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.8 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d + interfaces: + Loopback0: + ipv6: fc00:c:c:8::1/128 + Ethernet1: + ipv6: fc00:a::1e/126 + bp_interface: + ipv6: fc00:b::8/64 + + ARISTA07T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.9 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::21 + interfaces: + Loopback0: + ipv6: fc00:c:c:9::1/128 + Ethernet1: + ipv6: fc00:a::22/126 + bp_interface: + ipv6: fc00:b::9/64 + + ARISTA08T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.10 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::25 + interfaces: + Loopback0: + ipv6: fc00:c:c:a::1/128 + Ethernet1: + ipv6: fc00:a::26/126 + bp_interface: + ipv6: fc00:b::a/64 + + ARISTA09T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.11 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::29 + interfaces: + Loopback0: + ipv6: fc00:c:c:b::1/128 + Ethernet1: + ipv6: fc00:a::2a/126 + bp_interface: + ipv6: fc00:b::b/64 + + ARISTA10T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.12 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d + interfaces: + Loopback0: + ipv6: fc00:c:c:c::1/128 + Ethernet1: + ipv6: fc00:a::2e/126 + bp_interface: + ipv6: fc00:b::c/64 + + ARISTA11T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.13 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::31 + interfaces: + Loopback0: + ipv6: fc00:c:c:d::1/128 + Ethernet1: + ipv6: fc00:a::32/126 + bp_interface: + ipv6: fc00:b::d/64 + + ARISTA12T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.14 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::35 + interfaces: + Loopback0: + ipv6: fc00:c:c:e::1/128 + Ethernet1: + ipv6: fc00:a::36/126 + bp_interface: + ipv6: fc00:b::e/64 + + ARISTA13T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.15 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::39 + interfaces: + Loopback0: + ipv6: fc00:c:c:f::1/128 + Ethernet1: + ipv6: fc00:a::3a/126 + bp_interface: + ipv6: fc00:b::f/64 + + ARISTA14T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.16 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d + interfaces: + Loopback0: + ipv6: fc00:c:c:10::1/128 + Ethernet1: + ipv6: fc00:a::3e/126 + bp_interface: + ipv6: fc00:b::10/64 + + ARISTA15T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.17 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::41 + interfaces: + Loopback0: + ipv6: fc00:c:c:11::1/128 + Ethernet1: + ipv6: fc00:a::42/126 + bp_interface: + ipv6: fc00:b::11/64 + + ARISTA16T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.18 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::45 + interfaces: + Loopback0: + ipv6: fc00:c:c:12::1/128 + Ethernet1: + ipv6: fc00:a::46/126 + bp_interface: + ipv6: fc00:b::12/64 + + ARISTA17T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.19 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::49 + interfaces: + Loopback0: + ipv6: fc00:c:c:13::1/128 + Ethernet1: + ipv6: fc00:a::4a/126 + bp_interface: + ipv6: fc00:b::13/64 + + ARISTA18T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.20 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4d + interfaces: + Loopback0: + ipv6: fc00:c:c:14::1/128 + Ethernet1: + ipv6: fc00:a::4e/126 + bp_interface: + ipv6: fc00:b::14/64 + + ARISTA19T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.21 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::51 + interfaces: + Loopback0: + ipv6: fc00:c:c:15::1/128 + Ethernet1: + ipv6: fc00:a::52/126 + bp_interface: + ipv6: fc00:b::15/64 + + ARISTA20T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.22 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::55 + interfaces: + Loopback0: + ipv6: fc00:c:c:16::1/128 + Ethernet1: + ipv6: fc00:a::56/126 + bp_interface: + ipv6: fc00:b::16/64 + + ARISTA21T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.23 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::59 + interfaces: + Loopback0: + ipv6: fc00:c:c:17::1/128 + Ethernet1: + ipv6: fc00:a::5a/126 + bp_interface: + ipv6: fc00:b::17/64 + + ARISTA22T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.24 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5d + interfaces: + Loopback0: + ipv6: fc00:c:c:18::1/128 + Ethernet1: + ipv6: fc00:a::5e/126 + bp_interface: + ipv6: fc00:b::18/64 + + ARISTA23T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.25 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::61 + interfaces: + Loopback0: + ipv6: fc00:c:c:19::1/128 + Ethernet1: + ipv6: fc00:a::62/126 + bp_interface: + ipv6: fc00:b::19/64 + + ARISTA24T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.26 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::65 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a::1/128 + Ethernet1: + ipv6: fc00:a::66/126 + bp_interface: + ipv6: fc00:b::1a/64 + + ARISTA25T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.27 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::69 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b::1/128 + Ethernet1: + ipv6: fc00:a::6a/126 + bp_interface: + ipv6: fc00:b::1b/64 + + ARISTA26T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.28 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c::1/128 + Ethernet1: + ipv6: fc00:a::6e/126 + bp_interface: + ipv6: fc00:b::1c/64 + + ARISTA27T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.29 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::71 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d::1/128 + Ethernet1: + ipv6: fc00:a::72/126 + bp_interface: + ipv6: fc00:b::1d/64 + + ARISTA28T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.30 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::75 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e::1/128 + Ethernet1: + ipv6: fc00:a::76/126 + bp_interface: + ipv6: fc00:b::1e/64 + + ARISTA29T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.31 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::79 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f::1/128 + Ethernet1: + ipv6: fc00:a::7a/126 + bp_interface: + ipv6: fc00:b::1f/64 + + ARISTA30T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.32 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7d + interfaces: + Loopback0: + ipv6: fc00:c:c:20::1/128 + Ethernet1: + ipv6: fc00:a::7e/126 + bp_interface: + ipv6: fc00:b::20/64 + + ARISTA31T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.33 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::81 + interfaces: + Loopback0: + ipv6: fc00:c:c:21::1/128 + Ethernet1: + ipv6: fc00:a::82/126 + bp_interface: + ipv6: fc00:b::21/64 + + ARISTA32T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.34 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::85 + interfaces: + Loopback0: + ipv6: fc00:c:c:22::1/128 + Ethernet1: + ipv6: fc00:a::86/126 + bp_interface: + ipv6: fc00:b::22/64 + + ARISTA33T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.35 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::89 + interfaces: + Loopback0: + ipv6: fc00:c:c:23::1/128 + Ethernet1: + ipv6: fc00:a::8a/126 + bp_interface: + ipv6: fc00:b::23/64 + + ARISTA34T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.36 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::8d + interfaces: + Loopback0: + ipv6: fc00:c:c:24::1/128 + Ethernet1: + ipv6: fc00:a::8e/126 + bp_interface: + ipv6: fc00:b::24/64 + + ARISTA35T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.37 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::91 + interfaces: + Loopback0: + ipv6: fc00:c:c:25::1/128 + Ethernet1: + ipv6: fc00:a::92/126 + bp_interface: + ipv6: fc00:b::25/64 + + ARISTA36T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.38 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::95 + interfaces: + Loopback0: + ipv6: fc00:c:c:26::1/128 + Ethernet1: + ipv6: fc00:a::96/126 + bp_interface: + ipv6: fc00:b::26/64 + + ARISTA37T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.39 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::99 + interfaces: + Loopback0: + ipv6: fc00:c:c:27::1/128 + Ethernet1: + ipv6: fc00:a::9a/126 + bp_interface: + ipv6: fc00:b::27/64 + + ARISTA38T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.40 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::9d + interfaces: + Loopback0: + ipv6: fc00:c:c:28::1/128 + Ethernet1: + ipv6: fc00:a::9e/126 + bp_interface: + ipv6: fc00:b::28/64 + + ARISTA39T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.41 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:29::1/128 + Ethernet1: + ipv6: fc00:a::a2/126 + bp_interface: + ipv6: fc00:b::29/64 + + ARISTA40T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.42 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2a::1/128 + Ethernet1: + ipv6: fc00:a::a6/126 + bp_interface: + ipv6: fc00:b::2a/64 + + ARISTA41T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.43 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2b::1/128 + Ethernet1: + ipv6: fc00:a::aa/126 + bp_interface: + ipv6: fc00:b::2b/64 + + ARISTA42T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.44 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::ad + interfaces: + Loopback0: + ipv6: fc00:c:c:2c::1/128 + Ethernet1: + ipv6: fc00:a::ae/126 + bp_interface: + ipv6: fc00:b::2c/64 + + ARISTA43T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.45 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:2d::1/128 + Ethernet1: + ipv6: fc00:a::b2/126 + bp_interface: + ipv6: fc00:b::2d/64 + + ARISTA44T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.46 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2e::1/128 + Ethernet1: + ipv6: fc00:a::b6/126 + bp_interface: + ipv6: fc00:b::2e/64 + + ARISTA45T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.47 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2f::1/128 + Ethernet1: + ipv6: fc00:a::ba/126 + bp_interface: + ipv6: fc00:b::2f/64 + + ARISTA46T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.48 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::bd + interfaces: + Loopback0: + ipv6: fc00:c:c:30::1/128 + Ethernet1: + ipv6: fc00:a::be/126 + bp_interface: + ipv6: fc00:b::30/64 + + ARISTA47T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.49 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:31::1/128 + Ethernet1: + ipv6: fc00:a::c2/126 + bp_interface: + ipv6: fc00:b::31/64 + + ARISTA48T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.50 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:32::1/128 + Ethernet1: + ipv6: fc00:a::c6/126 + bp_interface: + ipv6: fc00:b::32/64 + + ARISTA49T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.51 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:33::1/128 + Ethernet1: + ipv6: fc00:a::ca/126 + bp_interface: + ipv6: fc00:b::33/64 + + ARISTA50T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.52 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::cd + interfaces: + Loopback0: + ipv6: fc00:c:c:34::1/128 + Ethernet1: + ipv6: fc00:a::ce/126 + bp_interface: + ipv6: fc00:b::34/64 + + ARISTA51T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.53 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:35::1/128 + Ethernet1: + ipv6: fc00:a::d2/126 + bp_interface: + ipv6: fc00:b::35/64 + + ARISTA52T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.54 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:36::1/128 + Ethernet1: + ipv6: fc00:a::d6/126 + bp_interface: + ipv6: fc00:b::36/64 + + ARISTA53T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.55 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:37::1/128 + Ethernet1: + ipv6: fc00:a::da/126 + bp_interface: + ipv6: fc00:b::37/64 + + ARISTA54T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.56 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::dd + interfaces: + Loopback0: + ipv6: fc00:c:c:38::1/128 + Ethernet1: + ipv6: fc00:a::de/126 + bp_interface: + ipv6: fc00:b::38/64 + + ARISTA55T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.57 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:39::1/128 + Ethernet1: + ipv6: fc00:a::e2/126 + bp_interface: + ipv6: fc00:b::39/64 + + ARISTA56T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.58 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3a::1/128 + Ethernet1: + ipv6: fc00:a::e6/126 + bp_interface: + ipv6: fc00:b::3a/64 + + ARISTA57T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.59 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3b::1/128 + Ethernet1: + ipv6: fc00:a::ea/126 + bp_interface: + ipv6: fc00:b::3b/64 + + ARISTA58T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.60 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::ed + interfaces: + Loopback0: + ipv6: fc00:c:c:3c::1/128 + Ethernet1: + ipv6: fc00:a::ee/126 + bp_interface: + ipv6: fc00:b::3c/64 + + ARISTA59T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.61 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:3d::1/128 + Ethernet1: + ipv6: fc00:a::f2/126 + bp_interface: + ipv6: fc00:b::3d/64 + + ARISTA60T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.62 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3e::1/128 + Ethernet1: + ipv6: fc00:a::f6/126 + bp_interface: + ipv6: fc00:b::3e/64 + + ARISTA61T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.63 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3f::1/128 + Ethernet1: + ipv6: fc00:a::fa/126 + bp_interface: + ipv6: fc00:b::3f/64 + + ARISTA62T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.64 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::fd + interfaces: + Loopback0: + ipv6: fc00:c:c:40::1/128 + Ethernet1: + ipv6: fc00:a::fe/126 + bp_interface: + ipv6: fc00:b::40/64 + + ARISTA63T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.65 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::101 + interfaces: + Loopback0: + ipv6: fc00:c:c:41::1/128 + Ethernet1: + ipv6: fc00:a::102/126 + bp_interface: + ipv6: fc00:b::41/64 + + ARISTA64T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.66 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::105 + interfaces: + Loopback0: + ipv6: fc00:c:c:42::1/128 + Ethernet1: + ipv6: fc00:a::106/126 + bp_interface: + ipv6: fc00:b::42/64 + + ARISTA65T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.67 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::109 + interfaces: + Loopback0: + ipv6: fc00:c:c:43::1/128 + Ethernet1: + ipv6: fc00:a::10a/126 + bp_interface: + ipv6: fc00:b::43/64 + + ARISTA66T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.68 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::10d + interfaces: + Loopback0: + ipv6: fc00:c:c:44::1/128 + Ethernet1: + ipv6: fc00:a::10e/126 + bp_interface: + ipv6: fc00:b::44/64 + + ARISTA67T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.69 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::111 + interfaces: + Loopback0: + ipv6: fc00:c:c:45::1/128 + Ethernet1: + ipv6: fc00:a::112/126 + bp_interface: + ipv6: fc00:b::45/64 + + ARISTA68T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.70 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::115 + interfaces: + Loopback0: + ipv6: fc00:c:c:46::1/128 + Ethernet1: + ipv6: fc00:a::116/126 + bp_interface: + ipv6: fc00:b::46/64 + + ARISTA69T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.71 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::119 + interfaces: + Loopback0: + ipv6: fc00:c:c:47::1/128 + Ethernet1: + ipv6: fc00:a::11a/126 + bp_interface: + ipv6: fc00:b::47/64 + + ARISTA70T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.72 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::11d + interfaces: + Loopback0: + ipv6: fc00:c:c:48::1/128 + Ethernet1: + ipv6: fc00:a::11e/126 + bp_interface: + ipv6: fc00:b::48/64 + + ARISTA71T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.73 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::121 + interfaces: + Loopback0: + ipv6: fc00:c:c:49::1/128 + Ethernet1: + ipv6: fc00:a::122/126 + bp_interface: + ipv6: fc00:b::49/64 + + ARISTA72T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.74 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::125 + interfaces: + Loopback0: + ipv6: fc00:c:c:4a::1/128 + Ethernet1: + ipv6: fc00:a::126/126 + bp_interface: + ipv6: fc00:b::4a/64 + + ARISTA73T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.75 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::129 + interfaces: + Loopback0: + ipv6: fc00:c:c:4b::1/128 + Ethernet1: + ipv6: fc00:a::12a/126 + bp_interface: + ipv6: fc00:b::4b/64 + + ARISTA74T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.76 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::12d + interfaces: + Loopback0: + ipv6: fc00:c:c:4c::1/128 + Ethernet1: + ipv6: fc00:a::12e/126 + bp_interface: + ipv6: fc00:b::4c/64 + + ARISTA75T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.77 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::131 + interfaces: + Loopback0: + ipv6: fc00:c:c:4d::1/128 + Ethernet1: + ipv6: fc00:a::132/126 + bp_interface: + ipv6: fc00:b::4d/64 + + ARISTA76T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.78 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::135 + interfaces: + Loopback0: + ipv6: fc00:c:c:4e::1/128 + Ethernet1: + ipv6: fc00:a::136/126 + bp_interface: + ipv6: fc00:b::4e/64 + + ARISTA77T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.79 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::139 + interfaces: + Loopback0: + ipv6: fc00:c:c:4f::1/128 + Ethernet1: + ipv6: fc00:a::13a/126 + bp_interface: + ipv6: fc00:b::4f/64 + + ARISTA78T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.80 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::13d + interfaces: + Loopback0: + ipv6: fc00:c:c:50::1/128 + Ethernet1: + ipv6: fc00:a::13e/126 + bp_interface: + ipv6: fc00:b::50/64 + + ARISTA79T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.81 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::141 + interfaces: + Loopback0: + ipv6: fc00:c:c:51::1/128 + Ethernet1: + ipv6: fc00:a::142/126 + bp_interface: + ipv6: fc00:b::51/64 + + ARISTA80T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.82 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::145 + interfaces: + Loopback0: + ipv6: fc00:c:c:52::1/128 + Ethernet1: + ipv6: fc00:a::146/126 + bp_interface: + ipv6: fc00:b::52/64 + + ARISTA81T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.83 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::149 + interfaces: + Loopback0: + ipv6: fc00:c:c:53::1/128 + Ethernet1: + ipv6: fc00:a::14a/126 + bp_interface: + ipv6: fc00:b::53/64 + + ARISTA82T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.84 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::14d + interfaces: + Loopback0: + ipv6: fc00:c:c:54::1/128 + Ethernet1: + ipv6: fc00:a::14e/126 + bp_interface: + ipv6: fc00:b::54/64 + + ARISTA83T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.85 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::151 + interfaces: + Loopback0: + ipv6: fc00:c:c:55::1/128 + Ethernet1: + ipv6: fc00:a::152/126 + bp_interface: + ipv6: fc00:b::55/64 + + ARISTA84T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.86 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::155 + interfaces: + Loopback0: + ipv6: fc00:c:c:56::1/128 + Ethernet1: + ipv6: fc00:a::156/126 + bp_interface: + ipv6: fc00:b::56/64 + + ARISTA85T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.87 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::159 + interfaces: + Loopback0: + ipv6: fc00:c:c:57::1/128 + Ethernet1: + ipv6: fc00:a::15a/126 + bp_interface: + ipv6: fc00:b::57/64 + + ARISTA86T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.88 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::15d + interfaces: + Loopback0: + ipv6: fc00:c:c:58::1/128 + Ethernet1: + ipv6: fc00:a::15e/126 + bp_interface: + ipv6: fc00:b::58/64 + + ARISTA87T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.89 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::161 + interfaces: + Loopback0: + ipv6: fc00:c:c:59::1/128 + Ethernet1: + ipv6: fc00:a::162/126 + bp_interface: + ipv6: fc00:b::59/64 + + ARISTA88T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.90 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::165 + interfaces: + Loopback0: + ipv6: fc00:c:c:5a::1/128 + Ethernet1: + ipv6: fc00:a::166/126 + bp_interface: + ipv6: fc00:b::5a/64 + + ARISTA89T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.91 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::169 + interfaces: + Loopback0: + ipv6: fc00:c:c:5b::1/128 + Ethernet1: + ipv6: fc00:a::16a/126 + bp_interface: + ipv6: fc00:b::5b/64 + + ARISTA90T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.92 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::16d + interfaces: + Loopback0: + ipv6: fc00:c:c:5c::1/128 + Ethernet1: + ipv6: fc00:a::16e/126 + bp_interface: + ipv6: fc00:b::5c/64 + + ARISTA91T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.93 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::171 + interfaces: + Loopback0: + ipv6: fc00:c:c:5d::1/128 + Ethernet1: + ipv6: fc00:a::172/126 + bp_interface: + ipv6: fc00:b::5d/64 + + ARISTA92T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.94 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::175 + interfaces: + Loopback0: + ipv6: fc00:c:c:5e::1/128 + Ethernet1: + ipv6: fc00:a::176/126 + bp_interface: + ipv6: fc00:b::5e/64 + + ARISTA93T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.95 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::179 + interfaces: + Loopback0: + ipv6: fc00:c:c:5f::1/128 + Ethernet1: + ipv6: fc00:a::17a/126 + bp_interface: + ipv6: fc00:b::5f/64 + + ARISTA94T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.96 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::17d + interfaces: + Loopback0: + ipv6: fc00:c:c:60::1/128 + Ethernet1: + ipv6: fc00:a::17e/126 + bp_interface: + ipv6: fc00:b::60/64 + + ARISTA95T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.97 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::181 + interfaces: + Loopback0: + ipv6: fc00:c:c:61::1/128 + Ethernet1: + ipv6: fc00:a::182/126 + bp_interface: + ipv6: fc00:b::61/64 + + ARISTA96T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.98 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::185 + interfaces: + Loopback0: + ipv6: fc00:c:c:62::1/128 + Ethernet1: + ipv6: fc00:a::186/126 + bp_interface: + ipv6: fc00:b::62/64 + + ARISTA97T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.99 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::189 + interfaces: + Loopback0: + ipv6: fc00:c:c:63::1/128 + Ethernet1: + ipv6: fc00:a::18a/126 + bp_interface: + ipv6: fc00:b::63/64 + + ARISTA98T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.100 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::18d + interfaces: + Loopback0: + ipv6: fc00:c:c:64::1/128 + Ethernet1: + ipv6: fc00:a::18e/126 + bp_interface: + ipv6: fc00:b::64/64 + + ARISTA99T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.101 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::191 + interfaces: + Loopback0: + ipv6: fc00:c:c:65::1/128 + Ethernet1: + ipv6: fc00:a::192/126 + bp_interface: + ipv6: fc00:b::65/64 + + ARISTA100T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.102 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::195 + interfaces: + Loopback0: + ipv6: fc00:c:c:66::1/128 + Ethernet1: + ipv6: fc00:a::196/126 + bp_interface: + ipv6: fc00:b::66/64 + + ARISTA101T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.103 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::199 + interfaces: + Loopback0: + ipv6: fc00:c:c:67::1/128 + Ethernet1: + ipv6: fc00:a::19a/126 + bp_interface: + ipv6: fc00:b::67/64 + + ARISTA102T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.104 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::19d + interfaces: + Loopback0: + ipv6: fc00:c:c:68::1/128 + Ethernet1: + ipv6: fc00:a::19e/126 + bp_interface: + ipv6: fc00:b::68/64 + + ARISTA103T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.105 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:69::1/128 + Ethernet1: + ipv6: fc00:a::1a2/126 + bp_interface: + ipv6: fc00:b::69/64 + + ARISTA104T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.106 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6a::1/128 + Ethernet1: + ipv6: fc00:a::1a6/126 + bp_interface: + ipv6: fc00:b::6a/64 + + ARISTA105T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.107 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6b::1/128 + Ethernet1: + ipv6: fc00:a::1aa/126 + bp_interface: + ipv6: fc00:b::6b/64 + + ARISTA106T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.108 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1ad + interfaces: + Loopback0: + ipv6: fc00:c:c:6c::1/128 + Ethernet1: + ipv6: fc00:a::1ae/126 + bp_interface: + ipv6: fc00:b::6c/64 + + ARISTA107T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.109 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:6d::1/128 + Ethernet1: + ipv6: fc00:a::1b2/126 + bp_interface: + ipv6: fc00:b::6d/64 + + ARISTA108T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.110 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6e::1/128 + Ethernet1: + ipv6: fc00:a::1b6/126 + bp_interface: + ipv6: fc00:b::6e/64 + + ARISTA109T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.111 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6f::1/128 + Ethernet1: + ipv6: fc00:a::1ba/126 + bp_interface: + ipv6: fc00:b::6f/64 + + ARISTA110T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.112 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1bd + interfaces: + Loopback0: + ipv6: fc00:c:c:70::1/128 + Ethernet1: + ipv6: fc00:a::1be/126 + bp_interface: + ipv6: fc00:b::70/64 + + ARISTA111T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.113 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:71::1/128 + Ethernet1: + ipv6: fc00:a::1c2/126 + bp_interface: + ipv6: fc00:b::71/64 + + ARISTA112T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.114 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:72::1/128 + Ethernet1: + ipv6: fc00:a::1c6/126 + bp_interface: + ipv6: fc00:b::72/64 + + ARISTA113T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.115 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:73::1/128 + Ethernet1: + ipv6: fc00:a::1ca/126 + bp_interface: + ipv6: fc00:b::73/64 + + ARISTA114T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.116 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1cd + interfaces: + Loopback0: + ipv6: fc00:c:c:74::1/128 + Ethernet1: + ipv6: fc00:a::1ce/126 + bp_interface: + ipv6: fc00:b::74/64 + + ARISTA115T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.117 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:75::1/128 + Ethernet1: + ipv6: fc00:a::1d2/126 + bp_interface: + ipv6: fc00:b::75/64 + + ARISTA116T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.118 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:76::1/128 + Ethernet1: + ipv6: fc00:a::1d6/126 + bp_interface: + ipv6: fc00:b::76/64 + + ARISTA117T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.119 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:77::1/128 + Ethernet1: + ipv6: fc00:a::1da/126 + bp_interface: + ipv6: fc00:b::77/64 + + ARISTA118T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.120 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1dd + interfaces: + Loopback0: + ipv6: fc00:c:c:78::1/128 + Ethernet1: + ipv6: fc00:a::1de/126 + bp_interface: + ipv6: fc00:b::78/64 + + ARISTA119T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.121 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:79::1/128 + Ethernet1: + ipv6: fc00:a::1e2/126 + bp_interface: + ipv6: fc00:b::79/64 + + ARISTA120T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.122 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7a::1/128 + Ethernet1: + ipv6: fc00:a::1e6/126 + bp_interface: + ipv6: fc00:b::7a/64 + + ARISTA121T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.123 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7b::1/128 + Ethernet1: + ipv6: fc00:a::1ea/126 + bp_interface: + ipv6: fc00:b::7b/64 + + ARISTA122T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.124 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1ed + interfaces: + Loopback0: + ipv6: fc00:c:c:7c::1/128 + Ethernet1: + ipv6: fc00:a::1ee/126 + bp_interface: + ipv6: fc00:b::7c/64 + + ARISTA123T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.125 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:7d::1/128 + Ethernet1: + ipv6: fc00:a::1f2/126 + bp_interface: + ipv6: fc00:b::7d/64 + + ARISTA124T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.126 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7e::1/128 + Ethernet1: + ipv6: fc00:a::1f6/126 + bp_interface: + ipv6: fc00:b::7e/64 + + ARISTA125T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.127 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7f::1/128 + Ethernet1: + ipv6: fc00:a::1fa/126 + bp_interface: + ipv6: fc00:b::7f/64 + + ARISTA126T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.128 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1fd + interfaces: + Loopback0: + ipv6: fc00:c:c:80::1/128 + Ethernet1: + ipv6: fc00:a::1fe/126 + bp_interface: + ipv6: fc00:b::80/64 + + ARISTA127T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.129 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::201 + interfaces: + Loopback0: + ipv6: fc00:c:c:81::1/128 + Ethernet1: + ipv6: fc00:a::202/126 + bp_interface: + ipv6: fc00:b::81/64 + + ARISTA128T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.130 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::205 + interfaces: + Loopback0: + ipv6: fc00:c:c:82::1/128 + Ethernet1: + ipv6: fc00:a::206/126 + bp_interface: + ipv6: fc00:b::82/64 + + ARISTA129T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.131 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::209 + interfaces: + Loopback0: + ipv6: fc00:c:c:83::1/128 + Ethernet1: + ipv6: fc00:a::20a/126 + bp_interface: + ipv6: fc00:b::83/64 + + ARISTA130T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.132 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::20d + interfaces: + Loopback0: + ipv6: fc00:c:c:84::1/128 + Ethernet1: + ipv6: fc00:a::20e/126 + bp_interface: + ipv6: fc00:b::84/64 + + ARISTA131T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.133 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::211 + interfaces: + Loopback0: + ipv6: fc00:c:c:85::1/128 + Ethernet1: + ipv6: fc00:a::212/126 + bp_interface: + ipv6: fc00:b::85/64 + + ARISTA132T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.134 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::215 + interfaces: + Loopback0: + ipv6: fc00:c:c:86::1/128 + Ethernet1: + ipv6: fc00:a::216/126 + bp_interface: + ipv6: fc00:b::86/64 + + ARISTA133T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.135 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::219 + interfaces: + Loopback0: + ipv6: fc00:c:c:87::1/128 + Ethernet1: + ipv6: fc00:a::21a/126 + bp_interface: + ipv6: fc00:b::87/64 + + ARISTA134T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.136 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::21d + interfaces: + Loopback0: + ipv6: fc00:c:c:88::1/128 + Ethernet1: + ipv6: fc00:a::21e/126 + bp_interface: + ipv6: fc00:b::88/64 + + ARISTA135T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.137 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::221 + interfaces: + Loopback0: + ipv6: fc00:c:c:89::1/128 + Ethernet1: + ipv6: fc00:a::222/126 + bp_interface: + ipv6: fc00:b::89/64 + + ARISTA136T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.138 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::225 + interfaces: + Loopback0: + ipv6: fc00:c:c:8a::1/128 + Ethernet1: + ipv6: fc00:a::226/126 + bp_interface: + ipv6: fc00:b::8a/64 + + ARISTA137T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.139 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::229 + interfaces: + Loopback0: + ipv6: fc00:c:c:8b::1/128 + Ethernet1: + ipv6: fc00:a::22a/126 + bp_interface: + ipv6: fc00:b::8b/64 + + ARISTA138T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.140 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::22d + interfaces: + Loopback0: + ipv6: fc00:c:c:8c::1/128 + Ethernet1: + ipv6: fc00:a::22e/126 + bp_interface: + ipv6: fc00:b::8c/64 + + ARISTA139T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.141 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::231 + interfaces: + Loopback0: + ipv6: fc00:c:c:8d::1/128 + Ethernet1: + ipv6: fc00:a::232/126 + bp_interface: + ipv6: fc00:b::8d/64 + + ARISTA140T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.142 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::235 + interfaces: + Loopback0: + ipv6: fc00:c:c:8e::1/128 + Ethernet1: + ipv6: fc00:a::236/126 + bp_interface: + ipv6: fc00:b::8e/64 + + ARISTA141T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.143 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::239 + interfaces: + Loopback0: + ipv6: fc00:c:c:8f::1/128 + Ethernet1: + ipv6: fc00:a::23a/126 + bp_interface: + ipv6: fc00:b::8f/64 + + ARISTA142T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.144 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::23d + interfaces: + Loopback0: + ipv6: fc00:c:c:90::1/128 + Ethernet1: + ipv6: fc00:a::23e/126 + bp_interface: + ipv6: fc00:b::90/64 + + ARISTA143T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.145 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::241 + interfaces: + Loopback0: + ipv6: fc00:c:c:91::1/128 + Ethernet1: + ipv6: fc00:a::242/126 + bp_interface: + ipv6: fc00:b::91/64 + + ARISTA144T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.146 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::245 + interfaces: + Loopback0: + ipv6: fc00:c:c:92::1/128 + Ethernet1: + ipv6: fc00:a::246/126 + bp_interface: + ipv6: fc00:b::92/64 + + ARISTA145T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.147 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::249 + interfaces: + Loopback0: + ipv6: fc00:c:c:93::1/128 + Ethernet1: + ipv6: fc00:a::24a/126 + bp_interface: + ipv6: fc00:b::93/64 + + ARISTA146T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.148 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::24d + interfaces: + Loopback0: + ipv6: fc00:c:c:94::1/128 + Ethernet1: + ipv6: fc00:a::24e/126 + bp_interface: + ipv6: fc00:b::94/64 + + ARISTA147T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.149 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::251 + interfaces: + Loopback0: + ipv6: fc00:c:c:95::1/128 + Ethernet1: + ipv6: fc00:a::252/126 + bp_interface: + ipv6: fc00:b::95/64 + + ARISTA148T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.150 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::255 + interfaces: + Loopback0: + ipv6: fc00:c:c:96::1/128 + Ethernet1: + ipv6: fc00:a::256/126 + bp_interface: + ipv6: fc00:b::96/64 + + ARISTA149T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.151 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::259 + interfaces: + Loopback0: + ipv6: fc00:c:c:97::1/128 + Ethernet1: + ipv6: fc00:a::25a/126 + bp_interface: + ipv6: fc00:b::97/64 + + ARISTA150T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.152 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::25d + interfaces: + Loopback0: + ipv6: fc00:c:c:98::1/128 + Ethernet1: + ipv6: fc00:a::25e/126 + bp_interface: + ipv6: fc00:b::98/64 + + ARISTA151T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.153 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::261 + interfaces: + Loopback0: + ipv6: fc00:c:c:99::1/128 + Ethernet1: + ipv6: fc00:a::262/126 + bp_interface: + ipv6: fc00:b::99/64 + + ARISTA152T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.154 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::265 + interfaces: + Loopback0: + ipv6: fc00:c:c:9a::1/128 + Ethernet1: + ipv6: fc00:a::266/126 + bp_interface: + ipv6: fc00:b::9a/64 + + ARISTA153T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.155 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::269 + interfaces: + Loopback0: + ipv6: fc00:c:c:9b::1/128 + Ethernet1: + ipv6: fc00:a::26a/126 + bp_interface: + ipv6: fc00:b::9b/64 + + ARISTA154T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.156 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::26d + interfaces: + Loopback0: + ipv6: fc00:c:c:9c::1/128 + Ethernet1: + ipv6: fc00:a::26e/126 + bp_interface: + ipv6: fc00:b::9c/64 + + ARISTA155T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.157 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::271 + interfaces: + Loopback0: + ipv6: fc00:c:c:9d::1/128 + Ethernet1: + ipv6: fc00:a::272/126 + bp_interface: + ipv6: fc00:b::9d/64 + + ARISTA156T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.158 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::275 + interfaces: + Loopback0: + ipv6: fc00:c:c:9e::1/128 + Ethernet1: + ipv6: fc00:a::276/126 + bp_interface: + ipv6: fc00:b::9e/64 + + ARISTA157T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.159 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::279 + interfaces: + Loopback0: + ipv6: fc00:c:c:9f::1/128 + Ethernet1: + ipv6: fc00:a::27a/126 + bp_interface: + ipv6: fc00:b::9f/64 + + ARISTA158T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.160 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::27d + interfaces: + Loopback0: + ipv6: fc00:c:c:a0::1/128 + Ethernet1: + ipv6: fc00:a::27e/126 + bp_interface: + ipv6: fc00:b::a0/64 + + ARISTA159T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.161 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::281 + interfaces: + Loopback0: + ipv6: fc00:c:c:a1::1/128 + Ethernet1: + ipv6: fc00:a::282/126 + bp_interface: + ipv6: fc00:b::a1/64 + + ARISTA160T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.162 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::285 + interfaces: + Loopback0: + ipv6: fc00:c:c:a2::1/128 + Ethernet1: + ipv6: fc00:a::286/126 + bp_interface: + ipv6: fc00:b::a2/64 + + ARISTA161T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.163 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::289 + interfaces: + Loopback0: + ipv6: fc00:c:c:a3::1/128 + Ethernet1: + ipv6: fc00:a::28a/126 + bp_interface: + ipv6: fc00:b::a3/64 + + ARISTA162T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.164 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::28d + interfaces: + Loopback0: + ipv6: fc00:c:c:a4::1/128 + Ethernet1: + ipv6: fc00:a::28e/126 + bp_interface: + ipv6: fc00:b::a4/64 + + ARISTA163T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.165 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::291 + interfaces: + Loopback0: + ipv6: fc00:c:c:a5::1/128 + Ethernet1: + ipv6: fc00:a::292/126 + bp_interface: + ipv6: fc00:b::a5/64 + + ARISTA164T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.166 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::295 + interfaces: + Loopback0: + ipv6: fc00:c:c:a6::1/128 + Ethernet1: + ipv6: fc00:a::296/126 + bp_interface: + ipv6: fc00:b::a6/64 + + ARISTA165T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.167 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::299 + interfaces: + Loopback0: + ipv6: fc00:c:c:a7::1/128 + Ethernet1: + ipv6: fc00:a::29a/126 + bp_interface: + ipv6: fc00:b::a7/64 + + ARISTA166T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.168 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::29d + interfaces: + Loopback0: + ipv6: fc00:c:c:a8::1/128 + Ethernet1: + ipv6: fc00:a::29e/126 + bp_interface: + ipv6: fc00:b::a8/64 + + ARISTA167T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.169 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:a9::1/128 + Ethernet1: + ipv6: fc00:a::2a2/126 + bp_interface: + ipv6: fc00:b::a9/64 + + ARISTA168T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.170 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:aa::1/128 + Ethernet1: + ipv6: fc00:a::2a6/126 + bp_interface: + ipv6: fc00:b::aa/64 + + ARISTA169T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.171 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ab::1/128 + Ethernet1: + ipv6: fc00:a::2aa/126 + bp_interface: + ipv6: fc00:b::ab/64 + + ARISTA170T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.172 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ac::1/128 + Ethernet1: + ipv6: fc00:a::2ae/126 + bp_interface: + ipv6: fc00:b::ac/64 + + ARISTA171T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.173 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ad::1/128 + Ethernet1: + ipv6: fc00:a::2b2/126 + bp_interface: + ipv6: fc00:b::ad/64 + + ARISTA172T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.174 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ae::1/128 + Ethernet1: + ipv6: fc00:a::2b6/126 + bp_interface: + ipv6: fc00:b::ae/64 + + ARISTA173T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.175 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:af::1/128 + Ethernet1: + ipv6: fc00:a::2ba/126 + bp_interface: + ipv6: fc00:b::af/64 + + ARISTA174T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.176 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2bd + interfaces: + Loopback0: + ipv6: fc00:c:c:b0::1/128 + Ethernet1: + ipv6: fc00:a::2be/126 + bp_interface: + ipv6: fc00:b::b0/64 + + ARISTA175T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.177 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b1::1/128 + Ethernet1: + ipv6: fc00:a::2c2/126 + bp_interface: + ipv6: fc00:b::b1/64 + + ARISTA176T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.178 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b2::1/128 + Ethernet1: + ipv6: fc00:a::2c6/126 + bp_interface: + ipv6: fc00:b::b2/64 + + ARISTA177T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.179 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b3::1/128 + Ethernet1: + ipv6: fc00:a::2ca/126 + bp_interface: + ipv6: fc00:b::b3/64 + + ARISTA178T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.180 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2cd + interfaces: + Loopback0: + ipv6: fc00:c:c:b4::1/128 + Ethernet1: + ipv6: fc00:a::2ce/126 + bp_interface: + ipv6: fc00:b::b4/64 + + ARISTA179T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.181 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b5::1/128 + Ethernet1: + ipv6: fc00:a::2d2/126 + bp_interface: + ipv6: fc00:b::b5/64 + + ARISTA180T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.182 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b6::1/128 + Ethernet1: + ipv6: fc00:a::2d6/126 + bp_interface: + ipv6: fc00:b::b6/64 + + ARISTA181T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.183 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b7::1/128 + Ethernet1: + ipv6: fc00:a::2da/126 + bp_interface: + ipv6: fc00:b::b7/64 + + ARISTA182T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.184 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2dd + interfaces: + Loopback0: + ipv6: fc00:c:c:b8::1/128 + Ethernet1: + ipv6: fc00:a::2de/126 + bp_interface: + ipv6: fc00:b::b8/64 + + ARISTA183T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.185 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b9::1/128 + Ethernet1: + ipv6: fc00:a::2e2/126 + bp_interface: + ipv6: fc00:b::b9/64 + + ARISTA184T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.186 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ba::1/128 + Ethernet1: + ipv6: fc00:a::2e6/126 + bp_interface: + ipv6: fc00:b::ba/64 + + ARISTA185T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.187 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bb::1/128 + Ethernet1: + ipv6: fc00:a::2ea/126 + bp_interface: + ipv6: fc00:b::bb/64 + + ARISTA186T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.188 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2ed + interfaces: + Loopback0: + ipv6: fc00:c:c:bc::1/128 + Ethernet1: + ipv6: fc00:a::2ee/126 + bp_interface: + ipv6: fc00:b::bc/64 + + ARISTA187T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.189 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:bd::1/128 + Ethernet1: + ipv6: fc00:a::2f2/126 + bp_interface: + ipv6: fc00:b::bd/64 + + ARISTA188T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.190 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:be::1/128 + Ethernet1: + ipv6: fc00:a::2f6/126 + bp_interface: + ipv6: fc00:b::be/64 + + ARISTA189T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.191 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bf::1/128 + Ethernet1: + ipv6: fc00:a::2fa/126 + bp_interface: + ipv6: fc00:b::bf/64 + + ARISTA190T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.192 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2fd + interfaces: + Loopback0: + ipv6: fc00:c:c:c0::1/128 + Ethernet1: + ipv6: fc00:a::2fe/126 + bp_interface: + ipv6: fc00:b::c0/64 + + ARISTA191T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.193 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::301 + interfaces: + Loopback0: + ipv6: fc00:c:c:c1::1/128 + Ethernet1: + ipv6: fc00:a::302/126 + bp_interface: + ipv6: fc00:b::c1/64 + + ARISTA192T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.194 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::305 + interfaces: + Loopback0: + ipv6: fc00:c:c:c2::1/128 + Ethernet1: + ipv6: fc00:a::306/126 + bp_interface: + ipv6: fc00:b::c2/64 + + ARISTA193T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.195 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::309 + interfaces: + Loopback0: + ipv6: fc00:c:c:c3::1/128 + Ethernet1: + ipv6: fc00:a::30a/126 + bp_interface: + ipv6: fc00:b::c3/64 + + ARISTA194T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.196 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::30d + interfaces: + Loopback0: + ipv6: fc00:c:c:c4::1/128 + Ethernet1: + ipv6: fc00:a::30e/126 + bp_interface: + ipv6: fc00:b::c4/64 + + ARISTA195T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.197 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::311 + interfaces: + Loopback0: + ipv6: fc00:c:c:c5::1/128 + Ethernet1: + ipv6: fc00:a::312/126 + bp_interface: + ipv6: fc00:b::c5/64 + + ARISTA196T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.198 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::315 + interfaces: + Loopback0: + ipv6: fc00:c:c:c6::1/128 + Ethernet1: + ipv6: fc00:a::316/126 + bp_interface: + ipv6: fc00:b::c6/64 + + ARISTA197T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.199 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::319 + interfaces: + Loopback0: + ipv6: fc00:c:c:c7::1/128 + Ethernet1: + ipv6: fc00:a::31a/126 + bp_interface: + ipv6: fc00:b::c7/64 + + ARISTA198T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.200 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::31d + interfaces: + Loopback0: + ipv6: fc00:c:c:c8::1/128 + Ethernet1: + ipv6: fc00:a::31e/126 + bp_interface: + ipv6: fc00:b::c8/64 + + ARISTA199T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.201 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::321 + interfaces: + Loopback0: + ipv6: fc00:c:c:c9::1/128 + Ethernet1: + ipv6: fc00:a::322/126 + bp_interface: + ipv6: fc00:b::c9/64 + + ARISTA200T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.202 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::325 + interfaces: + Loopback0: + ipv6: fc00:c:c:ca::1/128 + Ethernet1: + ipv6: fc00:a::326/126 + bp_interface: + ipv6: fc00:b::ca/64 + + ARISTA201T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.203 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::329 + interfaces: + Loopback0: + ipv6: fc00:c:c:cb::1/128 + Ethernet1: + ipv6: fc00:a::32a/126 + bp_interface: + ipv6: fc00:b::cb/64 + + ARISTA202T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.204 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::32d + interfaces: + Loopback0: + ipv6: fc00:c:c:cc::1/128 + Ethernet1: + ipv6: fc00:a::32e/126 + bp_interface: + ipv6: fc00:b::cc/64 + + ARISTA203T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.205 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::331 + interfaces: + Loopback0: + ipv6: fc00:c:c:cd::1/128 + Ethernet1: + ipv6: fc00:a::332/126 + bp_interface: + ipv6: fc00:b::cd/64 + + ARISTA204T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.206 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::335 + interfaces: + Loopback0: + ipv6: fc00:c:c:ce::1/128 + Ethernet1: + ipv6: fc00:a::336/126 + bp_interface: + ipv6: fc00:b::ce/64 + + ARISTA205T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.207 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::339 + interfaces: + Loopback0: + ipv6: fc00:c:c:cf::1/128 + Ethernet1: + ipv6: fc00:a::33a/126 + bp_interface: + ipv6: fc00:b::cf/64 + + ARISTA206T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.208 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::33d + interfaces: + Loopback0: + ipv6: fc00:c:c:d0::1/128 + Ethernet1: + ipv6: fc00:a::33e/126 + bp_interface: + ipv6: fc00:b::d0/64 + + ARISTA207T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.209 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::341 + interfaces: + Loopback0: + ipv6: fc00:c:c:d1::1/128 + Ethernet1: + ipv6: fc00:a::342/126 + bp_interface: + ipv6: fc00:b::d1/64 + + ARISTA208T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.210 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::345 + interfaces: + Loopback0: + ipv6: fc00:c:c:d2::1/128 + Ethernet1: + ipv6: fc00:a::346/126 + bp_interface: + ipv6: fc00:b::d2/64 + + ARISTA209T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.211 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::349 + interfaces: + Loopback0: + ipv6: fc00:c:c:d3::1/128 + Ethernet1: + ipv6: fc00:a::34a/126 + bp_interface: + ipv6: fc00:b::d3/64 + + ARISTA210T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.212 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::34d + interfaces: + Loopback0: + ipv6: fc00:c:c:d4::1/128 + Ethernet1: + ipv6: fc00:a::34e/126 + bp_interface: + ipv6: fc00:b::d4/64 + + ARISTA211T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.213 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::351 + interfaces: + Loopback0: + ipv6: fc00:c:c:d5::1/128 + Ethernet1: + ipv6: fc00:a::352/126 + bp_interface: + ipv6: fc00:b::d5/64 + + ARISTA212T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.214 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::355 + interfaces: + Loopback0: + ipv6: fc00:c:c:d6::1/128 + Ethernet1: + ipv6: fc00:a::356/126 + bp_interface: + ipv6: fc00:b::d6/64 + + ARISTA213T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.215 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::359 + interfaces: + Loopback0: + ipv6: fc00:c:c:d7::1/128 + Ethernet1: + ipv6: fc00:a::35a/126 + bp_interface: + ipv6: fc00:b::d7/64 + + ARISTA214T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.216 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::35d + interfaces: + Loopback0: + ipv6: fc00:c:c:d8::1/128 + Ethernet1: + ipv6: fc00:a::35e/126 + bp_interface: + ipv6: fc00:b::d8/64 + + ARISTA215T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.217 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::361 + interfaces: + Loopback0: + ipv6: fc00:c:c:d9::1/128 + Ethernet1: + ipv6: fc00:a::362/126 + bp_interface: + ipv6: fc00:b::d9/64 + + ARISTA216T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.218 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::365 + interfaces: + Loopback0: + ipv6: fc00:c:c:da::1/128 + Ethernet1: + ipv6: fc00:a::366/126 + bp_interface: + ipv6: fc00:b::da/64 + + ARISTA217T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.219 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::369 + interfaces: + Loopback0: + ipv6: fc00:c:c:db::1/128 + Ethernet1: + ipv6: fc00:a::36a/126 + bp_interface: + ipv6: fc00:b::db/64 + + ARISTA218T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.220 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::36d + interfaces: + Loopback0: + ipv6: fc00:c:c:dc::1/128 + Ethernet1: + ipv6: fc00:a::36e/126 + bp_interface: + ipv6: fc00:b::dc/64 + + ARISTA219T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.221 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::371 + interfaces: + Loopback0: + ipv6: fc00:c:c:dd::1/128 + Ethernet1: + ipv6: fc00:a::372/126 + bp_interface: + ipv6: fc00:b::dd/64 + + ARISTA220T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.222 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::375 + interfaces: + Loopback0: + ipv6: fc00:c:c:de::1/128 + Ethernet1: + ipv6: fc00:a::376/126 + bp_interface: + ipv6: fc00:b::de/64 + + ARISTA221T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.223 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::379 + interfaces: + Loopback0: + ipv6: fc00:c:c:df::1/128 + Ethernet1: + ipv6: fc00:a::37a/126 + bp_interface: + ipv6: fc00:b::df/64 + + ARISTA222T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.224 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::37d + interfaces: + Loopback0: + ipv6: fc00:c:c:e0::1/128 + Ethernet1: + ipv6: fc00:a::37e/126 + bp_interface: + ipv6: fc00:b::e0/64 + + ARISTA223T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.225 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::381 + interfaces: + Loopback0: + ipv6: fc00:c:c:e1::1/128 + Ethernet1: + ipv6: fc00:a::382/126 + bp_interface: + ipv6: fc00:b::e1/64 + + ARISTA224T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.226 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::385 + interfaces: + Loopback0: + ipv6: fc00:c:c:e2::1/128 + Ethernet1: + ipv6: fc00:a::386/126 + bp_interface: + ipv6: fc00:b::e2/64 + + ARISTA225T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.227 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::389 + interfaces: + Loopback0: + ipv6: fc00:c:c:e3::1/128 + Ethernet1: + ipv6: fc00:a::38a/126 + bp_interface: + ipv6: fc00:b::e3/64 + + ARISTA226T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.228 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::38d + interfaces: + Loopback0: + ipv6: fc00:c:c:e4::1/128 + Ethernet1: + ipv6: fc00:a::38e/126 + bp_interface: + ipv6: fc00:b::e4/64 + + ARISTA227T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.229 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::391 + interfaces: + Loopback0: + ipv6: fc00:c:c:e5::1/128 + Ethernet1: + ipv6: fc00:a::392/126 + bp_interface: + ipv6: fc00:b::e5/64 + + ARISTA228T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.230 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::395 + interfaces: + Loopback0: + ipv6: fc00:c:c:e6::1/128 + Ethernet1: + ipv6: fc00:a::396/126 + bp_interface: + ipv6: fc00:b::e6/64 + + ARISTA229T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.231 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::399 + interfaces: + Loopback0: + ipv6: fc00:c:c:e7::1/128 + Ethernet1: + ipv6: fc00:a::39a/126 + bp_interface: + ipv6: fc00:b::e7/64 + + ARISTA230T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.232 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::39d + interfaces: + Loopback0: + ipv6: fc00:c:c:e8::1/128 + Ethernet1: + ipv6: fc00:a::39e/126 + bp_interface: + ipv6: fc00:b::e8/64 + + ARISTA231T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.233 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:e9::1/128 + Ethernet1: + ipv6: fc00:a::3a2/126 + bp_interface: + ipv6: fc00:b::e9/64 + + ARISTA232T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.234 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ea::1/128 + Ethernet1: + ipv6: fc00:a::3a6/126 + bp_interface: + ipv6: fc00:b::ea/64 + + ARISTA233T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.235 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:eb::1/128 + Ethernet1: + ipv6: fc00:a::3aa/126 + bp_interface: + ipv6: fc00:b::eb/64 + + ARISTA234T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.236 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ec::1/128 + Ethernet1: + ipv6: fc00:a::3ae/126 + bp_interface: + ipv6: fc00:b::ec/64 + + ARISTA235T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.237 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ed::1/128 + Ethernet1: + ipv6: fc00:a::3b2/126 + bp_interface: + ipv6: fc00:b::ed/64 + + ARISTA236T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.238 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ee::1/128 + Ethernet1: + ipv6: fc00:a::3b6/126 + bp_interface: + ipv6: fc00:b::ee/64 + + ARISTA237T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.239 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ef::1/128 + Ethernet1: + ipv6: fc00:a::3ba/126 + bp_interface: + ipv6: fc00:b::ef/64 + + ARISTA238T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.240 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3bd + interfaces: + Loopback0: + ipv6: fc00:c:c:f0::1/128 + Ethernet1: + ipv6: fc00:a::3be/126 + bp_interface: + ipv6: fc00:b::f0/64 + + ARISTA239T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.241 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f1::1/128 + Ethernet1: + ipv6: fc00:a::3c2/126 + bp_interface: + ipv6: fc00:b::f1/64 + + ARISTA240T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.242 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f2::1/128 + Ethernet1: + ipv6: fc00:a::3c6/126 + bp_interface: + ipv6: fc00:b::f2/64 + + ARISTA241T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.243 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f3::1/128 + Ethernet1: + ipv6: fc00:a::3ca/126 + bp_interface: + ipv6: fc00:b::f3/64 + + ARISTA242T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.244 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3cd + interfaces: + Loopback0: + ipv6: fc00:c:c:f4::1/128 + Ethernet1: + ipv6: fc00:a::3ce/126 + bp_interface: + ipv6: fc00:b::f4/64 + + ARISTA243T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.245 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f5::1/128 + Ethernet1: + ipv6: fc00:a::3d2/126 + bp_interface: + ipv6: fc00:b::f5/64 + + ARISTA244T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.246 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f6::1/128 + Ethernet1: + ipv6: fc00:a::3d6/126 + bp_interface: + ipv6: fc00:b::f6/64 + + ARISTA245T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.247 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f7::1/128 + Ethernet1: + ipv6: fc00:a::3da/126 + bp_interface: + ipv6: fc00:b::f7/64 + + ARISTA246T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.248 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3dd + interfaces: + Loopback0: + ipv6: fc00:c:c:f8::1/128 + Ethernet1: + ipv6: fc00:a::3de/126 + bp_interface: + ipv6: fc00:b::f8/64 + + ARISTA247T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.249 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f9::1/128 + Ethernet1: + ipv6: fc00:a::3e2/126 + bp_interface: + ipv6: fc00:b::f9/64 + + ARISTA248T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.250 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fa::1/128 + Ethernet1: + ipv6: fc00:a::3e6/126 + bp_interface: + ipv6: fc00:b::fa/64 + + ARISTA249T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.251 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:fb::1/128 + Ethernet1: + ipv6: fc00:a::3ea/126 + bp_interface: + ipv6: fc00:b::fb/64 + + ARISTA250T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.252 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3ed + interfaces: + Loopback0: + ipv6: fc00:c:c:fc::1/128 + Ethernet1: + ipv6: fc00:a::3ee/126 + bp_interface: + ipv6: fc00:b::fc/64 + + ARISTA251T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.253 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:fd::1/128 + Ethernet1: + ipv6: fc00:a::3f2/126 + bp_interface: + ipv6: fc00:b::fd/64 + + ARISTA252T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.254 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fe::1/128 + Ethernet1: + ipv6: fc00:a::3f6/126 + bp_interface: + ipv6: fc00:b::fe/64 + + ARISTA253T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.255 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ff::1/128 + Ethernet1: + ipv6: fc00:a::3fa/126 + bp_interface: + ipv6: fc00:b::ff/64 + + ARISTA254T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.0 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3fd + interfaces: + Loopback0: + ipv6: fc00:c:c:100::1/128 + Ethernet1: + ipv6: fc00:a::3fe/126 + bp_interface: + ipv6: fc00:b::100/64 diff --git a/ansible/vars/topo_t1-isolated-u2d510.yaml b/ansible/vars/topo_t1-isolated-u2d510.yaml new file mode 100644 index 00000000000..33ab6dea7d3 --- /dev/null +++ b/ansible/vars/topo_t1-isolated-u2d510.yaml @@ -0,0 +1,11282 @@ +topology: + VMs: + ARISTA01T2: + vlans: + - 0 + vm_offset: 0 + ARISTA02T2: + vlans: + - 1 + vm_offset: 1 + ARISTA01T0: + vlans: + - 2 + vm_offset: 2 + ARISTA02T0: + vlans: + - 3 + vm_offset: 3 + ARISTA03T0: + vlans: + - 4 + vm_offset: 4 + ARISTA04T0: + vlans: + - 5 + vm_offset: 5 + ARISTA05T0: + vlans: + - 6 + vm_offset: 6 + ARISTA06T0: + vlans: + - 7 + vm_offset: 7 + ARISTA07T0: + vlans: + - 8 + vm_offset: 8 + ARISTA08T0: + vlans: + - 9 + vm_offset: 9 + ARISTA09T0: + vlans: + - 10 + vm_offset: 10 + ARISTA10T0: + vlans: + - 11 + vm_offset: 11 + ARISTA11T0: + vlans: + - 12 + vm_offset: 12 + ARISTA12T0: + vlans: + - 13 + vm_offset: 13 + ARISTA13T0: + vlans: + - 14 + vm_offset: 14 + ARISTA14T0: + vlans: + - 15 + vm_offset: 15 + ARISTA15T0: + vlans: + - 16 + vm_offset: 16 + ARISTA16T0: + vlans: + - 17 + vm_offset: 17 + ARISTA17T0: + vlans: + - 18 + vm_offset: 18 + ARISTA18T0: + vlans: + - 19 + vm_offset: 19 + ARISTA19T0: + vlans: + - 20 + vm_offset: 20 + ARISTA20T0: + vlans: + - 21 + vm_offset: 21 + ARISTA21T0: + vlans: + - 22 + vm_offset: 22 + ARISTA22T0: + vlans: + - 23 + vm_offset: 23 + ARISTA23T0: + vlans: + - 24 + vm_offset: 24 + ARISTA24T0: + vlans: + - 25 + vm_offset: 25 + ARISTA25T0: + vlans: + - 26 + vm_offset: 26 + ARISTA26T0: + vlans: + - 27 + vm_offset: 27 + ARISTA27T0: + vlans: + - 28 + vm_offset: 28 + ARISTA28T0: + vlans: + - 29 + vm_offset: 29 + ARISTA29T0: + vlans: + - 30 + vm_offset: 30 + ARISTA30T0: + vlans: + - 31 + vm_offset: 31 + ARISTA31T0: + vlans: + - 32 + vm_offset: 32 + ARISTA32T0: + vlans: + - 33 + vm_offset: 33 + ARISTA33T0: + vlans: + - 34 + vm_offset: 34 + ARISTA34T0: + vlans: + - 35 + vm_offset: 35 + ARISTA35T0: + vlans: + - 36 + vm_offset: 36 + ARISTA36T0: + vlans: + - 37 + vm_offset: 37 + ARISTA37T0: + vlans: + - 38 + vm_offset: 38 + ARISTA38T0: + vlans: + - 39 + vm_offset: 39 + ARISTA39T0: + vlans: + - 40 + vm_offset: 40 + ARISTA40T0: + vlans: + - 41 + vm_offset: 41 + ARISTA41T0: + vlans: + - 42 + vm_offset: 42 + ARISTA42T0: + vlans: + - 43 + vm_offset: 43 + ARISTA43T0: + vlans: + - 44 + vm_offset: 44 + ARISTA44T0: + vlans: + - 45 + vm_offset: 45 + ARISTA45T0: + vlans: + - 46 + vm_offset: 46 + ARISTA46T0: + vlans: + - 47 + vm_offset: 47 + ARISTA47T0: + vlans: + - 48 + vm_offset: 48 + ARISTA48T0: + vlans: + - 49 + vm_offset: 49 + ARISTA49T0: + vlans: + - 50 + vm_offset: 50 + ARISTA50T0: + vlans: + - 51 + vm_offset: 51 + ARISTA51T0: + vlans: + - 52 + vm_offset: 52 + ARISTA52T0: + vlans: + - 53 + vm_offset: 53 + ARISTA53T0: + vlans: + - 54 + vm_offset: 54 + ARISTA54T0: + vlans: + - 55 + vm_offset: 55 + ARISTA55T0: + vlans: + - 56 + vm_offset: 56 + ARISTA56T0: + vlans: + - 57 + vm_offset: 57 + ARISTA57T0: + vlans: + - 58 + vm_offset: 58 + ARISTA58T0: + vlans: + - 59 + vm_offset: 59 + ARISTA59T0: + vlans: + - 60 + vm_offset: 60 + ARISTA60T0: + vlans: + - 61 + vm_offset: 61 + ARISTA61T0: + vlans: + - 62 + vm_offset: 62 + ARISTA62T0: + vlans: + - 63 + vm_offset: 63 + ARISTA63T0: + vlans: + - 64 + vm_offset: 64 + ARISTA64T0: + vlans: + - 65 + vm_offset: 65 + ARISTA65T0: + vlans: + - 66 + vm_offset: 66 + ARISTA66T0: + vlans: + - 67 + vm_offset: 67 + ARISTA67T0: + vlans: + - 68 + vm_offset: 68 + ARISTA68T0: + vlans: + - 69 + vm_offset: 69 + ARISTA69T0: + vlans: + - 70 + vm_offset: 70 + ARISTA70T0: + vlans: + - 71 + vm_offset: 71 + ARISTA71T0: + vlans: + - 72 + vm_offset: 72 + ARISTA72T0: + vlans: + - 73 + vm_offset: 73 + ARISTA73T0: + vlans: + - 74 + vm_offset: 74 + ARISTA74T0: + vlans: + - 75 + vm_offset: 75 + ARISTA75T0: + vlans: + - 76 + vm_offset: 76 + ARISTA76T0: + vlans: + - 77 + vm_offset: 77 + ARISTA77T0: + vlans: + - 78 + vm_offset: 78 + ARISTA78T0: + vlans: + - 79 + vm_offset: 79 + ARISTA79T0: + vlans: + - 80 + vm_offset: 80 + ARISTA80T0: + vlans: + - 81 + vm_offset: 81 + ARISTA81T0: + vlans: + - 82 + vm_offset: 82 + ARISTA82T0: + vlans: + - 83 + vm_offset: 83 + ARISTA83T0: + vlans: + - 84 + vm_offset: 84 + ARISTA84T0: + vlans: + - 85 + vm_offset: 85 + ARISTA85T0: + vlans: + - 86 + vm_offset: 86 + ARISTA86T0: + vlans: + - 87 + vm_offset: 87 + ARISTA87T0: + vlans: + - 88 + vm_offset: 88 + ARISTA88T0: + vlans: + - 89 + vm_offset: 89 + ARISTA89T0: + vlans: + - 90 + vm_offset: 90 + ARISTA90T0: + vlans: + - 91 + vm_offset: 91 + ARISTA91T0: + vlans: + - 92 + vm_offset: 92 + ARISTA92T0: + vlans: + - 93 + vm_offset: 93 + ARISTA93T0: + vlans: + - 94 + vm_offset: 94 + ARISTA94T0: + vlans: + - 95 + vm_offset: 95 + ARISTA95T0: + vlans: + - 96 + vm_offset: 96 + ARISTA96T0: + vlans: + - 97 + vm_offset: 97 + ARISTA97T0: + vlans: + - 98 + vm_offset: 98 + ARISTA98T0: + vlans: + - 99 + vm_offset: 99 + ARISTA99T0: + vlans: + - 100 + vm_offset: 100 + ARISTA100T0: + vlans: + - 101 + vm_offset: 101 + ARISTA101T0: + vlans: + - 102 + vm_offset: 102 + ARISTA102T0: + vlans: + - 103 + vm_offset: 103 + ARISTA103T0: + vlans: + - 104 + vm_offset: 104 + ARISTA104T0: + vlans: + - 105 + vm_offset: 105 + ARISTA105T0: + vlans: + - 106 + vm_offset: 106 + ARISTA106T0: + vlans: + - 107 + vm_offset: 107 + ARISTA107T0: + vlans: + - 108 + vm_offset: 108 + ARISTA108T0: + vlans: + - 109 + vm_offset: 109 + ARISTA109T0: + vlans: + - 110 + vm_offset: 110 + ARISTA110T0: + vlans: + - 111 + vm_offset: 111 + ARISTA111T0: + vlans: + - 112 + vm_offset: 112 + ARISTA112T0: + vlans: + - 113 + vm_offset: 113 + ARISTA113T0: + vlans: + - 114 + vm_offset: 114 + ARISTA114T0: + vlans: + - 115 + vm_offset: 115 + ARISTA115T0: + vlans: + - 116 + vm_offset: 116 + ARISTA116T0: + vlans: + - 117 + vm_offset: 117 + ARISTA117T0: + vlans: + - 118 + vm_offset: 118 + ARISTA118T0: + vlans: + - 119 + vm_offset: 119 + ARISTA119T0: + vlans: + - 120 + vm_offset: 120 + ARISTA120T0: + vlans: + - 121 + vm_offset: 121 + ARISTA121T0: + vlans: + - 122 + vm_offset: 122 + ARISTA122T0: + vlans: + - 123 + vm_offset: 123 + ARISTA123T0: + vlans: + - 124 + vm_offset: 124 + ARISTA124T0: + vlans: + - 125 + vm_offset: 125 + ARISTA125T0: + vlans: + - 126 + vm_offset: 126 + ARISTA126T0: + vlans: + - 127 + vm_offset: 127 + ARISTA127T0: + vlans: + - 128 + vm_offset: 128 + ARISTA128T0: + vlans: + - 129 + vm_offset: 129 + ARISTA129T0: + vlans: + - 130 + vm_offset: 130 + ARISTA130T0: + vlans: + - 131 + vm_offset: 131 + ARISTA131T0: + vlans: + - 132 + vm_offset: 132 + ARISTA132T0: + vlans: + - 133 + vm_offset: 133 + ARISTA133T0: + vlans: + - 134 + vm_offset: 134 + ARISTA134T0: + vlans: + - 135 + vm_offset: 135 + ARISTA135T0: + vlans: + - 136 + vm_offset: 136 + ARISTA136T0: + vlans: + - 137 + vm_offset: 137 + ARISTA137T0: + vlans: + - 138 + vm_offset: 138 + ARISTA138T0: + vlans: + - 139 + vm_offset: 139 + ARISTA139T0: + vlans: + - 140 + vm_offset: 140 + ARISTA140T0: + vlans: + - 141 + vm_offset: 141 + ARISTA141T0: + vlans: + - 142 + vm_offset: 142 + ARISTA142T0: + vlans: + - 143 + vm_offset: 143 + ARISTA143T0: + vlans: + - 144 + vm_offset: 144 + ARISTA144T0: + vlans: + - 145 + vm_offset: 145 + ARISTA145T0: + vlans: + - 146 + vm_offset: 146 + ARISTA146T0: + vlans: + - 147 + vm_offset: 147 + ARISTA147T0: + vlans: + - 148 + vm_offset: 148 + ARISTA148T0: + vlans: + - 149 + vm_offset: 149 + ARISTA149T0: + vlans: + - 150 + vm_offset: 150 + ARISTA150T0: + vlans: + - 151 + vm_offset: 151 + ARISTA151T0: + vlans: + - 152 + vm_offset: 152 + ARISTA152T0: + vlans: + - 153 + vm_offset: 153 + ARISTA153T0: + vlans: + - 154 + vm_offset: 154 + ARISTA154T0: + vlans: + - 155 + vm_offset: 155 + ARISTA155T0: + vlans: + - 156 + vm_offset: 156 + ARISTA156T0: + vlans: + - 157 + vm_offset: 157 + ARISTA157T0: + vlans: + - 158 + vm_offset: 158 + ARISTA158T0: + vlans: + - 159 + vm_offset: 159 + ARISTA159T0: + vlans: + - 160 + vm_offset: 160 + ARISTA160T0: + vlans: + - 161 + vm_offset: 161 + ARISTA161T0: + vlans: + - 162 + vm_offset: 162 + ARISTA162T0: + vlans: + - 163 + vm_offset: 163 + ARISTA163T0: + vlans: + - 164 + vm_offset: 164 + ARISTA164T0: + vlans: + - 165 + vm_offset: 165 + ARISTA165T0: + vlans: + - 166 + vm_offset: 166 + ARISTA166T0: + vlans: + - 167 + vm_offset: 167 + ARISTA167T0: + vlans: + - 168 + vm_offset: 168 + ARISTA168T0: + vlans: + - 169 + vm_offset: 169 + ARISTA169T0: + vlans: + - 170 + vm_offset: 170 + ARISTA170T0: + vlans: + - 171 + vm_offset: 171 + ARISTA171T0: + vlans: + - 172 + vm_offset: 172 + ARISTA172T0: + vlans: + - 173 + vm_offset: 173 + ARISTA173T0: + vlans: + - 174 + vm_offset: 174 + ARISTA174T0: + vlans: + - 175 + vm_offset: 175 + ARISTA175T0: + vlans: + - 176 + vm_offset: 176 + ARISTA176T0: + vlans: + - 177 + vm_offset: 177 + ARISTA177T0: + vlans: + - 178 + vm_offset: 178 + ARISTA178T0: + vlans: + - 179 + vm_offset: 179 + ARISTA179T0: + vlans: + - 180 + vm_offset: 180 + ARISTA180T0: + vlans: + - 181 + vm_offset: 181 + ARISTA181T0: + vlans: + - 182 + vm_offset: 182 + ARISTA182T0: + vlans: + - 183 + vm_offset: 183 + ARISTA183T0: + vlans: + - 184 + vm_offset: 184 + ARISTA184T0: + vlans: + - 185 + vm_offset: 185 + ARISTA185T0: + vlans: + - 186 + vm_offset: 186 + ARISTA186T0: + vlans: + - 187 + vm_offset: 187 + ARISTA187T0: + vlans: + - 188 + vm_offset: 188 + ARISTA188T0: + vlans: + - 189 + vm_offset: 189 + ARISTA189T0: + vlans: + - 190 + vm_offset: 190 + ARISTA190T0: + vlans: + - 191 + vm_offset: 191 + ARISTA191T0: + vlans: + - 192 + vm_offset: 192 + ARISTA192T0: + vlans: + - 193 + vm_offset: 193 + ARISTA193T0: + vlans: + - 194 + vm_offset: 194 + ARISTA194T0: + vlans: + - 195 + vm_offset: 195 + ARISTA195T0: + vlans: + - 196 + vm_offset: 196 + ARISTA196T0: + vlans: + - 197 + vm_offset: 197 + ARISTA197T0: + vlans: + - 198 + vm_offset: 198 + ARISTA198T0: + vlans: + - 199 + vm_offset: 199 + ARISTA199T0: + vlans: + - 200 + vm_offset: 200 + ARISTA200T0: + vlans: + - 201 + vm_offset: 201 + ARISTA201T0: + vlans: + - 202 + vm_offset: 202 + ARISTA202T0: + vlans: + - 203 + vm_offset: 203 + ARISTA203T0: + vlans: + - 204 + vm_offset: 204 + ARISTA204T0: + vlans: + - 205 + vm_offset: 205 + ARISTA205T0: + vlans: + - 206 + vm_offset: 206 + ARISTA206T0: + vlans: + - 207 + vm_offset: 207 + ARISTA207T0: + vlans: + - 208 + vm_offset: 208 + ARISTA208T0: + vlans: + - 209 + vm_offset: 209 + ARISTA209T0: + vlans: + - 210 + vm_offset: 210 + ARISTA210T0: + vlans: + - 211 + vm_offset: 211 + ARISTA211T0: + vlans: + - 212 + vm_offset: 212 + ARISTA212T0: + vlans: + - 213 + vm_offset: 213 + ARISTA213T0: + vlans: + - 214 + vm_offset: 214 + ARISTA214T0: + vlans: + - 215 + vm_offset: 215 + ARISTA215T0: + vlans: + - 216 + vm_offset: 216 + ARISTA216T0: + vlans: + - 217 + vm_offset: 217 + ARISTA217T0: + vlans: + - 218 + vm_offset: 218 + ARISTA218T0: + vlans: + - 219 + vm_offset: 219 + ARISTA219T0: + vlans: + - 220 + vm_offset: 220 + ARISTA220T0: + vlans: + - 221 + vm_offset: 221 + ARISTA221T0: + vlans: + - 222 + vm_offset: 222 + ARISTA222T0: + vlans: + - 223 + vm_offset: 223 + ARISTA223T0: + vlans: + - 224 + vm_offset: 224 + ARISTA224T0: + vlans: + - 225 + vm_offset: 225 + ARISTA225T0: + vlans: + - 226 + vm_offset: 226 + ARISTA226T0: + vlans: + - 227 + vm_offset: 227 + ARISTA227T0: + vlans: + - 228 + vm_offset: 228 + ARISTA228T0: + vlans: + - 229 + vm_offset: 229 + ARISTA229T0: + vlans: + - 230 + vm_offset: 230 + ARISTA230T0: + vlans: + - 231 + vm_offset: 231 + ARISTA231T0: + vlans: + - 232 + vm_offset: 232 + ARISTA232T0: + vlans: + - 233 + vm_offset: 233 + ARISTA233T0: + vlans: + - 234 + vm_offset: 234 + ARISTA234T0: + vlans: + - 235 + vm_offset: 235 + ARISTA235T0: + vlans: + - 236 + vm_offset: 236 + ARISTA236T0: + vlans: + - 237 + vm_offset: 237 + ARISTA237T0: + vlans: + - 238 + vm_offset: 238 + ARISTA238T0: + vlans: + - 239 + vm_offset: 239 + ARISTA239T0: + vlans: + - 240 + vm_offset: 240 + ARISTA240T0: + vlans: + - 241 + vm_offset: 241 + ARISTA241T0: + vlans: + - 242 + vm_offset: 242 + ARISTA242T0: + vlans: + - 243 + vm_offset: 243 + ARISTA243T0: + vlans: + - 244 + vm_offset: 244 + ARISTA244T0: + vlans: + - 245 + vm_offset: 245 + ARISTA245T0: + vlans: + - 246 + vm_offset: 246 + ARISTA246T0: + vlans: + - 247 + vm_offset: 247 + ARISTA247T0: + vlans: + - 248 + vm_offset: 248 + ARISTA248T0: + vlans: + - 249 + vm_offset: 249 + ARISTA249T0: + vlans: + - 250 + vm_offset: 250 + ARISTA250T0: + vlans: + - 251 + vm_offset: 251 + ARISTA251T0: + vlans: + - 252 + vm_offset: 252 + ARISTA252T0: + vlans: + - 253 + vm_offset: 253 + ARISTA253T0: + vlans: + - 254 + vm_offset: 254 + ARISTA254T0: + vlans: + - 255 + vm_offset: 255 + ARISTA255T0: + vlans: + - 256 + vm_offset: 256 + ARISTA256T0: + vlans: + - 257 + vm_offset: 257 + ARISTA257T0: + vlans: + - 258 + vm_offset: 258 + ARISTA258T0: + vlans: + - 259 + vm_offset: 259 + ARISTA259T0: + vlans: + - 260 + vm_offset: 260 + ARISTA260T0: + vlans: + - 261 + vm_offset: 261 + ARISTA261T0: + vlans: + - 262 + vm_offset: 262 + ARISTA262T0: + vlans: + - 263 + vm_offset: 263 + ARISTA263T0: + vlans: + - 264 + vm_offset: 264 + ARISTA264T0: + vlans: + - 265 + vm_offset: 265 + ARISTA265T0: + vlans: + - 266 + vm_offset: 266 + ARISTA266T0: + vlans: + - 267 + vm_offset: 267 + ARISTA267T0: + vlans: + - 268 + vm_offset: 268 + ARISTA268T0: + vlans: + - 269 + vm_offset: 269 + ARISTA269T0: + vlans: + - 270 + vm_offset: 270 + ARISTA270T0: + vlans: + - 271 + vm_offset: 271 + ARISTA271T0: + vlans: + - 272 + vm_offset: 272 + ARISTA272T0: + vlans: + - 273 + vm_offset: 273 + ARISTA273T0: + vlans: + - 274 + vm_offset: 274 + ARISTA274T0: + vlans: + - 275 + vm_offset: 275 + ARISTA275T0: + vlans: + - 276 + vm_offset: 276 + ARISTA276T0: + vlans: + - 277 + vm_offset: 277 + ARISTA277T0: + vlans: + - 278 + vm_offset: 278 + ARISTA278T0: + vlans: + - 279 + vm_offset: 279 + ARISTA279T0: + vlans: + - 280 + vm_offset: 280 + ARISTA280T0: + vlans: + - 281 + vm_offset: 281 + ARISTA281T0: + vlans: + - 282 + vm_offset: 282 + ARISTA282T0: + vlans: + - 283 + vm_offset: 283 + ARISTA283T0: + vlans: + - 284 + vm_offset: 284 + ARISTA284T0: + vlans: + - 285 + vm_offset: 285 + ARISTA285T0: + vlans: + - 286 + vm_offset: 286 + ARISTA286T0: + vlans: + - 287 + vm_offset: 287 + ARISTA287T0: + vlans: + - 288 + vm_offset: 288 + ARISTA288T0: + vlans: + - 289 + vm_offset: 289 + ARISTA289T0: + vlans: + - 290 + vm_offset: 290 + ARISTA290T0: + vlans: + - 291 + vm_offset: 291 + ARISTA291T0: + vlans: + - 292 + vm_offset: 292 + ARISTA292T0: + vlans: + - 293 + vm_offset: 293 + ARISTA293T0: + vlans: + - 294 + vm_offset: 294 + ARISTA294T0: + vlans: + - 295 + vm_offset: 295 + ARISTA295T0: + vlans: + - 296 + vm_offset: 296 + ARISTA296T0: + vlans: + - 297 + vm_offset: 297 + ARISTA297T0: + vlans: + - 298 + vm_offset: 298 + ARISTA298T0: + vlans: + - 299 + vm_offset: 299 + ARISTA299T0: + vlans: + - 300 + vm_offset: 300 + ARISTA300T0: + vlans: + - 301 + vm_offset: 301 + ARISTA301T0: + vlans: + - 302 + vm_offset: 302 + ARISTA302T0: + vlans: + - 303 + vm_offset: 303 + ARISTA303T0: + vlans: + - 304 + vm_offset: 304 + ARISTA304T0: + vlans: + - 305 + vm_offset: 305 + ARISTA305T0: + vlans: + - 306 + vm_offset: 306 + ARISTA306T0: + vlans: + - 307 + vm_offset: 307 + ARISTA307T0: + vlans: + - 308 + vm_offset: 308 + ARISTA308T0: + vlans: + - 309 + vm_offset: 309 + ARISTA309T0: + vlans: + - 310 + vm_offset: 310 + ARISTA310T0: + vlans: + - 311 + vm_offset: 311 + ARISTA311T0: + vlans: + - 312 + vm_offset: 312 + ARISTA312T0: + vlans: + - 313 + vm_offset: 313 + ARISTA313T0: + vlans: + - 314 + vm_offset: 314 + ARISTA314T0: + vlans: + - 315 + vm_offset: 315 + ARISTA315T0: + vlans: + - 316 + vm_offset: 316 + ARISTA316T0: + vlans: + - 317 + vm_offset: 317 + ARISTA317T0: + vlans: + - 318 + vm_offset: 318 + ARISTA318T0: + vlans: + - 319 + vm_offset: 319 + ARISTA319T0: + vlans: + - 320 + vm_offset: 320 + ARISTA320T0: + vlans: + - 321 + vm_offset: 321 + ARISTA321T0: + vlans: + - 322 + vm_offset: 322 + ARISTA322T0: + vlans: + - 323 + vm_offset: 323 + ARISTA323T0: + vlans: + - 324 + vm_offset: 324 + ARISTA324T0: + vlans: + - 325 + vm_offset: 325 + ARISTA325T0: + vlans: + - 326 + vm_offset: 326 + ARISTA326T0: + vlans: + - 327 + vm_offset: 327 + ARISTA327T0: + vlans: + - 328 + vm_offset: 328 + ARISTA328T0: + vlans: + - 329 + vm_offset: 329 + ARISTA329T0: + vlans: + - 330 + vm_offset: 330 + ARISTA330T0: + vlans: + - 331 + vm_offset: 331 + ARISTA331T0: + vlans: + - 332 + vm_offset: 332 + ARISTA332T0: + vlans: + - 333 + vm_offset: 333 + ARISTA333T0: + vlans: + - 334 + vm_offset: 334 + ARISTA334T0: + vlans: + - 335 + vm_offset: 335 + ARISTA335T0: + vlans: + - 336 + vm_offset: 336 + ARISTA336T0: + vlans: + - 337 + vm_offset: 337 + ARISTA337T0: + vlans: + - 338 + vm_offset: 338 + ARISTA338T0: + vlans: + - 339 + vm_offset: 339 + ARISTA339T0: + vlans: + - 340 + vm_offset: 340 + ARISTA340T0: + vlans: + - 341 + vm_offset: 341 + ARISTA341T0: + vlans: + - 342 + vm_offset: 342 + ARISTA342T0: + vlans: + - 343 + vm_offset: 343 + ARISTA343T0: + vlans: + - 344 + vm_offset: 344 + ARISTA344T0: + vlans: + - 345 + vm_offset: 345 + ARISTA345T0: + vlans: + - 346 + vm_offset: 346 + ARISTA346T0: + vlans: + - 347 + vm_offset: 347 + ARISTA347T0: + vlans: + - 348 + vm_offset: 348 + ARISTA348T0: + vlans: + - 349 + vm_offset: 349 + ARISTA349T0: + vlans: + - 350 + vm_offset: 350 + ARISTA350T0: + vlans: + - 351 + vm_offset: 351 + ARISTA351T0: + vlans: + - 352 + vm_offset: 352 + ARISTA352T0: + vlans: + - 353 + vm_offset: 353 + ARISTA353T0: + vlans: + - 354 + vm_offset: 354 + ARISTA354T0: + vlans: + - 355 + vm_offset: 355 + ARISTA355T0: + vlans: + - 356 + vm_offset: 356 + ARISTA356T0: + vlans: + - 357 + vm_offset: 357 + ARISTA357T0: + vlans: + - 358 + vm_offset: 358 + ARISTA358T0: + vlans: + - 359 + vm_offset: 359 + ARISTA359T0: + vlans: + - 360 + vm_offset: 360 + ARISTA360T0: + vlans: + - 361 + vm_offset: 361 + ARISTA361T0: + vlans: + - 362 + vm_offset: 362 + ARISTA362T0: + vlans: + - 363 + vm_offset: 363 + ARISTA363T0: + vlans: + - 364 + vm_offset: 364 + ARISTA364T0: + vlans: + - 365 + vm_offset: 365 + ARISTA365T0: + vlans: + - 366 + vm_offset: 366 + ARISTA366T0: + vlans: + - 367 + vm_offset: 367 + ARISTA367T0: + vlans: + - 368 + vm_offset: 368 + ARISTA368T0: + vlans: + - 369 + vm_offset: 369 + ARISTA369T0: + vlans: + - 370 + vm_offset: 370 + ARISTA370T0: + vlans: + - 371 + vm_offset: 371 + ARISTA371T0: + vlans: + - 372 + vm_offset: 372 + ARISTA372T0: + vlans: + - 373 + vm_offset: 373 + ARISTA373T0: + vlans: + - 374 + vm_offset: 374 + ARISTA374T0: + vlans: + - 375 + vm_offset: 375 + ARISTA375T0: + vlans: + - 376 + vm_offset: 376 + ARISTA376T0: + vlans: + - 377 + vm_offset: 377 + ARISTA377T0: + vlans: + - 378 + vm_offset: 378 + ARISTA378T0: + vlans: + - 379 + vm_offset: 379 + ARISTA379T0: + vlans: + - 380 + vm_offset: 380 + ARISTA380T0: + vlans: + - 381 + vm_offset: 381 + ARISTA381T0: + vlans: + - 382 + vm_offset: 382 + ARISTA382T0: + vlans: + - 383 + vm_offset: 383 + ARISTA383T0: + vlans: + - 384 + vm_offset: 384 + ARISTA384T0: + vlans: + - 385 + vm_offset: 385 + ARISTA385T0: + vlans: + - 386 + vm_offset: 386 + ARISTA386T0: + vlans: + - 387 + vm_offset: 387 + ARISTA387T0: + vlans: + - 388 + vm_offset: 388 + ARISTA388T0: + vlans: + - 389 + vm_offset: 389 + ARISTA389T0: + vlans: + - 390 + vm_offset: 390 + ARISTA390T0: + vlans: + - 391 + vm_offset: 391 + ARISTA391T0: + vlans: + - 392 + vm_offset: 392 + ARISTA392T0: + vlans: + - 393 + vm_offset: 393 + ARISTA393T0: + vlans: + - 394 + vm_offset: 394 + ARISTA394T0: + vlans: + - 395 + vm_offset: 395 + ARISTA395T0: + vlans: + - 396 + vm_offset: 396 + ARISTA396T0: + vlans: + - 397 + vm_offset: 397 + ARISTA397T0: + vlans: + - 398 + vm_offset: 398 + ARISTA398T0: + vlans: + - 399 + vm_offset: 399 + ARISTA399T0: + vlans: + - 400 + vm_offset: 400 + ARISTA400T0: + vlans: + - 401 + vm_offset: 401 + ARISTA401T0: + vlans: + - 402 + vm_offset: 402 + ARISTA402T0: + vlans: + - 403 + vm_offset: 403 + ARISTA403T0: + vlans: + - 404 + vm_offset: 404 + ARISTA404T0: + vlans: + - 405 + vm_offset: 405 + ARISTA405T0: + vlans: + - 406 + vm_offset: 406 + ARISTA406T0: + vlans: + - 407 + vm_offset: 407 + ARISTA407T0: + vlans: + - 408 + vm_offset: 408 + ARISTA408T0: + vlans: + - 409 + vm_offset: 409 + ARISTA409T0: + vlans: + - 410 + vm_offset: 410 + ARISTA410T0: + vlans: + - 411 + vm_offset: 411 + ARISTA411T0: + vlans: + - 412 + vm_offset: 412 + ARISTA412T0: + vlans: + - 413 + vm_offset: 413 + ARISTA413T0: + vlans: + - 414 + vm_offset: 414 + ARISTA414T0: + vlans: + - 415 + vm_offset: 415 + ARISTA415T0: + vlans: + - 416 + vm_offset: 416 + ARISTA416T0: + vlans: + - 417 + vm_offset: 417 + ARISTA417T0: + vlans: + - 418 + vm_offset: 418 + ARISTA418T0: + vlans: + - 419 + vm_offset: 419 + ARISTA419T0: + vlans: + - 420 + vm_offset: 420 + ARISTA420T0: + vlans: + - 421 + vm_offset: 421 + ARISTA421T0: + vlans: + - 422 + vm_offset: 422 + ARISTA422T0: + vlans: + - 423 + vm_offset: 423 + ARISTA423T0: + vlans: + - 424 + vm_offset: 424 + ARISTA424T0: + vlans: + - 425 + vm_offset: 425 + ARISTA425T0: + vlans: + - 426 + vm_offset: 426 + ARISTA426T0: + vlans: + - 427 + vm_offset: 427 + ARISTA427T0: + vlans: + - 428 + vm_offset: 428 + ARISTA428T0: + vlans: + - 429 + vm_offset: 429 + ARISTA429T0: + vlans: + - 430 + vm_offset: 430 + ARISTA430T0: + vlans: + - 431 + vm_offset: 431 + ARISTA431T0: + vlans: + - 432 + vm_offset: 432 + ARISTA432T0: + vlans: + - 433 + vm_offset: 433 + ARISTA433T0: + vlans: + - 434 + vm_offset: 434 + ARISTA434T0: + vlans: + - 435 + vm_offset: 435 + ARISTA435T0: + vlans: + - 436 + vm_offset: 436 + ARISTA436T0: + vlans: + - 437 + vm_offset: 437 + ARISTA437T0: + vlans: + - 438 + vm_offset: 438 + ARISTA438T0: + vlans: + - 439 + vm_offset: 439 + ARISTA439T0: + vlans: + - 440 + vm_offset: 440 + ARISTA440T0: + vlans: + - 441 + vm_offset: 441 + ARISTA441T0: + vlans: + - 442 + vm_offset: 442 + ARISTA442T0: + vlans: + - 443 + vm_offset: 443 + ARISTA443T0: + vlans: + - 444 + vm_offset: 444 + ARISTA444T0: + vlans: + - 445 + vm_offset: 445 + ARISTA445T0: + vlans: + - 446 + vm_offset: 446 + ARISTA446T0: + vlans: + - 447 + vm_offset: 447 + ARISTA447T0: + vlans: + - 448 + vm_offset: 448 + ARISTA448T0: + vlans: + - 449 + vm_offset: 449 + ARISTA449T0: + vlans: + - 450 + vm_offset: 450 + ARISTA450T0: + vlans: + - 451 + vm_offset: 451 + ARISTA451T0: + vlans: + - 452 + vm_offset: 452 + ARISTA452T0: + vlans: + - 453 + vm_offset: 453 + ARISTA453T0: + vlans: + - 454 + vm_offset: 454 + ARISTA454T0: + vlans: + - 455 + vm_offset: 455 + ARISTA455T0: + vlans: + - 456 + vm_offset: 456 + ARISTA456T0: + vlans: + - 457 + vm_offset: 457 + ARISTA457T0: + vlans: + - 458 + vm_offset: 458 + ARISTA458T0: + vlans: + - 459 + vm_offset: 459 + ARISTA459T0: + vlans: + - 460 + vm_offset: 460 + ARISTA460T0: + vlans: + - 461 + vm_offset: 461 + ARISTA461T0: + vlans: + - 462 + vm_offset: 462 + ARISTA462T0: + vlans: + - 463 + vm_offset: 463 + ARISTA463T0: + vlans: + - 464 + vm_offset: 464 + ARISTA464T0: + vlans: + - 465 + vm_offset: 465 + ARISTA465T0: + vlans: + - 466 + vm_offset: 466 + ARISTA466T0: + vlans: + - 467 + vm_offset: 467 + ARISTA467T0: + vlans: + - 468 + vm_offset: 468 + ARISTA468T0: + vlans: + - 469 + vm_offset: 469 + ARISTA469T0: + vlans: + - 470 + vm_offset: 470 + ARISTA470T0: + vlans: + - 471 + vm_offset: 471 + ARISTA471T0: + vlans: + - 472 + vm_offset: 472 + ARISTA472T0: + vlans: + - 473 + vm_offset: 473 + ARISTA473T0: + vlans: + - 474 + vm_offset: 474 + ARISTA474T0: + vlans: + - 475 + vm_offset: 475 + ARISTA475T0: + vlans: + - 476 + vm_offset: 476 + ARISTA476T0: + vlans: + - 477 + vm_offset: 477 + ARISTA477T0: + vlans: + - 478 + vm_offset: 478 + ARISTA478T0: + vlans: + - 479 + vm_offset: 479 + ARISTA479T0: + vlans: + - 480 + vm_offset: 480 + ARISTA480T0: + vlans: + - 481 + vm_offset: 481 + ARISTA481T0: + vlans: + - 482 + vm_offset: 482 + ARISTA482T0: + vlans: + - 483 + vm_offset: 483 + ARISTA483T0: + vlans: + - 484 + vm_offset: 484 + ARISTA484T0: + vlans: + - 485 + vm_offset: 485 + ARISTA485T0: + vlans: + - 486 + vm_offset: 486 + ARISTA486T0: + vlans: + - 487 + vm_offset: 487 + ARISTA487T0: + vlans: + - 488 + vm_offset: 488 + ARISTA488T0: + vlans: + - 489 + vm_offset: 489 + ARISTA489T0: + vlans: + - 490 + vm_offset: 490 + ARISTA490T0: + vlans: + - 491 + vm_offset: 491 + ARISTA491T0: + vlans: + - 492 + vm_offset: 492 + ARISTA492T0: + vlans: + - 493 + vm_offset: 493 + ARISTA493T0: + vlans: + - 494 + vm_offset: 494 + ARISTA494T0: + vlans: + - 495 + vm_offset: 495 + ARISTA495T0: + vlans: + - 496 + vm_offset: 496 + ARISTA496T0: + vlans: + - 497 + vm_offset: 497 + ARISTA497T0: + vlans: + - 498 + vm_offset: 498 + ARISTA498T0: + vlans: + - 499 + vm_offset: 499 + ARISTA499T0: + vlans: + - 500 + vm_offset: 500 + ARISTA500T0: + vlans: + - 501 + vm_offset: 501 + ARISTA501T0: + vlans: + - 502 + vm_offset: 502 + ARISTA502T0: + vlans: + - 503 + vm_offset: 503 + ARISTA503T0: + vlans: + - 504 + vm_offset: 504 + ARISTA504T0: + vlans: + - 505 + vm_offset: 505 + ARISTA505T0: + vlans: + - 506 + vm_offset: 506 + ARISTA506T0: + vlans: + - 507 + vm_offset: 507 + ARISTA507T0: + vlans: + - 508 + vm_offset: 508 + ARISTA508T0: + vlans: + - 509 + vm_offset: 509 + ARISTA509T0: + vlans: + - 510 + vm_offset: 510 + ARISTA510T0: + vlans: + - 511 + vm_offset: 511 + +configuration_properties: + common: + dut_asn: 4200100000 + dut_type: LeafRouter + podset_number: 200 + tor_number: 16 + tor_subnet_number: 2 + max_tor_subnet_number: 16 + tor_subnet_size: 128 + nhipv6: FC0A::FF + spine: + swrole: spine + tor: + swrole: tor + +configuration: + ARISTA01T2: + properties: + - common + - spine + bgp: + router-id: 0.12.0.1 + asn: 4200200000 + peers: + 4200100000: + - fc00:a::1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1::1/128 + Ethernet1: + ipv6: fc00:a::2/126 + bp_interface: + ipv6: fc00:b::1/64 + + ARISTA02T2: + properties: + - common + - spine + bgp: + router-id: 0.12.0.2 + asn: 4200200000 + peers: + 4200100000: + - fc00:a::5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2::1/128 + Ethernet1: + ipv6: fc00:a::6/126 + bp_interface: + ipv6: fc00:b::2/64 + + ARISTA01T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.3 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3::1/128 + Ethernet1: + ipv6: fc00:a::a/126 + bp_interface: + ipv6: fc00:b::3/64 + + ARISTA02T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.4 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d + interfaces: + Loopback0: + ipv6: fc00:c:c:4::1/128 + Ethernet1: + ipv6: fc00:a::e/126 + bp_interface: + ipv6: fc00:b::4/64 + + ARISTA03T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.5 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::11 + interfaces: + Loopback0: + ipv6: fc00:c:c:5::1/128 + Ethernet1: + ipv6: fc00:a::12/126 + bp_interface: + ipv6: fc00:b::5/64 + + ARISTA04T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.6 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::15 + interfaces: + Loopback0: + ipv6: fc00:c:c:6::1/128 + Ethernet1: + ipv6: fc00:a::16/126 + bp_interface: + ipv6: fc00:b::6/64 + + ARISTA05T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.7 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::19 + interfaces: + Loopback0: + ipv6: fc00:c:c:7::1/128 + Ethernet1: + ipv6: fc00:a::1a/126 + bp_interface: + ipv6: fc00:b::7/64 + + ARISTA06T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.8 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d + interfaces: + Loopback0: + ipv6: fc00:c:c:8::1/128 + Ethernet1: + ipv6: fc00:a::1e/126 + bp_interface: + ipv6: fc00:b::8/64 + + ARISTA07T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.9 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::21 + interfaces: + Loopback0: + ipv6: fc00:c:c:9::1/128 + Ethernet1: + ipv6: fc00:a::22/126 + bp_interface: + ipv6: fc00:b::9/64 + + ARISTA08T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.10 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::25 + interfaces: + Loopback0: + ipv6: fc00:c:c:a::1/128 + Ethernet1: + ipv6: fc00:a::26/126 + bp_interface: + ipv6: fc00:b::a/64 + + ARISTA09T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.11 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::29 + interfaces: + Loopback0: + ipv6: fc00:c:c:b::1/128 + Ethernet1: + ipv6: fc00:a::2a/126 + bp_interface: + ipv6: fc00:b::b/64 + + ARISTA10T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.12 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d + interfaces: + Loopback0: + ipv6: fc00:c:c:c::1/128 + Ethernet1: + ipv6: fc00:a::2e/126 + bp_interface: + ipv6: fc00:b::c/64 + + ARISTA11T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.13 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::31 + interfaces: + Loopback0: + ipv6: fc00:c:c:d::1/128 + Ethernet1: + ipv6: fc00:a::32/126 + bp_interface: + ipv6: fc00:b::d/64 + + ARISTA12T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.14 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::35 + interfaces: + Loopback0: + ipv6: fc00:c:c:e::1/128 + Ethernet1: + ipv6: fc00:a::36/126 + bp_interface: + ipv6: fc00:b::e/64 + + ARISTA13T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.15 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::39 + interfaces: + Loopback0: + ipv6: fc00:c:c:f::1/128 + Ethernet1: + ipv6: fc00:a::3a/126 + bp_interface: + ipv6: fc00:b::f/64 + + ARISTA14T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.16 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d + interfaces: + Loopback0: + ipv6: fc00:c:c:10::1/128 + Ethernet1: + ipv6: fc00:a::3e/126 + bp_interface: + ipv6: fc00:b::10/64 + + ARISTA15T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.17 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::41 + interfaces: + Loopback0: + ipv6: fc00:c:c:11::1/128 + Ethernet1: + ipv6: fc00:a::42/126 + bp_interface: + ipv6: fc00:b::11/64 + + ARISTA16T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.18 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::45 + interfaces: + Loopback0: + ipv6: fc00:c:c:12::1/128 + Ethernet1: + ipv6: fc00:a::46/126 + bp_interface: + ipv6: fc00:b::12/64 + + ARISTA17T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.19 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::49 + interfaces: + Loopback0: + ipv6: fc00:c:c:13::1/128 + Ethernet1: + ipv6: fc00:a::4a/126 + bp_interface: + ipv6: fc00:b::13/64 + + ARISTA18T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.20 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4d + interfaces: + Loopback0: + ipv6: fc00:c:c:14::1/128 + Ethernet1: + ipv6: fc00:a::4e/126 + bp_interface: + ipv6: fc00:b::14/64 + + ARISTA19T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.21 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::51 + interfaces: + Loopback0: + ipv6: fc00:c:c:15::1/128 + Ethernet1: + ipv6: fc00:a::52/126 + bp_interface: + ipv6: fc00:b::15/64 + + ARISTA20T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.22 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::55 + interfaces: + Loopback0: + ipv6: fc00:c:c:16::1/128 + Ethernet1: + ipv6: fc00:a::56/126 + bp_interface: + ipv6: fc00:b::16/64 + + ARISTA21T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.23 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::59 + interfaces: + Loopback0: + ipv6: fc00:c:c:17::1/128 + Ethernet1: + ipv6: fc00:a::5a/126 + bp_interface: + ipv6: fc00:b::17/64 + + ARISTA22T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.24 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5d + interfaces: + Loopback0: + ipv6: fc00:c:c:18::1/128 + Ethernet1: + ipv6: fc00:a::5e/126 + bp_interface: + ipv6: fc00:b::18/64 + + ARISTA23T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.25 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::61 + interfaces: + Loopback0: + ipv6: fc00:c:c:19::1/128 + Ethernet1: + ipv6: fc00:a::62/126 + bp_interface: + ipv6: fc00:b::19/64 + + ARISTA24T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.26 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::65 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a::1/128 + Ethernet1: + ipv6: fc00:a::66/126 + bp_interface: + ipv6: fc00:b::1a/64 + + ARISTA25T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.27 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::69 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b::1/128 + Ethernet1: + ipv6: fc00:a::6a/126 + bp_interface: + ipv6: fc00:b::1b/64 + + ARISTA26T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.28 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c::1/128 + Ethernet1: + ipv6: fc00:a::6e/126 + bp_interface: + ipv6: fc00:b::1c/64 + + ARISTA27T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.29 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::71 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d::1/128 + Ethernet1: + ipv6: fc00:a::72/126 + bp_interface: + ipv6: fc00:b::1d/64 + + ARISTA28T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.30 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::75 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e::1/128 + Ethernet1: + ipv6: fc00:a::76/126 + bp_interface: + ipv6: fc00:b::1e/64 + + ARISTA29T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.31 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::79 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f::1/128 + Ethernet1: + ipv6: fc00:a::7a/126 + bp_interface: + ipv6: fc00:b::1f/64 + + ARISTA30T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.32 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7d + interfaces: + Loopback0: + ipv6: fc00:c:c:20::1/128 + Ethernet1: + ipv6: fc00:a::7e/126 + bp_interface: + ipv6: fc00:b::20/64 + + ARISTA31T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.33 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::81 + interfaces: + Loopback0: + ipv6: fc00:c:c:21::1/128 + Ethernet1: + ipv6: fc00:a::82/126 + bp_interface: + ipv6: fc00:b::21/64 + + ARISTA32T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.34 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::85 + interfaces: + Loopback0: + ipv6: fc00:c:c:22::1/128 + Ethernet1: + ipv6: fc00:a::86/126 + bp_interface: + ipv6: fc00:b::22/64 + + ARISTA33T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.35 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::89 + interfaces: + Loopback0: + ipv6: fc00:c:c:23::1/128 + Ethernet1: + ipv6: fc00:a::8a/126 + bp_interface: + ipv6: fc00:b::23/64 + + ARISTA34T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.36 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::8d + interfaces: + Loopback0: + ipv6: fc00:c:c:24::1/128 + Ethernet1: + ipv6: fc00:a::8e/126 + bp_interface: + ipv6: fc00:b::24/64 + + ARISTA35T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.37 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::91 + interfaces: + Loopback0: + ipv6: fc00:c:c:25::1/128 + Ethernet1: + ipv6: fc00:a::92/126 + bp_interface: + ipv6: fc00:b::25/64 + + ARISTA36T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.38 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::95 + interfaces: + Loopback0: + ipv6: fc00:c:c:26::1/128 + Ethernet1: + ipv6: fc00:a::96/126 + bp_interface: + ipv6: fc00:b::26/64 + + ARISTA37T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.39 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::99 + interfaces: + Loopback0: + ipv6: fc00:c:c:27::1/128 + Ethernet1: + ipv6: fc00:a::9a/126 + bp_interface: + ipv6: fc00:b::27/64 + + ARISTA38T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.40 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::9d + interfaces: + Loopback0: + ipv6: fc00:c:c:28::1/128 + Ethernet1: + ipv6: fc00:a::9e/126 + bp_interface: + ipv6: fc00:b::28/64 + + ARISTA39T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.41 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:29::1/128 + Ethernet1: + ipv6: fc00:a::a2/126 + bp_interface: + ipv6: fc00:b::29/64 + + ARISTA40T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.42 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2a::1/128 + Ethernet1: + ipv6: fc00:a::a6/126 + bp_interface: + ipv6: fc00:b::2a/64 + + ARISTA41T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.43 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2b::1/128 + Ethernet1: + ipv6: fc00:a::aa/126 + bp_interface: + ipv6: fc00:b::2b/64 + + ARISTA42T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.44 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::ad + interfaces: + Loopback0: + ipv6: fc00:c:c:2c::1/128 + Ethernet1: + ipv6: fc00:a::ae/126 + bp_interface: + ipv6: fc00:b::2c/64 + + ARISTA43T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.45 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:2d::1/128 + Ethernet1: + ipv6: fc00:a::b2/126 + bp_interface: + ipv6: fc00:b::2d/64 + + ARISTA44T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.46 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:2e::1/128 + Ethernet1: + ipv6: fc00:a::b6/126 + bp_interface: + ipv6: fc00:b::2e/64 + + ARISTA45T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.47 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:2f::1/128 + Ethernet1: + ipv6: fc00:a::ba/126 + bp_interface: + ipv6: fc00:b::2f/64 + + ARISTA46T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.48 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::bd + interfaces: + Loopback0: + ipv6: fc00:c:c:30::1/128 + Ethernet1: + ipv6: fc00:a::be/126 + bp_interface: + ipv6: fc00:b::30/64 + + ARISTA47T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.49 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:31::1/128 + Ethernet1: + ipv6: fc00:a::c2/126 + bp_interface: + ipv6: fc00:b::31/64 + + ARISTA48T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.50 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:32::1/128 + Ethernet1: + ipv6: fc00:a::c6/126 + bp_interface: + ipv6: fc00:b::32/64 + + ARISTA49T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.51 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:33::1/128 + Ethernet1: + ipv6: fc00:a::ca/126 + bp_interface: + ipv6: fc00:b::33/64 + + ARISTA50T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.52 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::cd + interfaces: + Loopback0: + ipv6: fc00:c:c:34::1/128 + Ethernet1: + ipv6: fc00:a::ce/126 + bp_interface: + ipv6: fc00:b::34/64 + + ARISTA51T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.53 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:35::1/128 + Ethernet1: + ipv6: fc00:a::d2/126 + bp_interface: + ipv6: fc00:b::35/64 + + ARISTA52T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.54 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:36::1/128 + Ethernet1: + ipv6: fc00:a::d6/126 + bp_interface: + ipv6: fc00:b::36/64 + + ARISTA53T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.55 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:37::1/128 + Ethernet1: + ipv6: fc00:a::da/126 + bp_interface: + ipv6: fc00:b::37/64 + + ARISTA54T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.56 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::dd + interfaces: + Loopback0: + ipv6: fc00:c:c:38::1/128 + Ethernet1: + ipv6: fc00:a::de/126 + bp_interface: + ipv6: fc00:b::38/64 + + ARISTA55T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.57 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:39::1/128 + Ethernet1: + ipv6: fc00:a::e2/126 + bp_interface: + ipv6: fc00:b::39/64 + + ARISTA56T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.58 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3a::1/128 + Ethernet1: + ipv6: fc00:a::e6/126 + bp_interface: + ipv6: fc00:b::3a/64 + + ARISTA57T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.59 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3b::1/128 + Ethernet1: + ipv6: fc00:a::ea/126 + bp_interface: + ipv6: fc00:b::3b/64 + + ARISTA58T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.60 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::ed + interfaces: + Loopback0: + ipv6: fc00:c:c:3c::1/128 + Ethernet1: + ipv6: fc00:a::ee/126 + bp_interface: + ipv6: fc00:b::3c/64 + + ARISTA59T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.61 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:3d::1/128 + Ethernet1: + ipv6: fc00:a::f2/126 + bp_interface: + ipv6: fc00:b::3d/64 + + ARISTA60T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.62 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:3e::1/128 + Ethernet1: + ipv6: fc00:a::f6/126 + bp_interface: + ipv6: fc00:b::3e/64 + + ARISTA61T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.63 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:3f::1/128 + Ethernet1: + ipv6: fc00:a::fa/126 + bp_interface: + ipv6: fc00:b::3f/64 + + ARISTA62T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.64 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::fd + interfaces: + Loopback0: + ipv6: fc00:c:c:40::1/128 + Ethernet1: + ipv6: fc00:a::fe/126 + bp_interface: + ipv6: fc00:b::40/64 + + ARISTA63T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.65 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::101 + interfaces: + Loopback0: + ipv6: fc00:c:c:41::1/128 + Ethernet1: + ipv6: fc00:a::102/126 + bp_interface: + ipv6: fc00:b::41/64 + + ARISTA64T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.66 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::105 + interfaces: + Loopback0: + ipv6: fc00:c:c:42::1/128 + Ethernet1: + ipv6: fc00:a::106/126 + bp_interface: + ipv6: fc00:b::42/64 + + ARISTA65T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.67 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::109 + interfaces: + Loopback0: + ipv6: fc00:c:c:43::1/128 + Ethernet1: + ipv6: fc00:a::10a/126 + bp_interface: + ipv6: fc00:b::43/64 + + ARISTA66T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.68 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::10d + interfaces: + Loopback0: + ipv6: fc00:c:c:44::1/128 + Ethernet1: + ipv6: fc00:a::10e/126 + bp_interface: + ipv6: fc00:b::44/64 + + ARISTA67T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.69 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::111 + interfaces: + Loopback0: + ipv6: fc00:c:c:45::1/128 + Ethernet1: + ipv6: fc00:a::112/126 + bp_interface: + ipv6: fc00:b::45/64 + + ARISTA68T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.70 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::115 + interfaces: + Loopback0: + ipv6: fc00:c:c:46::1/128 + Ethernet1: + ipv6: fc00:a::116/126 + bp_interface: + ipv6: fc00:b::46/64 + + ARISTA69T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.71 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::119 + interfaces: + Loopback0: + ipv6: fc00:c:c:47::1/128 + Ethernet1: + ipv6: fc00:a::11a/126 + bp_interface: + ipv6: fc00:b::47/64 + + ARISTA70T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.72 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::11d + interfaces: + Loopback0: + ipv6: fc00:c:c:48::1/128 + Ethernet1: + ipv6: fc00:a::11e/126 + bp_interface: + ipv6: fc00:b::48/64 + + ARISTA71T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.73 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::121 + interfaces: + Loopback0: + ipv6: fc00:c:c:49::1/128 + Ethernet1: + ipv6: fc00:a::122/126 + bp_interface: + ipv6: fc00:b::49/64 + + ARISTA72T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.74 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::125 + interfaces: + Loopback0: + ipv6: fc00:c:c:4a::1/128 + Ethernet1: + ipv6: fc00:a::126/126 + bp_interface: + ipv6: fc00:b::4a/64 + + ARISTA73T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.75 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::129 + interfaces: + Loopback0: + ipv6: fc00:c:c:4b::1/128 + Ethernet1: + ipv6: fc00:a::12a/126 + bp_interface: + ipv6: fc00:b::4b/64 + + ARISTA74T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.76 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::12d + interfaces: + Loopback0: + ipv6: fc00:c:c:4c::1/128 + Ethernet1: + ipv6: fc00:a::12e/126 + bp_interface: + ipv6: fc00:b::4c/64 + + ARISTA75T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.77 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::131 + interfaces: + Loopback0: + ipv6: fc00:c:c:4d::1/128 + Ethernet1: + ipv6: fc00:a::132/126 + bp_interface: + ipv6: fc00:b::4d/64 + + ARISTA76T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.78 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::135 + interfaces: + Loopback0: + ipv6: fc00:c:c:4e::1/128 + Ethernet1: + ipv6: fc00:a::136/126 + bp_interface: + ipv6: fc00:b::4e/64 + + ARISTA77T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.79 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::139 + interfaces: + Loopback0: + ipv6: fc00:c:c:4f::1/128 + Ethernet1: + ipv6: fc00:a::13a/126 + bp_interface: + ipv6: fc00:b::4f/64 + + ARISTA78T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.80 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::13d + interfaces: + Loopback0: + ipv6: fc00:c:c:50::1/128 + Ethernet1: + ipv6: fc00:a::13e/126 + bp_interface: + ipv6: fc00:b::50/64 + + ARISTA79T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.81 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::141 + interfaces: + Loopback0: + ipv6: fc00:c:c:51::1/128 + Ethernet1: + ipv6: fc00:a::142/126 + bp_interface: + ipv6: fc00:b::51/64 + + ARISTA80T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.82 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::145 + interfaces: + Loopback0: + ipv6: fc00:c:c:52::1/128 + Ethernet1: + ipv6: fc00:a::146/126 + bp_interface: + ipv6: fc00:b::52/64 + + ARISTA81T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.83 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::149 + interfaces: + Loopback0: + ipv6: fc00:c:c:53::1/128 + Ethernet1: + ipv6: fc00:a::14a/126 + bp_interface: + ipv6: fc00:b::53/64 + + ARISTA82T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.84 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::14d + interfaces: + Loopback0: + ipv6: fc00:c:c:54::1/128 + Ethernet1: + ipv6: fc00:a::14e/126 + bp_interface: + ipv6: fc00:b::54/64 + + ARISTA83T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.85 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::151 + interfaces: + Loopback0: + ipv6: fc00:c:c:55::1/128 + Ethernet1: + ipv6: fc00:a::152/126 + bp_interface: + ipv6: fc00:b::55/64 + + ARISTA84T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.86 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::155 + interfaces: + Loopback0: + ipv6: fc00:c:c:56::1/128 + Ethernet1: + ipv6: fc00:a::156/126 + bp_interface: + ipv6: fc00:b::56/64 + + ARISTA85T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.87 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::159 + interfaces: + Loopback0: + ipv6: fc00:c:c:57::1/128 + Ethernet1: + ipv6: fc00:a::15a/126 + bp_interface: + ipv6: fc00:b::57/64 + + ARISTA86T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.88 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::15d + interfaces: + Loopback0: + ipv6: fc00:c:c:58::1/128 + Ethernet1: + ipv6: fc00:a::15e/126 + bp_interface: + ipv6: fc00:b::58/64 + + ARISTA87T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.89 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::161 + interfaces: + Loopback0: + ipv6: fc00:c:c:59::1/128 + Ethernet1: + ipv6: fc00:a::162/126 + bp_interface: + ipv6: fc00:b::59/64 + + ARISTA88T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.90 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::165 + interfaces: + Loopback0: + ipv6: fc00:c:c:5a::1/128 + Ethernet1: + ipv6: fc00:a::166/126 + bp_interface: + ipv6: fc00:b::5a/64 + + ARISTA89T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.91 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::169 + interfaces: + Loopback0: + ipv6: fc00:c:c:5b::1/128 + Ethernet1: + ipv6: fc00:a::16a/126 + bp_interface: + ipv6: fc00:b::5b/64 + + ARISTA90T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.92 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::16d + interfaces: + Loopback0: + ipv6: fc00:c:c:5c::1/128 + Ethernet1: + ipv6: fc00:a::16e/126 + bp_interface: + ipv6: fc00:b::5c/64 + + ARISTA91T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.93 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::171 + interfaces: + Loopback0: + ipv6: fc00:c:c:5d::1/128 + Ethernet1: + ipv6: fc00:a::172/126 + bp_interface: + ipv6: fc00:b::5d/64 + + ARISTA92T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.94 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::175 + interfaces: + Loopback0: + ipv6: fc00:c:c:5e::1/128 + Ethernet1: + ipv6: fc00:a::176/126 + bp_interface: + ipv6: fc00:b::5e/64 + + ARISTA93T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.95 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::179 + interfaces: + Loopback0: + ipv6: fc00:c:c:5f::1/128 + Ethernet1: + ipv6: fc00:a::17a/126 + bp_interface: + ipv6: fc00:b::5f/64 + + ARISTA94T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.96 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::17d + interfaces: + Loopback0: + ipv6: fc00:c:c:60::1/128 + Ethernet1: + ipv6: fc00:a::17e/126 + bp_interface: + ipv6: fc00:b::60/64 + + ARISTA95T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.97 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::181 + interfaces: + Loopback0: + ipv6: fc00:c:c:61::1/128 + Ethernet1: + ipv6: fc00:a::182/126 + bp_interface: + ipv6: fc00:b::61/64 + + ARISTA96T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.98 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::185 + interfaces: + Loopback0: + ipv6: fc00:c:c:62::1/128 + Ethernet1: + ipv6: fc00:a::186/126 + bp_interface: + ipv6: fc00:b::62/64 + + ARISTA97T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.99 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::189 + interfaces: + Loopback0: + ipv6: fc00:c:c:63::1/128 + Ethernet1: + ipv6: fc00:a::18a/126 + bp_interface: + ipv6: fc00:b::63/64 + + ARISTA98T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.100 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::18d + interfaces: + Loopback0: + ipv6: fc00:c:c:64::1/128 + Ethernet1: + ipv6: fc00:a::18e/126 + bp_interface: + ipv6: fc00:b::64/64 + + ARISTA99T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.101 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::191 + interfaces: + Loopback0: + ipv6: fc00:c:c:65::1/128 + Ethernet1: + ipv6: fc00:a::192/126 + bp_interface: + ipv6: fc00:b::65/64 + + ARISTA100T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.102 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::195 + interfaces: + Loopback0: + ipv6: fc00:c:c:66::1/128 + Ethernet1: + ipv6: fc00:a::196/126 + bp_interface: + ipv6: fc00:b::66/64 + + ARISTA101T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.103 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::199 + interfaces: + Loopback0: + ipv6: fc00:c:c:67::1/128 + Ethernet1: + ipv6: fc00:a::19a/126 + bp_interface: + ipv6: fc00:b::67/64 + + ARISTA102T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.104 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::19d + interfaces: + Loopback0: + ipv6: fc00:c:c:68::1/128 + Ethernet1: + ipv6: fc00:a::19e/126 + bp_interface: + ipv6: fc00:b::68/64 + + ARISTA103T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.105 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:69::1/128 + Ethernet1: + ipv6: fc00:a::1a2/126 + bp_interface: + ipv6: fc00:b::69/64 + + ARISTA104T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.106 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6a::1/128 + Ethernet1: + ipv6: fc00:a::1a6/126 + bp_interface: + ipv6: fc00:b::6a/64 + + ARISTA105T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.107 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6b::1/128 + Ethernet1: + ipv6: fc00:a::1aa/126 + bp_interface: + ipv6: fc00:b::6b/64 + + ARISTA106T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.108 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1ad + interfaces: + Loopback0: + ipv6: fc00:c:c:6c::1/128 + Ethernet1: + ipv6: fc00:a::1ae/126 + bp_interface: + ipv6: fc00:b::6c/64 + + ARISTA107T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.109 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:6d::1/128 + Ethernet1: + ipv6: fc00:a::1b2/126 + bp_interface: + ipv6: fc00:b::6d/64 + + ARISTA108T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.110 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:6e::1/128 + Ethernet1: + ipv6: fc00:a::1b6/126 + bp_interface: + ipv6: fc00:b::6e/64 + + ARISTA109T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.111 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:6f::1/128 + Ethernet1: + ipv6: fc00:a::1ba/126 + bp_interface: + ipv6: fc00:b::6f/64 + + ARISTA110T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.112 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1bd + interfaces: + Loopback0: + ipv6: fc00:c:c:70::1/128 + Ethernet1: + ipv6: fc00:a::1be/126 + bp_interface: + ipv6: fc00:b::70/64 + + ARISTA111T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.113 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:71::1/128 + Ethernet1: + ipv6: fc00:a::1c2/126 + bp_interface: + ipv6: fc00:b::71/64 + + ARISTA112T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.114 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:72::1/128 + Ethernet1: + ipv6: fc00:a::1c6/126 + bp_interface: + ipv6: fc00:b::72/64 + + ARISTA113T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.115 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:73::1/128 + Ethernet1: + ipv6: fc00:a::1ca/126 + bp_interface: + ipv6: fc00:b::73/64 + + ARISTA114T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.116 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1cd + interfaces: + Loopback0: + ipv6: fc00:c:c:74::1/128 + Ethernet1: + ipv6: fc00:a::1ce/126 + bp_interface: + ipv6: fc00:b::74/64 + + ARISTA115T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.117 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:75::1/128 + Ethernet1: + ipv6: fc00:a::1d2/126 + bp_interface: + ipv6: fc00:b::75/64 + + ARISTA116T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.118 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:76::1/128 + Ethernet1: + ipv6: fc00:a::1d6/126 + bp_interface: + ipv6: fc00:b::76/64 + + ARISTA117T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.119 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:77::1/128 + Ethernet1: + ipv6: fc00:a::1da/126 + bp_interface: + ipv6: fc00:b::77/64 + + ARISTA118T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.120 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1dd + interfaces: + Loopback0: + ipv6: fc00:c:c:78::1/128 + Ethernet1: + ipv6: fc00:a::1de/126 + bp_interface: + ipv6: fc00:b::78/64 + + ARISTA119T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.121 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:79::1/128 + Ethernet1: + ipv6: fc00:a::1e2/126 + bp_interface: + ipv6: fc00:b::79/64 + + ARISTA120T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.122 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7a::1/128 + Ethernet1: + ipv6: fc00:a::1e6/126 + bp_interface: + ipv6: fc00:b::7a/64 + + ARISTA121T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.123 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7b::1/128 + Ethernet1: + ipv6: fc00:a::1ea/126 + bp_interface: + ipv6: fc00:b::7b/64 + + ARISTA122T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.124 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1ed + interfaces: + Loopback0: + ipv6: fc00:c:c:7c::1/128 + Ethernet1: + ipv6: fc00:a::1ee/126 + bp_interface: + ipv6: fc00:b::7c/64 + + ARISTA123T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.125 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:7d::1/128 + Ethernet1: + ipv6: fc00:a::1f2/126 + bp_interface: + ipv6: fc00:b::7d/64 + + ARISTA124T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.126 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:7e::1/128 + Ethernet1: + ipv6: fc00:a::1f6/126 + bp_interface: + ipv6: fc00:b::7e/64 + + ARISTA125T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.127 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:7f::1/128 + Ethernet1: + ipv6: fc00:a::1fa/126 + bp_interface: + ipv6: fc00:b::7f/64 + + ARISTA126T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.128 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::1fd + interfaces: + Loopback0: + ipv6: fc00:c:c:80::1/128 + Ethernet1: + ipv6: fc00:a::1fe/126 + bp_interface: + ipv6: fc00:b::80/64 + + ARISTA127T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.129 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::201 + interfaces: + Loopback0: + ipv6: fc00:c:c:81::1/128 + Ethernet1: + ipv6: fc00:a::202/126 + bp_interface: + ipv6: fc00:b::81/64 + + ARISTA128T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.130 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::205 + interfaces: + Loopback0: + ipv6: fc00:c:c:82::1/128 + Ethernet1: + ipv6: fc00:a::206/126 + bp_interface: + ipv6: fc00:b::82/64 + + ARISTA129T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.131 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::209 + interfaces: + Loopback0: + ipv6: fc00:c:c:83::1/128 + Ethernet1: + ipv6: fc00:a::20a/126 + bp_interface: + ipv6: fc00:b::83/64 + + ARISTA130T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.132 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::20d + interfaces: + Loopback0: + ipv6: fc00:c:c:84::1/128 + Ethernet1: + ipv6: fc00:a::20e/126 + bp_interface: + ipv6: fc00:b::84/64 + + ARISTA131T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.133 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::211 + interfaces: + Loopback0: + ipv6: fc00:c:c:85::1/128 + Ethernet1: + ipv6: fc00:a::212/126 + bp_interface: + ipv6: fc00:b::85/64 + + ARISTA132T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.134 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::215 + interfaces: + Loopback0: + ipv6: fc00:c:c:86::1/128 + Ethernet1: + ipv6: fc00:a::216/126 + bp_interface: + ipv6: fc00:b::86/64 + + ARISTA133T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.135 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::219 + interfaces: + Loopback0: + ipv6: fc00:c:c:87::1/128 + Ethernet1: + ipv6: fc00:a::21a/126 + bp_interface: + ipv6: fc00:b::87/64 + + ARISTA134T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.136 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::21d + interfaces: + Loopback0: + ipv6: fc00:c:c:88::1/128 + Ethernet1: + ipv6: fc00:a::21e/126 + bp_interface: + ipv6: fc00:b::88/64 + + ARISTA135T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.137 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::221 + interfaces: + Loopback0: + ipv6: fc00:c:c:89::1/128 + Ethernet1: + ipv6: fc00:a::222/126 + bp_interface: + ipv6: fc00:b::89/64 + + ARISTA136T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.138 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::225 + interfaces: + Loopback0: + ipv6: fc00:c:c:8a::1/128 + Ethernet1: + ipv6: fc00:a::226/126 + bp_interface: + ipv6: fc00:b::8a/64 + + ARISTA137T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.139 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::229 + interfaces: + Loopback0: + ipv6: fc00:c:c:8b::1/128 + Ethernet1: + ipv6: fc00:a::22a/126 + bp_interface: + ipv6: fc00:b::8b/64 + + ARISTA138T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.140 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::22d + interfaces: + Loopback0: + ipv6: fc00:c:c:8c::1/128 + Ethernet1: + ipv6: fc00:a::22e/126 + bp_interface: + ipv6: fc00:b::8c/64 + + ARISTA139T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.141 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::231 + interfaces: + Loopback0: + ipv6: fc00:c:c:8d::1/128 + Ethernet1: + ipv6: fc00:a::232/126 + bp_interface: + ipv6: fc00:b::8d/64 + + ARISTA140T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.142 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::235 + interfaces: + Loopback0: + ipv6: fc00:c:c:8e::1/128 + Ethernet1: + ipv6: fc00:a::236/126 + bp_interface: + ipv6: fc00:b::8e/64 + + ARISTA141T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.143 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::239 + interfaces: + Loopback0: + ipv6: fc00:c:c:8f::1/128 + Ethernet1: + ipv6: fc00:a::23a/126 + bp_interface: + ipv6: fc00:b::8f/64 + + ARISTA142T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.144 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::23d + interfaces: + Loopback0: + ipv6: fc00:c:c:90::1/128 + Ethernet1: + ipv6: fc00:a::23e/126 + bp_interface: + ipv6: fc00:b::90/64 + + ARISTA143T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.145 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::241 + interfaces: + Loopback0: + ipv6: fc00:c:c:91::1/128 + Ethernet1: + ipv6: fc00:a::242/126 + bp_interface: + ipv6: fc00:b::91/64 + + ARISTA144T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.146 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::245 + interfaces: + Loopback0: + ipv6: fc00:c:c:92::1/128 + Ethernet1: + ipv6: fc00:a::246/126 + bp_interface: + ipv6: fc00:b::92/64 + + ARISTA145T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.147 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::249 + interfaces: + Loopback0: + ipv6: fc00:c:c:93::1/128 + Ethernet1: + ipv6: fc00:a::24a/126 + bp_interface: + ipv6: fc00:b::93/64 + + ARISTA146T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.148 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::24d + interfaces: + Loopback0: + ipv6: fc00:c:c:94::1/128 + Ethernet1: + ipv6: fc00:a::24e/126 + bp_interface: + ipv6: fc00:b::94/64 + + ARISTA147T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.149 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::251 + interfaces: + Loopback0: + ipv6: fc00:c:c:95::1/128 + Ethernet1: + ipv6: fc00:a::252/126 + bp_interface: + ipv6: fc00:b::95/64 + + ARISTA148T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.150 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::255 + interfaces: + Loopback0: + ipv6: fc00:c:c:96::1/128 + Ethernet1: + ipv6: fc00:a::256/126 + bp_interface: + ipv6: fc00:b::96/64 + + ARISTA149T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.151 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::259 + interfaces: + Loopback0: + ipv6: fc00:c:c:97::1/128 + Ethernet1: + ipv6: fc00:a::25a/126 + bp_interface: + ipv6: fc00:b::97/64 + + ARISTA150T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.152 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::25d + interfaces: + Loopback0: + ipv6: fc00:c:c:98::1/128 + Ethernet1: + ipv6: fc00:a::25e/126 + bp_interface: + ipv6: fc00:b::98/64 + + ARISTA151T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.153 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::261 + interfaces: + Loopback0: + ipv6: fc00:c:c:99::1/128 + Ethernet1: + ipv6: fc00:a::262/126 + bp_interface: + ipv6: fc00:b::99/64 + + ARISTA152T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.154 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::265 + interfaces: + Loopback0: + ipv6: fc00:c:c:9a::1/128 + Ethernet1: + ipv6: fc00:a::266/126 + bp_interface: + ipv6: fc00:b::9a/64 + + ARISTA153T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.155 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::269 + interfaces: + Loopback0: + ipv6: fc00:c:c:9b::1/128 + Ethernet1: + ipv6: fc00:a::26a/126 + bp_interface: + ipv6: fc00:b::9b/64 + + ARISTA154T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.156 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::26d + interfaces: + Loopback0: + ipv6: fc00:c:c:9c::1/128 + Ethernet1: + ipv6: fc00:a::26e/126 + bp_interface: + ipv6: fc00:b::9c/64 + + ARISTA155T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.157 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::271 + interfaces: + Loopback0: + ipv6: fc00:c:c:9d::1/128 + Ethernet1: + ipv6: fc00:a::272/126 + bp_interface: + ipv6: fc00:b::9d/64 + + ARISTA156T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.158 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::275 + interfaces: + Loopback0: + ipv6: fc00:c:c:9e::1/128 + Ethernet1: + ipv6: fc00:a::276/126 + bp_interface: + ipv6: fc00:b::9e/64 + + ARISTA157T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.159 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::279 + interfaces: + Loopback0: + ipv6: fc00:c:c:9f::1/128 + Ethernet1: + ipv6: fc00:a::27a/126 + bp_interface: + ipv6: fc00:b::9f/64 + + ARISTA158T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.160 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::27d + interfaces: + Loopback0: + ipv6: fc00:c:c:a0::1/128 + Ethernet1: + ipv6: fc00:a::27e/126 + bp_interface: + ipv6: fc00:b::a0/64 + + ARISTA159T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.161 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::281 + interfaces: + Loopback0: + ipv6: fc00:c:c:a1::1/128 + Ethernet1: + ipv6: fc00:a::282/126 + bp_interface: + ipv6: fc00:b::a1/64 + + ARISTA160T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.162 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::285 + interfaces: + Loopback0: + ipv6: fc00:c:c:a2::1/128 + Ethernet1: + ipv6: fc00:a::286/126 + bp_interface: + ipv6: fc00:b::a2/64 + + ARISTA161T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.163 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::289 + interfaces: + Loopback0: + ipv6: fc00:c:c:a3::1/128 + Ethernet1: + ipv6: fc00:a::28a/126 + bp_interface: + ipv6: fc00:b::a3/64 + + ARISTA162T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.164 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::28d + interfaces: + Loopback0: + ipv6: fc00:c:c:a4::1/128 + Ethernet1: + ipv6: fc00:a::28e/126 + bp_interface: + ipv6: fc00:b::a4/64 + + ARISTA163T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.165 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::291 + interfaces: + Loopback0: + ipv6: fc00:c:c:a5::1/128 + Ethernet1: + ipv6: fc00:a::292/126 + bp_interface: + ipv6: fc00:b::a5/64 + + ARISTA164T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.166 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::295 + interfaces: + Loopback0: + ipv6: fc00:c:c:a6::1/128 + Ethernet1: + ipv6: fc00:a::296/126 + bp_interface: + ipv6: fc00:b::a6/64 + + ARISTA165T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.167 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::299 + interfaces: + Loopback0: + ipv6: fc00:c:c:a7::1/128 + Ethernet1: + ipv6: fc00:a::29a/126 + bp_interface: + ipv6: fc00:b::a7/64 + + ARISTA166T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.168 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::29d + interfaces: + Loopback0: + ipv6: fc00:c:c:a8::1/128 + Ethernet1: + ipv6: fc00:a::29e/126 + bp_interface: + ipv6: fc00:b::a8/64 + + ARISTA167T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.169 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:a9::1/128 + Ethernet1: + ipv6: fc00:a::2a2/126 + bp_interface: + ipv6: fc00:b::a9/64 + + ARISTA168T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.170 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:aa::1/128 + Ethernet1: + ipv6: fc00:a::2a6/126 + bp_interface: + ipv6: fc00:b::aa/64 + + ARISTA169T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.171 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ab::1/128 + Ethernet1: + ipv6: fc00:a::2aa/126 + bp_interface: + ipv6: fc00:b::ab/64 + + ARISTA170T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.172 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ac::1/128 + Ethernet1: + ipv6: fc00:a::2ae/126 + bp_interface: + ipv6: fc00:b::ac/64 + + ARISTA171T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.173 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ad::1/128 + Ethernet1: + ipv6: fc00:a::2b2/126 + bp_interface: + ipv6: fc00:b::ad/64 + + ARISTA172T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.174 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ae::1/128 + Ethernet1: + ipv6: fc00:a::2b6/126 + bp_interface: + ipv6: fc00:b::ae/64 + + ARISTA173T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.175 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:af::1/128 + Ethernet1: + ipv6: fc00:a::2ba/126 + bp_interface: + ipv6: fc00:b::af/64 + + ARISTA174T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.176 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2bd + interfaces: + Loopback0: + ipv6: fc00:c:c:b0::1/128 + Ethernet1: + ipv6: fc00:a::2be/126 + bp_interface: + ipv6: fc00:b::b0/64 + + ARISTA175T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.177 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b1::1/128 + Ethernet1: + ipv6: fc00:a::2c2/126 + bp_interface: + ipv6: fc00:b::b1/64 + + ARISTA176T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.178 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b2::1/128 + Ethernet1: + ipv6: fc00:a::2c6/126 + bp_interface: + ipv6: fc00:b::b2/64 + + ARISTA177T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.179 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b3::1/128 + Ethernet1: + ipv6: fc00:a::2ca/126 + bp_interface: + ipv6: fc00:b::b3/64 + + ARISTA178T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.180 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2cd + interfaces: + Loopback0: + ipv6: fc00:c:c:b4::1/128 + Ethernet1: + ipv6: fc00:a::2ce/126 + bp_interface: + ipv6: fc00:b::b4/64 + + ARISTA179T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.181 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b5::1/128 + Ethernet1: + ipv6: fc00:a::2d2/126 + bp_interface: + ipv6: fc00:b::b5/64 + + ARISTA180T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.182 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:b6::1/128 + Ethernet1: + ipv6: fc00:a::2d6/126 + bp_interface: + ipv6: fc00:b::b6/64 + + ARISTA181T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.183 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:b7::1/128 + Ethernet1: + ipv6: fc00:a::2da/126 + bp_interface: + ipv6: fc00:b::b7/64 + + ARISTA182T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.184 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2dd + interfaces: + Loopback0: + ipv6: fc00:c:c:b8::1/128 + Ethernet1: + ipv6: fc00:a::2de/126 + bp_interface: + ipv6: fc00:b::b8/64 + + ARISTA183T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.185 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:b9::1/128 + Ethernet1: + ipv6: fc00:a::2e2/126 + bp_interface: + ipv6: fc00:b::b9/64 + + ARISTA184T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.186 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ba::1/128 + Ethernet1: + ipv6: fc00:a::2e6/126 + bp_interface: + ipv6: fc00:b::ba/64 + + ARISTA185T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.187 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bb::1/128 + Ethernet1: + ipv6: fc00:a::2ea/126 + bp_interface: + ipv6: fc00:b::bb/64 + + ARISTA186T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.188 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2ed + interfaces: + Loopback0: + ipv6: fc00:c:c:bc::1/128 + Ethernet1: + ipv6: fc00:a::2ee/126 + bp_interface: + ipv6: fc00:b::bc/64 + + ARISTA187T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.189 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:bd::1/128 + Ethernet1: + ipv6: fc00:a::2f2/126 + bp_interface: + ipv6: fc00:b::bd/64 + + ARISTA188T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.190 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:be::1/128 + Ethernet1: + ipv6: fc00:a::2f6/126 + bp_interface: + ipv6: fc00:b::be/64 + + ARISTA189T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.191 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:bf::1/128 + Ethernet1: + ipv6: fc00:a::2fa/126 + bp_interface: + ipv6: fc00:b::bf/64 + + ARISTA190T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.192 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::2fd + interfaces: + Loopback0: + ipv6: fc00:c:c:c0::1/128 + Ethernet1: + ipv6: fc00:a::2fe/126 + bp_interface: + ipv6: fc00:b::c0/64 + + ARISTA191T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.193 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::301 + interfaces: + Loopback0: + ipv6: fc00:c:c:c1::1/128 + Ethernet1: + ipv6: fc00:a::302/126 + bp_interface: + ipv6: fc00:b::c1/64 + + ARISTA192T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.194 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::305 + interfaces: + Loopback0: + ipv6: fc00:c:c:c2::1/128 + Ethernet1: + ipv6: fc00:a::306/126 + bp_interface: + ipv6: fc00:b::c2/64 + + ARISTA193T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.195 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::309 + interfaces: + Loopback0: + ipv6: fc00:c:c:c3::1/128 + Ethernet1: + ipv6: fc00:a::30a/126 + bp_interface: + ipv6: fc00:b::c3/64 + + ARISTA194T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.196 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::30d + interfaces: + Loopback0: + ipv6: fc00:c:c:c4::1/128 + Ethernet1: + ipv6: fc00:a::30e/126 + bp_interface: + ipv6: fc00:b::c4/64 + + ARISTA195T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.197 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::311 + interfaces: + Loopback0: + ipv6: fc00:c:c:c5::1/128 + Ethernet1: + ipv6: fc00:a::312/126 + bp_interface: + ipv6: fc00:b::c5/64 + + ARISTA196T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.198 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::315 + interfaces: + Loopback0: + ipv6: fc00:c:c:c6::1/128 + Ethernet1: + ipv6: fc00:a::316/126 + bp_interface: + ipv6: fc00:b::c6/64 + + ARISTA197T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.199 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::319 + interfaces: + Loopback0: + ipv6: fc00:c:c:c7::1/128 + Ethernet1: + ipv6: fc00:a::31a/126 + bp_interface: + ipv6: fc00:b::c7/64 + + ARISTA198T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.200 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::31d + interfaces: + Loopback0: + ipv6: fc00:c:c:c8::1/128 + Ethernet1: + ipv6: fc00:a::31e/126 + bp_interface: + ipv6: fc00:b::c8/64 + + ARISTA199T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.201 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::321 + interfaces: + Loopback0: + ipv6: fc00:c:c:c9::1/128 + Ethernet1: + ipv6: fc00:a::322/126 + bp_interface: + ipv6: fc00:b::c9/64 + + ARISTA200T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.202 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::325 + interfaces: + Loopback0: + ipv6: fc00:c:c:ca::1/128 + Ethernet1: + ipv6: fc00:a::326/126 + bp_interface: + ipv6: fc00:b::ca/64 + + ARISTA201T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.203 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::329 + interfaces: + Loopback0: + ipv6: fc00:c:c:cb::1/128 + Ethernet1: + ipv6: fc00:a::32a/126 + bp_interface: + ipv6: fc00:b::cb/64 + + ARISTA202T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.204 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::32d + interfaces: + Loopback0: + ipv6: fc00:c:c:cc::1/128 + Ethernet1: + ipv6: fc00:a::32e/126 + bp_interface: + ipv6: fc00:b::cc/64 + + ARISTA203T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.205 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::331 + interfaces: + Loopback0: + ipv6: fc00:c:c:cd::1/128 + Ethernet1: + ipv6: fc00:a::332/126 + bp_interface: + ipv6: fc00:b::cd/64 + + ARISTA204T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.206 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::335 + interfaces: + Loopback0: + ipv6: fc00:c:c:ce::1/128 + Ethernet1: + ipv6: fc00:a::336/126 + bp_interface: + ipv6: fc00:b::ce/64 + + ARISTA205T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.207 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::339 + interfaces: + Loopback0: + ipv6: fc00:c:c:cf::1/128 + Ethernet1: + ipv6: fc00:a::33a/126 + bp_interface: + ipv6: fc00:b::cf/64 + + ARISTA206T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.208 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::33d + interfaces: + Loopback0: + ipv6: fc00:c:c:d0::1/128 + Ethernet1: + ipv6: fc00:a::33e/126 + bp_interface: + ipv6: fc00:b::d0/64 + + ARISTA207T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.209 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::341 + interfaces: + Loopback0: + ipv6: fc00:c:c:d1::1/128 + Ethernet1: + ipv6: fc00:a::342/126 + bp_interface: + ipv6: fc00:b::d1/64 + + ARISTA208T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.210 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::345 + interfaces: + Loopback0: + ipv6: fc00:c:c:d2::1/128 + Ethernet1: + ipv6: fc00:a::346/126 + bp_interface: + ipv6: fc00:b::d2/64 + + ARISTA209T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.211 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::349 + interfaces: + Loopback0: + ipv6: fc00:c:c:d3::1/128 + Ethernet1: + ipv6: fc00:a::34a/126 + bp_interface: + ipv6: fc00:b::d3/64 + + ARISTA210T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.212 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::34d + interfaces: + Loopback0: + ipv6: fc00:c:c:d4::1/128 + Ethernet1: + ipv6: fc00:a::34e/126 + bp_interface: + ipv6: fc00:b::d4/64 + + ARISTA211T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.213 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::351 + interfaces: + Loopback0: + ipv6: fc00:c:c:d5::1/128 + Ethernet1: + ipv6: fc00:a::352/126 + bp_interface: + ipv6: fc00:b::d5/64 + + ARISTA212T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.214 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::355 + interfaces: + Loopback0: + ipv6: fc00:c:c:d6::1/128 + Ethernet1: + ipv6: fc00:a::356/126 + bp_interface: + ipv6: fc00:b::d6/64 + + ARISTA213T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.215 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::359 + interfaces: + Loopback0: + ipv6: fc00:c:c:d7::1/128 + Ethernet1: + ipv6: fc00:a::35a/126 + bp_interface: + ipv6: fc00:b::d7/64 + + ARISTA214T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.216 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::35d + interfaces: + Loopback0: + ipv6: fc00:c:c:d8::1/128 + Ethernet1: + ipv6: fc00:a::35e/126 + bp_interface: + ipv6: fc00:b::d8/64 + + ARISTA215T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.217 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::361 + interfaces: + Loopback0: + ipv6: fc00:c:c:d9::1/128 + Ethernet1: + ipv6: fc00:a::362/126 + bp_interface: + ipv6: fc00:b::d9/64 + + ARISTA216T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.218 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::365 + interfaces: + Loopback0: + ipv6: fc00:c:c:da::1/128 + Ethernet1: + ipv6: fc00:a::366/126 + bp_interface: + ipv6: fc00:b::da/64 + + ARISTA217T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.219 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::369 + interfaces: + Loopback0: + ipv6: fc00:c:c:db::1/128 + Ethernet1: + ipv6: fc00:a::36a/126 + bp_interface: + ipv6: fc00:b::db/64 + + ARISTA218T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.220 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::36d + interfaces: + Loopback0: + ipv6: fc00:c:c:dc::1/128 + Ethernet1: + ipv6: fc00:a::36e/126 + bp_interface: + ipv6: fc00:b::dc/64 + + ARISTA219T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.221 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::371 + interfaces: + Loopback0: + ipv6: fc00:c:c:dd::1/128 + Ethernet1: + ipv6: fc00:a::372/126 + bp_interface: + ipv6: fc00:b::dd/64 + + ARISTA220T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.222 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::375 + interfaces: + Loopback0: + ipv6: fc00:c:c:de::1/128 + Ethernet1: + ipv6: fc00:a::376/126 + bp_interface: + ipv6: fc00:b::de/64 + + ARISTA221T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.223 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::379 + interfaces: + Loopback0: + ipv6: fc00:c:c:df::1/128 + Ethernet1: + ipv6: fc00:a::37a/126 + bp_interface: + ipv6: fc00:b::df/64 + + ARISTA222T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.224 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::37d + interfaces: + Loopback0: + ipv6: fc00:c:c:e0::1/128 + Ethernet1: + ipv6: fc00:a::37e/126 + bp_interface: + ipv6: fc00:b::e0/64 + + ARISTA223T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.225 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::381 + interfaces: + Loopback0: + ipv6: fc00:c:c:e1::1/128 + Ethernet1: + ipv6: fc00:a::382/126 + bp_interface: + ipv6: fc00:b::e1/64 + + ARISTA224T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.226 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::385 + interfaces: + Loopback0: + ipv6: fc00:c:c:e2::1/128 + Ethernet1: + ipv6: fc00:a::386/126 + bp_interface: + ipv6: fc00:b::e2/64 + + ARISTA225T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.227 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::389 + interfaces: + Loopback0: + ipv6: fc00:c:c:e3::1/128 + Ethernet1: + ipv6: fc00:a::38a/126 + bp_interface: + ipv6: fc00:b::e3/64 + + ARISTA226T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.228 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::38d + interfaces: + Loopback0: + ipv6: fc00:c:c:e4::1/128 + Ethernet1: + ipv6: fc00:a::38e/126 + bp_interface: + ipv6: fc00:b::e4/64 + + ARISTA227T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.229 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::391 + interfaces: + Loopback0: + ipv6: fc00:c:c:e5::1/128 + Ethernet1: + ipv6: fc00:a::392/126 + bp_interface: + ipv6: fc00:b::e5/64 + + ARISTA228T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.230 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::395 + interfaces: + Loopback0: + ipv6: fc00:c:c:e6::1/128 + Ethernet1: + ipv6: fc00:a::396/126 + bp_interface: + ipv6: fc00:b::e6/64 + + ARISTA229T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.231 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::399 + interfaces: + Loopback0: + ipv6: fc00:c:c:e7::1/128 + Ethernet1: + ipv6: fc00:a::39a/126 + bp_interface: + ipv6: fc00:b::e7/64 + + ARISTA230T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.232 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::39d + interfaces: + Loopback0: + ipv6: fc00:c:c:e8::1/128 + Ethernet1: + ipv6: fc00:a::39e/126 + bp_interface: + ipv6: fc00:b::e8/64 + + ARISTA231T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.233 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:e9::1/128 + Ethernet1: + ipv6: fc00:a::3a2/126 + bp_interface: + ipv6: fc00:b::e9/64 + + ARISTA232T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.234 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ea::1/128 + Ethernet1: + ipv6: fc00:a::3a6/126 + bp_interface: + ipv6: fc00:b::ea/64 + + ARISTA233T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.235 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:eb::1/128 + Ethernet1: + ipv6: fc00:a::3aa/126 + bp_interface: + ipv6: fc00:b::eb/64 + + ARISTA234T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.236 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3ad + interfaces: + Loopback0: + ipv6: fc00:c:c:ec::1/128 + Ethernet1: + ipv6: fc00:a::3ae/126 + bp_interface: + ipv6: fc00:b::ec/64 + + ARISTA235T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.237 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:ed::1/128 + Ethernet1: + ipv6: fc00:a::3b2/126 + bp_interface: + ipv6: fc00:b::ed/64 + + ARISTA236T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.238 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:ee::1/128 + Ethernet1: + ipv6: fc00:a::3b6/126 + bp_interface: + ipv6: fc00:b::ee/64 + + ARISTA237T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.239 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ef::1/128 + Ethernet1: + ipv6: fc00:a::3ba/126 + bp_interface: + ipv6: fc00:b::ef/64 + + ARISTA238T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.240 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3bd + interfaces: + Loopback0: + ipv6: fc00:c:c:f0::1/128 + Ethernet1: + ipv6: fc00:a::3be/126 + bp_interface: + ipv6: fc00:b::f0/64 + + ARISTA239T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.241 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f1::1/128 + Ethernet1: + ipv6: fc00:a::3c2/126 + bp_interface: + ipv6: fc00:b::f1/64 + + ARISTA240T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.242 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f2::1/128 + Ethernet1: + ipv6: fc00:a::3c6/126 + bp_interface: + ipv6: fc00:b::f2/64 + + ARISTA241T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.243 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f3::1/128 + Ethernet1: + ipv6: fc00:a::3ca/126 + bp_interface: + ipv6: fc00:b::f3/64 + + ARISTA242T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.244 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3cd + interfaces: + Loopback0: + ipv6: fc00:c:c:f4::1/128 + Ethernet1: + ipv6: fc00:a::3ce/126 + bp_interface: + ipv6: fc00:b::f4/64 + + ARISTA243T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.245 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f5::1/128 + Ethernet1: + ipv6: fc00:a::3d2/126 + bp_interface: + ipv6: fc00:b::f5/64 + + ARISTA244T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.246 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:f6::1/128 + Ethernet1: + ipv6: fc00:a::3d6/126 + bp_interface: + ipv6: fc00:b::f6/64 + + ARISTA245T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.247 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:f7::1/128 + Ethernet1: + ipv6: fc00:a::3da/126 + bp_interface: + ipv6: fc00:b::f7/64 + + ARISTA246T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.248 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3dd + interfaces: + Loopback0: + ipv6: fc00:c:c:f8::1/128 + Ethernet1: + ipv6: fc00:a::3de/126 + bp_interface: + ipv6: fc00:b::f8/64 + + ARISTA247T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.249 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:f9::1/128 + Ethernet1: + ipv6: fc00:a::3e2/126 + bp_interface: + ipv6: fc00:b::f9/64 + + ARISTA248T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.250 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fa::1/128 + Ethernet1: + ipv6: fc00:a::3e6/126 + bp_interface: + ipv6: fc00:b::fa/64 + + ARISTA249T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.251 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:fb::1/128 + Ethernet1: + ipv6: fc00:a::3ea/126 + bp_interface: + ipv6: fc00:b::fb/64 + + ARISTA250T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.252 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3ed + interfaces: + Loopback0: + ipv6: fc00:c:c:fc::1/128 + Ethernet1: + ipv6: fc00:a::3ee/126 + bp_interface: + ipv6: fc00:b::fc/64 + + ARISTA251T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.253 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:fd::1/128 + Ethernet1: + ipv6: fc00:a::3f2/126 + bp_interface: + ipv6: fc00:b::fd/64 + + ARISTA252T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.254 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:fe::1/128 + Ethernet1: + ipv6: fc00:a::3f6/126 + bp_interface: + ipv6: fc00:b::fe/64 + + ARISTA253T0: + properties: + - common + - tor + bgp: + router-id: 0.12.0.255 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:ff::1/128 + Ethernet1: + ipv6: fc00:a::3fa/126 + bp_interface: + ipv6: fc00:b::ff/64 + + ARISTA254T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.0 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::3fd + interfaces: + Loopback0: + ipv6: fc00:c:c:100::1/128 + Ethernet1: + ipv6: fc00:a::3fe/126 + bp_interface: + ipv6: fc00:b::100/64 + + ARISTA255T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.1 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::401 + interfaces: + Loopback0: + ipv6: fc00:c:c:101::1/128 + Ethernet1: + ipv6: fc00:a::402/126 + bp_interface: + ipv6: fc00:b::101/64 + + ARISTA256T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.2 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::405 + interfaces: + Loopback0: + ipv6: fc00:c:c:102::1/128 + Ethernet1: + ipv6: fc00:a::406/126 + bp_interface: + ipv6: fc00:b::102/64 + + ARISTA257T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.3 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::409 + interfaces: + Loopback0: + ipv6: fc00:c:c:103::1/128 + Ethernet1: + ipv6: fc00:a::40a/126 + bp_interface: + ipv6: fc00:b::103/64 + + ARISTA258T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.4 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::40d + interfaces: + Loopback0: + ipv6: fc00:c:c:104::1/128 + Ethernet1: + ipv6: fc00:a::40e/126 + bp_interface: + ipv6: fc00:b::104/64 + + ARISTA259T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.5 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::411 + interfaces: + Loopback0: + ipv6: fc00:c:c:105::1/128 + Ethernet1: + ipv6: fc00:a::412/126 + bp_interface: + ipv6: fc00:b::105/64 + + ARISTA260T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.6 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::415 + interfaces: + Loopback0: + ipv6: fc00:c:c:106::1/128 + Ethernet1: + ipv6: fc00:a::416/126 + bp_interface: + ipv6: fc00:b::106/64 + + ARISTA261T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.7 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::419 + interfaces: + Loopback0: + ipv6: fc00:c:c:107::1/128 + Ethernet1: + ipv6: fc00:a::41a/126 + bp_interface: + ipv6: fc00:b::107/64 + + ARISTA262T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.8 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::41d + interfaces: + Loopback0: + ipv6: fc00:c:c:108::1/128 + Ethernet1: + ipv6: fc00:a::41e/126 + bp_interface: + ipv6: fc00:b::108/64 + + ARISTA263T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.9 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::421 + interfaces: + Loopback0: + ipv6: fc00:c:c:109::1/128 + Ethernet1: + ipv6: fc00:a::422/126 + bp_interface: + ipv6: fc00:b::109/64 + + ARISTA264T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.10 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::425 + interfaces: + Loopback0: + ipv6: fc00:c:c:10a::1/128 + Ethernet1: + ipv6: fc00:a::426/126 + bp_interface: + ipv6: fc00:b::10a/64 + + ARISTA265T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.11 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::429 + interfaces: + Loopback0: + ipv6: fc00:c:c:10b::1/128 + Ethernet1: + ipv6: fc00:a::42a/126 + bp_interface: + ipv6: fc00:b::10b/64 + + ARISTA266T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.12 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::42d + interfaces: + Loopback0: + ipv6: fc00:c:c:10c::1/128 + Ethernet1: + ipv6: fc00:a::42e/126 + bp_interface: + ipv6: fc00:b::10c/64 + + ARISTA267T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.13 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::431 + interfaces: + Loopback0: + ipv6: fc00:c:c:10d::1/128 + Ethernet1: + ipv6: fc00:a::432/126 + bp_interface: + ipv6: fc00:b::10d/64 + + ARISTA268T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.14 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::435 + interfaces: + Loopback0: + ipv6: fc00:c:c:10e::1/128 + Ethernet1: + ipv6: fc00:a::436/126 + bp_interface: + ipv6: fc00:b::10e/64 + + ARISTA269T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.15 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::439 + interfaces: + Loopback0: + ipv6: fc00:c:c:10f::1/128 + Ethernet1: + ipv6: fc00:a::43a/126 + bp_interface: + ipv6: fc00:b::10f/64 + + ARISTA270T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.16 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::43d + interfaces: + Loopback0: + ipv6: fc00:c:c:110::1/128 + Ethernet1: + ipv6: fc00:a::43e/126 + bp_interface: + ipv6: fc00:b::110/64 + + ARISTA271T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.17 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::441 + interfaces: + Loopback0: + ipv6: fc00:c:c:111::1/128 + Ethernet1: + ipv6: fc00:a::442/126 + bp_interface: + ipv6: fc00:b::111/64 + + ARISTA272T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.18 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::445 + interfaces: + Loopback0: + ipv6: fc00:c:c:112::1/128 + Ethernet1: + ipv6: fc00:a::446/126 + bp_interface: + ipv6: fc00:b::112/64 + + ARISTA273T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.19 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::449 + interfaces: + Loopback0: + ipv6: fc00:c:c:113::1/128 + Ethernet1: + ipv6: fc00:a::44a/126 + bp_interface: + ipv6: fc00:b::113/64 + + ARISTA274T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.20 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::44d + interfaces: + Loopback0: + ipv6: fc00:c:c:114::1/128 + Ethernet1: + ipv6: fc00:a::44e/126 + bp_interface: + ipv6: fc00:b::114/64 + + ARISTA275T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.21 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::451 + interfaces: + Loopback0: + ipv6: fc00:c:c:115::1/128 + Ethernet1: + ipv6: fc00:a::452/126 + bp_interface: + ipv6: fc00:b::115/64 + + ARISTA276T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.22 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::455 + interfaces: + Loopback0: + ipv6: fc00:c:c:116::1/128 + Ethernet1: + ipv6: fc00:a::456/126 + bp_interface: + ipv6: fc00:b::116/64 + + ARISTA277T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.23 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::459 + interfaces: + Loopback0: + ipv6: fc00:c:c:117::1/128 + Ethernet1: + ipv6: fc00:a::45a/126 + bp_interface: + ipv6: fc00:b::117/64 + + ARISTA278T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.24 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::45d + interfaces: + Loopback0: + ipv6: fc00:c:c:118::1/128 + Ethernet1: + ipv6: fc00:a::45e/126 + bp_interface: + ipv6: fc00:b::118/64 + + ARISTA279T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.25 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::461 + interfaces: + Loopback0: + ipv6: fc00:c:c:119::1/128 + Ethernet1: + ipv6: fc00:a::462/126 + bp_interface: + ipv6: fc00:b::119/64 + + ARISTA280T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.26 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::465 + interfaces: + Loopback0: + ipv6: fc00:c:c:11a::1/128 + Ethernet1: + ipv6: fc00:a::466/126 + bp_interface: + ipv6: fc00:b::11a/64 + + ARISTA281T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.27 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::469 + interfaces: + Loopback0: + ipv6: fc00:c:c:11b::1/128 + Ethernet1: + ipv6: fc00:a::46a/126 + bp_interface: + ipv6: fc00:b::11b/64 + + ARISTA282T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.28 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::46d + interfaces: + Loopback0: + ipv6: fc00:c:c:11c::1/128 + Ethernet1: + ipv6: fc00:a::46e/126 + bp_interface: + ipv6: fc00:b::11c/64 + + ARISTA283T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.29 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::471 + interfaces: + Loopback0: + ipv6: fc00:c:c:11d::1/128 + Ethernet1: + ipv6: fc00:a::472/126 + bp_interface: + ipv6: fc00:b::11d/64 + + ARISTA284T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.30 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::475 + interfaces: + Loopback0: + ipv6: fc00:c:c:11e::1/128 + Ethernet1: + ipv6: fc00:a::476/126 + bp_interface: + ipv6: fc00:b::11e/64 + + ARISTA285T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.31 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::479 + interfaces: + Loopback0: + ipv6: fc00:c:c:11f::1/128 + Ethernet1: + ipv6: fc00:a::47a/126 + bp_interface: + ipv6: fc00:b::11f/64 + + ARISTA286T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.32 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::47d + interfaces: + Loopback0: + ipv6: fc00:c:c:120::1/128 + Ethernet1: + ipv6: fc00:a::47e/126 + bp_interface: + ipv6: fc00:b::120/64 + + ARISTA287T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.33 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::481 + interfaces: + Loopback0: + ipv6: fc00:c:c:121::1/128 + Ethernet1: + ipv6: fc00:a::482/126 + bp_interface: + ipv6: fc00:b::121/64 + + ARISTA288T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.34 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::485 + interfaces: + Loopback0: + ipv6: fc00:c:c:122::1/128 + Ethernet1: + ipv6: fc00:a::486/126 + bp_interface: + ipv6: fc00:b::122/64 + + ARISTA289T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.35 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::489 + interfaces: + Loopback0: + ipv6: fc00:c:c:123::1/128 + Ethernet1: + ipv6: fc00:a::48a/126 + bp_interface: + ipv6: fc00:b::123/64 + + ARISTA290T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.36 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::48d + interfaces: + Loopback0: + ipv6: fc00:c:c:124::1/128 + Ethernet1: + ipv6: fc00:a::48e/126 + bp_interface: + ipv6: fc00:b::124/64 + + ARISTA291T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.37 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::491 + interfaces: + Loopback0: + ipv6: fc00:c:c:125::1/128 + Ethernet1: + ipv6: fc00:a::492/126 + bp_interface: + ipv6: fc00:b::125/64 + + ARISTA292T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.38 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::495 + interfaces: + Loopback0: + ipv6: fc00:c:c:126::1/128 + Ethernet1: + ipv6: fc00:a::496/126 + bp_interface: + ipv6: fc00:b::126/64 + + ARISTA293T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.39 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::499 + interfaces: + Loopback0: + ipv6: fc00:c:c:127::1/128 + Ethernet1: + ipv6: fc00:a::49a/126 + bp_interface: + ipv6: fc00:b::127/64 + + ARISTA294T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.40 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::49d + interfaces: + Loopback0: + ipv6: fc00:c:c:128::1/128 + Ethernet1: + ipv6: fc00:a::49e/126 + bp_interface: + ipv6: fc00:b::128/64 + + ARISTA295T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.41 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:129::1/128 + Ethernet1: + ipv6: fc00:a::4a2/126 + bp_interface: + ipv6: fc00:b::129/64 + + ARISTA296T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.42 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:12a::1/128 + Ethernet1: + ipv6: fc00:a::4a6/126 + bp_interface: + ipv6: fc00:b::12a/64 + + ARISTA297T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.43 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:12b::1/128 + Ethernet1: + ipv6: fc00:a::4aa/126 + bp_interface: + ipv6: fc00:b::12b/64 + + ARISTA298T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.44 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4ad + interfaces: + Loopback0: + ipv6: fc00:c:c:12c::1/128 + Ethernet1: + ipv6: fc00:a::4ae/126 + bp_interface: + ipv6: fc00:b::12c/64 + + ARISTA299T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.45 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:12d::1/128 + Ethernet1: + ipv6: fc00:a::4b2/126 + bp_interface: + ipv6: fc00:b::12d/64 + + ARISTA300T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.46 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:12e::1/128 + Ethernet1: + ipv6: fc00:a::4b6/126 + bp_interface: + ipv6: fc00:b::12e/64 + + ARISTA301T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.47 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:12f::1/128 + Ethernet1: + ipv6: fc00:a::4ba/126 + bp_interface: + ipv6: fc00:b::12f/64 + + ARISTA302T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.48 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4bd + interfaces: + Loopback0: + ipv6: fc00:c:c:130::1/128 + Ethernet1: + ipv6: fc00:a::4be/126 + bp_interface: + ipv6: fc00:b::130/64 + + ARISTA303T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.49 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:131::1/128 + Ethernet1: + ipv6: fc00:a::4c2/126 + bp_interface: + ipv6: fc00:b::131/64 + + ARISTA304T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.50 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:132::1/128 + Ethernet1: + ipv6: fc00:a::4c6/126 + bp_interface: + ipv6: fc00:b::132/64 + + ARISTA305T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.51 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:133::1/128 + Ethernet1: + ipv6: fc00:a::4ca/126 + bp_interface: + ipv6: fc00:b::133/64 + + ARISTA306T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.52 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4cd + interfaces: + Loopback0: + ipv6: fc00:c:c:134::1/128 + Ethernet1: + ipv6: fc00:a::4ce/126 + bp_interface: + ipv6: fc00:b::134/64 + + ARISTA307T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.53 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:135::1/128 + Ethernet1: + ipv6: fc00:a::4d2/126 + bp_interface: + ipv6: fc00:b::135/64 + + ARISTA308T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.54 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:136::1/128 + Ethernet1: + ipv6: fc00:a::4d6/126 + bp_interface: + ipv6: fc00:b::136/64 + + ARISTA309T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.55 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:137::1/128 + Ethernet1: + ipv6: fc00:a::4da/126 + bp_interface: + ipv6: fc00:b::137/64 + + ARISTA310T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.56 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4dd + interfaces: + Loopback0: + ipv6: fc00:c:c:138::1/128 + Ethernet1: + ipv6: fc00:a::4de/126 + bp_interface: + ipv6: fc00:b::138/64 + + ARISTA311T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.57 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:139::1/128 + Ethernet1: + ipv6: fc00:a::4e2/126 + bp_interface: + ipv6: fc00:b::139/64 + + ARISTA312T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.58 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:13a::1/128 + Ethernet1: + ipv6: fc00:a::4e6/126 + bp_interface: + ipv6: fc00:b::13a/64 + + ARISTA313T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.59 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:13b::1/128 + Ethernet1: + ipv6: fc00:a::4ea/126 + bp_interface: + ipv6: fc00:b::13b/64 + + ARISTA314T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.60 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4ed + interfaces: + Loopback0: + ipv6: fc00:c:c:13c::1/128 + Ethernet1: + ipv6: fc00:a::4ee/126 + bp_interface: + ipv6: fc00:b::13c/64 + + ARISTA315T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.61 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:13d::1/128 + Ethernet1: + ipv6: fc00:a::4f2/126 + bp_interface: + ipv6: fc00:b::13d/64 + + ARISTA316T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.62 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:13e::1/128 + Ethernet1: + ipv6: fc00:a::4f6/126 + bp_interface: + ipv6: fc00:b::13e/64 + + ARISTA317T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.63 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:13f::1/128 + Ethernet1: + ipv6: fc00:a::4fa/126 + bp_interface: + ipv6: fc00:b::13f/64 + + ARISTA318T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.64 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::4fd + interfaces: + Loopback0: + ipv6: fc00:c:c:140::1/128 + Ethernet1: + ipv6: fc00:a::4fe/126 + bp_interface: + ipv6: fc00:b::140/64 + + ARISTA319T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.65 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::501 + interfaces: + Loopback0: + ipv6: fc00:c:c:141::1/128 + Ethernet1: + ipv6: fc00:a::502/126 + bp_interface: + ipv6: fc00:b::141/64 + + ARISTA320T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.66 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::505 + interfaces: + Loopback0: + ipv6: fc00:c:c:142::1/128 + Ethernet1: + ipv6: fc00:a::506/126 + bp_interface: + ipv6: fc00:b::142/64 + + ARISTA321T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.67 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::509 + interfaces: + Loopback0: + ipv6: fc00:c:c:143::1/128 + Ethernet1: + ipv6: fc00:a::50a/126 + bp_interface: + ipv6: fc00:b::143/64 + + ARISTA322T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.68 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::50d + interfaces: + Loopback0: + ipv6: fc00:c:c:144::1/128 + Ethernet1: + ipv6: fc00:a::50e/126 + bp_interface: + ipv6: fc00:b::144/64 + + ARISTA323T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.69 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::511 + interfaces: + Loopback0: + ipv6: fc00:c:c:145::1/128 + Ethernet1: + ipv6: fc00:a::512/126 + bp_interface: + ipv6: fc00:b::145/64 + + ARISTA324T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.70 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::515 + interfaces: + Loopback0: + ipv6: fc00:c:c:146::1/128 + Ethernet1: + ipv6: fc00:a::516/126 + bp_interface: + ipv6: fc00:b::146/64 + + ARISTA325T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.71 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::519 + interfaces: + Loopback0: + ipv6: fc00:c:c:147::1/128 + Ethernet1: + ipv6: fc00:a::51a/126 + bp_interface: + ipv6: fc00:b::147/64 + + ARISTA326T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.72 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::51d + interfaces: + Loopback0: + ipv6: fc00:c:c:148::1/128 + Ethernet1: + ipv6: fc00:a::51e/126 + bp_interface: + ipv6: fc00:b::148/64 + + ARISTA327T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.73 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::521 + interfaces: + Loopback0: + ipv6: fc00:c:c:149::1/128 + Ethernet1: + ipv6: fc00:a::522/126 + bp_interface: + ipv6: fc00:b::149/64 + + ARISTA328T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.74 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::525 + interfaces: + Loopback0: + ipv6: fc00:c:c:14a::1/128 + Ethernet1: + ipv6: fc00:a::526/126 + bp_interface: + ipv6: fc00:b::14a/64 + + ARISTA329T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.75 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::529 + interfaces: + Loopback0: + ipv6: fc00:c:c:14b::1/128 + Ethernet1: + ipv6: fc00:a::52a/126 + bp_interface: + ipv6: fc00:b::14b/64 + + ARISTA330T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.76 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::52d + interfaces: + Loopback0: + ipv6: fc00:c:c:14c::1/128 + Ethernet1: + ipv6: fc00:a::52e/126 + bp_interface: + ipv6: fc00:b::14c/64 + + ARISTA331T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.77 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::531 + interfaces: + Loopback0: + ipv6: fc00:c:c:14d::1/128 + Ethernet1: + ipv6: fc00:a::532/126 + bp_interface: + ipv6: fc00:b::14d/64 + + ARISTA332T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.78 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::535 + interfaces: + Loopback0: + ipv6: fc00:c:c:14e::1/128 + Ethernet1: + ipv6: fc00:a::536/126 + bp_interface: + ipv6: fc00:b::14e/64 + + ARISTA333T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.79 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::539 + interfaces: + Loopback0: + ipv6: fc00:c:c:14f::1/128 + Ethernet1: + ipv6: fc00:a::53a/126 + bp_interface: + ipv6: fc00:b::14f/64 + + ARISTA334T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.80 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::53d + interfaces: + Loopback0: + ipv6: fc00:c:c:150::1/128 + Ethernet1: + ipv6: fc00:a::53e/126 + bp_interface: + ipv6: fc00:b::150/64 + + ARISTA335T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.81 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::541 + interfaces: + Loopback0: + ipv6: fc00:c:c:151::1/128 + Ethernet1: + ipv6: fc00:a::542/126 + bp_interface: + ipv6: fc00:b::151/64 + + ARISTA336T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.82 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::545 + interfaces: + Loopback0: + ipv6: fc00:c:c:152::1/128 + Ethernet1: + ipv6: fc00:a::546/126 + bp_interface: + ipv6: fc00:b::152/64 + + ARISTA337T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.83 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::549 + interfaces: + Loopback0: + ipv6: fc00:c:c:153::1/128 + Ethernet1: + ipv6: fc00:a::54a/126 + bp_interface: + ipv6: fc00:b::153/64 + + ARISTA338T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.84 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::54d + interfaces: + Loopback0: + ipv6: fc00:c:c:154::1/128 + Ethernet1: + ipv6: fc00:a::54e/126 + bp_interface: + ipv6: fc00:b::154/64 + + ARISTA339T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.85 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::551 + interfaces: + Loopback0: + ipv6: fc00:c:c:155::1/128 + Ethernet1: + ipv6: fc00:a::552/126 + bp_interface: + ipv6: fc00:b::155/64 + + ARISTA340T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.86 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::555 + interfaces: + Loopback0: + ipv6: fc00:c:c:156::1/128 + Ethernet1: + ipv6: fc00:a::556/126 + bp_interface: + ipv6: fc00:b::156/64 + + ARISTA341T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.87 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::559 + interfaces: + Loopback0: + ipv6: fc00:c:c:157::1/128 + Ethernet1: + ipv6: fc00:a::55a/126 + bp_interface: + ipv6: fc00:b::157/64 + + ARISTA342T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.88 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::55d + interfaces: + Loopback0: + ipv6: fc00:c:c:158::1/128 + Ethernet1: + ipv6: fc00:a::55e/126 + bp_interface: + ipv6: fc00:b::158/64 + + ARISTA343T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.89 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::561 + interfaces: + Loopback0: + ipv6: fc00:c:c:159::1/128 + Ethernet1: + ipv6: fc00:a::562/126 + bp_interface: + ipv6: fc00:b::159/64 + + ARISTA344T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.90 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::565 + interfaces: + Loopback0: + ipv6: fc00:c:c:15a::1/128 + Ethernet1: + ipv6: fc00:a::566/126 + bp_interface: + ipv6: fc00:b::15a/64 + + ARISTA345T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.91 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::569 + interfaces: + Loopback0: + ipv6: fc00:c:c:15b::1/128 + Ethernet1: + ipv6: fc00:a::56a/126 + bp_interface: + ipv6: fc00:b::15b/64 + + ARISTA346T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.92 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::56d + interfaces: + Loopback0: + ipv6: fc00:c:c:15c::1/128 + Ethernet1: + ipv6: fc00:a::56e/126 + bp_interface: + ipv6: fc00:b::15c/64 + + ARISTA347T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.93 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::571 + interfaces: + Loopback0: + ipv6: fc00:c:c:15d::1/128 + Ethernet1: + ipv6: fc00:a::572/126 + bp_interface: + ipv6: fc00:b::15d/64 + + ARISTA348T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.94 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::575 + interfaces: + Loopback0: + ipv6: fc00:c:c:15e::1/128 + Ethernet1: + ipv6: fc00:a::576/126 + bp_interface: + ipv6: fc00:b::15e/64 + + ARISTA349T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.95 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::579 + interfaces: + Loopback0: + ipv6: fc00:c:c:15f::1/128 + Ethernet1: + ipv6: fc00:a::57a/126 + bp_interface: + ipv6: fc00:b::15f/64 + + ARISTA350T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.96 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::57d + interfaces: + Loopback0: + ipv6: fc00:c:c:160::1/128 + Ethernet1: + ipv6: fc00:a::57e/126 + bp_interface: + ipv6: fc00:b::160/64 + + ARISTA351T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.97 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::581 + interfaces: + Loopback0: + ipv6: fc00:c:c:161::1/128 + Ethernet1: + ipv6: fc00:a::582/126 + bp_interface: + ipv6: fc00:b::161/64 + + ARISTA352T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.98 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::585 + interfaces: + Loopback0: + ipv6: fc00:c:c:162::1/128 + Ethernet1: + ipv6: fc00:a::586/126 + bp_interface: + ipv6: fc00:b::162/64 + + ARISTA353T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.99 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::589 + interfaces: + Loopback0: + ipv6: fc00:c:c:163::1/128 + Ethernet1: + ipv6: fc00:a::58a/126 + bp_interface: + ipv6: fc00:b::163/64 + + ARISTA354T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.100 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::58d + interfaces: + Loopback0: + ipv6: fc00:c:c:164::1/128 + Ethernet1: + ipv6: fc00:a::58e/126 + bp_interface: + ipv6: fc00:b::164/64 + + ARISTA355T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.101 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::591 + interfaces: + Loopback0: + ipv6: fc00:c:c:165::1/128 + Ethernet1: + ipv6: fc00:a::592/126 + bp_interface: + ipv6: fc00:b::165/64 + + ARISTA356T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.102 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::595 + interfaces: + Loopback0: + ipv6: fc00:c:c:166::1/128 + Ethernet1: + ipv6: fc00:a::596/126 + bp_interface: + ipv6: fc00:b::166/64 + + ARISTA357T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.103 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::599 + interfaces: + Loopback0: + ipv6: fc00:c:c:167::1/128 + Ethernet1: + ipv6: fc00:a::59a/126 + bp_interface: + ipv6: fc00:b::167/64 + + ARISTA358T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.104 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::59d + interfaces: + Loopback0: + ipv6: fc00:c:c:168::1/128 + Ethernet1: + ipv6: fc00:a::59e/126 + bp_interface: + ipv6: fc00:b::168/64 + + ARISTA359T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.105 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:169::1/128 + Ethernet1: + ipv6: fc00:a::5a2/126 + bp_interface: + ipv6: fc00:b::169/64 + + ARISTA360T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.106 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:16a::1/128 + Ethernet1: + ipv6: fc00:a::5a6/126 + bp_interface: + ipv6: fc00:b::16a/64 + + ARISTA361T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.107 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:16b::1/128 + Ethernet1: + ipv6: fc00:a::5aa/126 + bp_interface: + ipv6: fc00:b::16b/64 + + ARISTA362T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.108 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5ad + interfaces: + Loopback0: + ipv6: fc00:c:c:16c::1/128 + Ethernet1: + ipv6: fc00:a::5ae/126 + bp_interface: + ipv6: fc00:b::16c/64 + + ARISTA363T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.109 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:16d::1/128 + Ethernet1: + ipv6: fc00:a::5b2/126 + bp_interface: + ipv6: fc00:b::16d/64 + + ARISTA364T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.110 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:16e::1/128 + Ethernet1: + ipv6: fc00:a::5b6/126 + bp_interface: + ipv6: fc00:b::16e/64 + + ARISTA365T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.111 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:16f::1/128 + Ethernet1: + ipv6: fc00:a::5ba/126 + bp_interface: + ipv6: fc00:b::16f/64 + + ARISTA366T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.112 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5bd + interfaces: + Loopback0: + ipv6: fc00:c:c:170::1/128 + Ethernet1: + ipv6: fc00:a::5be/126 + bp_interface: + ipv6: fc00:b::170/64 + + ARISTA367T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.113 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:171::1/128 + Ethernet1: + ipv6: fc00:a::5c2/126 + bp_interface: + ipv6: fc00:b::171/64 + + ARISTA368T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.114 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:172::1/128 + Ethernet1: + ipv6: fc00:a::5c6/126 + bp_interface: + ipv6: fc00:b::172/64 + + ARISTA369T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.115 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:173::1/128 + Ethernet1: + ipv6: fc00:a::5ca/126 + bp_interface: + ipv6: fc00:b::173/64 + + ARISTA370T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.116 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5cd + interfaces: + Loopback0: + ipv6: fc00:c:c:174::1/128 + Ethernet1: + ipv6: fc00:a::5ce/126 + bp_interface: + ipv6: fc00:b::174/64 + + ARISTA371T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.117 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:175::1/128 + Ethernet1: + ipv6: fc00:a::5d2/126 + bp_interface: + ipv6: fc00:b::175/64 + + ARISTA372T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.118 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:176::1/128 + Ethernet1: + ipv6: fc00:a::5d6/126 + bp_interface: + ipv6: fc00:b::176/64 + + ARISTA373T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.119 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:177::1/128 + Ethernet1: + ipv6: fc00:a::5da/126 + bp_interface: + ipv6: fc00:b::177/64 + + ARISTA374T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.120 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5dd + interfaces: + Loopback0: + ipv6: fc00:c:c:178::1/128 + Ethernet1: + ipv6: fc00:a::5de/126 + bp_interface: + ipv6: fc00:b::178/64 + + ARISTA375T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.121 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:179::1/128 + Ethernet1: + ipv6: fc00:a::5e2/126 + bp_interface: + ipv6: fc00:b::179/64 + + ARISTA376T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.122 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:17a::1/128 + Ethernet1: + ipv6: fc00:a::5e6/126 + bp_interface: + ipv6: fc00:b::17a/64 + + ARISTA377T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.123 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:17b::1/128 + Ethernet1: + ipv6: fc00:a::5ea/126 + bp_interface: + ipv6: fc00:b::17b/64 + + ARISTA378T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.124 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5ed + interfaces: + Loopback0: + ipv6: fc00:c:c:17c::1/128 + Ethernet1: + ipv6: fc00:a::5ee/126 + bp_interface: + ipv6: fc00:b::17c/64 + + ARISTA379T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.125 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:17d::1/128 + Ethernet1: + ipv6: fc00:a::5f2/126 + bp_interface: + ipv6: fc00:b::17d/64 + + ARISTA380T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.126 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:17e::1/128 + Ethernet1: + ipv6: fc00:a::5f6/126 + bp_interface: + ipv6: fc00:b::17e/64 + + ARISTA381T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.127 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:17f::1/128 + Ethernet1: + ipv6: fc00:a::5fa/126 + bp_interface: + ipv6: fc00:b::17f/64 + + ARISTA382T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.128 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::5fd + interfaces: + Loopback0: + ipv6: fc00:c:c:180::1/128 + Ethernet1: + ipv6: fc00:a::5fe/126 + bp_interface: + ipv6: fc00:b::180/64 + + ARISTA383T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.129 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::601 + interfaces: + Loopback0: + ipv6: fc00:c:c:181::1/128 + Ethernet1: + ipv6: fc00:a::602/126 + bp_interface: + ipv6: fc00:b::181/64 + + ARISTA384T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.130 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::605 + interfaces: + Loopback0: + ipv6: fc00:c:c:182::1/128 + Ethernet1: + ipv6: fc00:a::606/126 + bp_interface: + ipv6: fc00:b::182/64 + + ARISTA385T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.131 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::609 + interfaces: + Loopback0: + ipv6: fc00:c:c:183::1/128 + Ethernet1: + ipv6: fc00:a::60a/126 + bp_interface: + ipv6: fc00:b::183/64 + + ARISTA386T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.132 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::60d + interfaces: + Loopback0: + ipv6: fc00:c:c:184::1/128 + Ethernet1: + ipv6: fc00:a::60e/126 + bp_interface: + ipv6: fc00:b::184/64 + + ARISTA387T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.133 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::611 + interfaces: + Loopback0: + ipv6: fc00:c:c:185::1/128 + Ethernet1: + ipv6: fc00:a::612/126 + bp_interface: + ipv6: fc00:b::185/64 + + ARISTA388T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.134 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::615 + interfaces: + Loopback0: + ipv6: fc00:c:c:186::1/128 + Ethernet1: + ipv6: fc00:a::616/126 + bp_interface: + ipv6: fc00:b::186/64 + + ARISTA389T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.135 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::619 + interfaces: + Loopback0: + ipv6: fc00:c:c:187::1/128 + Ethernet1: + ipv6: fc00:a::61a/126 + bp_interface: + ipv6: fc00:b::187/64 + + ARISTA390T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.136 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::61d + interfaces: + Loopback0: + ipv6: fc00:c:c:188::1/128 + Ethernet1: + ipv6: fc00:a::61e/126 + bp_interface: + ipv6: fc00:b::188/64 + + ARISTA391T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.137 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::621 + interfaces: + Loopback0: + ipv6: fc00:c:c:189::1/128 + Ethernet1: + ipv6: fc00:a::622/126 + bp_interface: + ipv6: fc00:b::189/64 + + ARISTA392T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.138 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::625 + interfaces: + Loopback0: + ipv6: fc00:c:c:18a::1/128 + Ethernet1: + ipv6: fc00:a::626/126 + bp_interface: + ipv6: fc00:b::18a/64 + + ARISTA393T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.139 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::629 + interfaces: + Loopback0: + ipv6: fc00:c:c:18b::1/128 + Ethernet1: + ipv6: fc00:a::62a/126 + bp_interface: + ipv6: fc00:b::18b/64 + + ARISTA394T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.140 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::62d + interfaces: + Loopback0: + ipv6: fc00:c:c:18c::1/128 + Ethernet1: + ipv6: fc00:a::62e/126 + bp_interface: + ipv6: fc00:b::18c/64 + + ARISTA395T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.141 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::631 + interfaces: + Loopback0: + ipv6: fc00:c:c:18d::1/128 + Ethernet1: + ipv6: fc00:a::632/126 + bp_interface: + ipv6: fc00:b::18d/64 + + ARISTA396T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.142 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::635 + interfaces: + Loopback0: + ipv6: fc00:c:c:18e::1/128 + Ethernet1: + ipv6: fc00:a::636/126 + bp_interface: + ipv6: fc00:b::18e/64 + + ARISTA397T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.143 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::639 + interfaces: + Loopback0: + ipv6: fc00:c:c:18f::1/128 + Ethernet1: + ipv6: fc00:a::63a/126 + bp_interface: + ipv6: fc00:b::18f/64 + + ARISTA398T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.144 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::63d + interfaces: + Loopback0: + ipv6: fc00:c:c:190::1/128 + Ethernet1: + ipv6: fc00:a::63e/126 + bp_interface: + ipv6: fc00:b::190/64 + + ARISTA399T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.145 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::641 + interfaces: + Loopback0: + ipv6: fc00:c:c:191::1/128 + Ethernet1: + ipv6: fc00:a::642/126 + bp_interface: + ipv6: fc00:b::191/64 + + ARISTA400T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.146 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::645 + interfaces: + Loopback0: + ipv6: fc00:c:c:192::1/128 + Ethernet1: + ipv6: fc00:a::646/126 + bp_interface: + ipv6: fc00:b::192/64 + + ARISTA401T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.147 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::649 + interfaces: + Loopback0: + ipv6: fc00:c:c:193::1/128 + Ethernet1: + ipv6: fc00:a::64a/126 + bp_interface: + ipv6: fc00:b::193/64 + + ARISTA402T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.148 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::64d + interfaces: + Loopback0: + ipv6: fc00:c:c:194::1/128 + Ethernet1: + ipv6: fc00:a::64e/126 + bp_interface: + ipv6: fc00:b::194/64 + + ARISTA403T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.149 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::651 + interfaces: + Loopback0: + ipv6: fc00:c:c:195::1/128 + Ethernet1: + ipv6: fc00:a::652/126 + bp_interface: + ipv6: fc00:b::195/64 + + ARISTA404T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.150 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::655 + interfaces: + Loopback0: + ipv6: fc00:c:c:196::1/128 + Ethernet1: + ipv6: fc00:a::656/126 + bp_interface: + ipv6: fc00:b::196/64 + + ARISTA405T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.151 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::659 + interfaces: + Loopback0: + ipv6: fc00:c:c:197::1/128 + Ethernet1: + ipv6: fc00:a::65a/126 + bp_interface: + ipv6: fc00:b::197/64 + + ARISTA406T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.152 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::65d + interfaces: + Loopback0: + ipv6: fc00:c:c:198::1/128 + Ethernet1: + ipv6: fc00:a::65e/126 + bp_interface: + ipv6: fc00:b::198/64 + + ARISTA407T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.153 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::661 + interfaces: + Loopback0: + ipv6: fc00:c:c:199::1/128 + Ethernet1: + ipv6: fc00:a::662/126 + bp_interface: + ipv6: fc00:b::199/64 + + ARISTA408T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.154 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::665 + interfaces: + Loopback0: + ipv6: fc00:c:c:19a::1/128 + Ethernet1: + ipv6: fc00:a::666/126 + bp_interface: + ipv6: fc00:b::19a/64 + + ARISTA409T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.155 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::669 + interfaces: + Loopback0: + ipv6: fc00:c:c:19b::1/128 + Ethernet1: + ipv6: fc00:a::66a/126 + bp_interface: + ipv6: fc00:b::19b/64 + + ARISTA410T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.156 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::66d + interfaces: + Loopback0: + ipv6: fc00:c:c:19c::1/128 + Ethernet1: + ipv6: fc00:a::66e/126 + bp_interface: + ipv6: fc00:b::19c/64 + + ARISTA411T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.157 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::671 + interfaces: + Loopback0: + ipv6: fc00:c:c:19d::1/128 + Ethernet1: + ipv6: fc00:a::672/126 + bp_interface: + ipv6: fc00:b::19d/64 + + ARISTA412T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.158 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::675 + interfaces: + Loopback0: + ipv6: fc00:c:c:19e::1/128 + Ethernet1: + ipv6: fc00:a::676/126 + bp_interface: + ipv6: fc00:b::19e/64 + + ARISTA413T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.159 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::679 + interfaces: + Loopback0: + ipv6: fc00:c:c:19f::1/128 + Ethernet1: + ipv6: fc00:a::67a/126 + bp_interface: + ipv6: fc00:b::19f/64 + + ARISTA414T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.160 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::67d + interfaces: + Loopback0: + ipv6: fc00:c:c:1a0::1/128 + Ethernet1: + ipv6: fc00:a::67e/126 + bp_interface: + ipv6: fc00:b::1a0/64 + + ARISTA415T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.161 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::681 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a1::1/128 + Ethernet1: + ipv6: fc00:a::682/126 + bp_interface: + ipv6: fc00:b::1a1/64 + + ARISTA416T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.162 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::685 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a2::1/128 + Ethernet1: + ipv6: fc00:a::686/126 + bp_interface: + ipv6: fc00:b::1a2/64 + + ARISTA417T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.163 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::689 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a3::1/128 + Ethernet1: + ipv6: fc00:a::68a/126 + bp_interface: + ipv6: fc00:b::1a3/64 + + ARISTA418T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.164 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::68d + interfaces: + Loopback0: + ipv6: fc00:c:c:1a4::1/128 + Ethernet1: + ipv6: fc00:a::68e/126 + bp_interface: + ipv6: fc00:b::1a4/64 + + ARISTA419T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.165 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::691 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a5::1/128 + Ethernet1: + ipv6: fc00:a::692/126 + bp_interface: + ipv6: fc00:b::1a5/64 + + ARISTA420T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.166 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::695 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a6::1/128 + Ethernet1: + ipv6: fc00:a::696/126 + bp_interface: + ipv6: fc00:b::1a6/64 + + ARISTA421T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.167 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::699 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a7::1/128 + Ethernet1: + ipv6: fc00:a::69a/126 + bp_interface: + ipv6: fc00:b::1a7/64 + + ARISTA422T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.168 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::69d + interfaces: + Loopback0: + ipv6: fc00:c:c:1a8::1/128 + Ethernet1: + ipv6: fc00:a::69e/126 + bp_interface: + ipv6: fc00:b::1a8/64 + + ARISTA423T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.169 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1a9::1/128 + Ethernet1: + ipv6: fc00:a::6a2/126 + bp_interface: + ipv6: fc00:b::1a9/64 + + ARISTA424T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.170 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1aa::1/128 + Ethernet1: + ipv6: fc00:a::6a6/126 + bp_interface: + ipv6: fc00:b::1aa/64 + + ARISTA425T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.171 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ab::1/128 + Ethernet1: + ipv6: fc00:a::6aa/126 + bp_interface: + ipv6: fc00:b::1ab/64 + + ARISTA426T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.172 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6ad + interfaces: + Loopback0: + ipv6: fc00:c:c:1ac::1/128 + Ethernet1: + ipv6: fc00:a::6ae/126 + bp_interface: + ipv6: fc00:b::1ac/64 + + ARISTA427T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.173 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ad::1/128 + Ethernet1: + ipv6: fc00:a::6b2/126 + bp_interface: + ipv6: fc00:b::1ad/64 + + ARISTA428T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.174 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ae::1/128 + Ethernet1: + ipv6: fc00:a::6b6/126 + bp_interface: + ipv6: fc00:b::1ae/64 + + ARISTA429T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.175 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1af::1/128 + Ethernet1: + ipv6: fc00:a::6ba/126 + bp_interface: + ipv6: fc00:b::1af/64 + + ARISTA430T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.176 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6bd + interfaces: + Loopback0: + ipv6: fc00:c:c:1b0::1/128 + Ethernet1: + ipv6: fc00:a::6be/126 + bp_interface: + ipv6: fc00:b::1b0/64 + + ARISTA431T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.177 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b1::1/128 + Ethernet1: + ipv6: fc00:a::6c2/126 + bp_interface: + ipv6: fc00:b::1b1/64 + + ARISTA432T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.178 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b2::1/128 + Ethernet1: + ipv6: fc00:a::6c6/126 + bp_interface: + ipv6: fc00:b::1b2/64 + + ARISTA433T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.179 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b3::1/128 + Ethernet1: + ipv6: fc00:a::6ca/126 + bp_interface: + ipv6: fc00:b::1b3/64 + + ARISTA434T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.180 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6cd + interfaces: + Loopback0: + ipv6: fc00:c:c:1b4::1/128 + Ethernet1: + ipv6: fc00:a::6ce/126 + bp_interface: + ipv6: fc00:b::1b4/64 + + ARISTA435T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.181 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b5::1/128 + Ethernet1: + ipv6: fc00:a::6d2/126 + bp_interface: + ipv6: fc00:b::1b5/64 + + ARISTA436T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.182 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b6::1/128 + Ethernet1: + ipv6: fc00:a::6d6/126 + bp_interface: + ipv6: fc00:b::1b6/64 + + ARISTA437T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.183 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b7::1/128 + Ethernet1: + ipv6: fc00:a::6da/126 + bp_interface: + ipv6: fc00:b::1b7/64 + + ARISTA438T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.184 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6dd + interfaces: + Loopback0: + ipv6: fc00:c:c:1b8::1/128 + Ethernet1: + ipv6: fc00:a::6de/126 + bp_interface: + ipv6: fc00:b::1b8/64 + + ARISTA439T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.185 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1b9::1/128 + Ethernet1: + ipv6: fc00:a::6e2/126 + bp_interface: + ipv6: fc00:b::1b9/64 + + ARISTA440T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.186 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ba::1/128 + Ethernet1: + ipv6: fc00:a::6e6/126 + bp_interface: + ipv6: fc00:b::1ba/64 + + ARISTA441T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.187 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1bb::1/128 + Ethernet1: + ipv6: fc00:a::6ea/126 + bp_interface: + ipv6: fc00:b::1bb/64 + + ARISTA442T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.188 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6ed + interfaces: + Loopback0: + ipv6: fc00:c:c:1bc::1/128 + Ethernet1: + ipv6: fc00:a::6ee/126 + bp_interface: + ipv6: fc00:b::1bc/64 + + ARISTA443T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.189 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1bd::1/128 + Ethernet1: + ipv6: fc00:a::6f2/126 + bp_interface: + ipv6: fc00:b::1bd/64 + + ARISTA444T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.190 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1be::1/128 + Ethernet1: + ipv6: fc00:a::6f6/126 + bp_interface: + ipv6: fc00:b::1be/64 + + ARISTA445T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.191 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1bf::1/128 + Ethernet1: + ipv6: fc00:a::6fa/126 + bp_interface: + ipv6: fc00:b::1bf/64 + + ARISTA446T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.192 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::6fd + interfaces: + Loopback0: + ipv6: fc00:c:c:1c0::1/128 + Ethernet1: + ipv6: fc00:a::6fe/126 + bp_interface: + ipv6: fc00:b::1c0/64 + + ARISTA447T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.193 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::701 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c1::1/128 + Ethernet1: + ipv6: fc00:a::702/126 + bp_interface: + ipv6: fc00:b::1c1/64 + + ARISTA448T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.194 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::705 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c2::1/128 + Ethernet1: + ipv6: fc00:a::706/126 + bp_interface: + ipv6: fc00:b::1c2/64 + + ARISTA449T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.195 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::709 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c3::1/128 + Ethernet1: + ipv6: fc00:a::70a/126 + bp_interface: + ipv6: fc00:b::1c3/64 + + ARISTA450T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.196 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::70d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c4::1/128 + Ethernet1: + ipv6: fc00:a::70e/126 + bp_interface: + ipv6: fc00:b::1c4/64 + + ARISTA451T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.197 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::711 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c5::1/128 + Ethernet1: + ipv6: fc00:a::712/126 + bp_interface: + ipv6: fc00:b::1c5/64 + + ARISTA452T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.198 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::715 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c6::1/128 + Ethernet1: + ipv6: fc00:a::716/126 + bp_interface: + ipv6: fc00:b::1c6/64 + + ARISTA453T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.199 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::719 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c7::1/128 + Ethernet1: + ipv6: fc00:a::71a/126 + bp_interface: + ipv6: fc00:b::1c7/64 + + ARISTA454T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.200 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::71d + interfaces: + Loopback0: + ipv6: fc00:c:c:1c8::1/128 + Ethernet1: + ipv6: fc00:a::71e/126 + bp_interface: + ipv6: fc00:b::1c8/64 + + ARISTA455T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.201 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::721 + interfaces: + Loopback0: + ipv6: fc00:c:c:1c9::1/128 + Ethernet1: + ipv6: fc00:a::722/126 + bp_interface: + ipv6: fc00:b::1c9/64 + + ARISTA456T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.202 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::725 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ca::1/128 + Ethernet1: + ipv6: fc00:a::726/126 + bp_interface: + ipv6: fc00:b::1ca/64 + + ARISTA457T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.203 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::729 + interfaces: + Loopback0: + ipv6: fc00:c:c:1cb::1/128 + Ethernet1: + ipv6: fc00:a::72a/126 + bp_interface: + ipv6: fc00:b::1cb/64 + + ARISTA458T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.204 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::72d + interfaces: + Loopback0: + ipv6: fc00:c:c:1cc::1/128 + Ethernet1: + ipv6: fc00:a::72e/126 + bp_interface: + ipv6: fc00:b::1cc/64 + + ARISTA459T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.205 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::731 + interfaces: + Loopback0: + ipv6: fc00:c:c:1cd::1/128 + Ethernet1: + ipv6: fc00:a::732/126 + bp_interface: + ipv6: fc00:b::1cd/64 + + ARISTA460T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.206 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::735 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ce::1/128 + Ethernet1: + ipv6: fc00:a::736/126 + bp_interface: + ipv6: fc00:b::1ce/64 + + ARISTA461T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.207 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::739 + interfaces: + Loopback0: + ipv6: fc00:c:c:1cf::1/128 + Ethernet1: + ipv6: fc00:a::73a/126 + bp_interface: + ipv6: fc00:b::1cf/64 + + ARISTA462T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.208 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::73d + interfaces: + Loopback0: + ipv6: fc00:c:c:1d0::1/128 + Ethernet1: + ipv6: fc00:a::73e/126 + bp_interface: + ipv6: fc00:b::1d0/64 + + ARISTA463T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.209 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::741 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d1::1/128 + Ethernet1: + ipv6: fc00:a::742/126 + bp_interface: + ipv6: fc00:b::1d1/64 + + ARISTA464T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.210 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::745 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d2::1/128 + Ethernet1: + ipv6: fc00:a::746/126 + bp_interface: + ipv6: fc00:b::1d2/64 + + ARISTA465T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.211 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::749 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d3::1/128 + Ethernet1: + ipv6: fc00:a::74a/126 + bp_interface: + ipv6: fc00:b::1d3/64 + + ARISTA466T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.212 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::74d + interfaces: + Loopback0: + ipv6: fc00:c:c:1d4::1/128 + Ethernet1: + ipv6: fc00:a::74e/126 + bp_interface: + ipv6: fc00:b::1d4/64 + + ARISTA467T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.213 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::751 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d5::1/128 + Ethernet1: + ipv6: fc00:a::752/126 + bp_interface: + ipv6: fc00:b::1d5/64 + + ARISTA468T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.214 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::755 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d6::1/128 + Ethernet1: + ipv6: fc00:a::756/126 + bp_interface: + ipv6: fc00:b::1d6/64 + + ARISTA469T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.215 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::759 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d7::1/128 + Ethernet1: + ipv6: fc00:a::75a/126 + bp_interface: + ipv6: fc00:b::1d7/64 + + ARISTA470T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.216 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::75d + interfaces: + Loopback0: + ipv6: fc00:c:c:1d8::1/128 + Ethernet1: + ipv6: fc00:a::75e/126 + bp_interface: + ipv6: fc00:b::1d8/64 + + ARISTA471T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.217 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::761 + interfaces: + Loopback0: + ipv6: fc00:c:c:1d9::1/128 + Ethernet1: + ipv6: fc00:a::762/126 + bp_interface: + ipv6: fc00:b::1d9/64 + + ARISTA472T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.218 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::765 + interfaces: + Loopback0: + ipv6: fc00:c:c:1da::1/128 + Ethernet1: + ipv6: fc00:a::766/126 + bp_interface: + ipv6: fc00:b::1da/64 + + ARISTA473T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.219 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::769 + interfaces: + Loopback0: + ipv6: fc00:c:c:1db::1/128 + Ethernet1: + ipv6: fc00:a::76a/126 + bp_interface: + ipv6: fc00:b::1db/64 + + ARISTA474T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.220 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::76d + interfaces: + Loopback0: + ipv6: fc00:c:c:1dc::1/128 + Ethernet1: + ipv6: fc00:a::76e/126 + bp_interface: + ipv6: fc00:b::1dc/64 + + ARISTA475T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.221 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::771 + interfaces: + Loopback0: + ipv6: fc00:c:c:1dd::1/128 + Ethernet1: + ipv6: fc00:a::772/126 + bp_interface: + ipv6: fc00:b::1dd/64 + + ARISTA476T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.222 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::775 + interfaces: + Loopback0: + ipv6: fc00:c:c:1de::1/128 + Ethernet1: + ipv6: fc00:a::776/126 + bp_interface: + ipv6: fc00:b::1de/64 + + ARISTA477T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.223 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::779 + interfaces: + Loopback0: + ipv6: fc00:c:c:1df::1/128 + Ethernet1: + ipv6: fc00:a::77a/126 + bp_interface: + ipv6: fc00:b::1df/64 + + ARISTA478T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.224 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::77d + interfaces: + Loopback0: + ipv6: fc00:c:c:1e0::1/128 + Ethernet1: + ipv6: fc00:a::77e/126 + bp_interface: + ipv6: fc00:b::1e0/64 + + ARISTA479T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.225 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::781 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e1::1/128 + Ethernet1: + ipv6: fc00:a::782/126 + bp_interface: + ipv6: fc00:b::1e1/64 + + ARISTA480T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.226 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::785 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e2::1/128 + Ethernet1: + ipv6: fc00:a::786/126 + bp_interface: + ipv6: fc00:b::1e2/64 + + ARISTA481T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.227 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::789 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e3::1/128 + Ethernet1: + ipv6: fc00:a::78a/126 + bp_interface: + ipv6: fc00:b::1e3/64 + + ARISTA482T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.228 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::78d + interfaces: + Loopback0: + ipv6: fc00:c:c:1e4::1/128 + Ethernet1: + ipv6: fc00:a::78e/126 + bp_interface: + ipv6: fc00:b::1e4/64 + + ARISTA483T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.229 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::791 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e5::1/128 + Ethernet1: + ipv6: fc00:a::792/126 + bp_interface: + ipv6: fc00:b::1e5/64 + + ARISTA484T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.230 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::795 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e6::1/128 + Ethernet1: + ipv6: fc00:a::796/126 + bp_interface: + ipv6: fc00:b::1e6/64 + + ARISTA485T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.231 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::799 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e7::1/128 + Ethernet1: + ipv6: fc00:a::79a/126 + bp_interface: + ipv6: fc00:b::1e7/64 + + ARISTA486T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.232 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::79d + interfaces: + Loopback0: + ipv6: fc00:c:c:1e8::1/128 + Ethernet1: + ipv6: fc00:a::79e/126 + bp_interface: + ipv6: fc00:b::1e8/64 + + ARISTA487T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.233 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7a1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1e9::1/128 + Ethernet1: + ipv6: fc00:a::7a2/126 + bp_interface: + ipv6: fc00:b::1e9/64 + + ARISTA488T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.234 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7a5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ea::1/128 + Ethernet1: + ipv6: fc00:a::7a6/126 + bp_interface: + ipv6: fc00:b::1ea/64 + + ARISTA489T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.235 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7a9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1eb::1/128 + Ethernet1: + ipv6: fc00:a::7aa/126 + bp_interface: + ipv6: fc00:b::1eb/64 + + ARISTA490T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.236 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7ad + interfaces: + Loopback0: + ipv6: fc00:c:c:1ec::1/128 + Ethernet1: + ipv6: fc00:a::7ae/126 + bp_interface: + ipv6: fc00:b::1ec/64 + + ARISTA491T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.237 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7b1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ed::1/128 + Ethernet1: + ipv6: fc00:a::7b2/126 + bp_interface: + ipv6: fc00:b::1ed/64 + + ARISTA492T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.238 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7b5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ee::1/128 + Ethernet1: + ipv6: fc00:a::7b6/126 + bp_interface: + ipv6: fc00:b::1ee/64 + + ARISTA493T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.239 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7b9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ef::1/128 + Ethernet1: + ipv6: fc00:a::7ba/126 + bp_interface: + ipv6: fc00:b::1ef/64 + + ARISTA494T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.240 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7bd + interfaces: + Loopback0: + ipv6: fc00:c:c:1f0::1/128 + Ethernet1: + ipv6: fc00:a::7be/126 + bp_interface: + ipv6: fc00:b::1f0/64 + + ARISTA495T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.241 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7c1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f1::1/128 + Ethernet1: + ipv6: fc00:a::7c2/126 + bp_interface: + ipv6: fc00:b::1f1/64 + + ARISTA496T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.242 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7c5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f2::1/128 + Ethernet1: + ipv6: fc00:a::7c6/126 + bp_interface: + ipv6: fc00:b::1f2/64 + + ARISTA497T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.243 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7c9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f3::1/128 + Ethernet1: + ipv6: fc00:a::7ca/126 + bp_interface: + ipv6: fc00:b::1f3/64 + + ARISTA498T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.244 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7cd + interfaces: + Loopback0: + ipv6: fc00:c:c:1f4::1/128 + Ethernet1: + ipv6: fc00:a::7ce/126 + bp_interface: + ipv6: fc00:b::1f4/64 + + ARISTA499T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.245 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7d1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f5::1/128 + Ethernet1: + ipv6: fc00:a::7d2/126 + bp_interface: + ipv6: fc00:b::1f5/64 + + ARISTA500T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.246 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7d5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f6::1/128 + Ethernet1: + ipv6: fc00:a::7d6/126 + bp_interface: + ipv6: fc00:b::1f6/64 + + ARISTA501T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.247 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7d9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f7::1/128 + Ethernet1: + ipv6: fc00:a::7da/126 + bp_interface: + ipv6: fc00:b::1f7/64 + + ARISTA502T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.248 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7dd + interfaces: + Loopback0: + ipv6: fc00:c:c:1f8::1/128 + Ethernet1: + ipv6: fc00:a::7de/126 + bp_interface: + ipv6: fc00:b::1f8/64 + + ARISTA503T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.249 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7e1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1f9::1/128 + Ethernet1: + ipv6: fc00:a::7e2/126 + bp_interface: + ipv6: fc00:b::1f9/64 + + ARISTA504T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.250 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7e5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fa::1/128 + Ethernet1: + ipv6: fc00:a::7e6/126 + bp_interface: + ipv6: fc00:b::1fa/64 + + ARISTA505T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.251 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7e9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fb::1/128 + Ethernet1: + ipv6: fc00:a::7ea/126 + bp_interface: + ipv6: fc00:b::1fb/64 + + ARISTA506T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.252 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7ed + interfaces: + Loopback0: + ipv6: fc00:c:c:1fc::1/128 + Ethernet1: + ipv6: fc00:a::7ee/126 + bp_interface: + ipv6: fc00:b::1fc/64 + + ARISTA507T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.253 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7f1 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fd::1/128 + Ethernet1: + ipv6: fc00:a::7f2/126 + bp_interface: + ipv6: fc00:b::1fd/64 + + ARISTA508T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.254 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7f5 + interfaces: + Loopback0: + ipv6: fc00:c:c:1fe::1/128 + Ethernet1: + ipv6: fc00:a::7f6/126 + bp_interface: + ipv6: fc00:b::1fe/64 + + ARISTA509T0: + properties: + - common + - tor + bgp: + router-id: 0.12.1.255 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7f9 + interfaces: + Loopback0: + ipv6: fc00:c:c:1ff::1/128 + Ethernet1: + ipv6: fc00:a::7fa/126 + bp_interface: + ipv6: fc00:b::1ff/64 + + ARISTA510T0: + properties: + - common + - tor + bgp: + router-id: 0.12.2.0 + asn: 4200000000 + peers: + 4200100000: + - fc00:a::7fd + interfaces: + Loopback0: + ipv6: fc00:c:c:200::1/128 + Ethernet1: + ipv6: fc00:a::7fe/126 + bp_interface: + ipv6: fc00:b::200/64 From ea1108a414688d239be633b93b9635832c016376 Mon Sep 17 00:00:00 2001 From: Zhijian Li Date: Wed, 20 Nov 2024 19:20:31 -0800 Subject: [PATCH 207/221] [M0/Mx] Fix test_route_flap (#15641) PR #14804 caused test_route_flap fail on M0/Mx with below error: > pytest.fail("Did not find a dut in duthosts that for topo type {} that has upstream nbr type {}". format(tbinfo["topo"]["type"], upstream_nbr_type)) E Failed: Did not find a dut in duthosts that for topo type m0 that has upstream nbr type T3 What is the motivation for this PR? Fix test_route_flap on M0/Mx topo. How did you do it? Support upstream neighbor on M0/Mx. How did you verify/test it? Verified on Nokia-7215 M0. Verified on Arista-720DT M0. --- tests/conftest.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 4885d240aaa..b8b4e0c15c0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1875,7 +1875,11 @@ def enum_rand_one_frontend_asic_index(request): @pytest.fixture(scope='module') def enum_upstream_dut_hostname(duthosts, tbinfo): - if tbinfo["topo"]["type"] == "t0": + if tbinfo["topo"]["type"] == "m0": + upstream_nbr_type = "M1" + elif tbinfo["topo"]["type"] == "mx": + upstream_nbr_type = "M0" + elif tbinfo["topo"]["type"] == "t0": upstream_nbr_type = "T1" elif tbinfo["topo"]["type"] == "t1": upstream_nbr_type = "T2" From b038a6328e9b19324a591b4233148086bf863993 Mon Sep 17 00:00:00 2001 From: Chris <156943338+ccroy-arista@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:08:00 -0800 Subject: [PATCH 208/221] sonic-mgmt: fix port toggle timeout on many ports (#15573) For topologies leveraging many ports, such as in the case of t0-isolated-d128u128s2, the timeout for non-mellanox fixed-chassis devices is a static value and is too low for the number of ports being configured. In contrast, Mellanox devices use a timeout proportional to the number of ports being toggled. This change moves fixed-chassis broadcom devices to use a proportional timeout as well. --- tests/common/port_toggle.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/common/port_toggle.py b/tests/common/port_toggle.py index 890288394b7..d387c7229d4 100644 --- a/tests/common/port_toggle.py +++ b/tests/common/port_toggle.py @@ -121,14 +121,16 @@ def default_port_toggle_wait_time(duthost, port_count): port_down_wait_time, port_up_wait_time = 120, 180 asic_type = duthost.facts["asic_type"] - if asic_type == "mellanox": + is_modular_chassis = duthost.get_facts().get("modular_chassis") + + if (asic_type == "mellanox") or (asic_type == "broadcom" and not is_modular_chassis): if port_count <= BASE_PORT_COUNT: port_count = BASE_PORT_COUNT port_count_factor = port_count / BASE_PORT_COUNT port_down_wait_time = int(port_down_wait_time * port_count_factor) port_up_wait_time = int(port_up_wait_time * port_count_factor) - elif duthost.get_facts().get("modular_chassis"): + elif is_modular_chassis: port_down_wait_time = 300 port_up_wait_time = 300 From f265a734f5c77838b336a58e1bd99a4845a03fa0 Mon Sep 17 00:00:00 2001 From: vkjammala-arista <152394203+vkjammala-arista@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:11:00 +0530 Subject: [PATCH 209/221] [sonic-mgmt] Fix "enum_dut_lossy_prio_with_completeness_level" collection failure (#15626) PR#15057 has introduced logic to select dut queue priority list based on the completeness_level. If completeness_level is "debug", we are selecting one queue priority randomly from the dut priority list which can be empty also, and this will cause "ValueError: Sample larger than population or is negative". --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index b8b4e0c15c0..bff93f580c3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1550,7 +1550,7 @@ def generate_priority_lists(request, prio_scope, with_completeness_level=False): # if completeness_level in ["debug"], only select one item # if completeness_level in ["basic", "confident"], select 1 priority per DUT - if completeness_level in ["debug"]: + if completeness_level in ["debug"] and ret: ret = random.sample(ret, 1) elif completeness_level in ["basic", "confident"]: ret = [] From 0bcec187d50fbe07d3abef4aad426b2910d0744e Mon Sep 17 00:00:00 2001 From: Chun'ang Li <39114813+lerry-lee@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:41:46 +0800 Subject: [PATCH 210/221] [CI]Add new parameter retry_cases_include and retry_cases_exclude to template for Elastictest specific retry (#15635) What is the motivation for this PR? [CI]Add new parameter retry_cases_include and retry_cases_exclude to template for Elastictest specific retry. How did you do it? Add new parameters retry_cases_include and retry_cases_exclude and set default value. How did you verify/test it? Add new parameters wouldn't block current normal runnings. This PR test need passed. Signed-off-by: Chun'ang Li --- .../run-test-elastictest-template.yml | 13 ++++++++++ .azure-pipelines/test_plan.py | 26 +++++++++++++++++++ azure-pipelines.yml | 20 +++++++------- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 740bbc8db7b..4d1092e50eb 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -115,10 +115,21 @@ parameters: type: string default: "" + # The number of retries when the script fails. Global retry if retry_cases_include and retry_cases_exclude are both empty, otherwise specific retry - name: RETRY_TIMES type: string default: "" + # Retry cases to include, works when retry_times>0, support both feature and script level, such as "bgp,test_features.py" + - name: RETRY_CASES_INCLUDE + type: string + default: "" + + # Retry cases to exclude, works when retry_times>0, support both feature and script level, such as "bgp,test_features.py" + - name: RETRY_CASES_EXCLUDE + type: string + default: "" + - name: DUMP_KVM_IF_FAIL type: string default: "False" # KVM dump has beed deleted @@ -248,6 +259,8 @@ steps: --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ --retry-times ${{ parameters.RETRY_TIMES }} \ + --retry-cases-include ${{ parameters.RETRY_CASES_INCLUDE }} \ + --retry-cases-exclude ${{ parameters.RETRY_CASES_EXCLUDE }} \ --dump-kvm-if-fail ${{ parameters.DUMP_KVM_IF_FAIL }} \ --requester "${{ parameters.REQUESTER }}" \ --max-execute-seconds $((${{ parameters.MAX_RUN_TEST_MINUTES }} * 60)) \ diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index f4b07bb2d18..4052be78e3d 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -227,6 +227,8 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params features = parse_list_from_str(kwargs.get("features", None)) scripts_exclude = parse_list_from_str(kwargs.get("scripts_exclude", None)) features_exclude = parse_list_from_str(kwargs.get("features_exclude", None)) + retry_cases_include = parse_list_from_str(kwargs.get("retry_cases_include", None)) + retry_cases_exclude = parse_list_from_str(kwargs.get("retry_cases_exclude", None)) ptf_image_tag = kwargs.get("ptf_image_tag", None) print("Creating test plan, topology: {}, name: {}, build info:{} {} {}".format(topology, test_plan_name, @@ -284,6 +286,8 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params "test_option": { "stop_on_failure": kwargs.get("stop_on_failure", True), "retry_times": kwargs.get("retry_times", 2), + "retry_cases_include": retry_cases_include, + "retry_cases_exclude": retry_cases_exclude, "test_cases": { "features": features, "scripts": scripts, @@ -829,6 +833,26 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte required=False, help="Retry times after tests failed." ) + parser_create.add_argument( + "--retry-cases-include", + type=str, + dest="retry_cases_include", + nargs='?', + const=None, + default=None, + required=False, + help="Include testcases to retry, support feature/script. Split by ',', like: 'bgp, lldp, ecmp/test_fgnhg.py'" + ) + parser_create.add_argument( + "--retry-cases-exclude", + type=str, + dest="retry_cases_exclude", + nargs='?', + const=None, + default=None, + required=False, + help="Exclude testcases to retry, support feature/script. Split by ',', like: 'bgp, lldp, ecmp/test_fgnhg.py'" + ) parser_create.add_argument( "--dump-kvm-if-fail", type=ast.literal_eval, @@ -1022,6 +1046,8 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte platform=args.platform, stop_on_failure=args.stop_on_failure, retry_times=args.retry_times, + retry_cases_include=args.retry_cases_include, + retry_cases_exclude=args.retry_cases_exclude, dump_kvm_if_fail=args.dump_kvm_if_fail, requester=args.requester, max_execute_seconds=args.max_execute_seconds, diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 76cacd39c1d..bd19abd9c7a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -80,7 +80,7 @@ stages: MIN_WORKER: $(T0_INSTANCE_NUM) MAX_WORKER: $(T0_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: t0_2vlans_elastictest displayName: "kvmtest-t0-2vlans by Elastictest" @@ -96,7 +96,7 @@ stages: MAX_WORKER: $(T0_2VLANS_INSTANCE_NUM) DEPLOY_MG_EXTRA_PARAMS: "-e vlan_config=two_vlan_a" KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: t1_lag_elastictest displayName: "kvmtest-t1-lag by Elastictest" @@ -110,7 +110,7 @@ stages: MIN_WORKER: $(T1_LAG_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: dualtor_elastictest displayName: "kvmtest-dualtor-t0 by Elastictest" @@ -125,7 +125,7 @@ stages: MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) COMMON_EXTRA_PARAMS: "--disable_loganalyzer " KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: multi_asic_elastictest displayName: "kvmtest-multi-asic-t1-lag by Elastictest" @@ -141,7 +141,7 @@ stages: MAX_WORKER: $(MULTI_ASIC_INSTANCE_NUM) NUM_ASIC: 4 KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: sonic_t0_elastictest displayName: "kvmtest-t0-sonic by Elastictest" @@ -158,7 +158,7 @@ stages: COMMON_EXTRA_PARAMS: "--neighbor_type=sonic " VM_TYPE: vsonic KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: dpu_elastictest displayName: "kvmtest-dpu by Elastictest" @@ -172,7 +172,7 @@ stages: MIN_WORKER: $(T0_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" - job: onboarding_elastictest_t0 displayName: "onboarding t0 testcases by Elastictest - optional" @@ -188,7 +188,7 @@ stages: MIN_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) MAX_WORKER: $(T0_ONBOARDING_SONIC_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" TEST_SET: onboarding_t0 - job: onboarding_elastictest_t1 @@ -205,7 +205,7 @@ stages: MIN_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) MAX_WORKER: $(T1_LAG_ONBOARDING_INSTANCE_NUM) KVM_IMAGE_BRANCH: $(BUILD_BRANCH) - MGMT_BRANCH: $(BUILD_BRANCH) + MGMT_BRANCH: "master" TEST_SET: onboarding_t1 # - job: onboarding_elastictest_dualtor @@ -222,7 +222,7 @@ stages: # MIN_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # MAX_WORKER: $(T0_DUALTOR_INSTANCE_NUM) # KVM_IMAGE_BRANCH: $(BUILD_BRANCH) -# MGMT_BRANCH: $(BUILD_BRANCH) +# MGMT_BRANCH: "master" # TEST_SET: onboarding_dualtor # - job: wan_elastictest From 579f7ba37abdfd4b5a0d32ac7f9d41c52e94e776 Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:42:47 +0800 Subject: [PATCH 211/221] Refactor the shared scripts under `configlet` to a common place. (#15606) The functions in the script tests/configlet/util/common.py were being used by common utilities, resulting in cross-feature dependencies. To address this issue and improve code modularity, we refactored and relocated the script to tests/common/configlet/utils.py. Similarly, the helper.py script under tests/configlet/util, which also contained shared functions, was refactored and moved to tests/common/configlet to align with the updated structure and reduce cross-feature dependencies. --- tests/common/config_reload.py | 2 +- tests/common/configlet/__init__.py | 0 .../{configlet/util => common/configlet}/helpers.py | 0 .../util/common.py => common/configlet/utils.py} | 0 tests/configlet/test_add_rack.py | 2 +- tests/configlet/util/base_test.py | 13 +++++++------ tests/configlet/util/configlet.py | 6 +++--- tests/configlet/util/generic_patch.py | 2 +- tests/configlet/util/mock_for_switch.py | 2 +- tests/configlet/util/run_test_in_switch.py | 2 +- tests/configlet/util/strip.py | 4 ++-- 11 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 tests/common/configlet/__init__.py rename tests/{configlet/util => common/configlet}/helpers.py (100%) rename tests/{configlet/util/common.py => common/configlet/utils.py} (100%) mode change 100755 => 100644 diff --git a/tests/common/config_reload.py b/tests/common/config_reload.py index b6e2542bece..5916a63b2bf 100644 --- a/tests/common/config_reload.py +++ b/tests/common/config_reload.py @@ -6,7 +6,7 @@ from tests.common.plugins.loganalyzer.utils import ignore_loganalyzer from tests.common.platform.processes_utils import wait_critical_processes from tests.common.utilities import wait_until -from tests.configlet.util.common import chk_for_pfc_wd +from tests.common.configlet.utils import chk_for_pfc_wd from tests.common.platform.interface_utils import check_interface_status_of_up_ports from tests.common.helpers.dut_utils import ignore_t2_syslog_msgs diff --git a/tests/common/configlet/__init__.py b/tests/common/configlet/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/configlet/util/helpers.py b/tests/common/configlet/helpers.py similarity index 100% rename from tests/configlet/util/helpers.py rename to tests/common/configlet/helpers.py diff --git a/tests/configlet/util/common.py b/tests/common/configlet/utils.py old mode 100755 new mode 100644 similarity index 100% rename from tests/configlet/util/common.py rename to tests/common/configlet/utils.py diff --git a/tests/configlet/test_add_rack.py b/tests/configlet/test_add_rack.py index a2b66d716af..32e568ee529 100644 --- a/tests/configlet/test_add_rack.py +++ b/tests/configlet/test_add_rack.py @@ -4,7 +4,7 @@ import sys from tests.common.utilities import skip_release from .util.base_test import do_test_add_rack, backup_minigraph, restore_orig_minigraph -from .util.helpers import log_info +from tests.common.configlet.helpers import log_info pytestmark = [ pytest.mark.topology("t1") diff --git a/tests/configlet/util/base_test.py b/tests/configlet/util/base_test.py index 60bc3024307..32f60172bbe 100644 --- a/tests/configlet/util/base_test.py +++ b/tests/configlet/util/base_test.py @@ -3,15 +3,16 @@ import json import os -from helpers import set_log_prefix_msg, get_prefix_lvl, set_prefix_lvl, append_log_prefix_msg,\ +from tests.configlet.util import strip +from tests.configlet.util import generic_patch +from tests.configlet.util import configlet +from tests.common.configlet.helpers import set_log_prefix_msg, get_prefix_lvl, set_prefix_lvl, append_log_prefix_msg,\ log_info, log_debug -from common import base_dir, data_dir, orig_db_dir, no_t0_db_dir, clet_db_dir, managed_files,\ - patch_add_t0_dir, patch_rm_t0_dir, files_dir, tor_data, init_data,\ +from tests.common.configlet.utils import base_dir, data_dir, orig_db_dir, no_t0_db_dir, clet_db_dir, managed_files,\ + patch_add_t0_dir, patch_rm_t0_dir, files_dir, tor_data, init_data, \ RELOAD_WAIT_TIME, PAUSE_INTF_DOWN, PAUSE_INTF_UP, PAUSE_CLET_APPLY, DB_COMP_WAIT_TIME,\ do_pause, db_comp, chk_bgp_session, chk_for_pfc_wd, report_error, take_DB_dumps, init_global_data -import strip -import configlet -import generic_patch + if os.path.exists("/etc/sonic/sonic-environment"): from mock_for_switch import config_reload, wait_until diff --git a/tests/configlet/util/configlet.py b/tests/configlet/util/configlet.py index b03b55cfd58..48348c17369 100755 --- a/tests/configlet/util/configlet.py +++ b/tests/configlet/util/configlet.py @@ -3,10 +3,10 @@ import json from tempfile import mkstemp -from helpers import log_info, log_debug -from common import tor_data, init_data, config_db_data_orig, managed_files # noqa F401 +from tests.common.configlet.helpers import log_info, log_debug +from tests.common.configlet.utils import tor_data, init_data, config_db_data_orig, managed_files # noqa F401 -import strip +from tests.configlet.util import strip orig_config = None diff --git a/tests/configlet/util/generic_patch.py b/tests/configlet/util/generic_patch.py index f734f1ff835..ce0833368fe 100644 --- a/tests/configlet/util/generic_patch.py +++ b/tests/configlet/util/generic_patch.py @@ -6,7 +6,7 @@ import os import re -from common import orig_db_dir, no_t0_db_dir, patch_add_t0_dir, patch_rm_t0_dir, tor_data,\ +from tests.common.configlet.utils import orig_db_dir, no_t0_db_dir, patch_add_t0_dir, patch_rm_t0_dir, tor_data,\ RELOAD_WAIT_TIME, PAUSE_INTF_DOWN, PAUSE_INTF_UP, PAUSE_CLET_APPLY, DB_COMP_WAIT_TIME,\ do_pause, db_comp, chk_bgp_session diff --git a/tests/configlet/util/mock_for_switch.py b/tests/configlet/util/mock_for_switch.py index df13b3b420a..7170a3162c9 100644 --- a/tests/configlet/util/mock_for_switch.py +++ b/tests/configlet/util/mock_for_switch.py @@ -11,7 +11,7 @@ import time import traceback -from helpers import log_error, log_info, log_debug +from tests.common.configlet.helpers import log_error, log_info, log_debug class DutHost: diff --git a/tests/configlet/util/run_test_in_switch.py b/tests/configlet/util/run_test_in_switch.py index fc88d0450d5..1c61da8b623 100644 --- a/tests/configlet/util/run_test_in_switch.py +++ b/tests/configlet/util/run_test_in_switch.py @@ -8,7 +8,7 @@ from mock_for_switch import get_duthost from base_test import do_test_add_rack, backup_minigraph, restore_orig_minigraph -from helpers import log_error, set_print +from tests.common.configlet.helpers import log_error, set_print # To run test in switch: # Copy all files in this dir (tests/configlet/util) into switch diff --git a/tests/configlet/util/strip.py b/tests/configlet/util/strip.py index 5a7eb139177..8ac435682b9 100755 --- a/tests/configlet/util/strip.py +++ b/tests/configlet/util/strip.py @@ -4,8 +4,8 @@ import sys import xml.etree.ElementTree as ET -from helpers import log_info, log_debug -from common import tor_data, config_db_data_orig, managed_files, report_error # noqa F401 +from tests.common.configlet.helpers import log_info, log_debug +from tests.common.configlet.utils import tor_data, config_db_data_orig, managed_files, report_error # noqa F401 from tempfile import mkstemp ns_val = "Microsoft.Search.Autopilot.Evolution" From e1b82f39ec507660ab5e9b50d75593f30c5c9654 Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:44:49 +0800 Subject: [PATCH 212/221] [Bugfix] Del wrong condition of case qos/test_qos_sai.py::TestQosSai::testQosSaiPgSharedWatermark[None-wm_pg_shared_lossy] (#15660) --- tests/common/plugins/conditional_mark/tests_mark_conditions.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index cd5255da248..3ed679e9de3 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1571,7 +1571,6 @@ qos/test_qos_sai.py::TestQosSai::testQosSaiPgSharedWatermark[None-wm_pg_shared_l reason: "Image issue on Arista platforms / Unsupported testbed type." conditions: - "platform in ['x86_64-arista_7050cx3_32s']" - - "topo_name not in ['t0', 't0-64', 't0-116', 't0-35', 't0-56', 't0-standalone-32', 't0-standalone-64', 't0-standalone-128', 't0-standalone-256', 'dualtor-56', 'dualtor-120', 'dualtor', 't0-80', 't0-backend', 't1-lag', 't1-64-lag', 't1-56-lag', 't1-backend', 't2', 't2_2lc_36p-masic', 't2_2lc_min_ports-masic'] and asic_type not in ['mellanox']" qos/test_qos_sai.py::TestQosSai::testQosSaiQWatermarkAllPorts: skip: From 475f52f47fe2e8ecb9d786d3194e1c04fbcc883c Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:47:46 +0800 Subject: [PATCH 213/221] Move fixture `platform_api_conn` to common place. (#15605) What is the motivation for this PR? The platform_api_conn fixture is utilized by scripts in both the smatswitch and platform_tests directories. To reduce cross-feature dependencies and improve code organization, I relocated the fixture to a shared common location, making it accessible without creating unnecessary interdependencies between these feature-specific directories. How did you do it? I relocated the fixture platform_api_conn to a shared common location --- tests/common/platform/device_utils.py | 13 +++++ tests/platform_tests/api/conftest.py | 13 ----- tests/platform_tests/api/test_chassis.py | 52 ++++++++++--------- tests/platform_tests/api/test_component.py | 39 +++++++------- tests/platform_tests/api/test_fan_drawer.py | 26 +++++----- tests/platform_tests/api/test_psu.py | 33 ++++++------ tests/platform_tests/api/test_psu_fans.py | 34 ++++++------ tests/platform_tests/api/test_watchdog.py | 21 +++++--- tests/smartswitch/common/device_utils_dpu.py | 16 +++--- .../platform_tests/test_reload_dpu.py | 8 ++- .../platform_tests/test_show_platform_dpu.py | 11 ++-- 11 files changed, 134 insertions(+), 132 deletions(-) diff --git a/tests/common/platform/device_utils.py b/tests/common/platform/device_utils.py index 6676b2f6afa..b74cf94e908 100644 --- a/tests/common/platform/device_utils.py +++ b/tests/common/platform/device_utils.py @@ -6,6 +6,7 @@ import os import json import glob +import http.client from datetime import datetime from collections import OrderedDict from tests.common.utilities import wait_until @@ -938,3 +939,15 @@ def advanceboot_neighbor_restore(duthosts, enum_rand_one_per_hwsku_frontend_host duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] from tests.common.plugins.sanity_check.recover import neighbor_vm_restore neighbor_vm_restore(duthost, nbrhosts, tbinfo) + + +@pytest.fixture(scope='function') +def platform_api_conn(duthosts, enum_rand_one_per_hwsku_hostname, start_platform_api_service): + duthost = duthosts[enum_rand_one_per_hwsku_hostname] + dut_ip = duthost.mgmt_ip + + conn = http.client.HTTPConnection(dut_ip, 8000) + try: + yield conn + finally: + conn.close() diff --git a/tests/platform_tests/api/conftest.py b/tests/platform_tests/api/conftest.py index a6471834a8b..5fc3640ffa9 100644 --- a/tests/platform_tests/api/conftest.py +++ b/tests/platform_tests/api/conftest.py @@ -1,6 +1,5 @@ import os import pytest -import http.client from tests.common.plugins.loganalyzer.loganalyzer import LogAnalyzer @@ -86,18 +85,6 @@ def stop_platform_api_service(duthosts): duthost.command(IPTABLES_DELETE_RULE_CMD, module_ignore_errors=True) -@pytest.fixture(scope='function') -def platform_api_conn(duthosts, enum_rand_one_per_hwsku_hostname, start_platform_api_service): - duthost = duthosts[enum_rand_one_per_hwsku_hostname] - dut_ip = duthost.mgmt_ip - - conn = http.client.HTTPConnection(dut_ip, SERVER_PORT) - try: - yield conn - finally: - conn.close() - - @pytest.fixture(autouse=True) def check_not_implemented_warnings(duthosts, enum_rand_one_per_hwsku_hostname): duthost = duthosts[enum_rand_one_per_hwsku_hostname] diff --git a/tests/platform_tests/api/test_chassis.py b/tests/platform_tests/api/test_chassis.py index 7f823331466..6ad2a1b2f43 100644 --- a/tests/platform_tests/api/test_chassis.py +++ b/tests/platform_tests/api/test_chassis.py @@ -11,6 +11,7 @@ from tests.common.utilities import get_host_visible_vars from tests.common.utilities import skip_release from tests.common.platform.interface_utils import get_physical_port_indices +from tests.common.platform.device_utils import platform_api_conn # noqa F401 from tests.platform_tests.cli.util import get_skip_mod_list from .platform_api_test_base import PlatformApiTestBase @@ -121,53 +122,53 @@ def compare_value_with_device_facts(self, duthost, key, value, case_sensitive=Tr # Functions to test methods inherited from DeviceBase class # - def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] name = chassis.get_name(platform_api_conn) pytest_assert(name is not None, "Unable to retrieve chassis name") pytest_assert(isinstance(name, STRING_TYPE), "Chassis name appears incorrect") self.compare_value_with_platform_facts(duthost, 'name', name) - def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 presence = chassis.get_presence(platform_api_conn) pytest_assert(presence is not None, "Unable to retrieve chassis presence") pytest_assert(isinstance(presence, bool), "Chassis presence appears incorrect") # Chassis should always be present pytest_assert(presence is True, "Chassis is not present") - def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] model = chassis.get_model(platform_api_conn) pytest_assert(model is not None, "Unable to retrieve chassis model") pytest_assert(isinstance(model, STRING_TYPE), "Chassis model appears incorrect") self.compare_value_with_device_facts(duthost, 'model', model) - def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] serial = chassis.get_serial(platform_api_conn) pytest_assert(serial is not None, "Unable to retrieve chassis serial number") pytest_assert(isinstance(serial, STRING_TYPE), "Chassis serial number appears incorrect") self.compare_value_with_device_facts(duthost, 'serial', serial) - def test_get_revision(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_revision(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release(duthost, ["201811", "201911", "202012"]) revision = chassis.get_revision(platform_api_conn) pytest_assert(revision is not None, "Unable to retrieve chassis revision") pytest_assert(isinstance(revision, STRING_TYPE), "Revision appears incorrect") - def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 status = chassis.get_status(platform_api_conn) pytest_assert(status is not None, "Unable to retrieve chassis status") pytest_assert(isinstance(status, bool), "Chassis status appears incorrect") - def test_get_position_in_parent(self, platform_api_conn): + def test_get_position_in_parent(self, platform_api_conn): # noqa F811 position = chassis.get_position_in_parent(platform_api_conn) if self.expect(position is not None, "Failed to perform get_position_in_parent"): self.expect(isinstance(position, int), "Position value must be an integer value") self.assert_expectations() - def test_is_replaceable(self, platform_api_conn): + def test_is_replaceable(self, platform_api_conn): # noqa F811 replaceable = chassis.is_replaceable(platform_api_conn) if self.expect(replaceable is not None, "Failed to perform is_replaceable"): self.expect(isinstance(replaceable, bool), "Replaceable value must be a bool value") @@ -177,7 +178,7 @@ def test_is_replaceable(self, platform_api_conn): # Functions to test methods defined in ChassisBase class # - def test_get_base_mac(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_base_mac(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 # Ensure the base MAC address is sane duthost = duthosts[enum_rand_one_per_hwsku_hostname] base_mac = chassis.get_base_mac(platform_api_conn) @@ -185,7 +186,8 @@ def test_get_base_mac(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos pytest_assert(re.match(REGEX_MAC_ADDRESS, base_mac), "Base MAC address appears to be incorrect") self.compare_value_with_device_facts(duthost, 'base_mac', base_mac, False) - def test_get_system_eeprom_info(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_system_eeprom_info(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 ''' Test that we can retrieve sane system EEPROM info from the DUT via the platform API ''' # OCP ONIE TlvInfo EEPROM type codes defined here: @@ -258,7 +260,8 @@ def test_get_system_eeprom_info(self, duthosts, enum_rand_one_per_hwsku_hostname format(field, syseeprom_info_dict[field], expected_syseeprom_info_dict[field], duthost.hostname)) - def test_get_reboot_cause(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_reboot_cause(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 # TODO: Compare return values to potential combinations reboot_cause = chassis.get_reboot_cause(platform_api_conn) @@ -268,7 +271,7 @@ def test_get_reboot_cause(self, duthosts, enum_rand_one_per_hwsku_hostname, loca pytest_assert(isinstance(reboot_cause, list) and len(reboot_cause) == 2, "Reboot cause appears to be incorrect") - def test_components(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_components(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] try: @@ -297,7 +300,7 @@ def test_components(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, "Component {} is incorrect".format(i)) self.assert_expectations() - def test_modules(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_modules(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 try: num_modules = int(chassis.get_num_modules(platform_api_conn)) except Exception: @@ -319,7 +322,7 @@ def test_modules(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, pl self.expect(module_index == i, "Module index {} is not correct".format(module_index)) self.assert_expectations() - def test_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] try: num_fans = int(chassis.get_num_fans(platform_api_conn)) @@ -344,7 +347,7 @@ def test_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platf self.expect(fan and fan == fan_list[i], "Fan {} is incorrect".format(i)) self.assert_expectations() - def test_fan_drawers(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_fan_drawers(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] try: num_fan_drawers = int(chassis.get_num_fan_drawers(platform_api_conn)) @@ -371,7 +374,7 @@ def test_fan_drawers(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost "Fan drawer {} is incorrect".format(i)) self.assert_expectations() - def test_psus(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_psus(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] try: num_psus = int(chassis.get_num_psus(platform_api_conn)) @@ -396,7 +399,7 @@ def test_psus(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platf self.expect(psu and psu == psu_list[i], "PSU {} is incorrect".format(i)) self.assert_expectations() - def test_thermals(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_thermals(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] try: num_thermals = int(chassis.get_num_thermals(platform_api_conn)) @@ -424,7 +427,7 @@ def test_thermals(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, p self.assert_expectations() def test_sfps(self, duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn, physical_port_indices): + localhost, platform_api_conn, physical_port_indices): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] if duthost.is_supervisor_node(): pytest.skip("skipping for supervisor node") @@ -463,7 +466,7 @@ def test_sfps(self, duthosts, enum_rand_one_per_hwsku_hostname, self.expect(sfp and sfp in sfp_list, "SFP object for PORT{} NOT found".format(index)) self.assert_expectations() - def test_status_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_status_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] # TODO: Get a platform-specific list of available colors for the status LED @@ -537,19 +540,20 @@ def test_status_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_thermal_manager(self, localhost, platform_api_conn, thermal_manager_enabled): + def test_get_thermal_manager(self, localhost, platform_api_conn, thermal_manager_enabled): # noqa F811 thermal_mgr = chassis.get_thermal_manager(platform_api_conn) pytest_assert(thermal_mgr is not None, "Failed to retrieve thermal manager") - def test_get_watchdog(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_watchdog(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 watchdog = chassis.get_watchdog(platform_api_conn) pytest_assert(watchdog is not None, "Failed to retrieve watchdog") - def test_get_eeprom(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_eeprom(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 eeprom = chassis.get_eeprom(platform_api_conn) pytest_assert(eeprom is not None, "Failed to retrieve system EEPROM") - def test_get_supervisor_slot(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_supervisor_slot(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 if chassis.is_modular_chassis(platform_api_conn): sup_slot = chassis.get_supervisor_slot(platform_api_conn) pytest_assert(isinstance(sup_slot, int) or isinstance(sup_slot, STRING_TYPE), @@ -557,7 +561,7 @@ def test_get_supervisor_slot(self, duthosts, enum_rand_one_per_hwsku_hostname, l else: pytest.skip("skipped as this test is applicable to modular chassis only") - def test_get_my_slot(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_my_slot(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 if chassis.is_modular_chassis(platform_api_conn): my_slot = chassis.get_my_slot(platform_api_conn) pytest_assert(isinstance(my_slot, int) or isinstance(my_slot, STRING_TYPE), diff --git a/tests/platform_tests/api/test_component.py b/tests/platform_tests/api/test_component.py index 826be7eaa53..67f37b5c6a0 100644 --- a/tests/platform_tests/api/test_component.py +++ b/tests/platform_tests/api/test_component.py @@ -5,6 +5,7 @@ from tests.common.helpers.platform_api import chassis, component from .platform_api_test_base import PlatformApiTestBase from tests.common.utilities import skip_release_for_platform +from tests.common.platform.device_utils import platform_api_conn # noqa F401 ################################################### # TODO: Remove this after we transition to Python 3 @@ -41,7 +42,7 @@ class TestComponentApi(PlatformApiTestBase): # it relies on the platform_api_conn fixture, which is scoped at the function # level, so we must do the same here to prevent a scope mismatch. @pytest.fixture(scope="function", autouse=True) - def setup(self, platform_api_conn): + def setup(self, platform_api_conn): # noqa F811 if self.num_components is None: try: self.num_components = int(chassis.get_num_components(platform_api_conn)) @@ -73,7 +74,7 @@ def compare_value_with_platform_facts(self, duthost, key, value, component_idx): # Functions to test methods inherited from DeviceBase class # - def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] for i in range(self.num_components): @@ -83,8 +84,7 @@ def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, p self.compare_value_with_platform_facts(duthost, 'name', name, i) self.assert_expectations() - def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_components): presence = component.get_presence(platform_api_conn, i) if self.expect(presence is not None, "Component {}: Unable to retrieve presence".format(i)): @@ -93,16 +93,14 @@ def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos self.expect(presence is True, "Component {} not present".format(i)) self.assert_expectations() - def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_components): model = component.get_model(platform_api_conn, i) if self.expect(model is not None, "Component {}: Unable to retrieve model".format(i)): self.expect(isinstance(model, STRING_TYPE), "Component {}: Model appears incorrect".format(i)) self.assert_expectations() - def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_components): serial = component.get_serial(platform_api_conn, i) if self.expect(serial is not None, "Component {}: Unable to retrieve serial number".format(i)): @@ -110,15 +108,14 @@ def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, "Component {}: Serial number appears incorrect".format(i)) self.assert_expectations() - def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_components): status = component.get_status(platform_api_conn, i) if self.expect(status is not None, "Component {}: Unable to retrieve status".format(i)): self.expect(isinstance(status, bool), "Component {}: Status appears incorrect".format(i)) self.assert_expectations() - def test_get_position_in_parent(self, platform_api_conn): + def test_get_position_in_parent(self, platform_api_conn): # noqa F811 for i in range(self.num_components): position = component.get_position_in_parent(platform_api_conn, i) if self.expect(position is not None, @@ -127,7 +124,7 @@ def test_get_position_in_parent(self, platform_api_conn): "Position value must be an integer value for component {}".format(i)) self.assert_expectations() - def test_is_replaceable(self, platform_api_conn): + def test_is_replaceable(self, platform_api_conn): # noqa F811 for i in range(self.num_components): replaceable = component.is_replaceable(platform_api_conn, i) if self.expect(replaceable is not None, @@ -140,8 +137,8 @@ def test_is_replaceable(self, platform_api_conn): # Functions to test methods defined in ComponentBase class # - def test_get_description(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_description(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 for i in range(self.num_components): description = component.get_description(platform_api_conn, i) if self.expect(description is not None, "Component {}: Failed to retrieve description".format(i)): @@ -149,8 +146,8 @@ def test_get_description(self, duthosts, enum_rand_one_per_hwsku_hostname, local "Component {}: Description appears to be incorrect".format(i)) self.assert_expectations() - def test_get_firmware_version(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_firmware_version(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 for i in range(self.num_components): fw_version = component.get_firmware_version(platform_api_conn, i) if self.expect(fw_version is not None, "Component {}: Failed to retrieve firmware version".format(i)): @@ -159,7 +156,7 @@ def test_get_firmware_version(self, duthosts, enum_rand_one_per_hwsku_hostname, self.assert_expectations() def test_get_available_firmware_version(self, duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn): + localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["nokia"]) @@ -175,7 +172,7 @@ def test_get_available_firmware_version(self, duthosts, enum_rand_one_per_hwsku_ self.assert_expectations() def test_get_firmware_update_notification(self, duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn): + localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["nokia"]) @@ -188,7 +185,8 @@ def test_get_firmware_update_notification(self, duthosts, enum_rand_one_per_hwsk "Component {}: Firmware update notification appears to be incorrect from image {}" .format(i, image)) - def test_install_firmware(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_install_firmware(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["nokia"]) @@ -202,7 +200,8 @@ def test_install_firmware(self, duthosts, enum_rand_one_per_hwsku_hostname, loca .format(i, image)) self.assert_expectations() - def test_update_firmware(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_update_firmware(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["nokia"]) diff --git a/tests/platform_tests/api/test_fan_drawer.py b/tests/platform_tests/api/test_fan_drawer.py index f9b67de1cd4..3baf54d029b 100644 --- a/tests/platform_tests/api/test_fan_drawer.py +++ b/tests/platform_tests/api/test_fan_drawer.py @@ -3,6 +3,7 @@ import pytest from tests.common.helpers.platform_api import chassis, fan_drawer +from tests.common.platform.device_utils import platform_api_conn # noqa F401 from .platform_api_test_base import PlatformApiTestBase @@ -39,7 +40,7 @@ class TestFanDrawerApi(PlatformApiTestBase): # it relies on the platform_api_conn fixture, which is scoped at the function # level, so we must do the same here to prevent a scope mismatch. @pytest.fixture(scope="function", autouse=True) - def setup(self, duthost, platform_api_conn): + def setup(self, duthost, platform_api_conn): # noqa F811 if self.num_fan_drawers is None: try: self.num_fan_drawers = int(chassis.get_num_fan_drawers(platform_api_conn)) @@ -87,7 +88,7 @@ def get_fan_drawer_facts(self, duthost, fan_drawer_idx, def_value, *keys): # # Functions to test methods inherited from DeviceBase class # - def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] for i in range(self.num_fan_drawers): name = fan_drawer.get_name(platform_api_conn, i) @@ -98,7 +99,7 @@ def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, p self.assert_expectations() - def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): presence = fan_drawer.get_presence(platform_api_conn, i) @@ -108,7 +109,7 @@ def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos self.assert_expectations() - def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): model = fan_drawer.get_model(platform_api_conn, i) @@ -117,7 +118,7 @@ def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): serial = fan_drawer.get_serial(platform_api_conn, i) @@ -126,7 +127,7 @@ def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): status = fan_drawer.get_status(platform_api_conn, i) @@ -135,7 +136,7 @@ def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_position_in_parent(self, platform_api_conn): + def test_get_position_in_parent(self, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): position = fan_drawer.get_position_in_parent(platform_api_conn, i) if self.expect(position is not None, @@ -144,7 +145,7 @@ def test_get_position_in_parent(self, platform_api_conn): "Position value must be an integer value for fan drawer {}".format(i)) self.assert_expectations() - def test_is_replaceable(self, platform_api_conn): + def test_is_replaceable(self, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): replaceable = fan_drawer.is_replaceable(platform_api_conn, i) if self.expect(replaceable is not None, "Failed to perform is_replaceable for fan drawer {}".format(i)): @@ -155,7 +156,7 @@ def test_is_replaceable(self, platform_api_conn): # # Functions to test methods defined in Fan_drawerBase class # - def test_get_num_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_num_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] for i in range(self.num_fan_drawers): @@ -166,7 +167,7 @@ def test_get_num_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos self.compare_value_with_platform_facts(duthost, 'num_fans', num_fans, i) self.assert_expectations() - def test_get_all_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_all_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_fan_drawers): fans_list = fan_drawer.get_all_fans(platform_api_conn, i) @@ -175,7 +176,8 @@ def test_get_all_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos "fan drawer {} list of fans appear to be incorrect".format(i)) self.assert_expectations() - def test_set_fan_drawers_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_set_fan_drawers_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] FAULT_LED_COLOR_LIST = [ @@ -253,7 +255,7 @@ def test_set_fan_drawers_led(self, duthosts, enum_rand_one_per_hwsku_hostname, l self.assert_expectations() def test_get_maximum_consumed_power(self, duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn): + localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] max_power_skipped = 0 diff --git a/tests/platform_tests/api/test_psu.py b/tests/platform_tests/api/test_psu.py index b9ad83b1ea2..d20298a6a7d 100644 --- a/tests/platform_tests/api/test_psu.py +++ b/tests/platform_tests/api/test_psu.py @@ -7,6 +7,7 @@ from tests.platform_tests.cli.util import get_skip_mod_list from .platform_api_test_base import PlatformApiTestBase from tests.common.utilities import skip_release_for_platform, wait_until +from tests.common.platform.device_utils import platform_api_conn # noqa F401 ################################################### @@ -41,7 +42,7 @@ class TestPsuApi(PlatformApiTestBase): chassis_facts = None @pytest.fixture(scope="function", autouse=True) - def setup(self, platform_api_conn, duthosts, enum_rand_one_per_hwsku_hostname): + def setup(self, platform_api_conn, duthosts, enum_rand_one_per_hwsku_hostname): # noqa F811 if self.num_psus is None: try: self.num_psus = int(chassis.get_num_psus(platform_api_conn)) @@ -82,7 +83,7 @@ def get_psu_facts(self, duthost, psu_idx, def_value, *keys): return def_value - def skip_absent_psu(self, psu_num, platform_api_conn): + def skip_absent_psu(self, psu_num, platform_api_conn): # noqa F811 name = psu.get_name(platform_api_conn, psu_num) if name in self.psu_skip_list: logger.info("Skipping PSU {} since it is part of psu_skip_list".format(name)) @@ -103,7 +104,7 @@ def get_psu_parameter(self, psu_info, psu_parameter, get_data, message): # Functions to test methods inherited from DeviceBase class # - def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] for i in range(self.num_psus): if self.skip_absent_psu(i, platform_api_conn): @@ -114,7 +115,7 @@ def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, p self.compare_value_with_platform_facts(duthost, 'name', name, i) self.assert_expectations() - def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_psus): presence = psu.get_presence(platform_api_conn, i) name = psu.get_name(platform_api_conn, i) @@ -127,7 +128,7 @@ def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos # that the psu is not present when in the skip list self.assert_expectations() - def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_psus): if self.skip_absent_psu(i, platform_api_conn): continue @@ -136,7 +137,7 @@ def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.expect(isinstance(model, STRING_TYPE), "PSU {} model appears incorrect".format(i)) self.assert_expectations() - def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_psus): if self.skip_absent_psu(i, platform_api_conn): continue @@ -145,7 +146,7 @@ def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.expect(isinstance(serial, STRING_TYPE), "PSU {} serial number appears incorrect".format(i)) self.assert_expectations() - def test_get_revision(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_revision(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release(duthost, ["201811", "201911", "202012"]) for i in range(self.num_psus): @@ -156,7 +157,7 @@ def test_get_revision(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos self.expect(isinstance(revision, STRING_TYPE), "PSU {} serial number appears incorrect".format(i)) self.assert_expectations() - def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for i in range(self.num_psus): if self.skip_absent_psu(i, platform_api_conn): continue @@ -165,7 +166,7 @@ def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.expect(isinstance(status, bool), "PSU {} status appears incorrect".format(i)) self.assert_expectations() - def test_get_position_in_parent(self, platform_api_conn): + def test_get_position_in_parent(self, platform_api_conn): # noqa F811 for psu_id in range(self.num_psus): if self.skip_absent_psu(psu_id, platform_api_conn): continue @@ -176,7 +177,7 @@ def test_get_position_in_parent(self, platform_api_conn): "Position value must be an integer value for psu id {}".format(psu_id)) self.assert_expectations() - def test_is_replaceable(self, platform_api_conn): + def test_is_replaceable(self, platform_api_conn): # noqa F811 for psu_id in range(self.num_psus): if self.skip_absent_psu(psu_id, platform_api_conn): continue @@ -191,7 +192,7 @@ def test_is_replaceable(self, platform_api_conn): # Functions to test methods defined in PsuBase class # - def test_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 ''' PSU fan test ''' for psu_id in range(self.num_psus): try: @@ -210,7 +211,7 @@ def test_fans(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platf self.expect(fan and fan == fan_list[i], "Fan {} of PSU {} is incorrect".format(i, psu_id)) self.assert_expectations() - def test_power(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_power(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 ''' PSU power test ''' duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["arista"]) @@ -271,7 +272,7 @@ def check_psu_power(failure_count): self.assert_expectations() - def test_temperature(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_temperature(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 ''' PSU temperature test ''' duthost = duthosts[enum_rand_one_per_hwsku_hostname] skip_release_for_platform(duthost, ["202012", "201911", "201811"], ["arista"]) @@ -306,7 +307,7 @@ def test_temperature(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost self.assert_expectations() - def test_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 ''' PSU status led test ''' duthost = duthosts[enum_rand_one_per_hwsku_hostname] FAULT_LED_COLOR_LIST = [ @@ -397,7 +398,7 @@ def test_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platfo self.assert_expectations() - def test_thermals(self, platform_api_conn): + def test_thermals(self, platform_api_conn): # noqa F811 for psu_id in range(self.num_psus): if self.skip_absent_psu(psu_id, platform_api_conn): continue @@ -418,7 +419,7 @@ def test_thermals(self, platform_api_conn): self.assert_expectations() - def test_master_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_master_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] FAULT_LED_COLOR_LIST = [ STATUS_LED_COLOR_AMBER, diff --git a/tests/platform_tests/api/test_psu_fans.py b/tests/platform_tests/api/test_psu_fans.py index f348ecb40a8..cc3e2bdc084 100644 --- a/tests/platform_tests/api/test_psu_fans.py +++ b/tests/platform_tests/api/test_psu_fans.py @@ -5,6 +5,7 @@ import pytest from tests.common.helpers.platform_api import chassis, psu, psu_fan +from tests.common.platform.device_utils import platform_api_conn # noqa F401 from .platform_api_test_base import PlatformApiTestBase @@ -46,7 +47,7 @@ class TestPsuFans(PlatformApiTestBase): # level, so we must do the same here to prevent a scope mismatch. @pytest.fixture(scope="function", autouse=True) - def setup(self, platform_api_conn): + def setup(self, platform_api_conn): # noqa F811 if self.num_psus is None: try: self.num_psus = chassis.get_num_psus(platform_api_conn) @@ -96,7 +97,7 @@ def get_fan_facts(self, duthost, psu_idx, fan_idx, def_value, *keys): # # Functions to test methods inherited from DeviceBase class # - def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) @@ -133,8 +134,7 @@ def test_get_name(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, p self.assert_expectations() - def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) @@ -150,8 +150,7 @@ def test_get_presence(self, duthosts, enum_rand_one_per_hwsku_hostname, localhos self.assert_expectations() - def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) @@ -163,8 +162,7 @@ def test_get_model(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) @@ -177,8 +175,7 @@ def test_get_serial(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) @@ -190,7 +187,7 @@ def test_get_status(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_position_in_parent(self, platform_api_conn): + def test_get_position_in_parent(self, platform_api_conn): # noqa F811 for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) for i in range(num_fans): @@ -201,7 +198,7 @@ def test_get_position_in_parent(self, platform_api_conn): "Position value must be an integer value for PSU {} fan {}".format(j, i)) self.assert_expectations() - def test_is_replaceable(self, platform_api_conn): + def test_is_replaceable(self, platform_api_conn): # noqa F811 for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) for i in range(num_fans): @@ -217,7 +214,7 @@ def test_is_replaceable(self, platform_api_conn): # Functions to test methods defined in FanBase class # - def test_get_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] for j in range(self.num_psus): num_fans = psu.get_num_fans(platform_api_conn, j) @@ -236,7 +233,7 @@ def test_get_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, self.assert_expectations() - def test_get_direction(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_get_direction(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 # Ensure the fan speed is sane FAN_DIRECTION_LIST = [ "intake", @@ -255,8 +252,8 @@ def test_get_direction(self, duthosts, enum_rand_one_per_hwsku_hostname, localho self.assert_expectations() - def test_get_fans_target_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_get_fans_target_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] psus_skipped = 0 @@ -296,8 +293,7 @@ def test_get_fans_target_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, self.assert_expectations() - def test_set_fans_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): - + def test_set_fans_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 duthost = duthosts[enum_rand_one_per_hwsku_hostname] psus_skipped = 0 @@ -338,7 +334,7 @@ def test_set_fans_speed(self, duthosts, enum_rand_one_per_hwsku_hostname, localh self.assert_expectations() - def test_set_fans_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): + def test_set_fans_led(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn): # noqa F811 LED_COLOR_LIST = [ "off", "red", diff --git a/tests/platform_tests/api/test_watchdog.py b/tests/platform_tests/api/test_watchdog.py index 73147b5b8a2..7a79ce9f246 100644 --- a/tests/platform_tests/api/test_watchdog.py +++ b/tests/platform_tests/api/test_watchdog.py @@ -6,6 +6,7 @@ import pytest from tests.common.helpers.platform_api import watchdog from tests.common.helpers.assertions import pytest_assert +from tests.common.platform.device_utils import platform_api_conn # noqa F401 from .platform_api_test_base import PlatformApiTestBase from collections import OrderedDict @@ -40,7 +41,7 @@ class TestWatchdogApi(PlatformApiTestBase): ''' Hardware watchdog platform API test cases ''' @pytest.fixture(scope='function', autouse=True) - def watchdog_not_running(self, platform_api_conn, duthosts, enum_rand_one_per_hwsku_hostname): + def watchdog_not_running(self, platform_api_conn, duthosts, enum_rand_one_per_hwsku_hostname): # noqa F811 ''' Fixture that automatically runs on each test case and verifies that watchdog is not running before the test begins and disables it after the test ends''' @@ -92,7 +93,8 @@ def conf(self, request, duthosts, enum_rand_one_per_hwsku_hostname): return config @pytest.mark.dependency() - def test_arm_disarm_states(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, platform_api_conn, conf): + def test_arm_disarm_states(self, duthosts, enum_rand_one_per_hwsku_hostname, localhost, + platform_api_conn, conf): # noqa F811 ''' arm watchdog with a valid timeout value, verify it is in armed state, disarm watchdog and verify it is in disarmed state ''' @@ -139,7 +141,7 @@ def test_arm_disarm_states(self, duthosts, enum_rand_one_per_hwsku_hostname, loc self.assert_expectations() @pytest.mark.dependency(depends=["test_arm_disarm_states"]) - def test_remaining_time(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): + def test_remaining_time(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): # noqa F811 ''' arm watchdog with a valid timeout and verify that remaining time API works correctly ''' watchdog_timeout = conf['valid_timeout'] @@ -168,7 +170,7 @@ def test_remaining_time(self, duthosts, enum_rand_one_per_hwsku_hostname, platfo self.assert_expectations() @pytest.mark.dependency(depends=["test_arm_disarm_states"]) - def test_periodic_arm(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): + def test_periodic_arm(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): # noqa F811 ''' arm watchdog several times as watchdog deamon would and verify API behaves correctly ''' watchdog_timeout = conf['valid_timeout'] @@ -190,7 +192,8 @@ def test_periodic_arm(self, duthosts, enum_rand_one_per_hwsku_hostname, platform self.assert_expectations() @pytest.mark.dependency(depends=["test_arm_disarm_states"]) - def test_arm_different_timeout_greater(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): + def test_arm_different_timeout_greater(self, duthosts, enum_rand_one_per_hwsku_hostname, + platform_api_conn, conf): # noqa F811 ''' arm the watchdog with greater timeout value and verify new timeout was accepted; If platform accepts only single valid timeout value, @greater_timeout should be None. ''' @@ -212,7 +215,8 @@ def test_arm_different_timeout_greater(self, duthosts, enum_rand_one_per_hwsku_h self.assert_expectations() @pytest.mark.dependency(depends=["test_arm_disarm_states"]) - def test_arm_different_timeout_smaller(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): + def test_arm_different_timeout_smaller(self, duthosts, enum_rand_one_per_hwsku_hostname, + platform_api_conn, conf): # noqa F811 ''' arm the watchdog with smaller timeout value and verify new timeout was accepted; If platform accepts only single valid timeout value, @greater_timeout should be None. ''' @@ -235,7 +239,8 @@ def test_arm_different_timeout_smaller(self, duthosts, enum_rand_one_per_hwsku_h self.assert_expectations() @pytest.mark.dependency(depends=["test_arm_disarm_states"]) - def test_arm_too_big_timeout(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn, conf): + def test_arm_too_big_timeout(self, duthosts, enum_rand_one_per_hwsku_hostname, + platform_api_conn, conf): # noqa F811 ''' try to arm the watchdog with timeout that is too big for hardware watchdog; If no such limitation exist, @too_big_timeout should be None for such platform. ''' @@ -249,7 +254,7 @@ def test_arm_too_big_timeout(self, duthosts, enum_rand_one_per_hwsku_hostname, p self.assert_expectations() @pytest.mark.dependency(depends=["test_arm_disarm_states"]) - def test_arm_negative_timeout(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn): + def test_arm_negative_timeout(self, duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn): # noqa F811 ''' try to arm the watchdog with negative value ''' watchdog_timeout = -1 diff --git a/tests/smartswitch/common/device_utils_dpu.py b/tests/smartswitch/common/device_utils_dpu.py index 9b80882dd66..b75335428e0 100644 --- a/tests/smartswitch/common/device_utils_dpu.py +++ b/tests/smartswitch/common/device_utils_dpu.py @@ -4,14 +4,14 @@ import logging import pytest from tests.common.devices.sonic import * # noqa: F401,F403 -from tests.platform_tests.api.conftest import * # noqa: F401,F403 +from tests.common.platform.device_utils import platform_api_conn # noqa: F401,F403 from tests.common.helpers.platform_api import chassis, module from tests.common.utilities import wait_until from tests.common.helpers.assertions import pytest_assert @pytest.fixture(scope='function') -def num_dpu_modules(platform_api_conn): +def num_dpu_modules(platform_api_conn): # noqa F811 """ Returns the number of DPU modules """ @@ -23,9 +23,8 @@ def num_dpu_modules(platform_api_conn): @pytest.fixture(scope='function', autouse=True) -def check_smartswitch_and_dark_mode(duthosts, - enum_rand_one_per_hwsku_hostname, - platform_api_conn, num_dpu_modules): +def check_smartswitch_and_dark_mode(duthosts, enum_rand_one_per_hwsku_hostname, + platform_api_conn, num_dpu_modules): # noqa F811 """ Checks whether given testbed is running 202405 image or below versions @@ -40,14 +39,13 @@ def check_smartswitch_and_dark_mode(duthosts, if "DPUS" not in duthost.facts: pytest.skip("Test is not supported for this testbed") - darkmode = is_dark_mode_enabled(duthost, platform_api_conn, - num_dpu_modules) + darkmode = is_dark_mode_enabled(duthost, platform_api_conn, num_dpu_modules) # noqa F811 if darkmode: dpu_power_on(duthost, platform_api_conn, num_dpu_modules) -def is_dark_mode_enabled(duthost, platform_api_conn, num_dpu_modules): +def is_dark_mode_enabled(duthost, platform_api_conn, num_dpu_modules): # noqa F811 """ Checks the liveliness of DPU Returns: @@ -76,7 +74,7 @@ def is_dark_mode_enabled(duthost, platform_api_conn, num_dpu_modules): return False -def dpu_power_on(duthost, platform_api_conn, num_dpu_modules): +def dpu_power_on(duthost, platform_api_conn, num_dpu_modules): # noqa F811 """ Executes power on all DPUs Returns: diff --git a/tests/smartswitch/platform_tests/test_reload_dpu.py b/tests/smartswitch/platform_tests/test_reload_dpu.py index 1e8e7518f33..ac97d435b91 100644 --- a/tests/smartswitch/platform_tests/test_reload_dpu.py +++ b/tests/smartswitch/platform_tests/test_reload_dpu.py @@ -14,7 +14,7 @@ from tests.common.config_reload import config_force_option_supported, config_system_checks_passed # noqa: F401, E501 from tests.smartswitch.common.device_utils_dpu import * # noqa: F401,F403,E501 from tests.common.helpers.platform_api import chassis, module # noqa: F401 -from tests.platform_tests.api.conftest import * # noqa: F401,F403 +from tests.common.platform.device_utils import platform_api_conn # noqa: F401,F403 pytestmark = [ pytest.mark.topology('smartswitch') @@ -22,8 +22,7 @@ def test_dpu_ping_after_reboot(duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn, - num_dpu_modules): + localhost, platform_api_conn, num_dpu_modules): # noqa F811 """ @summary: Verify output of `config chassis modules startup ` """ @@ -52,8 +51,7 @@ def test_dpu_ping_after_reboot(duthosts, enum_rand_one_per_hwsku_hostname, def test_show_ping_int_after_reload(duthosts, enum_rand_one_per_hwsku_hostname, - localhost, platform_api_conn, - num_dpu_modules): + localhost, platform_api_conn, num_dpu_modules): # noqa F811 """ @summary: To Check Ping between NPU and DPU after configuration reload on NPU diff --git a/tests/smartswitch/platform_tests/test_show_platform_dpu.py b/tests/smartswitch/platform_tests/test_show_platform_dpu.py index 5049975b67d..74951e9826a 100644 --- a/tests/smartswitch/platform_tests/test_show_platform_dpu.py +++ b/tests/smartswitch/platform_tests/test_show_platform_dpu.py @@ -8,7 +8,7 @@ from tests.common.helpers.assertions import pytest_assert from tests.smartswitch.common.device_utils_dpu import * # noqa: F403,F401,E501 from tests.common.helpers.platform_api import chassis, module # noqa: F401 -from tests.platform_tests.api.conftest import * # noqa: F401,F403 +from tests.common.platform.device_utils import platform_api_conn # noqa: F401,F403 from tests.common.devices.sonic import * # noqa: 403 pytestmark = [ @@ -16,8 +16,7 @@ ] -def test_midplane_ip(duthosts, enum_rand_one_per_hwsku_hostname, - platform_api_conn): +def test_midplane_ip(duthosts, enum_rand_one_per_hwsku_hostname, platform_api_conn): # noqa F811 """ @summary: Verify `Midplane ip address between NPU and DPU` """ @@ -39,7 +38,7 @@ def test_midplane_ip(duthosts, enum_rand_one_per_hwsku_hostname, def test_shutdown_power_up_dpu(duthosts, enum_rand_one_per_hwsku_hostname, - platform_api_conn, num_dpu_modules): + platform_api_conn, num_dpu_modules): # noqa F811 """ @summary: Verify `shut down and power up DPU` """ @@ -63,7 +62,7 @@ def test_shutdown_power_up_dpu(duthosts, enum_rand_one_per_hwsku_hostname, def test_reboot_cause(duthosts, enum_rand_one_per_hwsku_hostname, - platform_api_conn, num_dpu_modules): + platform_api_conn, num_dpu_modules): # noqa F811 """ @summary: Verify `Reboot Cause` """ @@ -88,7 +87,7 @@ def test_reboot_cause(duthosts, enum_rand_one_per_hwsku_hostname, def test_pcie_link(duthosts, enum_rand_one_per_hwsku_hostname, - platform_api_conn, num_dpu_modules): + platform_api_conn, num_dpu_modules): # noqa F811 """ @summary: Verify `PCIe link` """ From 2b39717753542e5a6337131ed8292eed87bd053d Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:48:03 +0800 Subject: [PATCH 214/221] Move the shared part in snappi to common place. (#15604) What is the motivation for this PR? Previously, there are some shared variables and scripts which were located in the feature-specific folder snappi_tests and were imported by the common scripts. To reduce cross-feature dependencies and improve modularity, I relocated them directly to the common path tests/common/snappi_tests. How did you do it? I relocated the shared part under folder snappi directly to the common path tests/common/snappi_tests. --- .../snappi_tests}/cisco_pfc_packet.py | 0 tests/common/snappi_tests/read_pcap.py | 2 +- tests/common/snappi_tests/snappi_fixtures.py | 5 ++--- .../common/snappi_tests/traffic_generation.py | 2 +- tests/common/snappi_tests/variables.py | 17 +++++++++++++++++ .../multidut/bgp/files/bgp_outbound_helper.py | 3 ++- ...response_to_external_pause_storms_helper.py | 2 +- ...sponse_to_throttling_pause_storms_helper.py | 2 +- .../files/m2o_fluctuating_lossless_helper.py | 2 +- .../files/m2o_oversubscribe_lossless_helper.py | 2 +- .../m2o_oversubscribe_lossless_lossy_helper.py | 2 +- .../files/m2o_oversubscribe_lossy_helper.py | 2 +- ...less_response_to_throttling_pause_storms.py | 2 +- .../test_m2o_oversubscribe_lossless_lossy.py | 2 +- .../pfcwd/files/pfcwd_multidut_basic_helper.py | 2 +- .../files/pfcwd_multidut_burst_storm_helper.py | 2 +- .../files/pfcwd_multidut_multi_node_helper.py | 2 +- .../pfcwd_multidut_runtime_traffic_helper.py | 2 +- .../pfcwd/files/pfcwd_basic_helper.py | 2 +- .../pfcwd/files/pfcwd_burst_storm_helper.py | 2 +- .../pfcwd/files/pfcwd_multi_node_helper.py | 2 +- .../files/pfcwd_runtime_traffic_helper.py | 2 +- tests/snappi_tests/variables.py | 18 ------------------ 23 files changed, 39 insertions(+), 40 deletions(-) rename tests/{snappi_tests/pfc/files => common/snappi_tests}/cisco_pfc_packet.py (100%) create mode 100644 tests/common/snappi_tests/variables.py diff --git a/tests/snappi_tests/pfc/files/cisco_pfc_packet.py b/tests/common/snappi_tests/cisco_pfc_packet.py similarity index 100% rename from tests/snappi_tests/pfc/files/cisco_pfc_packet.py rename to tests/common/snappi_tests/cisco_pfc_packet.py diff --git a/tests/common/snappi_tests/read_pcap.py b/tests/common/snappi_tests/read_pcap.py index f0a522b9576..fd93b27a420 100644 --- a/tests/common/snappi_tests/read_pcap.py +++ b/tests/common/snappi_tests/read_pcap.py @@ -3,7 +3,7 @@ from dpkt.utils import mac_to_str from tests.common.snappi_tests.pfc_packet import PFCPacket -from tests.snappi_tests.pfc.files.cisco_pfc_packet import CiscoPFCPacket +from tests.common.snappi_tests.cisco_pfc_packet import CiscoPFCPacket logger = logging.getLogger(__name__) diff --git a/tests/common/snappi_tests/snappi_fixtures.py b/tests/common/snappi_tests/snappi_fixtures.py index 6b268b3e409..300fce365ab 100755 --- a/tests/common/snappi_tests/snappi_fixtures.py +++ b/tests/common/snappi_tests/snappi_fixtures.py @@ -16,9 +16,8 @@ from tests.common.snappi_tests.snappi_helpers import SnappiFanoutManager, get_snappi_port_location from tests.common.snappi_tests.port import SnappiPortConfig, SnappiPortType from tests.common.helpers.assertions import pytest_assert -from tests.snappi_tests.variables import dut_ip_start, snappi_ip_start, prefix_length, \ - dut_ipv6_start, snappi_ipv6_start, v6_prefix_length, pfcQueueGroupSize, \ - pfcQueueValueDict # noqa: F401 +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict, dut_ip_start, snappi_ip_start, \ + prefix_length, dut_ipv6_start, snappi_ipv6_start, v6_prefix_length logger = logging.getLogger(__name__) diff --git a/tests/common/snappi_tests/traffic_generation.py b/tests/common/snappi_tests/traffic_generation.py index 005f53c0a00..49b21d08f35 100644 --- a/tests/common/snappi_tests/traffic_generation.py +++ b/tests/common/snappi_tests/traffic_generation.py @@ -11,7 +11,7 @@ traffic_flow_mode from tests.common.snappi_tests.port import select_ports, select_tx_port from tests.common.snappi_tests.snappi_helpers import wait_for_arp, fetch_snappi_flow_metrics -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from .variables import pfcQueueGroupSize, pfcQueueValueDict from tests.common.cisco_data import is_cisco_device logger = logging.getLogger(__name__) diff --git a/tests/common/snappi_tests/variables.py b/tests/common/snappi_tests/variables.py new file mode 100644 index 00000000000..e1b821141bb --- /dev/null +++ b/tests/common/snappi_tests/variables.py @@ -0,0 +1,17 @@ +pfcQueueGroupSize = 8 # can have values 4 or 8 +pfcQueueValueDict = {0: 0, + 1: 1, + 2: 0, + 3: 3, + 4: 2, + 5: 0, + 6: 1, + 7: 0} + +dut_ip_start = '20.1.1.0' +snappi_ip_start = '20.1.1.1' +prefix_length = 31 + +dut_ipv6_start = '2000:1::1' +snappi_ipv6_start = '2000:1::2' +v6_prefix_length = 126 diff --git a/tests/snappi_tests/multidut/bgp/files/bgp_outbound_helper.py b/tests/snappi_tests/multidut/bgp/files/bgp_outbound_helper.py index b77345db203..12de5bafbc7 100755 --- a/tests/snappi_tests/multidut/bgp/files/bgp_outbound_helper.py +++ b/tests/snappi_tests/multidut/bgp/files/bgp_outbound_helper.py @@ -14,13 +14,14 @@ from tests.common.helpers.assertions import pytest_assert # noqa: F401 from tests.common.snappi_tests.snappi_fixtures import create_ip_list # noqa: F401 from tests.snappi_tests.variables import T1_SNAPPI_AS_NUM, T2_SNAPPI_AS_NUM, T1_DUT_AS_NUM, T2_DUT_AS_NUM, t1_ports, \ - t2_uplink_portchannel_members, t1_t2_dut_ipv4_list, v4_prefix_length, v6_prefix_length, \ + t2_uplink_portchannel_members, t1_t2_dut_ipv4_list, v4_prefix_length, \ t1_t2_dut_ipv6_list, t1_t2_snappi_ipv4_list, portchannel_count, \ t1_t2_snappi_ipv6_list, t2_dut_portchannel_ipv4_list, t2_dut_portchannel_ipv6_list, \ snappi_portchannel_ipv4_list, snappi_portchannel_ipv6_list, AS_PATHS, \ BGP_TYPE, t1_side_interconnected_port, t2_side_interconnected_port, router_ids, \ snappi_community_for_t1, snappi_community_for_t2, SNAPPI_TRIGGER, DUT_TRIGGER, \ fanout_presence, t2_uplink_fanout_info # noqa: F401 +from tests.common.snappi_tests.variables import v6_prefix_length logger = logging.getLogger(__name__) total_routes = 0 diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py index fb139f3f255..5237c2c6cdf 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py @@ -15,7 +15,7 @@ from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import run_traffic, verify_pause_flow, \ setup_base_traffic_config # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) TEST_FLOW_NAME = 'Test Flow' diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py index b177fd58282..3177d527525 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py @@ -16,7 +16,7 @@ from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import run_traffic, verify_pause_flow, \ setup_base_traffic_config # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py index 5da4ec7d6bf..f8a097de2e2 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py @@ -10,7 +10,7 @@ from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import run_traffic, \ setup_base_traffic_config # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) PAUSE_FLOW_NAME = 'Pause Storm' diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py index 3f34d6a341b..b3b79f86862 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py @@ -15,7 +15,7 @@ from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import setup_base_traffic_config, \ run_traffic # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) PAUSE_FLOW_NAME = 'Pause Storm' diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py index 302ea6b852a..5696454ddc3 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py @@ -15,7 +15,7 @@ from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import run_traffic, \ setup_base_traffic_config # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict from tests.common.portstat_utilities import parse_portstat # noqa: F401 logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py index 9bacdc7ade5..d60ca4ecca8 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py @@ -15,7 +15,7 @@ from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.common.snappi_tests.traffic_generation import setup_base_traffic_config, \ run_traffic # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) PAUSE_FLOW_NAME = 'Pause Storm' diff --git a/tests/snappi_tests/multidut/pfc/test_lossless_response_to_throttling_pause_storms.py b/tests/snappi_tests/multidut/pfc/test_lossless_response_to_throttling_pause_storms.py index 443f25a7ec7..3af2d58a702 100644 --- a/tests/snappi_tests/multidut/pfc/test_lossless_response_to_throttling_pause_storms.py +++ b/tests/snappi_tests/multidut/pfc/test_lossless_response_to_throttling_pause_storms.py @@ -13,7 +13,7 @@ from tests.snappi_tests.multidut.pfc.files.lossless_response_to_throttling_pause_storms_helper import ( run_lossless_response_to_throttling_pause_storms_test) from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict # noqa: F401 +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict # noqa: F401 logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] diff --git a/tests/snappi_tests/multidut/pfc/test_m2o_oversubscribe_lossless_lossy.py b/tests/snappi_tests/multidut/pfc/test_m2o_oversubscribe_lossless_lossy.py index 19321a14edd..e1200d5c1e9 100644 --- a/tests/snappi_tests/multidut/pfc/test_m2o_oversubscribe_lossless_lossy.py +++ b/tests/snappi_tests/multidut/pfc/test_m2o_oversubscribe_lossless_lossy.py @@ -14,7 +14,7 @@ run_pfc_m2o_oversubscribe_lossless_lossy_test ) # noqa: F401 from tests.common.snappi_tests.snappi_test_params import SnappiTestParams # noqa: F401 -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict # noqa: F401 +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict # noqa: F401 logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] diff --git a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_basic_helper.py b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_basic_helper.py index 93995f72bda..8e4b33ccc7c 100644 --- a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_basic_helper.py +++ b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_basic_helper.py @@ -12,7 +12,7 @@ from tests.common.snappi_tests.port import select_ports, select_tx_port # noqa: F401 from tests.common.snappi_tests.snappi_helpers import wait_for_arp # noqa: F401 from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py index daa2048a2af..afa8feff005 100644 --- a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py +++ b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_burst_storm_helper.py @@ -10,7 +10,7 @@ from tests.common.snappi_tests.port import select_ports, select_tx_port # noqa: F401 from tests.common.snappi_tests.snappi_helpers import wait_for_arp from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_multi_node_helper.py b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_multi_node_helper.py index f1e4fd6f2c9..6a15b795db1 100644 --- a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_multi_node_helper.py +++ b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_multi_node_helper.py @@ -12,7 +12,7 @@ from tests.common.snappi_tests.port import select_ports # noqa: F401 from tests.common.snappi_tests.snappi_helpers import wait_for_arp # noqa: F401 from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_runtime_traffic_helper.py b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_runtime_traffic_helper.py index 8e97d4f62df..f92ad44f9ae 100644 --- a/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_runtime_traffic_helper.py +++ b/tests/snappi_tests/multidut/pfcwd/files/pfcwd_multidut_runtime_traffic_helper.py @@ -8,7 +8,7 @@ from tests.common.snappi_tests.port import select_ports, select_tx_port # noqa: F401 from tests.common.snappi_tests.snappi_helpers import wait_for_arp from tests.common.snappi_tests.snappi_test_params import SnappiTestParams -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict DATA_FLOW_NAME = "Data Flow" DATA_PKT_SIZE = 1024 diff --git a/tests/snappi_tests/pfcwd/files/pfcwd_basic_helper.py b/tests/snappi_tests/pfcwd/files/pfcwd_basic_helper.py index da163989f58..ea1abc8458c 100644 --- a/tests/snappi_tests/pfcwd/files/pfcwd_basic_helper.py +++ b/tests/snappi_tests/pfcwd/files/pfcwd_basic_helper.py @@ -11,7 +11,7 @@ enable_packet_aging, start_pfcwd, sec_to_nanosec from tests.common.snappi_tests.port import select_ports, select_tx_port from tests.common.snappi_tests.snappi_helpers import wait_for_arp -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/pfcwd/files/pfcwd_burst_storm_helper.py b/tests/snappi_tests/pfcwd/files/pfcwd_burst_storm_helper.py index d6f9a18f2d2..a13a20fe74a 100644 --- a/tests/snappi_tests/pfcwd/files/pfcwd_burst_storm_helper.py +++ b/tests/snappi_tests/pfcwd/files/pfcwd_burst_storm_helper.py @@ -9,7 +9,7 @@ enable_packet_aging, start_pfcwd, sec_to_nanosec from tests.common.snappi_tests.port import select_ports, select_tx_port from tests.common.snappi_tests.snappi_helpers import wait_for_arp -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/pfcwd/files/pfcwd_multi_node_helper.py b/tests/snappi_tests/pfcwd/files/pfcwd_multi_node_helper.py index 4cdfe5b7228..e6aeb6202be 100644 --- a/tests/snappi_tests/pfcwd/files/pfcwd_multi_node_helper.py +++ b/tests/snappi_tests/pfcwd/files/pfcwd_multi_node_helper.py @@ -10,7 +10,7 @@ start_pfcwd, enable_packet_aging, get_pfcwd_poll_interval, get_pfcwd_detect_time, sec_to_nanosec from tests.common.snappi_tests.port import select_ports from tests.common.snappi_tests.snappi_helpers import wait_for_arp -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict logger = logging.getLogger(__name__) diff --git a/tests/snappi_tests/pfcwd/files/pfcwd_runtime_traffic_helper.py b/tests/snappi_tests/pfcwd/files/pfcwd_runtime_traffic_helper.py index 14452d6cc41..832ffc991ea 100644 --- a/tests/snappi_tests/pfcwd/files/pfcwd_runtime_traffic_helper.py +++ b/tests/snappi_tests/pfcwd/files/pfcwd_runtime_traffic_helper.py @@ -6,7 +6,7 @@ from tests.common.snappi_tests.common_helpers import start_pfcwd, stop_pfcwd, sec_to_nanosec from tests.common.snappi_tests.port import select_ports, select_tx_port from tests.common.snappi_tests.snappi_helpers import wait_for_arp -from tests.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict +from tests.common.snappi_tests.variables import pfcQueueGroupSize, pfcQueueValueDict DATA_FLOW_NAME = "Data Flow" WARM_UP_TRAFFIC_NAME = "Warm Up Traffic" diff --git a/tests/snappi_tests/variables.py b/tests/snappi_tests/variables.py index c862c0c2f3b..d63fbfc9880 100644 --- a/tests/snappi_tests/variables.py +++ b/tests/snappi_tests/variables.py @@ -76,24 +76,6 @@ } } -dut_ip_start = '20.1.1.0' -snappi_ip_start = '20.1.1.1' -prefix_length = 31 - -dut_ipv6_start = '2000:1::1' -snappi_ipv6_start = '2000:1::2' -v6_prefix_length = 126 - -pfcQueueGroupSize = 8 # can have values 4 or 8 -pfcQueueValueDict = {0: 0, - 1: 1, - 2: 0, - 3: 3, - 4: 2, - 5: 0, - 6: 1, - 7: 0} - def create_ip_list(value, count, mask=32, incr=0): ''' From 5fbe52f2c88f061115e6f1523eb10690cf96a676 Mon Sep 17 00:00:00 2001 From: rraghav-cisco <58446052+rraghav-cisco@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:44:01 -0800 Subject: [PATCH 215/221] Fixing the import error and KeyError in snappi_test/multidut executions. (#15524) This PR attempts to fix the fixture-not-found error and KeyError that you are seeing in the snappi_test multidut runs. Pls let me know if this works for you. co-authorized by: jianquanye@microsoft.com --- tests/common/snappi_tests/common_helpers.py | 11 +++++++---- tests/snappi_tests/files/helper.py | 5 ++++- ...ssless_response_to_external_pause_storms_helper.py | 2 +- ...less_response_to_throttling_pause_storms_helper.py | 2 +- .../pfc/files/m2o_fluctuating_lossless_helper.py | 2 +- .../pfc/files/m2o_oversubscribe_lossless_helper.py | 2 +- .../files/m2o_oversubscribe_lossless_lossy_helper.py | 2 +- .../pfc/files/m2o_oversubscribe_lossy_helper.py | 2 +- .../pfcwd/test_multidut_pfcwd_basic_with_snappi.py | 6 +++--- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/common/snappi_tests/common_helpers.py b/tests/common/snappi_tests/common_helpers.py index 5521b6c2c97..37fd9454cc2 100644 --- a/tests/common/snappi_tests/common_helpers.py +++ b/tests/common/snappi_tests/common_helpers.py @@ -1137,6 +1137,9 @@ def get_interface_stats(duthost, port): n_out = parse_portstat(duthost.command('portstat -i {}'.format(port))['stdout_lines'])[port] i_stats[duthost.hostname][port] = n_out + for k in ['rx_ok', 'rx_err', 'rx_drp', 'rx_ovr', 'tx_ok', 'tx_err', 'tx_drp', 'tx_ovr']: + i_stats[duthost.hostname][port][k] = int("".join(i_stats[duthost.hostname][port][k].split(','))) + # rx_err, rx_ovr and rx_drp are counted in single counter rx_fail # tx_err, tx_ovr and tx_drp are counted in single counter tx_fail rx_err = ['rx_err', 'rx_ovr', 'rx_drp'] @@ -1144,9 +1147,9 @@ def get_interface_stats(duthost, port): rx_fail = 0 tx_fail = 0 for m in rx_err: - rx_fail = rx_fail + int(n_out[m].replace(',', '')) + rx_fail = rx_fail + n_out[m] for m in tx_err: - tx_fail = tx_fail + int(n_out[m].replace(',', '')) + tx_fail = tx_fail + n_out[m] # Any throughput below 1MBps is measured as 0 for simplicity. thrput = n_out['rx_bps'] @@ -1160,8 +1163,8 @@ def get_interface_stats(duthost, port): else: i_stats[duthost.hostname][port]['rx_thrput_Mbps'] = 0 - i_stats[duthost.hostname][port]['rx_pkts'] = int(n_out['rx_ok'].replace(',', '')) - i_stats[duthost.hostname][port]['tx_pkts'] = int(n_out['tx_ok'].replace(',', '')) + i_stats[duthost.hostname][port]['rx_pkts'] = n_out['rx_ok'] + i_stats[duthost.hostname][port]['tx_pkts'] = n_out['tx_ok'] i_stats[duthost.hostname][port]['rx_fail'] = rx_fail i_stats[duthost.hostname][port]['tx_fail'] = tx_fail diff --git a/tests/snappi_tests/files/helper.py b/tests/snappi_tests/files/helper.py index 44b86b2c5ec..c57f4b4f490 100644 --- a/tests/snappi_tests/files/helper.py +++ b/tests/snappi_tests/files/helper.py @@ -8,6 +8,7 @@ from tests.common.reboot import reboot from tests.common.helpers.parallel import parallel_run from tests.common.utilities import wait_until +from tests.common.platform.interface_utils import check_interface_status_of_up_ports from tests.common.snappi_tests.snappi_fixtures import get_snappi_ports_for_rdma, \ snappi_dut_base_config, is_snappi_multidut @@ -128,17 +129,19 @@ def reboot_duts(setup_ports_and_dut, localhost, request): skip_warm_reboot(snappi_ports[1]['duthost'], reboot_type) def save_config_and_reboot(node, results=None): + up_bgp_neighbors = node.get_bgp_neighbors_per_asic("established") logger.info("Issuing a {} reboot on the dut {}".format(reboot_type, node.hostname)) node.shell("mkdir /etc/sonic/orig_configs; mv /etc/sonic/config_db* /etc/sonic/orig_configs/") node.shell("sudo config save -y") reboot(node, localhost, reboot_type=reboot_type, safe_reboot=True) logger.info("Wait until the system is stable") wait_until(180, 20, 0, node.critical_services_fully_started) + wait_until(180, 20, 0, check_interface_status_of_up_ports, node) + wait_until(300, 10, 0, node.check_bgp_session_state_all_asics, up_bgp_neighbors, "established") # Convert the list of duthosts into a list of tuples as required for parallel func. args = set((snappi_ports[0]['duthost'], snappi_ports[1]['duthost'])) parallel_run(save_config_and_reboot, {}, {}, list(args), timeout=900) - yield def revert_config_and_reload(node, results=None): diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py index 5237c2c6cdf..8830cbbf42f 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_external_pause_storms_helper.py @@ -141,7 +141,7 @@ def run_lossless_response_to_external_pause_storms_test(api, dut_rx_port1 = tx_port[0]['peer_port'] dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[egress_duthost.hostname][dut_tx_port]['tx_drp'] rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets diff --git a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py index 3177d527525..15a0559ca1b 100644 --- a/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/lossless_response_to_throttling_pause_storms_helper.py @@ -148,7 +148,7 @@ def run_lossless_response_to_throttling_pause_storms_test(api, dut_rx_port1 = tx_port[0]['peer_port'] dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[egress_duthost.hostname][dut_tx_port]['tx_drp'] rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py index f8a097de2e2..8dc40c23dfd 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_fluctuating_lossless_helper.py @@ -130,7 +130,7 @@ def run_m2o_fluctuating_lossless_test(api, dut_rx_port1 = tx_port[0]['peer_port'] dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[egress_duthost.hostname][dut_tx_port]['tx_drp'] rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py index b3b79f86862..f3db2766cf6 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_helper.py @@ -133,7 +133,7 @@ def run_m2o_oversubscribe_lossless_test(api, dut_rx_port1 = tx_port[0]['peer_port'] dut_rx_port2 = tx_port[1]['peer_port'] # Fetch relevant statistics - pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[egress_duthost.hostname][dut_tx_port]['tx_drp'] rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py index 5696454ddc3..5dba3c588ec 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossless_lossy_helper.py @@ -138,7 +138,7 @@ def run_pfc_m2o_oversubscribe_lossless_lossy_test(api, dut_rx_port2 = tx_port[1]['peer_port'] dut_tx_port = rx_port['peer_port'] # Fetch relevant statistics - pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[egress_duthost.hostname][dut_tx_port]['tx_drp'] rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets diff --git a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py index d60ca4ecca8..3d7b37a389c 100644 --- a/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py +++ b/tests/snappi_tests/multidut/pfc/files/m2o_oversubscribe_lossy_helper.py @@ -139,7 +139,7 @@ def run_pfc_m2o_oversubscribe_lossy_test(api, dut_rx_port1 = tx_port[0]['peer_port'] dut_rx_port2 = tx_port[1]['peer_port'] - pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[ingress_duthost.hostname][dut_tx_port]['tx_drp'] + pkt_drop = get_interface_stats(egress_duthost, dut_tx_port)[egress_duthost.hostname][dut_tx_port]['tx_drp'] rx_pkts_1 = get_interface_stats(ingress_duthost, dut_rx_port1)[ingress_duthost.hostname][dut_rx_port1]['rx_ok'] rx_pkts_2 = get_interface_stats(ingress_duthost, dut_rx_port2)[ingress_duthost.hostname][dut_rx_port2]['rx_ok'] # Calculate the total received packets diff --git a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py index 9c09f674b45..1584c00fdd6 100644 --- a/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py +++ b/tests/snappi_tests/multidut/pfcwd/test_multidut_pfcwd_basic_with_snappi.py @@ -19,7 +19,7 @@ from tests.snappi_tests.multidut.pfcwd.files.pfcwd_multidut_basic_helper import run_pfcwd_basic_test from tests.common.snappi_tests.snappi_test_params import SnappiTestParams from tests.snappi_tests.files.helper import skip_pfcwd_test, reboot_duts, \ - setup_ports_and_dut # noqa: F401 + setup_ports_and_dut, multidut_port_info # noqa: F401 logger = logging.getLogger(__name__) pytestmark = [pytest.mark.topology('multidut-tgen', 'tgen')] @@ -193,10 +193,10 @@ def test_pfcwd_basic_multi_lossless_prio_reboot(snappi_api, # no conn_graph_facts, # noqa F811 fanout_graph_facts_multidut, # noqa F811 localhost, - duthosts, - enum_dut_lossless_prio_with_completeness_level, # noqa: F811 + lossless_prio_list, # noqa F811 tbinfo, # noqa: F811 prio_dscp_map, # noqa F811 + setup_ports_and_dut, # noqa: F811 reboot_duts, # noqa: F811 trigger_pfcwd): """ From 62e71c7025cd1e5170e74ad00c2ce4b1a7ee7756 Mon Sep 17 00:00:00 2001 From: Chenyang Wang <49756587+cyw233@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:33:19 +1100 Subject: [PATCH 216/221] feat: add parallel run toggle to pipeline (#15667) Description of PR Add parallel run toggle to pipeline definition Summary: Fixes # (issue) Microsoft ADO 29843837 Approach What is the motivation for this PR? We want to enable parallel run via pipeline, so we need to add the parallel run toggle to the pipeline definition co-authorized by: jianquanye@microsoft.com --- .azure-pipelines/run-test-elastictest-template.yml | 5 +++++ .azure-pipelines/test_plan.py | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/.azure-pipelines/run-test-elastictest-template.yml b/.azure-pipelines/run-test-elastictest-template.yml index 4d1092e50eb..c49f927ece0 100644 --- a/.azure-pipelines/run-test-elastictest-template.yml +++ b/.azure-pipelines/run-test-elastictest-template.yml @@ -115,6 +115,10 @@ parameters: type: string default: "" + - name: ENABLE_PARALLEL_RUN + type: string + default: "" + # The number of retries when the script fails. Global retry if retry_cases_include and retry_cases_exclude are both empty, otherwise specific retry - name: RETRY_TIMES type: string @@ -258,6 +262,7 @@ steps: --repo-name ${{ parameters.REPO_NAME }} \ --mgmt-branch ${{ parameters.MGMT_BRANCH }} \ --stop-on-failure ${{ parameters.STOP_ON_FAILURE }} \ + --enable-parallel-run ${{ parameters.ENABLE_PARALLEL_RUN }} \ --retry-times ${{ parameters.RETRY_TIMES }} \ --retry-cases-include ${{ parameters.RETRY_CASES_INCLUDE }} \ --retry-cases-exclude ${{ parameters.RETRY_CASES_EXCLUDE }} \ diff --git a/.azure-pipelines/test_plan.py b/.azure-pipelines/test_plan.py index 4052be78e3d..b339ee05337 100644 --- a/.azure-pipelines/test_plan.py +++ b/.azure-pipelines/test_plan.py @@ -285,6 +285,7 @@ def create(self, topology, test_plan_name="my_test_plan", deploy_mg_extra_params }, "test_option": { "stop_on_failure": kwargs.get("stop_on_failure", True), + "enable_parallel_run": kwargs.get("enable_parallel_run", False), "retry_times": kwargs.get("retry_times", 2), "retry_cases_include": retry_cases_include, "retry_cases_exclude": retry_cases_exclude, @@ -823,6 +824,17 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte choices=[True, False], help="Stop whole test plan if test failed." ) + parser_create.add_argument( + "--enable-parallel-run", + type=ast.literal_eval, + dest="enable_parallel_run", + nargs='?', + const='False', + default='False', + required=False, + choices=[True, False], + help="Enable parallel run or not." + ) parser_create.add_argument( "--retry-times", type=int, @@ -1045,6 +1057,7 @@ def poll(self, test_plan_id, interval=60, timeout=-1, expected_state="", expecte test_plan_type=args.test_plan_type, platform=args.platform, stop_on_failure=args.stop_on_failure, + enable_parallel_run=args.enable_parallel_run, retry_times=args.retry_times, retry_cases_include=args.retry_cases_include, retry_cases_exclude=args.retry_cases_exclude, From 9c2cbd009dad36c75202bdd6e8f5a3b7790a7fe4 Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:03:17 +0800 Subject: [PATCH 217/221] Enforce cross-feature dependency checker in pipeline (#15692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What is the motivation for this PR? In PR #15559, we introduced a checker to identify cross-feature dependencies within our repository. At the time, since some dependencies still existed, the checker was configured to only run the script without enforcing any pipeline failures. Now that all cross-feature dependencies have been eliminated, we’ve updated the checker to capture the script's return value and trigger a pipeline failure if any cross-feature dependencies are detected. How did you do it? We’ve updated the checker to capture the script's return value and trigger a pipeline failure if any cross-feature dependencies are detected. How did you verify/test it? --- .azure-pipelines/dependency-check.yml | 6 +++++- .azure-pipelines/dependency_check/dependency_check.py | 1 + azure-pipelines.yml | 1 - 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/dependency-check.yml b/.azure-pipelines/dependency-check.yml index ea9161927c3..8022c3648b6 100644 --- a/.azure-pipelines/dependency-check.yml +++ b/.azure-pipelines/dependency-check.yml @@ -4,5 +4,9 @@ steps: pip3 install natsort - python3 ./.azure-pipelines/dependency_check/dependency_check.py tests + CHECK_RESULT=$(python3 ./.azure-pipelines/dependency_check/dependency_check.py tests) + if [[ "$CHECK_RESULT" == "True" ]]; then + echo "##vso[task.complete result=Failed;]Condition check failed." + exit 1 + fi displayName: "Dependency Check" diff --git a/.azure-pipelines/dependency_check/dependency_check.py b/.azure-pipelines/dependency_check/dependency_check.py index 17c24a2b35b..fd6ae983b62 100644 --- a/.azure-pipelines/dependency_check/dependency_check.py +++ b/.azure-pipelines/dependency_check/dependency_check.py @@ -205,6 +205,7 @@ def check_cross_dependency(imports_in_script): print("There is a cross-feature dependence. File: {}, import module: {}" .format(file_path, imported_module["module"])) cross_dependency = True + print(cross_dependency) return cross_dependency diff --git a/azure-pipelines.yml b/azure-pipelines.yml index bd19abd9c7a..96c424bc1c5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -46,7 +46,6 @@ stages: - job: dependency_check displayName: "Dependency Check" timeoutInMinutes: 10 - continueOnError: true pool: sonic-common steps: - template: .azure-pipelines/dependency-check.yml From 55962d4e6132646a02e82485c850e59a6294c7c0 Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:10:44 +0800 Subject: [PATCH 218/221] [Bugfix] Add missing conditions for extended entries in `qos/test_buffer.py:` (#15663) Description of PR In #14912, we added conditions for longer matching entries in conditional marks. However, some conditions were missed under the entry qos/test_buffer.py:. This PR adds these missing conditions to entries that start with and extend beyond qos/test_buffer.py: Approach What is the motivation for this PR? In #14912, we added conditions for longer matching entries in conditional marks. However, some conditions were missed under the entry qos/test_buffer.py:. This PR adds these missing conditions to entries that start with and extend beyond qos/test_buffer.py: How did you do it? This PR adds these missing conditions to entries that start with and extend beyond qos/test_buffer.py --- tests/common/plugins/conditional_mark/tests_mark_conditions.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml index 3ed679e9de3..967725fa32a 100644 --- a/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml +++ b/tests/common/plugins/conditional_mark/tests_mark_conditions.yaml @@ -1353,6 +1353,7 @@ qos/test_buffer.py::test_buffer_model_test: conditions_logical_operator: or conditions: - "asic_type in ['mellanox'] or asic_subtype in ['broadcom-dnx']" + - "asic_type in ['cisco-8000'] or 't2' in topo_name" - "topo_type in ['m0', 'mx']" qos/test_buffer_traditional.py: From 21317edaeadda5ca6f637de6f7e214d3ddd6eb56 Mon Sep 17 00:00:00 2001 From: harjotsinghpawra Date: Fri, 22 Nov 2024 02:09:36 -0800 Subject: [PATCH 219/221] test_snmp_queue_counters.py/test_telemetry.py config_reload and snmpwwalk output time delay fix, test_snmp_queue_counters.py multi-asic KeyError fix (#15688) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_snmp_queue_counters.py/test_telemetry.py config_reload and snmpwalk output time delay fix, test_snmp_queue_counters.py multi-asic KeyError fix Description of PR Scripts: test_snmp_queue_counters.py test_telemetry ///////////////////////////////////////////////// First Issue : When we run these scripts sometimes based on the platform and image along with other factors it takes some time for ports to come up and buffer queues to be generated and then further Snmp OID or even gnmi info to be genrated . In script we immediately try to snmpwalk after all docker are up . But interfaces are still not up so no oid is generated . Snmpwalk says No Such Instance currently exists at this OID whihc script count as 1 counter being created when none is created, which causes test case to fail. enum_rand_one_per_hwsku_frontend_hostname = 'mth64-m5-2' get_bfr_queue_cntrs_cmd = 'docker exec snmp snmpwalk -v2c -c public 1.74.23.17 1.3.6.1.4.1.9.9.580.1.5.5.1.4.1' hostip = '1.74.23.17' multicast_expected_diff = 16 queue_counters_cnt_post = 1 queue_counters_cnt_pre = 1 unicast_expected_diff = 8 ["docker exec snmp snmpwalk -v2c -c public 1.74.23.17 1.3.6.1.4.1.9.9.580.1.5.5.1.4.1"], kwargs={} 12:37:54 base._run L0108 �[35mDEBUG �[0m| /data/tests/common/devices/multi_asic.py::_run_on_asics#134: [mth64-m5-2] AnsibleModule::shell Result => {"changed": true, "stdout": "iso.3.6.1.4.1.9.9.580.1.5.5.1.4.1 = No Such Instance currently exists at this OID", "stderr": "", "rc": 0, "cmd": "docker exec snmp snmpwalk -v2c -c public 1.74.23.17 1.3.6.1.4.1.9.9.580.1.5.5.1.4.1", "start": "2024-08-28 12:37:55.343677", "end": "2024-08-28 12:37:55.452104", "delta": "0:00:00.108427", "msg": "", "invocation": {"module_args": {"_raw_params": "docker exec snmp snmpwalk -v2c -c public 1.74.23.17 1.3.6.1.4.1.9.9.580.1.5.5.1.4.1", "_uses_shell": true, "warn": false, "stdin_add_newline": true, "strip_empty_ends": true, "argv": null, "chdir": null, "executable": null, "creates": null, "removes": null, "stdin": null}}, "stdout_lines": ["iso.3.6.1.4.1.9.9.580.1.5.5.1.4.1 = No Such Instance currently exists at this OID"], "stderr_lines": [], "_ansible_no_log": null, "failed": false} ////////////////////////////////////////////////// Second issue : In test_snmp_queue_counters script in multi-asic case we choose a buffer_queue of first interface mentioned in BUFFER_QUEUE config and then we try to match that, also we search asic.namepace in queue name which is invalid check which causes buffer_queue_to_del to be None. This in turn fails the test case by saying that KeyError: None when we try to delete buffer result = testfunction(**testargs) File "/var/src/sonic-mgmt/tests/snmp/test_snmp_queue_counters.py", line 123, in test_snmp_queue_counters del data['BUFFER_QUEUE'][buffer_queue_to_del] KeyError: None Summary: Fixes #15683 and #15686 Approach What is the motivation for this PR? How did you do it? 1.) added necessary checks so that all the interfaces are up and oid's are generated only then take command output. 2.) changed wrong logic of multi asic buffer queue selection and alsoimproved it to work for both single and multi-asic system. 3.) Also added extra check where i match the OID's of counters generated by snmp with queuestat output because they should match queuestat gives the latest information. How did you verify/test it? Ran it on local CISCO platforms and its passing co-authorized by: jianquanye@microsoft.com --- tests/snmp/test_snmp_queue_counters.py | 55 ++++++++++++++++++-------- tests/telemetry/test_telemetry.py | 14 ++++++- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/tests/snmp/test_snmp_queue_counters.py b/tests/snmp/test_snmp_queue_counters.py index 83824ea80ec..e35831c7a76 100644 --- a/tests/snmp/test_snmp_queue_counters.py +++ b/tests/snmp/test_snmp_queue_counters.py @@ -2,12 +2,12 @@ import json from tests.common import config_reload from tests.common.helpers.assertions import pytest_assert +from tests.common.utilities import wait_until CFG_DB_PATH = "/etc/sonic/config_db.json" ORIG_CFG_DB = "/etc/sonic/orig_config_db.json" UNICAST_CTRS = 4 MULTICAST_CTRS = 4 -BUFFER_QUEUES_REMOVED = 2 pytestmark = [ pytest.mark.topology('any', 't1-multi-asic'), @@ -17,13 +17,21 @@ def load_new_cfg(duthost, data): duthost.copy(content=json.dumps(data, indent=4), dest=CFG_DB_PATH) - config_reload(duthost, config_source='config_db', safe_reload=True) + config_reload(duthost, config_source='config_db', safe_reload=True, check_intf_up_ports=True, wait_for_bgp=True) def get_queue_ctrs(duthost, cmd): return len(duthost.shell(cmd)["stdout_lines"]) +def check_snmp_cmd_output(duthost, cmd): + out_len = len(duthost.shell(cmd)["stdout_lines"]) + if out_len > 1: + return True + else: + return False + + def get_queue_cntrs_oid(interface): """ @summary: Returns queue_cntrs_oid value based on the interface chosen @@ -82,15 +90,18 @@ def test_snmp_queue_counters(duthosts, if interface is None: pytest.skip("No active interface present on the asic {}".format(asic)) queue_cntrs_oid = get_queue_cntrs_oid(interface) + + get_queue_stat_cmd = "queuestat -p {}".format(interface) get_bfr_queue_cntrs_cmd \ = "docker exec snmp snmpwalk -v2c -c {} {} {}".format( creds_all_duts[duthost.hostname]['snmp_rocommunity'], hostip, queue_cntrs_oid) - # Generate sonic-cfggen commands for multi-asic and single-asic duts + # Generate sonic-cfggen and queue stat commands for multi-asic and single-asic duts if duthost.sonichost.is_multi_asic and asic is not None: ORIG_CFG_DB = "/etc/sonic/orig_config_db{}.json".format(asic.asic_index) CFG_DB_PATH = "/etc/sonic/config_db{}.json".format(asic.asic_index) cmd = "sonic-cfggen -n {} -d --print-data > {}".format(asic.namespace, ORIG_CFG_DB) + get_queue_stat_cmd = "queuestat -n {} -p {}".format(asic.namespace, interface) else: cmd = "sonic-cfggen -d --print-data > {}".format(ORIG_CFG_DB) @@ -98,17 +109,14 @@ def test_snmp_queue_counters(duthosts, data = json.loads(duthost.shell("cat {}".format(ORIG_CFG_DB), verbose=False)['stdout']) buffer_queue_to_del = None - # Get appropriate buffer queue value to delete in case of multi-asic - if duthost.sonichost.is_multi_asic: - buffer_queues = list(data['BUFFER_QUEUE'].keys()) - iface_to_check = buffer_queues[0].split('|')[0] - iface_buffer_queues = [bq for bq in buffer_queues if any(val in iface_to_check for val in bq.split('|'))] - for queue in iface_buffer_queues: - if asic.namespace in queue and queue.split('|')[-1] == '3-4' and queue.split('|')[-2] == interface: - buffer_queue_to_del = queue - break + + # Get appropriate buffer queue value to delete + buffer_queues = list(data['BUFFER_QUEUE'].keys()) + iface_buffer_queues = [bq for bq in buffer_queues if any(val in interface for val in bq.split('|'))] + if iface_buffer_queues: + buffer_queue_to_del = iface_buffer_queues[0] else: - buffer_queue_to_del = "{}|3-4".format(interface) + pytest_assert(False, "Buffer Queue list can't be empty if valid interface is selected.") # Add create_only_config_db_buffers entry to device metadata to enable # counters optimization and get number of queue counters of Ethernet0 prior @@ -116,13 +124,24 @@ def test_snmp_queue_counters(duthosts, data['DEVICE_METADATA']["localhost"]["create_only_config_db_buffers"] \ = "true" load_new_cfg(duthost, data) + stat_queue_counters_cnt_pre = (get_queue_ctrs(duthost, get_queue_stat_cmd) - 2) * UNICAST_CTRS + wait_until(60, 20, 0, check_snmp_cmd_output, duthost, get_bfr_queue_cntrs_cmd) queue_counters_cnt_pre = get_queue_ctrs(duthost, get_bfr_queue_cntrs_cmd) - # Remove buffer queue and reload and get number of queue counters of - # Ethernet0 after removing two buffer queues + # snmpwalk output should get info for same number of buffers as queuestat -p dose + pytest_assert((queue_counters_cnt_pre == stat_queue_counters_cnt_pre), + "Snmpwalk Queue counters actual count {} differs from expected queue stat count values {}". + format(queue_counters_cnt_pre, stat_queue_counters_cnt_pre)) + + # Remove buffer queue and reload and get number of queue counters of selected interface del data['BUFFER_QUEUE'][buffer_queue_to_del] load_new_cfg(duthost, data) + stat_queue_counters_cnt_post = (get_queue_ctrs(duthost, get_queue_stat_cmd) - 2) * UNICAST_CTRS + wait_until(60, 20, 0, check_snmp_cmd_output, duthost, get_bfr_queue_cntrs_cmd) queue_counters_cnt_post = get_queue_ctrs(duthost, get_bfr_queue_cntrs_cmd) + pytest_assert((queue_counters_cnt_post == stat_queue_counters_cnt_post), + "Snmpwalk Queue counters actual count {} differs from expected queue stat count values {}". + format(queue_counters_cnt_post, stat_queue_counters_cnt_post)) # For broadcom-dnx voq chassis, number of voq are fixed (static), which cannot be modified dynamically # Hence, make sure the queue counters before deletion and after deletion are same for broadcom-dnx voq chassis @@ -132,8 +151,10 @@ def test_snmp_queue_counters(duthosts, format(queue_counters_cnt_post, queue_counters_cnt_pre)) # check for other duts else: - unicast_expected_diff = BUFFER_QUEUES_REMOVED * UNICAST_CTRS - multicast_expected_diff = unicast_expected_diff + (BUFFER_QUEUES_REMOVED + range_str = str(buffer_queue_to_del.split('|')[-1]) + buffer_queues_removed = int(range_str.split('-')[1]) - int(range_str.split('-')[0]) + 1 + unicast_expected_diff = buffer_queues_removed * UNICAST_CTRS + multicast_expected_diff = unicast_expected_diff + (buffer_queues_removed * MULTICAST_CTRS) pytest_assert((queue_counters_cnt_pre - queue_counters_cnt_post) in [unicast_expected_diff, multicast_expected_diff], diff --git a/tests/telemetry/test_telemetry.py b/tests/telemetry/test_telemetry.py index be487aac402..b6b4e23212f 100644 --- a/tests/telemetry/test_telemetry.py +++ b/tests/telemetry/test_telemetry.py @@ -31,7 +31,7 @@ def load_new_cfg(duthost, data): duthost.copy(content=json.dumps(data, indent=4), dest=CFG_DB_PATH) - config_reload(duthost, config_source='config_db', safe_reload=True) + config_reload(duthost, config_source='config_db', safe_reload=True, check_intf_up_ports=True, wait_for_bgp=True) # config reload overrides testing telemetry config, ensure testing config exists setup_telemetry_forpyclient(duthost) @@ -52,6 +52,14 @@ def get_buffer_queues_cnt(ptfhost, gnxi_path, dut_ip, iface, gnmi_port): return cnt +def check_buffer_queues_cnt_cmd_output(ptfhost, gnxi_path, dut_ip, iface_to_check, gnmi_port): + cnt = get_buffer_queues_cnt(ptfhost, gnxi_path, dut_ip, iface_to_check, gnmi_port) + if cnt > 0: + return True + else: + return False + + def test_config_db_parameters(duthosts, enum_rand_one_per_hwsku_hostname): """Verifies required telemetry parameters from config_db. """ @@ -169,11 +177,15 @@ def test_telemetry_queue_buffer_cnt(duthosts, enum_rand_one_per_hwsku_hostname, data['DEVICE_METADATA']["localhost"]["create_only_config_db_buffers"] \ = "true" load_new_cfg(duthost, data) + wait_until(60, 20, 0, check_buffer_queues_cnt_cmd_output, ptfhost, gnxi_path, + dut_ip, iface_to_check, env.gnmi_port) pre_del_cnt = get_buffer_queues_cnt(ptfhost, gnxi_path, dut_ip, iface_to_check, env.gnmi_port) # Remove buffer queue and reload and get new number of queue counters del data['BUFFER_QUEUE'][iface_buffer_queues[0]] load_new_cfg(duthost, data) + wait_until(60, 20, 0, check_buffer_queues_cnt_cmd_output, ptfhost, gnxi_path, + dut_ip, iface_to_check, env.gnmi_port) post_del_cnt = get_buffer_queues_cnt(ptfhost, gnxi_path, dut_ip, iface_to_check, env.gnmi_port) pytest_assert(pre_del_cnt > post_del_cnt, From 61da28e283514d53b11b45f67f1b5a558cfbfa28 Mon Sep 17 00:00:00 2001 From: Jianquan Ye Date: Fri, 22 Nov 2024 21:43:56 +1000 Subject: [PATCH 220/221] Add timeout for Cisco 8800 snmp (#15701) Description of PR Summary: Fixes MSFT ADO 30112399 BY default, the snmp timeout is 1s, Cisco 8800 has lots of interfacts, this causes the high chance of the timeout of snmp. Add timeout to tolerate the latency. Approach What is the motivation for this PR? Fix the snmp timeout issues on Cisco 8800 chassis. How did you do it? Enable timeout for snmp query. How did you verify/test it? Locally test on physical chassis testbed: snmp/test_snmp_psu.py::test_snmp_numpsu[x-sup-2] PASSED [ 50%] snmp/test_snmp_psu.py::test_snmp_psu_status[x-sup-2] PASSED [100%] co-authorized by: jianquanye@microsoft.com --- ansible/library/snmp_facts.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ansible/library/snmp_facts.py b/ansible/library/snmp_facts.py index 141e11dc44b..a7dbdc9beb4 100644 --- a/ansible/library/snmp_facts.py +++ b/ansible/library/snmp_facts.py @@ -463,9 +463,10 @@ def Tree(): return defaultdict(Tree) elif current_oid == v.sysLocation: results['ansible_syslocation'] = current_val + # Cisco 8800 has lots of interfacts, add timeout to tolerate the latency errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( snmp_auth, - cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.UdpTransportTarget((m_args['host'], 161), timeout=m_args['timeout']), cmdgen.MibVariable(p.ifIndex,), cmdgen.MibVariable(p.ifDescr,), cmdgen.MibVariable(p.ifType,), @@ -890,9 +891,10 @@ def Tree(): return defaultdict(Tree) ifIndex = int(current_oid.split('.')[12]) results['snmp_interfaces'][ifIndex]['lldpRemManAddrOID'] = current_val + # Cisco 8800 has lots of interfacts, add timeout to tolerate the latency errorIndication, errorStatus, errorIndex, varTable = cmdGen.nextCmd( snmp_auth, - cmdgen.UdpTransportTarget((m_args['host'], 161)), + cmdgen.UdpTransportTarget((m_args['host'], 161), timeout=m_args['timeout']), cmdgen.MibVariable(p.cpfcIfRequests,), cmdgen.MibVariable(p.cpfcIfIndications,), cmdgen.MibVariable(p.requestsPerPriority,), From f0415611b7d28fa607facf0452687fc7ac2682df Mon Sep 17 00:00:00 2001 From: ranepbhagyashree Date: Fri, 22 Nov 2024 08:47:26 -0800 Subject: [PATCH 221/221] route_perf: Fix destination mac for multi asic (#15632) --- tests/route/test_route_perf.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/route/test_route_perf.py b/tests/route/test_route_perf.py index d54f46d95ca..4d3d4fac58c 100644 --- a/tests/route/test_route_perf.py +++ b/tests/route/test_route_perf.py @@ -335,11 +335,12 @@ def test_perf_add_remove_routes( if ip_versions == 4: ip_dst = generate_ips(1, dst_nw, []) send_and_verify_traffic( - duthost, ptfadapter, tbinfo, ip_dst, ptf_dst_ports, ptf_src_port + asichost, duthost, ptfadapter, tbinfo, ip_dst, ptf_dst_ports, ptf_src_port ) else: ip_dst = dst_nw.split("/")[0] + "1" send_and_verify_traffic( + asichost, duthost, ptfadapter, tbinfo, @@ -366,11 +367,11 @@ def test_perf_add_remove_routes( def send_and_verify_traffic( - duthost, ptfadapter, tbinfo, ip_dst, expected_ports, ptf_src_port, ipv6=False + asichost, duthost, ptfadapter, tbinfo, ip_dst, expected_ports, ptf_src_port, ipv6=False ): if ipv6: pkt = testutils.simple_tcpv6_packet( - eth_dst=duthost.facts["router_mac"], + eth_dst=asichost.get_router_mac().lower(), eth_src=ptfadapter.dataplane.get_mac(0, ptf_src_port), ipv6_src="2001:db8:85a3::8a2e:370:7334", ipv6_dst=ip_dst, @@ -380,7 +381,7 @@ def send_and_verify_traffic( ) else: pkt = testutils.simple_tcp_packet( - eth_dst=duthost.facts["router_mac"], + eth_dst=asichost.get_router_mac().lower(), eth_src=ptfadapter.dataplane.get_mac(0, ptf_src_port), ip_src="1.1.1.1", ip_dst=ip_dst,

    +S!J2uWa@a+!5rWeD729aOoY7BSs0(l& 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%0ApT!G*tp{<_(7fRE+=~IX=*P;iU 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

  • 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