|
| 1 | +from tests.snappi_tests.dataplane.imports import * # noqa F405 |
| 2 | +from snappi_tests.dataplane.files.helper import get_duthost_bgp_details, create_snappi_config, \ |
| 3 | + get_fanout_port_groups, set_primary_chassis, create_traffic_items, start_stop, get_stats # noqa: F401, F405 |
| 4 | + |
| 5 | +pytestmark = [pytest.mark.topology("nut")] |
| 6 | +logger = logging.getLogger(__name__) # noqa: F405 |
| 7 | + |
| 8 | +""" |
| 9 | + The following FEC ErrorTypes are the options available for AresOneM in 800G, 400G and 200G speed modes in IxNetwork |
| 10 | + with which the Ports go down when the error is injected or there is packet drop. |
| 11 | + example: |
| 12 | + For codeWords, laneMarkers, minConsecutiveUncorrectableWithLossOfLink link goes down and there is packet drop |
| 13 | + For maxConsecutiveUncorrectableWithoutLossOfLink link does not go down and there is packet drop |
| 14 | +
|
| 15 | + # Note: Need atleast two front panel ports for this test |
| 16 | +
|
| 17 | +""" |
| 18 | +ErrorTypes = [ |
| 19 | + "codeWords", |
| 20 | + "laneMarkers", |
| 21 | + "minConsecutiveUncorrectableWithLossOfLink", |
| 22 | + "maxConsecutiveUncorrectableWithoutLossOfLink", |
| 23 | +] |
| 24 | +# Example If the speed of the fanout port is 400G on a 800G front panel port then the fanout_per_port is 2 |
| 25 | +# (because 2 400G fanouts per 800G fron panel port), |
| 26 | +# if its 200G then fanout_per_port is 4, if its 100G then fanout_per_port is 8 |
| 27 | + |
| 28 | + |
| 29 | +@pytest.mark.parametrize("fanout_per_port", [2]) |
| 30 | +@pytest.mark.parametrize("error_type", ErrorTypes) |
| 31 | +@pytest.mark.parametrize("subnet_type", ["IPv6"]) |
| 32 | +@pytest.mark.parametrize("frame_rate", [20]) |
| 33 | +@pytest.mark.parametrize("frame_size", [1024]) |
| 34 | +def test_fec_error_injection( |
| 35 | + duthosts, |
| 36 | + snappi_api, |
| 37 | + get_snappi_ports, |
| 38 | + fanout_graph_facts_multidut, |
| 39 | + set_primary_chassis, # noqa: F811 |
| 40 | + subnet_type, |
| 41 | + create_snappi_config, # noqa: F811 |
| 42 | + fanout_per_port, |
| 43 | + error_type, |
| 44 | + frame_rate, |
| 45 | + frame_size, |
| 46 | +): |
| 47 | + """ |
| 48 | + Test to check if packets get dropped on injecting fec errors |
| 49 | + Note: fanout_per_port is the number of fanouts per fron panel port |
| 50 | + Example: For running the test on 400g fanout mode of a 800g port, |
| 51 | + fanout_per_port is 2 |
| 52 | + Note: Not supported for speed mode 8x100G |
| 53 | + """ |
| 54 | + snappi_extra_params = SnappiTestParams() |
| 55 | + snappi_ports = get_duthost_bgp_details(duthosts, get_snappi_ports, subnet_type) |
| 56 | + fanout_port_group_list = get_fanout_port_groups(snappi_ports, fanout_per_port) |
| 57 | + for iteration, fanout_port_group in enumerate(fanout_port_group_list): |
| 58 | + logger.info("|----------------------------------------|") |
| 59 | + logger.info("\t\tIteration: {} \n".format(iteration + 1)) |
| 60 | + logger.info("Using Fanout Ports :-") |
| 61 | + logger.info("\n") |
| 62 | + for port in fanout_port_group: |
| 63 | + logger.info( |
| 64 | + port["peer_port"] |
| 65 | + + " : " |
| 66 | + + port["location"] |
| 67 | + + " : " |
| 68 | + + port["snappi_speed_type"] |
| 69 | + ) |
| 70 | + logger.info("|----------------------------------------|\n") |
| 71 | + half_ports = int(len(fanout_port_group) / 2) |
| 72 | + Tx_ports = fanout_port_group[:half_ports] |
| 73 | + Rx_ports = fanout_port_group[half_ports:] |
| 74 | + logger.info('Tx Ports: {}'.format([port["peer_port"] for port in Tx_ports])) |
| 75 | + logger.info('Rx Ports: {}'.format([port["peer_port"] for port in Rx_ports])) |
| 76 | + logger.info("\n") |
| 77 | + snappi_extra_params.protocol_config = { |
| 78 | + "Tx": { |
| 79 | + "protocol_type": "bgp", |
| 80 | + "ports": Tx_ports, |
| 81 | + "subnet_type": subnet_type, |
| 82 | + "is_rdma": False, |
| 83 | + }, |
| 84 | + "Rx": { |
| 85 | + "protocol_type": "bgp", |
| 86 | + "ports": Rx_ports, |
| 87 | + "subnet_type": subnet_type, |
| 88 | + "is_rdma": False, |
| 89 | + }, |
| 90 | + } |
| 91 | + snappi_config, snappi_obj_handles = create_snappi_config(snappi_extra_params) |
| 92 | + snappi_extra_params.traffic_flow_config = [ |
| 93 | + { |
| 94 | + "line_rate": frame_rate, |
| 95 | + "frame_size": frame_size, |
| 96 | + "is_rdma": False, |
| 97 | + "flow_name": "Traffic Flow", |
| 98 | + "tx_names": snappi_obj_handles["Tx"]["ip"], |
| 99 | + "rx_names": snappi_obj_handles["Rx"]["ip"], |
| 100 | + }, |
| 101 | + ] |
| 102 | + snappi_config = create_traffic_items(snappi_config, snappi_extra_params) |
| 103 | + snappi_api.set_config(snappi_config) |
| 104 | + start_stop(snappi_api, operation="start", op_type="protocols") |
| 105 | + columns = ["frames_tx", "frames_rx", "loss", "frames_tx_rate", "frames_rx_rate"] |
| 106 | + ixnet = snappi_api._ixnetwork |
| 107 | + logger.info("Wait for Arp to Resolve ...") |
| 108 | + wait_for_arp(snappi_api, max_attempts=30, poll_interval_sec=2) |
| 109 | + logger.info("\n") |
| 110 | + tx_ports = [] |
| 111 | + ixnet_ports = ixnet.Vport.find() |
| 112 | + for port in ixnet_ports: |
| 113 | + for snappi_port in Tx_ports: |
| 114 | + if str(port.Location) == str(snappi_port["location"]): |
| 115 | + tx_ports.append(port) |
| 116 | + logger.info( |
| 117 | + "Setting FEC Error Type to : {} on Tx Snappi ports :-".format(error_type) |
| 118 | + ) |
| 119 | + for port in tx_ports: |
| 120 | + port.L1Config.FecErrorInsertion.ErrorType = error_type |
| 121 | + for snappi_port in fanout_port_group: |
| 122 | + if port.Location == snappi_port["location"]: |
| 123 | + logger.info('{} --- {}'.format(port.Name, snappi_port["peer_port"])) |
| 124 | + if error_type == "codeWords": |
| 125 | + port.L1Config.FecErrorInsertion.PerCodeword = 16 |
| 126 | + port.L1Config.FecErrorInsertion.Continuous = True |
| 127 | + wait(10, "To apply fec setting on the port") |
| 128 | + start_stop(snappi_api, operation="start", op_type="traffic") |
| 129 | + try: |
| 130 | + logger.info("Starting FEC Error Insertion") |
| 131 | + [port.StartFecErrorInsertion() for port in tx_ports] |
| 132 | + wait(15, "For error insertion to start") |
| 133 | + get_stats(snappi_api, "Traffic Item Statistics", columns, 'print') |
| 134 | + for snappi_port in tx_ports: |
| 135 | + for port in fanout_port_group: |
| 136 | + if port["location"] == snappi_port.Location: |
| 137 | + if ( |
| 138 | + error_type == "minConsecutiveUncorrectableWithLossOfLink" |
| 139 | + or error_type == "codeWords" |
| 140 | + or error_type == "laneMarkers" |
| 141 | + ): |
| 142 | + pytest_assert( |
| 143 | + port["duthost"].links_status_down(port["peer_port"]) is True, |
| 144 | + "FAIL: {} is still up after injecting FEC Error".format( |
| 145 | + port["peer_port"] |
| 146 | + ), |
| 147 | + ) |
| 148 | + logger.info( |
| 149 | + "PASS: {} Went down after injecting FEC Error: {}".format( |
| 150 | + port["peer_port"], error_type |
| 151 | + ) |
| 152 | + ) |
| 153 | + elif ( |
| 154 | + error_type == "maxConsecutiveUncorrectableWithoutLossOfLink" |
| 155 | + ): |
| 156 | + pytest_assert( |
| 157 | + port["duthost"].links_status_down(port["peer_port"]) is False, |
| 158 | + "FAIL: {} went down after injecting FEC Error".format( |
| 159 | + port["peer_port"] |
| 160 | + ), |
| 161 | + ) |
| 162 | + logger.info( |
| 163 | + "PASS: {} didn't go down after injecting FEC Error: {}".format( |
| 164 | + port["peer_port"], error_type |
| 165 | + ) |
| 166 | + ) |
| 167 | + flow_metrics = get_stats(snappi_api, "Traffic Item Statistics")[0] |
| 168 | + pytest_assert( |
| 169 | + flow_metrics.frames_tx > 0 and int(flow_metrics.loss) > 0, |
| 170 | + "FAIL: Rx Port did not drop packets after starting FEC Error Insertion", |
| 171 | + ) |
| 172 | + logger.info( |
| 173 | + "PASS : Snappi Rx Port observed packet drop after starting FEC Error Insertion" |
| 174 | + ) |
| 175 | + logger.info("Stopping FEC Error Insertion") |
| 176 | + [port.StopFecErrorInsertion() for port in tx_ports] |
| 177 | + wait(20, "For error insertion to stop") |
| 178 | + for snappi_port in tx_ports: |
| 179 | + for port in fanout_port_group: |
| 180 | + if port["location"] == snappi_port.Location: |
| 181 | + if ( |
| 182 | + error_type == "minConsecutiveUncorrectableWithLossOfLink" |
| 183 | + or error_type == "codeWords" |
| 184 | + or error_type == "laneMarkers" |
| 185 | + ): |
| 186 | + pytest_assert( |
| 187 | + port["duthost"].links_status_down(port["peer_port"]) is False, |
| 188 | + "FAIL: {} is still down after stopping FEC Error".format( |
| 189 | + port["peer_port"] |
| 190 | + ), |
| 191 | + ) |
| 192 | + logger.info( |
| 193 | + "PASS: {} is up after stopping FEC Error injection: {}".format( |
| 194 | + port["peer_port"], error_type |
| 195 | + ) |
| 196 | + ) |
| 197 | + ixnet.ClearStats() |
| 198 | + wait(10, "For clear stats operation to complete") |
| 199 | + get_stats(snappi_api, "Traffic Item Statistics", columns, 'print') |
| 200 | + flow_metrics = get_stats(snappi_api, "Traffic Item Statistics")[0] |
| 201 | + pytest_assert( |
| 202 | + int(flow_metrics.frames_rx_rate) > 0 and int(flow_metrics.loss) == 0, |
| 203 | + "FAIL: Rx Port did not resume receiving packets after stopping FEC Error Insertion", |
| 204 | + ) |
| 205 | + logger.info( |
| 206 | + "PASS : Rx Port resumed receiving packets after stopping FEC Error Insertion" |
| 207 | + ) |
| 208 | + start_stop(snappi_api, operation="stop", op_type="traffic") |
| 209 | + finally: |
| 210 | + logger.info("....Finally Block, Stopping FEC Error Insertion....") |
| 211 | + [port.StopFecErrorInsertion() for port in tx_ports] |
0 commit comments