From 32d63e6911402cb063eb2a3f1aee9dbd116c4e25 Mon Sep 17 00:00:00 2001 From: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Date: Wed, 31 Aug 2022 10:15:19 +0300 Subject: [PATCH 01/45] Added SAI-Challenger to CI setup. 1. Added SAI-Challenger submodule. 2. Added SAI-Challenger basic test. 3. Changed Makefile to build/start/stop SAI-Challenger. Signed-off-by: Maksym Hedeon --- .gitmodules | 3 ++ dash-pipeline/Makefile | 49 +++++++++++++++++++ test/SAI-Challenger.OCP | 1 + .../test_vector_example/__init__.py | 0 .../test_vector_example/conftest.py | 44 +++++++++++++++++ .../test_vector_example/test_dpu_basic.py | 5 ++ 6 files changed, 102 insertions(+) create mode 160000 test/SAI-Challenger.OCP create mode 100644 test/test-cases/test_vector_example/__init__.py create mode 100644 test/test-cases/test_vector_example/conftest.py create mode 100644 test/test-cases/test_vector_example/test_dpu_basic.py diff --git a/.gitmodules b/.gitmodules index cb32895b5..b57c1888f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = dash-pipeline/SAI/SAI url = https://github.com/reshmaintel/SAI.git branch = dash-ptf-ci +[submodule "test/SAI-Challenger.OCP"] + path = test/SAI-Challenger.OCP + url = https://github.com/plvisiondevs/SAI-Challenger.OCP diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 73f45f806..e6d953a97 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -496,6 +496,55 @@ deploy-ixiac: undeploy-ixiac: cd ../test/third-party/traffic_gen && ./undeploy_ixiac.sh +############################### +# SAI-CHALLENGER TARGETS +############################### + +SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger.OCP + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-build:sai-challenger-client-build sai-challenger-server-build + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-start:sai-challenger-client-start sai-challenger-server-start sai-challenger-create-veth + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-stop:sai-challenger-client-stop sai-challenger-server-stop + +sai-challenger-test: + cd $(SAI_CHALLENGER_PATH) && ./exec.sh -i client pytest --setup=../setups/sai_dpu_client_server.json -v -k "test_dpu_basic" + +sai-challenger-client-build: + cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client + +sai-challenger-client-start: +# cd $(SAI_CHALLENGER_PATH) && ./run.sh -i client -r + docker run --name sc-client-run \ + -v $(SAI_CHALLENGER_PATH):/sai-challenger \ + --cap-add=NET_ADMIN \ + --device /dev/net/tun:/dev/net/tun \ + --rm \ + -v $(SAI_CHALLENGER_PATH)/../test-cases/challenger_basic_test/:/sai-challenger/tests \ + -d sc-client + +sai-challenger-client-stop: + cd $(SAI_CHALLENGER_PATH) && ./run.sh -i client -c stop + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-server-build: + cd $(SAI_CHALLENGER_PATH) && ./build.sh -i server -a trident2 -t saivs + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-server-start: + cd $(SAI_CHALLENGER_PATH) && ./run.sh -i server -a trident2 -t saivs -r + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-server-stop: + cd $(SAI_CHALLENGER_PATH) && ./run.sh -i server -a trident2 -t saivs -c stop + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +sai-challenger-create-veth: + sudo $(SAI_CHALLENGER_PATH)/veth-create-host.sh sc-server-trident2-saivs-run sc-client-run ############################### # ENVIRONMENT SETUP TARGETS diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP new file mode 160000 index 000000000..c94bc2d01 --- /dev/null +++ b/test/SAI-Challenger.OCP @@ -0,0 +1 @@ +Subproject commit c94bc2d0103443ad9dca717952601c80a98e9894 diff --git a/test/test-cases/test_vector_example/__init__.py b/test/test-cases/test_vector_example/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py new file mode 100644 index 000000000..0fdd68fca --- /dev/null +++ b/test/test-cases/test_vector_example/conftest.py @@ -0,0 +1,44 @@ +import logging +import os +import sys +import traceback +import pytest +from sai_environment import init_setup + +def pytest_addoption(parser): + parser.addoption("--traffic", action="store_true", default=False, help="run tests with traffic") + parser.addoption("--loglevel", action="store", default='NOTICE', help="syncd logging level") + parser.addoption("--setup", action="store", default=None, help="Setup description (Path to the json file).") + + +@pytest.fixture(scope="session") +def exec_params(request): + config_param = {} + config_param["setup"] = init_setup(request.config) + config_param["traffic"] = request.config.getoption("--traffic") + config_param["loglevel"] = request.config.getoption("--loglevel") + logging.getLogger().setLevel(getattr(logging, config_param["loglevel"].upper(), "INFO")) + return config_param + +@pytest.fixture(scope="session") +def dpu(exec_params): + dpu = exec_params["setup"]["DPU"][0] + if dpu is not None: + dpu.reset() + return dpu + +@pytest.fixture(scope="session") +def dataplane_session(exec_params): + dataplane = exec_params["setup"]["DATAPLANE"][0] + # Set up the dataplane + dataplane.init() + yield dataplane + # Shutdown the dataplane + dataplane.remove() + + +@pytest.fixture(scope="function") +def dataplane(dataplane_session): + dataplane_session.setUp() + yield dataplane_session + dataplane_session.tearDown() diff --git a/test/test-cases/test_vector_example/test_dpu_basic.py b/test/test-cases/test_vector_example/test_dpu_basic.py new file mode 100644 index 000000000..b760e5dcd --- /dev/null +++ b/test/test-cases/test_vector_example/test_dpu_basic.py @@ -0,0 +1,5 @@ +import pytest + +def test_dpu_basic(dpu, dataplane): + pass + #TODO From cef877f721bd3627b574a454f365d8af8ffa8f43 Mon Sep 17 00:00:00 2001 From: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Date: Fri, 2 Sep 2022 16:20:50 +0300 Subject: [PATCH 02/45] Added saithrift to SAI-Challenger client docker image - Added saithrift to SAI-Challenger client docker image - Changed SAI-C submodule branch Signed-off-by: Maksym Hedeon --- .gitmodules | 1 + dash-pipeline/Makefile | 39 +++++++++++++------ .../Dockerfile.saic-saithrift-client | 28 +++++++++++++ 3 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client diff --git a/.gitmodules b/.gitmodules index b57c1888f..68a10863a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,4 @@ [submodule "test/SAI-Challenger.OCP"] path = test/SAI-Challenger.OCP url = https://github.com/plvisiondevs/SAI-Challenger.OCP + branch = dash-testing diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index e6d953a97..d0e2aaed8 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -502,6 +502,13 @@ undeploy-ixiac: SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger.OCP +DOCKER_SAI_CHALLENGER_CLIENT = sc-client-thrift + +CONTAINER_SAI_CHALLENGER_CLIENT_NAME = $(DOCKER_SAI_CHALLENGER_CLIENT)-run + +# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER +CONTAINER_SAI_CHALLENGER_SERVER_NAME = sc-server-trident2-saivs-run + # SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER sai-challenger-build:sai-challenger-client-build sai-challenger-server-build @@ -512,23 +519,33 @@ sai-challenger-start:sai-challenger-client-start sai-challenger-server-start sai sai-challenger-stop:sai-challenger-client-stop sai-challenger-server-stop sai-challenger-test: - cd $(SAI_CHALLENGER_PATH) && ./exec.sh -i client pytest --setup=../setups/sai_dpu_client_server.json -v -k "test_dpu_basic" + docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) pytest --setup=../setups/sai_dpu_client_server.json -v -k "test_dpu_basic" + +sai-challenger-test-ixiac:deploy-ixiac + docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) pytest --setup=../setups/snappi_bmv2_client_server.json -v -k "test_dpu_basic" sai-challenger-client-build: cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client + docker build \ + -f dockerfiles/Dockerfile.saic-saithrift-client \ + -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ + . sai-challenger-client-start: -# cd $(SAI_CHALLENGER_PATH) && ./run.sh -i client -r - docker run --name sc-client-run \ - -v $(SAI_CHALLENGER_PATH):/sai-challenger \ - --cap-add=NET_ADMIN \ - --device /dev/net/tun:/dev/net/tun \ - --rm \ - -v $(SAI_CHALLENGER_PATH)/../test-cases/challenger_basic_test/:/sai-challenger/tests \ - -d sc-client + docker run --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ + -v $(SAI_CHALLENGER_PATH):/sai-challenger \ + --cap-add=NET_ADMIN \ + --device /dev/net/tun:/dev/net/tun \ + --rm \ + -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/tests \ + -d \ + --network=host \ + --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ + $(DOCKER_SAI_CHALLENGER_CLIENT) sai-challenger-client-stop: - cd $(SAI_CHALLENGER_PATH) && ./run.sh -i client -c stop +# cd $(SAI_CHALLENGER_PATH) && ./run.sh -i client -c stop + docker container stop $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) # SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER sai-challenger-server-build: @@ -544,7 +561,7 @@ sai-challenger-server-stop: # SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER sai-challenger-create-veth: - sudo $(SAI_CHALLENGER_PATH)/veth-create-host.sh sc-server-trident2-saivs-run sc-client-run + sudo $(SAI_CHALLENGER_PATH)/veth-create-host.sh $(CONTAINER_SAI_CHALLENGER_SERVER_NAME) $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) ############################### # ENVIRONMENT SETUP TARGETS diff --git a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client new file mode 100644 index 000000000..c66498641 --- /dev/null +++ b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client @@ -0,0 +1,28 @@ +FROM sc-client + +ADD tests/ /tests/ + +RUN python3 -m pip install -r /tests/requirements.txt && \ + pip3 install scapy pysubnettree + +# Copy distro PTF submodule and tools from SAI repo +ADD SAI/SAI/test/ptf /SAI/test/ptf +# Install PTF test framework & test-cases from SAI repo +ADD SAI/SAI/ptf /SAI/ptf/ +# Copy thrift python distro +ADD SAI/rpc/thrift-0.11.0.tar.gz / +# Copy autogenerated saithrift library built from SAI headers for DASH dataplane +ADD SAI/rpc/saithrift-0.9.tar.gz / +# Install the python libraries +RUN cd /saithrift-0.9 && \ + python3 setup.py install && \ + cd / && \ + rm -rf saithrift-0.9 &&\ + cd thrift-0.11.0 && \ + python3 setup.py install && \ + cd / &&\ + rm -rf thrift-0.11.0 && \ + cd /SAI/test/ptf && \ + python3 setup.py install + +CMD ["/usr/bin/supervisord"] From a33167509ac13a4ca119cb71a0a81efb093d8e44 Mon Sep 17 00:00:00 2001 From: Kostiantyn Goloveshko Date: Mon, 5 Sep 2022 11:33:27 +0300 Subject: [PATCH 03/45] Update example vnet test. 1. Added SAI-Challenger submodule. 2. Added SAI-Challenger basic test. 3. Changed Makefile to build/start/stop SAI-Challenger. Signed-off-by: Kostiantyn Goloveshko Co-authored-by: Maksym Hedeon --- .gitmodules | 2 +- dash-pipeline/Makefile | 12 +- test/SAI-Challenger.OCP | 2 +- .../test_vector_example/conftest.py | 11 +- .../test_vector_example/test_vnet_inbound.py | 16 ++ .../test_vnet_inbound_cleanup_commands.json | 73 ++++++++ .../test_vnet_inbound_setup_commands.json | 157 ++++++++++++++++++ 7 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 test/test-cases/test_vector_example/test_vnet_inbound.py create mode 100644 test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json create mode 100644 test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json diff --git a/.gitmodules b/.gitmodules index 68a10863a..48920ce1d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,4 @@ [submodule "test/SAI-Challenger.OCP"] path = test/SAI-Challenger.OCP url = https://github.com/plvisiondevs/SAI-Challenger.OCP - branch = dash-testing + branch = dash-testing \ No newline at end of file diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index d0e2aaed8..7cbc60b2d 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -116,7 +116,7 @@ DOCKER_RUN_SAITHRIFT_BLDR =\ sai: fix-perms sai-clean sai-headers sai-meta libsai -sai-headers: fix-perms p4 | SAI/SAI +sai-headers: fix-perms p4 | SAI/SAI @echo "Generate SAI library headers and implementation..." mkdir -p SAI/lib $(DOCKER_RUN) \ @@ -127,7 +127,7 @@ sai-headers: fix-perms p4 | SAI/SAI # Fixup perms from generate_dash_api using sudo to call python,so subsequent scripts can access sudo chmod -R a+rw $(PWD)/SAI/SAI -sai-meta: fix-perms +sai-meta: fix-perms @echo "Generate SAI metadata..." # hack - remove scripts which cause Git ownership failures in CI pipelines # We don't need them, they're to check that SAI headers didn't experience enum changes etc. @@ -143,7 +143,7 @@ sai-meta: fix-perms sudo chmod -R o+rw SAI/ # TODO - add SAI header dependencies -libsai: fix-perms +libsai: fix-perms @echo "build libsai.so..." $(DOCKER_RUN) \ $(DOCKER_FLAGS) \ @@ -152,7 +152,7 @@ libsai: fix-perms $(DOCKER_BMV2_BLDR_IMG) \ make -libsai-clean: fix-perms +libsai-clean: fix-perms -rm -rf SAI/lib/libsai.so .PHONY:sai-clean @@ -336,7 +336,7 @@ docker-publish-saithrift-client-bldr: echo "TO DO when we have a proper repository" ############################### - + # Client image, rebuild any time SAI interface changes # TODO - add sai header (inc/ and experimental) dependencies docker-saithrift-client: @@ -537,7 +537,9 @@ sai-challenger-client-start: --cap-add=NET_ADMIN \ --device /dev/net/tun:/dev/net/tun \ --rm \ + --network=host \ -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/tests \ + -v $(PWD)/../:/dash \ -d \ --network=host \ --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP index c94bc2d01..b5a6d9416 160000 --- a/test/SAI-Challenger.OCP +++ b/test/SAI-Challenger.OCP @@ -1 +1 @@ -Subproject commit c94bc2d0103443ad9dca717952601c80a98e9894 +Subproject commit b5a6d9416778f584ac2264a11665b3b98ce8df4a diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py index 0fdd68fca..8dc3fa085 100644 --- a/test/test-cases/test_vector_example/conftest.py +++ b/test/test-cases/test_vector_example/conftest.py @@ -1,10 +1,13 @@ import logging -import os -import sys -import traceback + import pytest + +import sys +sys.path.insert(0, '/sai-challenger/common') # Needed for correct load_module +from sai_dpu import SaiDpu from sai_environment import init_setup + def pytest_addoption(parser): parser.addoption("--traffic", action="store_true", default=False, help="run tests with traffic") parser.addoption("--loglevel", action="store", default='NOTICE', help="syncd logging level") @@ -21,7 +24,7 @@ def exec_params(request): return config_param @pytest.fixture(scope="session") -def dpu(exec_params): +def dpu(exec_params) -> SaiDpu: dpu = exec_params["setup"]["DPU"][0] if dpu is not None: dpu.reset() diff --git a/test/test-cases/test_vector_example/test_vnet_inbound.py b/test/test-cases/test_vector_example/test_vnet_inbound.py new file mode 100644 index 000000000..7f3010d73 --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_inbound.py @@ -0,0 +1,16 @@ +import json +from pathlib import Path + +current_file_dir = Path(__file__).parent + + +def test_vnet_inbound(dpu, dataplane): + with (current_file_dir / 'test_vnet_inbound_setup_commands.json').open(mode='r') as config_file: + vnet_inbound_setup_commands = json.load(config_file) + + result = [*dpu.process_commands(vnet_inbound_setup_commands)] + + with (current_file_dir / 'test_vnet_inbound_cleanup_commands.json').open(mode='r') as config_file: + vnet_inbound_cleanup_commands = json.load(config_file) + + result = [*dpu.process_commands(vnet_inbound_cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json new file mode 100644 index 000000000..3de3d4b31 --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json @@ -0,0 +1,73 @@ +[ + { + "name": "pa_validation_entry", + "op": "remove", + "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_id", + "sip": "20.20.20.20", + "vni": "1000" + } + }, + { + "name": "inbound_routing_entry", + "op": "remove", + "type": "SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "1000" + } + }, + { + "name": "eni_ether_address_map_entry", + "op": "remove", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:AA:AA:AA:AA:00" + } + }, + { + "name": "eni_id", + "op": "remove", + "type": "SAI_OBJECT_TYPE_ENI", + "key": "$eni_id" + }, + { + "name": "vnet_1", + "op": "remove", + "type": "SAI_OBJECT_TYPE_VNET", + "key": "$vnet_1" + }, + { + "name": "acl_out_1", + "op": "remove", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "key": "$acl_out_1" + }, + { + "name": "acl_in_1", + "op": "remove", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "key": "$acl_in_1" + }, + { + "name": "direction_lookup_entry", + "op": "remove", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "2000" + } + }, + { + "name": "vip_entry", + "op": "remove", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "192.168.0.1" + } + } +] \ No newline at end of file diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json new file mode 100644 index 000000000..1dbdd9071 --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json @@ -0,0 +1,157 @@ +[ + { + "name": "vip_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "192.168.0.1" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", + "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "direction_lookup_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "2000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", + "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "acl_in_1", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", + "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "acl_out_1", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", + "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "vnet_1", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", + "2000" + ] + }, + { + "name": "eni_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", + "10000", + "SAI_ENI_ATTR_PPS", + "100000", + "SAI_ENI_ATTR_FLOWS", + "100000", + "SAI_ENI_ATTR_ADMIN_STATE", + "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", + "10.10.2.10", + "SAI_ENI_ATTR_VM_VNI", + "9", + "SAI_ENI_ATTR_VNET_ID", + "$vnet_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", + "0" + ] + }, + { + "name": "eni_ether_address_map_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:AA:AA:AA:AA:00" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", + "$eni_id" + ] + }, + { + "name": "inbound_routing_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "1000" + }, + "attributes": [ + "SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION", + "SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE" + ] + }, + { + "name": "pa_validation_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_id", + "sip": "10.10.2.10", + "vni": "1000" + }, + "attributes": [ + "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", + "SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT" + ] + } +] \ No newline at end of file From 946f1b26734dfc569f3df8ddddc42a1f5bf3d7b7 Mon Sep 17 00:00:00 2001 From: Maksym Prytoliuk <71631949+maksym-prytoliuk-plv@users.noreply.github.com> Date: Tue, 6 Sep 2022 13:46:10 +0300 Subject: [PATCH 04/45] Add vnet outbound test based on SAI description. Signed-off-by: Maksym Prytoliuk --- .../test_vector_example/test_vnet_outbound.py | 16 ++ .../test_vnet_outbound_cleanup_commands.json | 42 +++++ .../test_vnet_outbound_setup_commands.json | 145 ++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 test/test-cases/test_vector_example/test_vnet_outbound.py create mode 100644 test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json create mode 100644 test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json diff --git a/test/test-cases/test_vector_example/test_vnet_outbound.py b/test/test-cases/test_vector_example/test_vnet_outbound.py new file mode 100644 index 000000000..5d1b0188b --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_outbound.py @@ -0,0 +1,16 @@ +import json +from pathlib import Path + +current_file_dir = Path(__file__).parent + + +def test_vnet_outbound(dpu, dataplane): + with (current_file_dir / 'test_vnet_outbound_setup_commands.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + + result = [*dpu.process_commands(setup_commands)] + + with (current_file_dir / 'test_vnet_outbound_cleanup_commands.json').open(mode='r') as config_file: + cleanup_commands = json.load(config_file) + + result = [*dpu.process_commands(cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json new file mode 100644 index 000000000..556f415ce --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json @@ -0,0 +1,42 @@ +[ + { + "name": "ocpe", + "op": "remove" + }, + { + "name": "ore", + "op": "remove" + }, +# { +# "name": "out_acl_rule_id", +# "op": "remove" +# }, + { + "name": "eam", + "op": "remove" + }, + { + "name": "eni", + "op": "remove" + }, + { + "name": "vnet", + "op": "remove" + }, + { + "name": "out_acl_group_id", + "op": "remove" + }, + { + "name": "in_acl_group_id", + "op": "remove" + }, + { + "name": "dle", + "op": "remove" + }, + { + "name": "vpe", + "op": "remove" + } +] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json new file mode 100644 index 000000000..f5e537bd3 --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json @@ -0,0 +1,145 @@ +[ + { + "name": "vpe", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.16.1.20" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "dle", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "2000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "in_acl_group_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "out_acl_group_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "vnet", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "100" + ] + }, + { + "name": "eni", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", "10000", + "SAI_ENI_ATTR_PPS", "100000", + "SAI_ENI_ATTR_FLOWS", "100000", + "SAI_ENI_ATTR_ADMIN_STATE", "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.20", + "SAI_ENI_ATTR_VM_VNI", "9", + "SAI_ENI_ATTR_VNET_ID", "$vnet", +# "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "$in_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "$in_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "$in_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "$in_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "$in_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "$out_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "$out_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "$out_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "$out_acl_group_id", +# "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "$out_acl_group_id", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0" + ] + }, + { + "name": "eam", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:CC:CC:CC:CC:CC" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni" + ] + }, +# { +# "name": "out_acl_rule_id", +# "op": "create", +# "type": "SAI_OBJECT_TYPE_DASH_ACL_RULE", +# "attributes": [ +# "SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID", "$out_acl_group_id", +# "SAI_DASH_ACL_RULE_ATTR_DIP", "10.1.2.50", +# "SAI_DASH_ACL_RULE_ATTR_PRIORITY", "10", +# "SAI_DASH_ACL_RULE_ATTR_ACTION", "SAI_DASH_ACL_RULE_ACTION_PERMIT" +# ] +# }, + { + "name": "ore", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni", + "destination": "10.1.0.0/16" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet" + ] + }, + { + "name": "ocpe", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni", + "dip": "10.10.2.10", + "vni": "1000" + }, + "attributes": [ + "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", "SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT" + ] + } +] From 17b9093f1108ca7c8a4fd1bf9ce75ef985214351 Mon Sep 17 00:00:00 2001 From: Kostiantyn Goloveshko Date: Tue, 6 Sep 2022 13:47:09 +0300 Subject: [PATCH 05/45] Fixup double network host usage for sai-challenger-client Signed-off-by: Konstantin Goloveshko --- dash-pipeline/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 7cbc60b2d..b855836a6 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -541,7 +541,6 @@ sai-challenger-client-start: -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/tests \ -v $(PWD)/../:/dash \ -d \ - --network=host \ --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ $(DOCKER_SAI_CHALLENGER_CLIENT) From bfd02b332b3675b37d79917b7ae794f02c993547 Mon Sep 17 00:00:00 2001 From: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Date: Wed, 7 Sep 2022 17:20:51 +0300 Subject: [PATCH 06/45] Kdt 17: Update docker environment (#8) * Added cgyang submodule * Updated docker env for thrift tests * Makefile refactor Signed-off-by: Maksym Hedeon --- .gitmodules | 8 +++- dash-pipeline/Makefile | 44 +++---------------- .../Dockerfile.saic-saithrift-client | 30 +++++++++---- dash-pipeline/test/third-party/cgyang | 1 + 4 files changed, 36 insertions(+), 47 deletions(-) create mode 160000 dash-pipeline/test/third-party/cgyang diff --git a/.gitmodules b/.gitmodules index 48920ce1d..b498af97b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,10 @@ [submodule "test/SAI-Challenger.OCP"] path = test/SAI-Challenger.OCP url = https://github.com/plvisiondevs/SAI-Challenger.OCP - branch = dash-testing \ No newline at end of file + branch = dash-testing +[submodule "test/third-party/cgyang"] + path = test/third-party/cgyang + url = https://github.com/mgheorghe/cgyang +[submodule "dash-pipeline/test/third-party/cgyang"] + path = dash-pipeline/test/third-party/cgyang + url = https://github.com/mgheorghe/cgyang diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index b855836a6..3eb7270ae 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -506,33 +506,17 @@ DOCKER_SAI_CHALLENGER_CLIENT = sc-client-thrift CONTAINER_SAI_CHALLENGER_CLIENT_NAME = $(DOCKER_SAI_CHALLENGER_CLIENT)-run -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -CONTAINER_SAI_CHALLENGER_SERVER_NAME = sc-server-trident2-saivs-run +CONTAINER_SAI_CHALLENGER_CLIENT_EXEC = docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-build:sai-challenger-client-build sai-challenger-server-build - -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-start:sai-challenger-client-start sai-challenger-server-start sai-challenger-create-veth - -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-stop:sai-challenger-client-stop sai-challenger-server-stop - -sai-challenger-test: - docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) pytest --setup=../setups/sai_dpu_client_server.json -v -k "test_dpu_basic" - -sai-challenger-test-ixiac:deploy-ixiac - docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) pytest --setup=../setups/snappi_bmv2_client_server.json -v -k "test_dpu_basic" - -sai-challenger-client-build: +build-saic-client: cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client docker build \ -f dockerfiles/Dockerfile.saic-saithrift-client \ -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ . -sai-challenger-client-start: - docker run --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ +run-saic-client: + docker run \ -v $(SAI_CHALLENGER_PATH):/sai-challenger \ --cap-add=NET_ADMIN \ --device /dev/net/tun:/dev/net/tun \ @@ -544,25 +528,11 @@ sai-challenger-client-start: --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ $(DOCKER_SAI_CHALLENGER_CLIENT) -sai-challenger-client-stop: -# cd $(SAI_CHALLENGER_PATH) && ./run.sh -i client -c stop +kill-saic-client: undeploy-ixiac docker container stop $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-server-build: - cd $(SAI_CHALLENGER_PATH) && ./build.sh -i server -a trident2 -t saivs - -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-server-start: - cd $(SAI_CHALLENGER_PATH) && ./run.sh -i server -a trident2 -t saivs -r - -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-server-stop: - cd $(SAI_CHALLENGER_PATH) && ./run.sh -i server -a trident2 -t saivs -c stop - -# SAI-C SERVER STAFF IS TEMPORARY AND WILL BE REMOVED LATER -sai-challenger-create-veth: - sudo $(SAI_CHALLENGER_PATH)/veth-create-host.sh $(CONTAINER_SAI_CHALLENGER_SERVER_NAME) $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) +run-saic-test-thrift: deploy-ixiac + $(CONTAINER_SAI_CHALLENGER_CLIENT_EXEC) pytest -sv --setup=sai_dpu_client_server.json test_sai_vnet_inbound.py ############################### # ENVIRONMENT SETUP TARGETS diff --git a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client index c66498641..9ad8fc7ba 100644 --- a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client +++ b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client @@ -1,28 +1,40 @@ FROM sc-client -ADD tests/ /tests/ +ENV SAI_CHALLENGER_PATH /sai-challenger +ENV DASH_PATH /dash -RUN python3 -m pip install -r /tests/requirements.txt && \ - pip3 install scapy pysubnettree +ADD tests/ /tests/ # Copy distro PTF submodule and tools from SAI repo ADD SAI/SAI/test/ptf /SAI/test/ptf + # Install PTF test framework & test-cases from SAI repo ADD SAI/SAI/ptf /SAI/ptf/ + # Copy thrift python distro ADD SAI/rpc/thrift-0.11.0.tar.gz / + # Copy autogenerated saithrift library built from SAI headers for DASH dataplane ADD SAI/rpc/saithrift-0.9.tar.gz / + # Install the python libraries -RUN cd /saithrift-0.9 && \ - python3 setup.py install && \ +RUN python3 -m pip install -r /tests/requirements.txt && \ + pip3 install scapy \ + pysubnettree \ + macaddress \ + munch && \ + cd /saithrift-0.9 && \ + python3 setup.py install && \ cd / && \ - rm -rf saithrift-0.9 &&\ + rm -rf saithrift-0.9 &&\ cd thrift-0.11.0 && \ - python3 setup.py install && \ + python3 setup.py install && \ cd / &&\ - rm -rf thrift-0.11.0 && \ + rm -rf thrift-0.11.0 && \ cd /SAI/test/ptf && \ - python3 setup.py install + python3 setup.py install && \ + ln -s ${SAI_CHALLENGER_PATH} /usr/local/lib/python3.7/dist-packages/saichallenger && \ + ln -s ${DASH_PATH}/test/test-cases/test_vector_example ${SAI_CHALLENGER_PATH}/test_vector_example && \ + ln -s ${DASH_PATH}/test/third-party/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen CMD ["/usr/bin/supervisord"] diff --git a/dash-pipeline/test/third-party/cgyang b/dash-pipeline/test/third-party/cgyang new file mode 160000 index 000000000..d1c65a161 --- /dev/null +++ b/dash-pipeline/test/third-party/cgyang @@ -0,0 +1 @@ +Subproject commit d1c65a16128003e05f05f0c138c15260abedacdd From 9ce438c130be58ef62f6469a05030e8f1e198a15 Mon Sep 17 00:00:00 2001 From: Kostiantyn Goloveshko Date: Wed, 7 Sep 2022 17:22:51 +0300 Subject: [PATCH 07/45] Fixup VNET inbound cleanup removals in test config. Signed-off-by: Konstantin Goloveshko --- .../test_vnet_inbound_cleanup_commands.json | 53 ++++--------------- 1 file changed, 9 insertions(+), 44 deletions(-) diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json index 3de3d4b31..409525e57 100644 --- a/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json @@ -1,73 +1,38 @@ [ { "name": "pa_validation_entry", - "op": "remove", - "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", - "key": { - "switch_id": "$SWITCH_ID", - "eni_id": "$eni_id", - "sip": "20.20.20.20", - "vni": "1000" - } + "op": "remove" }, { "name": "inbound_routing_entry", - "op": "remove", - "type": "SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY", - "key": { - "switch_id": "$SWITCH_ID", - "vni": "1000" - } + "op": "remove" }, { "name": "eni_ether_address_map_entry", - "op": "remove", - "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", - "key": { - "switch_id": "$SWITCH_ID", - "address": "00:AA:AA:AA:AA:00" - } + "op": "remove" }, { "name": "eni_id", - "op": "remove", - "type": "SAI_OBJECT_TYPE_ENI", - "key": "$eni_id" + "op": "remove" }, { "name": "vnet_1", - "op": "remove", - "type": "SAI_OBJECT_TYPE_VNET", - "key": "$vnet_1" + "op": "remove" }, { "name": "acl_out_1", - "op": "remove", - "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", - "key": "$acl_out_1" + "op": "remove" }, { "name": "acl_in_1", - "op": "remove", - "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", - "key": "$acl_in_1" + "op": "remove" }, { "name": "direction_lookup_entry", - "op": "remove", - "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", - "key": { - "switch_id": "$SWITCH_ID", - "vni": "2000" - } + "op": "remove" }, { "name": "vip_entry", - "op": "remove", - "type": "SAI_OBJECT_TYPE_VIP_ENTRY", - "key": { - "switch_id": "$SWITCH_ID", - "vip": "192.168.0.1" - } + "op": "remove" } ] \ No newline at end of file From 987f8d1dcd83cd47dc40aead92c817e20db6933e Mon Sep 17 00:00:00 2001 From: Maksym Prytoliuk <71631949+maksym-prytoliuk-plv@users.noreply.github.com> Date: Wed, 7 Sep 2022 17:23:31 +0300 Subject: [PATCH 08/45] Update CA_TO_PA entry in outbound test Signed-off-by: Maksym Prytoliuk --- .../test_vnet_outbound_setup_commands.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json index f5e537bd3..799ba340e 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json @@ -134,12 +134,14 @@ "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "eni_id": "$eni", - "dip": "10.10.2.10", - "vni": "1000" + "dst_vnet_id": "$vnet", + "dip": "10.1.2.50" }, "attributes": [ - "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", "SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT" + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.1.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:DD", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" ] } ] + From ea542512041e0ccfb910096164a4937b0af11a97 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Wed, 7 Sep 2022 17:27:22 +0300 Subject: [PATCH 09/45] Add vnet scenarios in DASH config format. * Added dash-style VNET inbound routing test * Added dash-style VNET outbound routing test * Read config from json (temp workaround) * Added JSON setup configs for testbed Signed-off-by: Anton Putria Co-authored-by: Maksym Prytoliuk --- test/SAI-Challenger.OCP | 2 +- .../test_vector_example/conftest.py | 42 +++- .../sai_dpu_client_server_ptf.json | 41 ++++ .../sai_dpu_client_server_snappi.json | 42 ++++ .../test_sai_vnet_inbound.py | 184 ++++++++++++++++ .../test_sai_vnet_outbound.py | 203 ++++++++++++++++++ .../test_vnet_outbound_setup_commands.json | 32 +-- 7 files changed, 519 insertions(+), 27 deletions(-) create mode 100755 test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json create mode 100755 test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_inbound.py create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_outbound.py diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP index b5a6d9416..5674bdc6f 160000 --- a/test/SAI-Challenger.OCP +++ b/test/SAI-Challenger.OCP @@ -1 +1 @@ -Subproject commit b5a6d9416778f584ac2264a11665b3b98ce8df4a +Subproject commit 5674bdc6fcb4fe2094e0a8f3941e2360f4158d3e diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py index 8dc3fa085..f0986aa53 100644 --- a/test/test-cases/test_vector_example/conftest.py +++ b/test/test-cases/test_vector_example/conftest.py @@ -1,11 +1,14 @@ import logging - import pytest -import sys -sys.path.insert(0, '/sai-challenger/common') # Needed for correct load_module -from sai_dpu import SaiDpu -from sai_environment import init_setup +import saigen +from saigen.confbase import ConfBase + +# import sys +# sys.path.insert(0, '/sai-challenger/common') # Needed for correct load_module + +from saichallenger.common.sai_dpu import SaiDpu +from saichallenger.common.sai_environment import init_setup def pytest_addoption(parser): @@ -23,6 +26,7 @@ def exec_params(request): logging.getLogger().setLevel(getattr(logging, config_param["loglevel"].upper(), "INFO")) return config_param + @pytest.fixture(scope="session") def dpu(exec_params) -> SaiDpu: dpu = exec_params["setup"]["DPU"][0] @@ -30,6 +34,7 @@ def dpu(exec_params) -> SaiDpu: dpu.reset() return dpu + @pytest.fixture(scope="session") def dataplane_session(exec_params): dataplane = exec_params["setup"]["DATAPLANE"][0] @@ -45,3 +50,30 @@ def dataplane(dataplane_session): dataplane_session.setUp() yield dataplane_session dataplane_session.tearDown() + + +@pytest.fixture(scope="session") +def confgen(): + + class SaiConfig(ConfBase): + + def generate(self): + # Pass top-level params to sub-generrators. + self.configs = [ + saigen.vips.Vips(self.params_dict), + saigen.direction_lookup.DirectionLookup(self.params_dict), + saigen.acl_groups.AclGroups(self.params_dict), + saigen.vnets.Vnets(self.params_dict), + saigen.enis.Enis(self.params_dict), + saigen.address_maps.AddressMaps(self.params_dict), + saigen.inbound_routing.InboundRouting(self.params_dict), + saigen.pa_validation.PaValidation(self.params_dict), + ] + + def items(self, reverse=False): + result = [] + for c in self.configs: + result.extend(c.items()) + return result + + return SaiConfig({}, saigen.simple_params.simple_params) diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json b/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json new file mode 100755 index 000000000..80c55496a --- /dev/null +++ b/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json @@ -0,0 +1,41 @@ +{"DPU": [ + { + "alias": "dash", + "asic": "generic", + "target": "bmv2", + "type": null, + "sku": null, + "mode": "client-server", + "sai_server_ip": "127.0.0.1", + "client": { + "type": "thrift", + "config": { + "ip": "127.0.0.1", + "port": "9092" + } + }, + "port_groups": [{"1x10G": "Ethernet0", "init": "1x10G", "alias": 0}, + {"1x10G": "Ethernet1", "init": "1x10G", "alias": 1} + ], + "sai_dataplane": "ptf_nn" + } +], + +"DATAPLANE": [ + { + "alias": "ptf", + "type": "ptf", + "mode": "eth", + "port_groups": [{"10G": "veth1", "init": "10G", "alias": 0}, + {"10G": "veth2", "init": "10G", "alias": 1} + ] + } +], + +"CONNECTIONS": { + "ptf->dash": [[0, 0], + [1, 1] + ] +} + +} diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json b/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json new file mode 100755 index 000000000..4477124ab --- /dev/null +++ b/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json @@ -0,0 +1,42 @@ +{"DPU": [ + { + "alias": "dash", + "asic": "generic", + "target": "bmv2", + "type": null, + "sku": null, + "mode": "client-server", + "sai_server_ip": "127.0.0.1", + "client": { + "type": "thrift", + "config": { + "ip": "127.0.0.1", + "port": "9092" + } + }, + "port_groups": [{"1x10G": "Ethernet0", "init": "1x10G", "alias": 0}, + {"1x10G": "Ethernet1", "init": "1x10G", "alias": 1} + ], + "sai_dataplane": "ptf_nn" + } +], + +"DATAPLANE": [ + { + "alias": "ixia", + "type": "snappi", + "mode": "ixia_c", + "controller": "https://127.0.0.1:443", + "port_groups": [{"10G": "veth1", "init": "10G", "alias": 0}, + {"10G": "veth2", "init": "10G", "alias": 1} + ] + } +], + +"CONNECTIONS": { + "ixia->dash": [[0, 0], + [1, 1] + ] +} + +} diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py new file mode 100644 index 000000000..c11680a10 --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py @@ -0,0 +1,184 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_packet) + +current_file_dir = Path(__file__).parent + +# Constants +VIP = "10.10.1.1" +SWITCH_ID = 1 +DIR_LOOKUP_VNI = 60 +VM_VNI = 9 +ENI_MAC = "00:00:00:09:03:14" +PA_VALIDATION_SIP = "10.10.2.10" +PA_VALIDATION_DIP = "10.10.2.20" +INBOUND_ROUTING_VNI = 2 +INNER_VM_IP = "172.19.1.100" +INNER_REMOTE_IP = "172.19.1.1" + +# Test Vector +TEST_VNET_INBOUND_CONFIG = { + + 'ENI_COUNT': 1, + + 'DASH_VIP': [ + {'vip_1': {'IPv4': VIP}} + ], + + 'DASH_DIRECTION_LOOKUP': [ + {'direction_lookup': {'VNI': DIR_LOOKUP_VNI}} + ], + + 'DASH_ACL_GROUP': [ + {'acl_out_1': {'ADDR_FAMILY': 'IPv4'}} + ], + + 'DASH_ACL_RULE': [ + {'acl_rule_1': {'action': 'permit"', + 'dip': '10.0.0.1', + 'gid': '$acl_out_1', + 'priority': 10} + } + ], + + 'DASH_VNET': [ + {'vnet_1': {'VNI': DIR_LOOKUP_VNI}} + ], + + 'DASH_ENI': [ + {'eni_1': + {'ACL_GROUP': { + 'INBOUND': [{'STAGE1': '$acl_in_1'}, + {'STAGE2': '$acl_in_1'}, + {'STAGE3': '$acl_in_1'}, + {'STAGE4': '$acl_in_1'}, + {'STAGE5': '$acl_in_1'} + ], + 'OUTBOUND': [{'STAGE1': '$acl_out_1'}, + {'STAGE2': '$acl_out_1'}, + {'STAGE3': '$acl_out_1'}, + {'STAGE4': '$acl_out_1'}, + {'STAGE5': '$acl_out_1'} + ] + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': PA_VALIDATION_DIP, + 'VM_VNI': VM_VNI, + 'VNET_ID': '$vnet_1'} + } + ], + + 'DASH_ENI_ETHER_ADDRESS_MAP': [ + {'address_map_1': { + 'MAC': ENI_MAC, + 'VNI': INBOUND_ROUTING_VNI} + } + ], + + 'DASH_ROUTE_RULE_TABLE': [ + {'inbound_routing_1': { + 'VNI': INBOUND_ROUTING_VNI, + 'action_type': 'DECAP_PA_VALIDATE'} + } + ], + + 'DASH_PA_VALIDATION': [ + {'pa_validation_1': {'action': 'permit', + 'eni': '$eni_1', + 'sip': PA_VALIDATION_SIP, + 'switch_id': SWITCH_ID, + 'vni': INBOUND_ROUTING_VNI} + } + ] + +} + + +class TestSaiVnetInbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) + confgen.generate() + for item in confgen.items(): + pprint(item) + + with (current_file_dir / 'test_vnet_inbound_setup_commands.json').open(mode='r') as config_file: + vnet_inbound_setup_commands = json.load(config_file) + result = [*dpu.process_commands(vnet_inbound_setup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) + + def test_run_traffic_check(self, dpu, dataplane): + # Check forwarding + + outer_smac = "00:0a:05:06:06:06" + outer_dmac = "00:0b:05:06:06:06" + inner_smac = "00:0a:04:06:06:06" + inner_dmac = "00:0b:04:06:06:06" + + # PAcket to send + inner_pkt = simple_udp_packet(eth_dst=ENI_MAC, + eth_src=inner_smac, + ip_dst=INNER_VM_IP, + ip_src=INNER_REMOTE_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst=outer_dmac, + eth_src=outer_smac, + ip_dst=PA_VALIDATION_DIP, + ip_src=PA_VALIDATION_SIP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=DIR_LOOKUP_VNI, + inner_frame=inner_pkt) + + # Expected Packet to check + inner_exp_pkt = simple_udp_packet(eth_dst=inner_dmac, + eth_src=ENI_MAC, + ip_dst=INNER_VM_IP, + ip_src=INNER_REMOTE_IP) + vxlan_exp_pkt = simple_vxlan_packet(eth_dst="00:00:00:00:00:00", + eth_src="00:00:00:00:00:00", + ip_dst=PA_VALIDATION_DIP, + ip_src=PA_VALIDATION_SIP, + udp_sport=0, + with_udp_chksum=False, + vxlan_vni=INBOUND_ROUTING_VNI, + inner_frame=inner_exp_pkt) + # TODO: Fix IP chksum + vxlan_exp_pkt['IP'].chksum = 0 + # # TODO: Fix UDP length + vxlan_exp_pkt['IP']['UDP']['VXLAN'].flags = 0 + + dataplane.start_capture() + print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) + send_packet(dataplane, 0, vxlan_pkt) + + print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) + verify_packet(dataplane, vxlan_exp_pkt, 1) + + print ("run_traffic_check OK") + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) + confgen.generate() + + for item in confgen.items(): + item['OP'] = 'remove' + pprint(item) + + with (current_file_dir / 'test_vnet_inbound_cleanup_commands.json').open(mode='r') as config_file: + vnet_inbound_cleanup_commands = json.load(config_file) + + result = [*dpu.process_commands(vnet_inbound_cleanup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py new file mode 100644 index 000000000..bb15e6a04 --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py @@ -0,0 +1,203 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_packet) + +current_file_dir = Path(__file__).parent + +# Constants +SWITCH_ID = 5 +OUTBOUND_VNI = 60 +VNET_VNI = 100 +VM_VNI = 9 +ENI_MAC = "00:CC:CC:CC:CC:CC" +OUR_MAC = "00:00:02:03:04:05" +DST_CA_MAC = "00:DD:DD:DD:DD:DD" +VIP = "172.16.1.100" +OUTBOUND_VNI = 100 +DST_CA_IP = "10.1.2.50" +DST_PA_IP = "172.16.1.20" +SRC_VM_PA_IP = "172.16.1.1" +CA_PREFIX = "10.1.0.0/16" + +# Test Vector +TEST_VNET_OUTBOUND_CONFIG = { + 'DASH_VIP': [ + { 'vpe': + { 'SWITCH_ID': '$SWITCH_ID', + 'IPv4': VIP } + } + ], + + 'DASH_DIRECTION_LOOKUP': [ + { 'dle': + { 'SWITCH_ID': '$SWITCH_ID', + 'VNI': OUTBOUND_VNI, + 'ACTION': 'SET_OUTBOUND_DIRECTION' } + } + ], + + 'DASH_ACL_GROUP': [ + { 'in_acl_group_id': + { 'ADDR_FAMILY': 'IPv4' } + }, + { 'out_acl_group_id': + { 'ADDR_FAMILY': 'IPv4' } + } + ], + + 'DASH_VNET': [ + { 'vnet': + { 'VNI': VNET_VNI } + } + ], + + 'DASH_ENI': [ + { 'eni': + {'ACL_GROUP': { + 'INBOUND': [{ 'STAGE1': 0 }, + { 'STAGE2': 0 }, + { 'STAGE3': 0 }, + { 'STAGE4': 0 }, + { 'STAGE5': 0 } + ], + 'OUTBOUND': [{ 'STAGE1': 0 }, + { 'STAGE2': 0 }, + { 'STAGE3': 0 }, + { 'STAGE4': 0 }, + { 'STAGE5': 0 } + ] + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': SRC_VM_PA_IP, + 'VM_VNI': VM_VNI, + 'VNET_ID': '$vnet'} + } + ], + +# 'DASH_ACL_RULE': [ +# { 'out_acl_rule_id': +# { 'ACTION': 'PERMIT', +# 'DIP': DST_CA_IP, +# 'GID': '$out_acl_group_id', +# 'PRIORITY': 10 } +# } +# ], + + 'DASH_ENI_ETHER_ADDRESS_MAP': [ + { 'eam': + { 'SWITCH_ID': '$SWITCH_ID', + 'MAC': ENI_MAC, + 'ENI_ID': '$eni' } + } + ], + + 'DASH_OUTBOUND_ROUTING': [ + { 'ore': + { 'SWITCH_ID': '$SWITCH_ID', + 'ENI_ID': '$eni', + 'DESTINATION': CA_PREFIX, + 'ACTION': 'ROUTE_VNET', + 'DST_VNET_ID': '$vnet' } + } + ], + + 'DASH_OUTBOUND_CA_TO_PA': [ + { 'ocpe': + { 'SWITCH_ID': '$SWITCH_ID', + 'DST_VNET_ID': '$vnet', + 'DIP': DST_PA_IP, + 'UNDERLAY_DIP': DST_PA_IP, + 'OVERLAY_DMAC': DST_CA_MAC, + 'USE_DST_VNET_VNI': True } + } + ] +} + + +class TestSaiVnetOutbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) + confgen.generate() + + for item in confgen.items(): + # dpu.process_commands(item) + # dpu.process_commands(confgen.items()) + pprint(item) + + with (current_file_dir / 'test_vnet_outbound_setup_commands.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + + result = [*dpu.process_commands(setup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) + + def test_run_traffic_check(self, dpu, dataplane): + + src_vm_ip = "10.1.1.10" + outer_smac = "00:00:05:06:06:06" + inner_smac = "00:00:04:06:06:06" + + inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + eth_src=ENI_MAC, + ip_dst=DST_CA_IP, + ip_src=src_vm_ip) + vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + eth_src=outer_smac, + ip_dst=VIP, + ip_src=SRC_VM_PA_IP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=OUTBOUND_VNI, + inner_frame=inner_pkt) + + inner_exp_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, + eth_src=ENI_MAC, + ip_dst=DST_CA_IP, + ip_src=src_vm_ip) + vxlan_exp_pkt = simple_vxlan_packet(eth_dst="00:00:00:00:00:00", + eth_src="00:00:00:00:00:00", + ip_dst=DST_PA_IP, + ip_src=VIP, + udp_sport=0, # TODO: Fix sport in pipeline + with_udp_chksum=False, + vxlan_vni=VNET_VNI, + inner_frame=inner_exp_pkt) + # TODO: Fix IP chksum + vxlan_exp_pkt['IP'].chksum = 0 + # TODO: Fix UDP length + vxlan_exp_pkt['IP']['UDP']['VXLAN'].flags = 0 + self.pkt_exp = vxlan_exp_pkt + + print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) + send_packet(self, 0, vxlan_pkt) + print("\nVerifying packet...\n", self.pkt_exp.__repr__()) + verify_packet(self, self.pkt_exp, 0) + print ("test_sai_vnet_outbound OK") + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) + confgen.generate() + + for item in confgen.items(): + item['OP'] = 'remove' + pprint(item) + #dpu.process_commands(item) + + with (current_file_dir / 'test_vnet_outbound_cleanup_commands.json').open(mode='r') as config_file: + cleanup_commands = json.load(config_file) + + result = [*dpu.process_commands(cleanup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json index 799ba340e..97805bc2a 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json @@ -59,16 +59,6 @@ "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.20", "SAI_ENI_ATTR_VM_VNI", "9", "SAI_ENI_ATTR_VNET_ID", "$vnet", -# "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "$in_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "$in_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "$in_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "$in_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "$in_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "$out_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "$out_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "$out_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "$out_acl_group_id", -# "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "$out_acl_group_id", "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", @@ -103,17 +93,17 @@ "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni" ] }, -# { -# "name": "out_acl_rule_id", -# "op": "create", -# "type": "SAI_OBJECT_TYPE_DASH_ACL_RULE", -# "attributes": [ -# "SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID", "$out_acl_group_id", -# "SAI_DASH_ACL_RULE_ATTR_DIP", "10.1.2.50", -# "SAI_DASH_ACL_RULE_ATTR_PRIORITY", "10", -# "SAI_DASH_ACL_RULE_ATTR_ACTION", "SAI_DASH_ACL_RULE_ACTION_PERMIT" -# ] -# }, +{ + "name": "out_acl_rule_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_RULE", + "attributes": [ + "SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID", "$out_acl_group_id", + "SAI_DASH_ACL_RULE_ATTR_DIP", "10.1.2.50", + "SAI_DASH_ACL_RULE_ATTR_PRIORITY", "10", + "SAI_DASH_ACL_RULE_ATTR_ACTION", "SAI_DASH_ACL_RULE_ACTION_PERMIT" + ] + }, { "name": "ore", "op": "create", From 1d8df5988e25ea63b7416f1c7ca12c8d615dbed4 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Wed, 7 Sep 2022 16:31:10 +0000 Subject: [PATCH 10/45] Fixed saigen links. Signed-off-by: Anton Putria --- .gitmodules | 3 --- dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index b498af97b..264df5ad5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,9 +6,6 @@ path = test/SAI-Challenger.OCP url = https://github.com/plvisiondevs/SAI-Challenger.OCP branch = dash-testing -[submodule "test/third-party/cgyang"] - path = test/third-party/cgyang - url = https://github.com/mgheorghe/cgyang [submodule "dash-pipeline/test/third-party/cgyang"] path = dash-pipeline/test/third-party/cgyang url = https://github.com/mgheorghe/cgyang diff --git a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client index 9ad8fc7ba..e0f07bbc0 100644 --- a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client +++ b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client @@ -11,7 +11,7 @@ ADD SAI/SAI/test/ptf /SAI/test/ptf # Install PTF test framework & test-cases from SAI repo ADD SAI/SAI/ptf /SAI/ptf/ -# Copy thrift python distro +# Copy thrift python distro ADD SAI/rpc/thrift-0.11.0.tar.gz / # Copy autogenerated saithrift library built from SAI headers for DASH dataplane @@ -35,6 +35,6 @@ RUN python3 -m pip install -r /tests/requirements.txt && \ python3 setup.py install && \ ln -s ${SAI_CHALLENGER_PATH} /usr/local/lib/python3.7/dist-packages/saichallenger && \ ln -s ${DASH_PATH}/test/test-cases/test_vector_example ${SAI_CHALLENGER_PATH}/test_vector_example && \ - ln -s ${DASH_PATH}/test/third-party/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen + ln -s ${DASH_PATH}/dash-pipeline/test/third-party/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen CMD ["/usr/bin/supervisord"] From 4da8289f9a4258fdbb8cf528f159d89d24b70055 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Thu, 8 Sep 2022 07:44:45 +0000 Subject: [PATCH 11/45] Fixes in test scanario. Signed-off-by: Anton Putria --- .../test_vnet_inbound_setup_commands.json | 5 ++--- .../test_vnet_outbound_cleanup_commands.json | 4 ---- .../test_vnet_outbound_setup_commands.json | 11 ----------- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json index 1dbdd9071..8968a67d8 100644 --- a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json @@ -145,9 +145,8 @@ "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "eni_id": "$eni_id", - "sip": "10.10.2.10", - "vni": "1000" + "vnet_id": "$vnet_1", + "sip": "10.10.2.10" }, "attributes": [ "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json index 556f415ce..3a32ff45f 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json @@ -7,10 +7,6 @@ "name": "ore", "op": "remove" }, -# { -# "name": "out_acl_rule_id", -# "op": "remove" -# }, { "name": "eam", "op": "remove" diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json index 97805bc2a..28dc6458b 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json @@ -93,17 +93,6 @@ "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni" ] }, -{ - "name": "out_acl_rule_id", - "op": "create", - "type": "SAI_OBJECT_TYPE_DASH_ACL_RULE", - "attributes": [ - "SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID", "$out_acl_group_id", - "SAI_DASH_ACL_RULE_ATTR_DIP", "10.1.2.50", - "SAI_DASH_ACL_RULE_ATTR_PRIORITY", "10", - "SAI_DASH_ACL_RULE_ATTR_ACTION", "SAI_DASH_ACL_RULE_ACTION_PERMIT" - ] - }, { "name": "ore", "op": "create", From 49d62f6d7f41779d19a759fed47522241d1ad671 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Thu, 8 Sep 2022 09:26:51 +0000 Subject: [PATCH 12/45] Fixed path to saigen. Fixed inbound test. Signed-off-by: Anton Putria --- .gitmodules | 4 ++-- dash-pipeline/{test/third-party => }/cgyang | 0 dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client | 2 +- .../test_vnet_inbound_setup_commands.json | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) rename dash-pipeline/{test/third-party => }/cgyang (100%) diff --git a/.gitmodules b/.gitmodules index 264df5ad5..2e2092019 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,6 +6,6 @@ path = test/SAI-Challenger.OCP url = https://github.com/plvisiondevs/SAI-Challenger.OCP branch = dash-testing -[submodule "dash-pipeline/test/third-party/cgyang"] - path = dash-pipeline/test/third-party/cgyang +[submodule "dash-pipeline/cgyang"] + path = dash-pipeline/cgyang url = https://github.com/mgheorghe/cgyang diff --git a/dash-pipeline/test/third-party/cgyang b/dash-pipeline/cgyang similarity index 100% rename from dash-pipeline/test/third-party/cgyang rename to dash-pipeline/cgyang diff --git a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client index e0f07bbc0..5230ca8c9 100644 --- a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client +++ b/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client @@ -35,6 +35,6 @@ RUN python3 -m pip install -r /tests/requirements.txt && \ python3 setup.py install && \ ln -s ${SAI_CHALLENGER_PATH} /usr/local/lib/python3.7/dist-packages/saichallenger && \ ln -s ${DASH_PATH}/test/test-cases/test_vector_example ${SAI_CHALLENGER_PATH}/test_vector_example && \ - ln -s ${DASH_PATH}/dash-pipeline/test/third-party/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen + ln -s ${DASH_PATH}/dash-pipeline/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen CMD ["/usr/bin/supervisord"] diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json index 8968a67d8..1dbdd9071 100644 --- a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json @@ -145,8 +145,9 @@ "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "vnet_id": "$vnet_1", - "sip": "10.10.2.10" + "eni_id": "$eni_id", + "sip": "10.10.2.10", + "vni": "1000" }, "attributes": [ "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", From b2422907edd404a1507ce8807ffb8cd9e4ef75f8 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Thu, 8 Sep 2022 09:36:50 +0000 Subject: [PATCH 13/45] Update submodule Signed-off-by: Anton Putria --- test/SAI-Challenger.OCP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP index 5674bdc6f..06c7d9d44 160000 --- a/test/SAI-Challenger.OCP +++ b/test/SAI-Challenger.OCP @@ -1 +1 @@ -Subproject commit 5674bdc6fcb4fe2094e0a8f3941e2360f4158d3e +Subproject commit 06c7d9d4475045fbf243b1f5b055d36f97cf294f From bb44f60208345953c2000ed146e4bad9ef9e5537 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Thu, 8 Sep 2022 10:08:20 +0000 Subject: [PATCH 14/45] Final test fixes to align with submodue version. Signed-off-by: Anton Putria --- test/test-cases/test_vector_example/conftest.py | 3 ++- .../test_vector_example/test_sai_vnet_outbound.py | 11 ++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py index f0986aa53..b51ff4301 100644 --- a/test/test-cases/test_vector_example/conftest.py +++ b/test/test-cases/test_vector_example/conftest.py @@ -76,4 +76,5 @@ def items(self, reverse=False): result.extend(c.items()) return result - return SaiConfig({}, saigen.simple_params.simple_params) + return SaiConfig() + # return SaiConfig({}, saigen.simple_params.simple_params) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py index bb15e6a04..0605aa9cf 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py @@ -129,15 +129,11 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) confgen.generate() - for item in confgen.items(): - # dpu.process_commands(item) - # dpu.process_commands(confgen.items()) pprint(item) with (current_file_dir / 'test_vnet_outbound_setup_commands.json').open(mode='r') as config_file: setup_commands = json.load(config_file) - result = [*dpu.process_commands(setup_commands)] print("\n======= SAI commands RETURN values =======") pprint(result) @@ -180,9 +176,11 @@ def test_run_traffic_check(self, dpu, dataplane): self.pkt_exp = vxlan_exp_pkt print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) - send_packet(self, 0, vxlan_pkt) + send_packet(dataplane, 0, vxlan_pkt) + print("\nVerifying packet...\n", self.pkt_exp.__repr__()) - verify_packet(self, self.pkt_exp, 0) + verify_packet(dataplane, self.pkt_exp, 0) + print ("test_sai_vnet_outbound OK") def test_remove_vnet_config(self, confgen, dpu, dataplane): @@ -193,7 +191,6 @@ def test_remove_vnet_config(self, confgen, dpu, dataplane): for item in confgen.items(): item['OP'] = 'remove' pprint(item) - #dpu.process_commands(item) with (current_file_dir / 'test_vnet_outbound_cleanup_commands.json').open(mode='r') as config_file: cleanup_commands = json.load(config_file) From 608dbc05f3d58ec7f3252119dbb54ca0fed367f6 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Wed, 14 Sep 2022 06:33:40 +0000 Subject: [PATCH 15/45] Fixed VNET outbound test scenario. Signed-off-by: Anton Putria --- .../test_sai_vnet_inbound.py | 17 ++++--- .../test_sai_vnet_outbound.py | 48 +++++++++---------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py index c11680a10..c2a742349 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py @@ -25,7 +25,12 @@ # Test Vector TEST_VNET_INBOUND_CONFIG = { - 'ENI_COUNT': 1, + 'ACL_TABLE_COUNT': 1, + 'ENI_COUNT': 1, + 'ENI_START': 1, + 'IP_PER_ACL_RULE': 1, + 'IP_MAPPED_PER_ACL_RULE': 1, + 'IP_ROUTE_DIVIDER_PER_ACL_RULE': 8, 'DASH_VIP': [ {'vip_1': {'IPv4': VIP}} @@ -149,24 +154,18 @@ def test_run_traffic_check(self, dpu, dataplane): eth_src="00:00:00:00:00:00", ip_dst=PA_VALIDATION_DIP, ip_src=PA_VALIDATION_SIP, - udp_sport=0, + udp_sport=11638, with_udp_chksum=False, vxlan_vni=INBOUND_ROUTING_VNI, inner_frame=inner_exp_pkt) - # TODO: Fix IP chksum - vxlan_exp_pkt['IP'].chksum = 0 - # # TODO: Fix UDP length - vxlan_exp_pkt['IP']['UDP']['VXLAN'].flags = 0 - dataplane.start_capture() + # dataplane.start_capture() print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) send_packet(dataplane, 0, vxlan_pkt) print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) verify_packet(dataplane, vxlan_exp_pkt, 1) - print ("run_traffic_check OK") - def test_remove_vnet_config(self, confgen, dpu, dataplane): confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py index 0605aa9cf..ab3d818be 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py @@ -15,9 +15,9 @@ OUTBOUND_VNI = 60 VNET_VNI = 100 VM_VNI = 9 -ENI_MAC = "00:CC:CC:CC:CC:CC" +ENI_MAC = "00:cc:cc:cc:cc:cc" OUR_MAC = "00:00:02:03:04:05" -DST_CA_MAC = "00:DD:DD:DD:DD:DD" +DST_CA_MAC = "00:dd:dd:dd:dd:dd" VIP = "172.16.1.100" OUTBOUND_VNI = 100 DST_CA_IP = "10.1.2.50" @@ -27,6 +27,14 @@ # Test Vector TEST_VNET_OUTBOUND_CONFIG = { + + 'ACL_TABLE_COUNT': 1, + 'ENI_COUNT': 1, + 'ENI_START': 1, + 'IP_PER_ACL_RULE': 1, + 'IP_MAPPED_PER_ACL_RULE': 1, + 'IP_ROUTE_DIVIDER_PER_ACL_RULE': 8, + 'DASH_VIP': [ { 'vpe': { 'SWITCH_ID': '$SWITCH_ID', @@ -142,9 +150,8 @@ def test_run_traffic_check(self, dpu, dataplane): src_vm_ip = "10.1.1.10" outer_smac = "00:00:05:06:06:06" - inner_smac = "00:00:04:06:06:06" - inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + inner_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, eth_src=ENI_MAC, ip_dst=DST_CA_IP, ip_src=src_vm_ip) @@ -158,30 +165,23 @@ def test_run_traffic_check(self, dpu, dataplane): inner_frame=inner_pkt) inner_exp_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, - eth_src=ENI_MAC, - ip_dst=DST_CA_IP, - ip_src=src_vm_ip) - vxlan_exp_pkt = simple_vxlan_packet(eth_dst="00:00:00:00:00:00", - eth_src="00:00:00:00:00:00", - ip_dst=DST_PA_IP, - ip_src=VIP, - udp_sport=0, # TODO: Fix sport in pipeline - with_udp_chksum=False, - vxlan_vni=VNET_VNI, - inner_frame=inner_exp_pkt) - # TODO: Fix IP chksum - vxlan_exp_pkt['IP'].chksum = 0 - # TODO: Fix UDP length - vxlan_exp_pkt['IP']['UDP']['VXLAN'].flags = 0 - self.pkt_exp = vxlan_exp_pkt + eth_src=ENI_MAC, + ip_dst=DST_CA_IP, + ip_src=src_vm_ip) + vxlan_exp_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + eth_src=outer_smac, + ip_dst=VIP, + ip_src=SRC_VM_PA_IP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=VNET_VNI, + inner_frame=inner_exp_pkt) print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) send_packet(dataplane, 0, vxlan_pkt) - print("\nVerifying packet...\n", self.pkt_exp.__repr__()) - verify_packet(dataplane, self.pkt_exp, 0) - - print ("test_sai_vnet_outbound OK") + print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) + verify_packet(dataplane, vxlan_exp_pkt, 0) def test_remove_vnet_config(self, confgen, dpu, dataplane): From 72afca435a10080e231002e6dcf1ee91774530cd Mon Sep 17 00:00:00 2001 From: Maksym Prytoliuk <71631949+maksym-prytoliuk-plv@users.noreply.github.com> Date: Thu, 15 Sep 2022 15:22:49 +0300 Subject: [PATCH 16/45] Outbound test passes with traffic Fixed configuration based on changes in main. Signed-off-by: Maksym Prytoliuk --- .../test_sai_vnet_outbound.py | 115 ++++++++++++++---- .../test_vnet_inbound_setup_commands.json | 10 +- .../test_vnet_outbound_setup_commands.json | 6 +- 3 files changed, 98 insertions(+), 33 deletions(-) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py index ab3d818be..bb5849747 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py @@ -6,7 +6,8 @@ from saichallenger.dataplane.ptf_testutils import (send_packet, simple_udp_packet, simple_vxlan_packet, - verify_packet) + verify_packet, + verify_no_other_packets) current_file_dir = Path(__file__).parent @@ -148,40 +149,102 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): def test_run_traffic_check(self, dpu, dataplane): - src_vm_ip = "10.1.1.10" - outer_smac = "00:00:05:06:06:06" + SRC_VM_IP = "10.1.1.10" + OUTER_SMAC = "00:00:05:06:06:06" + INNER_SMAC = "00:00:04:06:06:06" - inner_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, + # # check VIP drop + # WRONG_VIP = "172.16.100.100" + # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + # eth_src=ENI_MAC, + # ip_dst=DST_CA_IP, + # ip_src=SRC_VM_IP) + # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + # eth_src=OUTER_SMAC, + # ip_dst=WRONG_VIP, + # ip_src=SRC_VM_PA_IP, + # udp_sport=11638, + # with_udp_chksum=False, + # vxlan_vni=OUTBOUND_VNI, + # inner_frame=inner_pkt) + # print("\n\nSending packet with wrong vip...\n\n", vxlan_pkt.__repr__()) + # send_packet(dataplane, 0, vxlan_pkt) + # print("\nVerifying drop...") + # verify_no_other_packets(dataplane) + + # # check routing drop + # WRONG_DST_CA = "10.200.2.50" + # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + # eth_src=ENI_MAC, + # ip_dst=WRONG_DST_CA, + # ip_src=SRC_VM_IP) + # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + # eth_src=OUTER_SMAC, + # ip_dst=VIP, + # ip_src=SRC_VM_PA_IP, + # udp_sport=11638, + # with_udp_chksum=False, + # vxlan_vni=OUTBOUND_VNI, + # inner_frame=inner_pkt) + # print("\nSending packet with wrong dst CA IP to verify routing drop...\n\n", vxlan_pkt.__repr__()) + # send_packet(dataplane, 0, vxlan_pkt) + # print("\nVerifying drop...") + # verify_no_other_packets(dataplane) + + # # check mapping drop + # WRONG_DST_CA = "10.1.211.211" + # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + # eth_src=ENI_MAC, + # ip_dst=WRONG_DST_CA, + # ip_src=SRC_VM_IP) + # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + # eth_src=OUTER_SMAC, + # ip_dst=VIP, + # ip_src=SRC_VM_PA_IP, + # udp_sport=11638, + # with_udp_chksum=False, + # vxlan_vni=OUTBOUND_VNI, + # inner_frame=inner_pkt) + # print("\nSending packet with wrong dst CA IP to verify mapping drop...\n\n", vxlan_pkt.__repr__()) + # send_packet(dataplane, 0, vxlan_pkt) + # print("\nVerifying drop...") + # verify_no_other_packets(dataplane) + + # check forwarding + inner_pkt = simple_udp_packet(eth_dst = "02:02:02:02:02:02", + eth_src = ENI_MAC, + ip_dst = DST_CA_IP, + ip_src = SRC_VM_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst = OUR_MAC, + eth_src = OUTER_SMAC, + ip_dst = VIP, + ip_src = SRC_VM_PA_IP, + udp_sport = 11638, + with_udp_chksum = False, + vxlan_vni = OUTBOUND_VNI, + inner_frame = inner_pkt) + + inner_exp_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, eth_src=ENI_MAC, ip_dst=DST_CA_IP, - ip_src=src_vm_ip) - vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - eth_src=outer_smac, - ip_dst=VIP, - ip_src=SRC_VM_PA_IP, - udp_sport=11638, + ip_src=SRC_VM_IP) + vxlan_exp_pkt = simple_vxlan_packet(eth_dst="00:00:00:00:00:00", + eth_src="00:00:00:00:00:00", + ip_dst=DST_PA_IP, + ip_src=VIP, + udp_sport=0, # TODO: Fix sport in pipeline with_udp_chksum=False, - vxlan_vni=OUTBOUND_VNI, - inner_frame=inner_pkt) - - inner_exp_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, - eth_src=ENI_MAC, - ip_dst=DST_CA_IP, - ip_src=src_vm_ip) - vxlan_exp_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - eth_src=outer_smac, - ip_dst=VIP, - ip_src=SRC_VM_PA_IP, - udp_sport=11638, - with_udp_chksum=False, - vxlan_vni=VNET_VNI, - inner_frame=inner_exp_pkt) + vxlan_vni=VNET_VNI, + vxlan_flags=0, + inner_frame=inner_exp_pkt) + vxlan_exp_pkt['IP'].chksum = 0 + self.pkt_exp = vxlan_exp_pkt print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) send_packet(dataplane, 0, vxlan_pkt) - print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) verify_packet(dataplane, vxlan_exp_pkt, 0) + print ("test_sai_thrift_outbound_udp_pkt_test OK") def test_remove_vnet_config(self, confgen, dpu, dataplane): diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json index 1dbdd9071..b9fe9d4de 100644 --- a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json @@ -132,11 +132,14 @@ "type": "SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY", "key": { "switch_id": "$SWITCH_ID", + "eni_id": "$eni_id", "vni": "1000" }, "attributes": [ "SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION", - "SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE" + "SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE", + "SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID", + "$vnet_1" ] }, { @@ -145,13 +148,12 @@ "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "eni_id": "$eni_id", "sip": "10.10.2.10", - "vni": "1000" + "vnet_id": "$vnet_1" }, "attributes": [ "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", "SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT" ] } -] \ No newline at end of file +] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json index 28dc6458b..1cf181ecb 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json +++ b/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json @@ -5,7 +5,7 @@ "type": "SAI_OBJECT_TYPE_VIP_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "vip": "172.16.1.20" + "vip": "172.16.1.100" }, "attributes": [ "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" @@ -17,7 +17,7 @@ "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "vni": "2000" + "vni": "100" }, "attributes": [ "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" @@ -56,7 +56,7 @@ "SAI_ENI_ATTR_PPS", "100000", "SAI_ENI_ATTR_FLOWS", "100000", "SAI_ENI_ATTR_ADMIN_STATE", "True", - "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.20", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.1", "SAI_ENI_ATTR_VM_VNI", "9", "SAI_ENI_ATTR_VNET_ID", "$vnet", "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", From a55b206dc450f8a282cd83e3a7fd6ecf7b53a031 Mon Sep 17 00:00:00 2001 From: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Date: Mon, 19 Sep 2022 12:43:25 +0300 Subject: [PATCH 17/45] Update documentation - Added dash-test-sai-challenger.md doc file under test/docs - Updated Makefile make run-saic-test-thrift target with passing parameters. Signed-off-by: Maksym Hedeon --- dash-pipeline/Makefile | 38 +++++++++++--- test/docs/dash-test-sai-challenger.md | 74 +++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 test/docs/dash-test-sai-challenger.md diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 3eb7270ae..38fb1a198 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -1,9 +1,9 @@ SHELL = /bin/bash # "All" type targets for convenience -all:fix-perms p4 sai saithrift-server docker-saithrift-client test +all:fix-perms p4 sai saithrift-server docker-saithrift-client test build-saic-client -run-all-tests:run-libsai-test deploy-ixiac run-saithrift-client-tests +run-all-tests:run-libsai-test deploy-ixiac run-saithrift-client-tests run-saic-test-thrift run-saithrift-client-tests: run-saithrift-ptftests run-saithrift-pytests run-saithrift-client-dev-tests: run-saithrift-dev-ptftests run-saithrift-dev-pytests @@ -11,7 +11,7 @@ run-saithrift-client-dev-tests: run-saithrift-dev-ptftests run-saithrift-dev-pyt clean: fix-perms kill-all p4-clean sai-clean test-clean network-clean saithrift-server-clean rm -rf bmv2/dash_pipeline.bmv2 -kill-all: kill-saithrift-server kill-switch undeploy-ixiac +kill-all: kill-saithrift-server kill-switch undeploy-ixiac kill-saic-client .PHONY: fix-perms @@ -508,6 +508,22 @@ CONTAINER_SAI_CHALLENGER_CLIENT_NAME = $(DOCKER_SAI_CHALLENGER_CLIENT)-run CONTAINER_SAI_CHALLENGER_CLIENT_EXEC = docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) +# Add passing parameters to the run-saic-test-thrift target. +ifeq (run-saic-test-thrift,$(firstword $(MAKECMDGOALS))) + SAI_CHALLENGER_SETUP_FILE := $(wordlist 2, 2, $(MAKECMDGOALS)) + SAI_CHALLENGER_TEST := $(wordlist 3, 3, $(MAKECMDGOALS)) + $(eval $(SAI_CHALLENGER_SETUP_FILE):;@:) + $(eval $(SAI_CHALLENGER_TEST):;@:) +endif +# If setup file's isn't passed, set it to the default. +ifeq ($(SAI_CHALLENGER_SETUP_FILE),) +SAI_CHALLENGER_SETUP_FILE := sai_dpu_client_server_snappi.json +endif +# If test's name isn't passed, set it to the default. +ifeq ($(SAI_CHALLENGER_TEST),) +SAI_CHALLENGER_TEST := test_sai_vnet_*.py +endif + build-saic-client: cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client docker build \ @@ -515,7 +531,7 @@ build-saic-client: -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ . -run-saic-client: +run-saic-client: deploy-ixiac docker run \ -v $(SAI_CHALLENGER_PATH):/sai-challenger \ --cap-add=NET_ADMIN \ @@ -529,10 +545,20 @@ run-saic-client: $(DOCKER_SAI_CHALLENGER_CLIENT) kill-saic-client: undeploy-ixiac - docker container stop $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) + -docker container stop $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) +# @brief Target with passing parameters. +# @param SAI_CHALLENGER_SETUP_FILE Path to the setup file. +# Default is "../setups/sai_dpu_client_server.json". +# @param SAI_CHALLENGER_TEST Test's name to start. +# Default is empty to start all tests. run-saic-test-thrift: deploy-ixiac - $(CONTAINER_SAI_CHALLENGER_CLIENT_EXEC) pytest -sv --setup=sai_dpu_client_server.json test_sai_vnet_inbound.py +# Check if client container is started. If not - start SAI-Challenger client + ifneq ($(shell docker container inspect -f '{{.State.Status}}' $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME)), running) + echo "SAI-Challenger client container isn't running. Starting client..." + @make -C . run-saic-client + endif + -$(CONTAINER_SAI_CHALLENGER_CLIENT_EXEC) sh -c "pytest -sv --setup=$(SAI_CHALLENGER_SETUP_FILE) $(SAI_CHALLENGER_TEST)" ############################### # ENVIRONMENT SETUP TARGETS diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md new file mode 100644 index 000000000..ccaa60204 --- /dev/null +++ b/test/docs/dash-test-sai-challenger.md @@ -0,0 +1,74 @@ +# General changes +* Added [SAI-Challenger](https://github.com/PLVision/SAI-Challenger.OCP) submodule by path: DASH/test/SAI-Challenger.OCP. +* Added [cgyang](https://github.com/mgheorghe/cgyang) submodule by path: DASH/test/third-party/cgyang. +* Added test cases for SAI-Challenger by path: DASH/test/test-cases/test_vector_example + +# New make targets: +**build-saic-client**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. + +**run-saic-client**: Start Ixia-C and docker container sc-client-thrift-run from image built on build-saic-client target. SAI-Challenger tests (DASH/test/SAI-Challenger.OCP/tests) folder replaced by DASH/test/test-cases/test_vector_example folder inside of container. Binded mount volume with DASH folder. + +**kill-saic-client**: Stop Ixia-C and sc-client-thrift-run container. + +**run-saic-test-thrift**: Run test manually. This target may be triggerred with passing parameters, or with default parameters. +Run with default parameters(Setup file: sai_dpu_client_server_snappi.json; Test: test_sai_vnet_*.pys): +``` +make run-saic-test-thrift +``` +Run with setup parameter and default test parameter (All tests): +``` +make run-saic-test-thrift +``` +Run with setup parameter and test parameter: +``` +make run-saic-test-thrift +``` + +# How to start +## Prepare repository +``` +git clone https://github.com/PLVision/DASH.git +cd DASH && git checkout dev-tests-extension +git submodule update --init --recursive +``` + +## Build environment +``` +cd dash-pipeline +make clean && make all +``` + +## Start environment +Run in the 3 separate windows/tabs. +``` +make run-switch +make run-saithrift-server +``` + +## Run tests manually +Execute test inside the docker `sc-client-thrift-run` container or by `docker exec sc-client-thrift-run ` or by `run-saic-test-thrift` target. + +### Pure SAI tests run +``` +Via Make target: +make run-saic-test-thrift sai_dpu_client_server_snappi.json test_vnet_inbound.py +make run-saic-test-thrift sai_dpu_client_server_snappi.json test_vnet_outbound.py + +Via docker exec: +pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_inbound.py +pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_outbound.py +``` + +### Test Vector format tests +``` +Via Make target: +make run-saic-test-thrift sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py +make run-saic-test-thrift sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py + +Via docker exec: +pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py +pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py +``` + +# Known issues +* [Test Vector format tests ](#Test Vector format tests): traffic check will fail as expected From 00ab287e3ddb27a67eba3149d76c299ade52ce6d Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Mon, 19 Sep 2022 11:19:11 +0000 Subject: [PATCH 18/45] Updated SAI-Challenger submodule. Signed-off-by: Anton Putria --- test/SAI-Challenger.OCP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP index 06c7d9d44..c1b44ba61 160000 --- a/test/SAI-Challenger.OCP +++ b/test/SAI-Challenger.OCP @@ -1 +1 @@ -Subproject commit 06c7d9d4475045fbf243b1f5b055d36f97cf294f +Subproject commit c1b44ba61d7267a5409bbc9c9838f1d327902d7a From 21c44ac32258f0acf8933b55956e759a84339834 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Wed, 21 Sep 2022 16:56:02 +0300 Subject: [PATCH 19/45] Improvements to SAI-Challenger docker flows. - Use docker hub to pull images - Fixed make run-saic-tests to do not show errors - Updated manuals Signed-off-by: Anton Putria --- dash-pipeline/Makefile | 61 +++++++++---------- test/docs/README.md | 9 +-- test/docs/dash-test-sai-challenger.md | 42 ++++++++----- .../test_vector_example/run_vnet_tests.sh | 3 + 4 files changed, 64 insertions(+), 51 deletions(-) create mode 100755 test/test-cases/test_vector_example/run_vnet_tests.sh diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 20e17b162..0d2d60cb6 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -1,7 +1,7 @@ SHELL = /bin/bash # "All" type targets for convenience -all:p4 sai saithrift-server docker-saithrift-client test build-saic-client +all:p4 sai saithrift-server docker-saithrift-client test run-all-tests:run-libsai-test run-saithrift-client-tests run-saithrift-client-tests: run-saithrift-ptftests run-saithrift-pytests @@ -500,14 +500,12 @@ undeploy-ixiac: SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger.OCP -DOCKER_SAI_CHALLENGER_CLIENT = sc-client-thrift +DOCKER_SAI_CHALLENGER_CLIENT = anton7811/dash-saichallenger-client:220920 -CONTAINER_SAI_CHALLENGER_CLIENT_NAME = $(DOCKER_SAI_CHALLENGER_CLIENT)-run - -CONTAINER_SAI_CHALLENGER_CLIENT_EXEC = docker exec $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) +CONTAINER_SAI_CHALLENGER_CLIENT_NAME = dash-saichallenger-client-$(USER) # Add passing parameters to the run-saic-test-thrift target. -ifeq (run-saic-test-thrift,$(firstword $(MAKECMDGOALS))) +ifeq (run-saic-tests,$(firstword $(MAKECMDGOALS))) SAI_CHALLENGER_SETUP_FILE := $(wordlist 2, 2, $(MAKECMDGOALS)) SAI_CHALLENGER_TEST := $(wordlist 3, 3, $(MAKECMDGOALS)) $(eval $(SAI_CHALLENGER_SETUP_FILE):;@:) @@ -529,34 +527,31 @@ build-saic-client: -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ . +DOCKER_RUN_SAI_CHALLENGER_CLEINT=docker run \ + -v $(SAI_CHALLENGER_PATH):/sai-challenger \ + -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/tests \ + -v $(PWD)/../:/dash \ + --cap-add=NET_ADMIN \ + --device /dev/net/tun:/dev/net/tun \ + --rm \ + --network=host \ + --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) + run-saic-client: deploy-ixiac - docker run \ - -v $(SAI_CHALLENGER_PATH):/sai-challenger \ - --cap-add=NET_ADMIN \ - --device /dev/net/tun:/dev/net/tun \ - --rm \ - --network=host \ - -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/tests \ - -v $(PWD)/../:/dash \ - -d \ - --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ - $(DOCKER_SAI_CHALLENGER_CLIENT) - -kill-saic-client: undeploy-ixiac - -docker container stop $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) - -# @brief Target with passing parameters. -# @param SAI_CHALLENGER_SETUP_FILE Path to the setup file. -# Default is "../setups/sai_dpu_client_server.json". -# @param SAI_CHALLENGER_TEST Test's name to start. -# Default is empty to start all tests. -run-saic-test-thrift: deploy-ixiac -# Check if client container is started. If not - start SAI-Challenger client - ifneq ($(shell docker container inspect -f '{{.State.Status}}' $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME)), running) - echo "SAI-Challenger client container isn't running. Starting client..." - @make -C . run-saic-client - endif - -$(CONTAINER_SAI_CHALLENGER_CLIENT_EXEC) sh -c "pytest -sv --setup=$(SAI_CHALLENGER_SETUP_FILE) $(SAI_CHALLENGER_TEST)" + $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ + -d \ + --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ + $(DOCKER_SAI_CHALLENGER_CLIENT) + +kill-saic-client: + -docker kill $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) + +run-saic-tests: deploy-ixiac + $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ + -w /sai-challenger/tests \ + $(DOCKER_FLAGS) \ + $(DOCKER_SAI_CHALLENGER_CLIENT) \ + ./run_vnet_tests.sh --setup=$(SAI_CHALLENGER_SETUP_FILE) $(SAI_CHALLENGER_TEST) ############################### # ENVIRONMENT SETUP TARGETS diff --git a/test/docs/README.md b/test/docs/README.md index c63dbe53a..c2feeb5c4 100644 --- a/test/docs/README.md +++ b/test/docs/README.md @@ -2,13 +2,14 @@ | Document | Description | |----------|-------------| -| [High-Level Description (HLD) Test Specification](dash-test-HLD.md) | High-level design for the testing of devices which conform to the SONiC-DASH requirements.| -| [Dash Test Maturity Stages](dash-test-maturity-stages.md) | Describes a progressive approach to DASH testing.| +| [High-Level Description (HLD) Test Specification](dash-test-HLD.md) | High-level design for the testing of devices which conform to the SONiC-DASH requirements.| +| [Dash Test Maturity Stages](dash-test-maturity-stages.md) | Describes a progressive approach to DASH testing.| | [DASH SAI-Thrift Test Workflow](dash-test-workflow-saithrift.md) | DASH test workflow with SAI-thrift. | | [SAI PTF Design](https://github.com/reshmaintel/SAI/blob/dash-ptf/doc/SAI-Proposal-SAI-PTF.md) | SAI Thrift auto-generated Python based testing framework doc. | | [SAI PTF User Guide](https://github.com/opencomputeproject/SAI/blob/master/ptf/SAI_PTF_user-guide.md) | SAI Thrift Server User Guide to autogenerate test frame work. | | [DASH P4 SAI-Thrift Test Workflow](dash-test-workflow-p4-saithrift.md) | Use of P4-based simulators or SW data planes to verify DASH behavior, using saithrift API. | -| [Testbed](testbed/README.md) | Describes the setup and configuration of a DASH testbed.| +| [Testbed](testbed/README.md) | Describes the setup and configuration of a DASH testbed.| +| [snappi and SAI-Challenger based tests](dash-test-sai-challenger.md) | How to run scalable tests using SAI-Challenger and snappi. The scalability is achieved with additional DASH/SAI abstraction level in test configuration to simplify high scale DUT configs. | -You can start with the [High-Level Description (HLD) Test Specification](dash-test-HLD.md). +You can start with the [High-Level Description (HLD) Test Specification](dash-test-HLD.md). diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index ccaa60204..52a4397f6 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -10,7 +10,7 @@ **kill-saic-client**: Stop Ixia-C and sc-client-thrift-run container. -**run-saic-test-thrift**: Run test manually. This target may be triggerred with passing parameters, or with default parameters. +**run-saic-test-thrift**: Run test manually. This target may be triggerred with passing parameters, or with default parameters. Run with default parameters(Setup file: sai_dpu_client_server_snappi.json; Test: test_sai_vnet_*.pys): ``` make run-saic-test-thrift @@ -46,29 +46,43 @@ make run-saithrift-server ``` ## Run tests manually -Execute test inside the docker `sc-client-thrift-run` container or by `docker exec sc-client-thrift-run ` or by `run-saic-test-thrift` target. -### Pure SAI tests run +### Using make target +Run all available VNET tests: +```sh +make run-saic-tests ``` -Via Make target: -make run-saic-test-thrift sai_dpu_client_server_snappi.json test_vnet_inbound.py -make run-saic-test-thrift sai_dpu_client_server_snappi.json test_vnet_outbound.py -Via docker exec: -pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_inbound.py -pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_outbound.py +Run tests in DASH config format with custom options: +```sh +make run-saic-tests sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py +make run-saic-tests sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py +``` + +Run tests in SAI config format with custom options: +```sh +make run-saic-tests sai_dpu_client_server_snappi.json test_vnet_inbound.py +make run-saic-tests sai_dpu_client_server_snappi.json test_vnet_outbound.py ``` -### Test Vector format tests +### Manually from the docker (developers mode) +Run the `dash-saichallenger-client-$USER` container. +```sh +make run-saic-client +docker exec dash-saichallenger-client-ubuntu-$USER ``` -Via Make target: -make run-saic-test-thrift sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py -make run-saic-test-thrift sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py -Via docker exec: +And execute tests in DASH config format (inside the container): +```sh pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py ``` +Or in SAI config format: +```sh +pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_inbound.py +pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_outbound.py +``` + # Known issues * [Test Vector format tests ](#Test Vector format tests): traffic check will fail as expected diff --git a/test/test-cases/test_vector_example/run_vnet_tests.sh b/test/test-cases/test_vector_example/run_vnet_tests.sh new file mode 100755 index 000000000..90d4caf05 --- /dev/null +++ b/test/test-cases/test_vector_example/run_vnet_tests.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +pytest -sv $@ From 59afa5b2ccd310ad5effd3029d548810c12b248e Mon Sep 17 00:00:00 2001 From: MirceaDan Date: Mon, 26 Sep 2022 04:39:24 -0700 Subject: [PATCH 20/45] Update dash-test-sai-challenger.md Signed-off-by: Mircea Dan Gheorghe --- test/docs/dash-test-sai-challenger.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index 52a4397f6..18163ff42 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -25,25 +25,38 @@ make run-saic-test-thrift ``` # How to start + +## os +- install ubuntu 20.04 + +## os depedencies +``` +apt install docker-compose + +``` + ## Prepare repository ``` git clone https://github.com/PLVision/DASH.git -cd DASH && git checkout dev-tests-extension +cd DASH && git checkout test-framework-extension git submodule update --init --recursive ``` ## Build environment ``` cd dash-pipeline -make clean && make all +make clean ;# skip on a fresh setup as it will fail +make all + +pwd ``` ## Start environment Run in the 3 separate windows/tabs. -``` -make run-switch -make run-saithrift-server -``` +- take the output of `pwd` from previous step and do `cd ` in each window +- window 1: `make run-switch` +- window 2: `make run-saithrift-server` +- window 3: will be used to run the test as per instructions bellow ## Run tests manually From 341ccb42c751005930104b693a9787c135babfc3 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Thu, 29 Sep 2022 17:45:15 -0700 Subject: [PATCH 21/45] Add bmv2 SAI port attributes (num_active, port_list), dflt vlan, dflt vrf) --- dash-pipeline/SAI/templates/utils.cpp.j2 | 59 +++++++++++++++++-- .../tests/saithrift/pytest/pytest.ini | 1 + .../pytest/switch/test_saithrift_switch.py | 28 ++++++++- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/dash-pipeline/SAI/templates/utils.cpp.j2 b/dash-pipeline/SAI/templates/utils.cpp.j2 index 683182933..2a59ac805 100644 --- a/dash-pipeline/SAI/templates/utils.cpp.j2 +++ b/dash-pipeline/SAI/templates/utils.cpp.j2 @@ -218,20 +218,71 @@ sai_status_t sai_create_switch_dummy( return SAI_STATUS_SUCCESS; } -sai_status_t sai_get_switch_attribute_dummy( +#define DASH_BMV2_NUM_PORTS 2 +#define DASH_BMV2_DEFAULT_VLAN_ID (sai_object_id_t)((SAI_OBJECT_TYPE_VLAN<<48)+1) +#define DASH_BMV2_DEFAULT_VRF_ID (sai_object_id_t)((SAI_OBJECT_TYPE_VIRTUAL_ROUTER<<48)+1) + +sai_object_id_t port_list[DASH_BMV2_NUM_PORTS] = { + (sai_object_id_t)((SAI_OBJECT_TYPE_PORT<<48) + 1), + (sai_object_id_t)((SAI_OBJECT_TYPE_PORT<<48) + 2) +}; + +sai_status_t sai_get_switch_attribute( _In_ sai_object_id_t switch_id, _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { - fprintf(stderr, "sai_get_switch_attribute_dummy()\n"); - return SAI_STATUS_SUCCESS; + fprintf(stderr, "sai_get_switch_attribute()\n"); + int i; + sai_attribute_t *attr = attr_list; + sai_object_list_t port_obj_list; + sai_object_id_t *objlist; + for (i = 0; i < attr_count ; i++, attr++) { + switch(attr->id) { + + case SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS: + attr->value.u32 = DASH_BMV2_NUM_PORTS; + fprintf(stderr, " sai_get_switch_attribute() [%d] attr %d SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS = %d\n", + i, attr->id, attr->value.u32); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_PORT_LIST: + // make a tmp port list, saiserver will free the memory + objlist = (sai_object_id_t *)malloc(sizeof(port_list)); + memcpy(objlist, port_list, sizeof(port_list)); + port_obj_list = { + .count = DASH_BMV2_NUM_PORTS, + .list = objlist + }; + attr->value.objlist = port_obj_list; + fprintf(stderr, " sai_get_switch_attribute() [%d] attr %d SAI_SWITCH_ATTR_PORT_LIST = [%d objids]\n", + i, attr->id, DASH_BMV2_NUM_PORTS); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_DEFAULT_VLAN_ID: + attr->value.oid = DASH_BMV2_DEFAULT_VLAN_ID; + fprintf(stderr, " sai_get_switch_attribute() [%d] attr %d SAI_SWITCH_ATTR_DEFAULT_VLAN_ID = %lx\n", + i, attr->id, attr->value.oid); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID: + attr->value.oid = DASH_BMV2_DEFAULT_VRF_ID; + fprintf(stderr, " sai_get_switch_attribute() [0] attr %d SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID = %lx\n", attr->id, attr->value.oid); + return SAI_STATUS_SUCCESS; + + default: + fprintf(stderr, " sai_get_switch_attribute() [0] attr %d is NOT SUPPORTED - returning SAI_STATUS_SUCCESS anyway\n", attr->id); + return SAI_STATUS_NOT_SUPPORTED; + } + } + return SAI_STATUS_NOT_SUPPORTED; } sai_switch_api_t sai_switch_api_impl = { .create_switch = sai_create_switch_dummy, .remove_switch = (void *)0, .set_switch_attribute = (void *)0, - .get_switch_attribute = sai_get_switch_attribute_dummy, + .get_switch_attribute = sai_get_switch_attribute, .get_switch_stats = (void *)0, .get_switch_stats_ext = (void *)0, .clear_switch_stats = (void *)0, diff --git a/dash-pipeline/tests/saithrift/pytest/pytest.ini b/dash-pipeline/tests/saithrift/pytest/pytest.ini index 42107e96f..4443adf18 100644 --- a/dash-pipeline/tests/saithrift/pytest/pytest.ini +++ b/dash-pipeline/tests/saithrift/pytest/pytest.ini @@ -2,5 +2,6 @@ markers = bmv2: test DASH bmv2 model saithrift: test DASH using saithrift API + switch: test DASH SAI switch APIs vnet: test DASH vnet scenarios \ No newline at end of file diff --git a/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py b/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py index f36cb7012..5ef43afca 100644 --- a/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py +++ b/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py @@ -6,10 +6,32 @@ @pytest.mark.saithrift @pytest.mark.bmv2 -def test_sai_thrift_get_switch_attribute(saithrift_client): +@pytest.mark.switch +def test_sai_thrift_get_switch_attributes(saithrift_client): attr = sai_thrift_get_switch_attribute( saithrift_client, number_of_active_ports=True) - print ("switch_attributes = %s" % attr) - print ("test_sai_thrift_get_switch_attribute OK") + number_of_active_ports = attr['number_of_active_ports'] + print ("number_of_active_ports = %d" % number_of_active_ports) + assert(number_of_active_ports != 0) + attr = sai_thrift_get_switch_attribute( + saithrift_client, + port_list=sai_thrift_object_list_t(idlist=[], count=int(number_of_active_ports))) + assert(number_of_active_ports == attr['port_list'].count) + port_list = attr['port_list'].idlist + print ("port list = ", port_list) + + attr = sai_thrift_get_switch_attribute( + saithrift_client, default_vlan_id=True) + default_vlan_id = attr['default_vlan_id'] + print ("default_vlan_id = %d" % default_vlan_id) + assert(default_vlan_id != 0) + + attr = sai_thrift_get_switch_attribute( + saithrift_client, default_virtual_router_id=True) + default_virtual_router_id = attr['default_virtual_router_id'] + print ("default_virtual_router_id = %d" % default_virtual_router_id) + assert(default_virtual_router_id != 0) + + print ("test_sai_thrift_get_switch_attribute OK") \ No newline at end of file From 86139a4070cd0aaeb1ab75c8636ee3e9a6a0a23b Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Fri, 30 Sep 2022 11:04:25 +0300 Subject: [PATCH 22/45] Added SAI-Challenger docker build verification to GitHub actions - Added SAI-Challenger docker verification action. - Fixed spellchecker and docker build issues. Signed-off-by: Anton Putria --- .github/workflows/dash-saic-client-docker.yml | 47 +++++++++++++++++++ .wordlist.txt | 2 + dash-pipeline/Makefile | 4 +- ...aithrift-client => Dockerfile.saic-client} | 0 test/docs/README.md | 2 +- test/docs/dash-test-sai-challenger.md | 29 ++++++------ 6 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/dash-saic-client-docker.yml rename dash-pipeline/dockerfiles/{Dockerfile.saic-saithrift-client => Dockerfile.saic-client} (100%) diff --git a/.github/workflows/dash-saic-client-docker.yml b/.github/workflows/dash-saic-client-docker.yml new file mode 100644 index 000000000..408d98be3 --- /dev/null +++ b/.github/workflows/dash-saic-client-docker.yml @@ -0,0 +1,47 @@ +name: DASH-docker-saic-client-image + +on: + push: + branches: [ "**" ] + paths: + - '.github/workflows/dash-saic-client-docker.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saic-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + pull_request: + branches: [ "main" ] + paths: + - '.github/workflows/dash-saic-client-docker.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saic-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + workflow_dispatch: + +jobs: + build: + name: Build dash-saic-client-image + runs-on: ubuntu-20.04 + env: + docker_fg_flags: -u root --privileged + docker_bg_flags: -d -u root --privileged + defaults: + run: + working-directory: ./dash-pipeline + steps: + - uses: actions/checkout@v3 + - name: Pull docker p4c image + run: make docker-pull-dash-p4c + - name: Build P4 software switch (bmv2) and P4Info + run: DOCKER_FLAGS=$docker_fg_flags make p4 + - name: Install SAI submodule + run: git submodule update --init + - name: Generate SAI API + run: DOCKER_FLAGS=$docker_fg_flags make sai + - name: Generate SAI-Thrift client and server code and libs + run: DOCKER_FLAGS=$docker_fg_flags make saithrift-server + - name: Build saithrift client docker image + run: DOCKER_FLAGS=$docker_fg_flags make docker-saithrift-client + - name: Build SAI-Challenger client docker image + run: DOCKER_FLAGS=$docker_fg_flags make docker-saic-client diff --git a/.wordlist.txt b/.wordlist.txt index 68f9e3d24..c8062567d 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -440,11 +440,13 @@ runtime rx SAI sai +saigen sairedis saiserver saithrift sata scalability +scalable Scalable scapy Schemas diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 0d2d60cb6..d94ed43aa 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -520,10 +520,10 @@ ifeq ($(SAI_CHALLENGER_TEST),) SAI_CHALLENGER_TEST := test_sai_vnet_*.py endif -build-saic-client: +docker-saic-client: cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client docker build \ - -f dockerfiles/Dockerfile.saic-saithrift-client \ + -f dockerfiles/Dockerfile.saic-client \ -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ . diff --git a/dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client b/dash-pipeline/dockerfiles/Dockerfile.saic-client similarity index 100% rename from dash-pipeline/dockerfiles/Dockerfile.saic-saithrift-client rename to dash-pipeline/dockerfiles/Dockerfile.saic-client diff --git a/test/docs/README.md b/test/docs/README.md index c2feeb5c4..e88335a61 100644 --- a/test/docs/README.md +++ b/test/docs/README.md @@ -9,7 +9,7 @@ | [SAI PTF User Guide](https://github.com/opencomputeproject/SAI/blob/master/ptf/SAI_PTF_user-guide.md) | SAI Thrift Server User Guide to autogenerate test frame work. | | [DASH P4 SAI-Thrift Test Workflow](dash-test-workflow-p4-saithrift.md) | Use of P4-based simulators or SW data planes to verify DASH behavior, using saithrift API. | | [Testbed](testbed/README.md) | Describes the setup and configuration of a DASH testbed.| -| [snappi and SAI-Challenger based tests](dash-test-sai-challenger.md) | How to run scalable tests using SAI-Challenger and snappi. The scalability is achieved with additional DASH/SAI abstraction level in test configuration to simplify high scale DUT configs. | +| [snappi and SAI-Challenger based tests](dash-test-sai-challenger.md) | How to run scalable tests using SAI-Challenger and snappi. The scalability is achieved with additional DASH/SAI abstraction level in test code to simplify high scale DUT configuration. | You can start with the [High-Level Description (HLD) Test Specification](dash-test-HLD.md). diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index 18163ff42..6bb5596fc 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -1,24 +1,26 @@ # General changes -* Added [SAI-Challenger](https://github.com/PLVision/SAI-Challenger.OCP) submodule by path: DASH/test/SAI-Challenger.OCP. -* Added [cgyang](https://github.com/mgheorghe/cgyang) submodule by path: DASH/test/third-party/cgyang. -* Added test cases for SAI-Challenger by path: DASH/test/test-cases/test_vector_example +* Added [SAI-Challenger](https://github.com/PLVision/SAI-Challenger.OCP) submodule by path: `DASH/test/SAI-Challenger.OCP`. +* Added [saigen](https://github.com/mgheorghe/cgyang) submodule by path: `DASH/test/third-party/cgyang/saigen`. +* Added test cases for SAI-Challenger by path: `DASH/test/test-cases/test_vector_example` # New make targets: -**build-saic-client**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. +**`docker-saic-client`**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. -**run-saic-client**: Start Ixia-C and docker container sc-client-thrift-run from image built on build-saic-client target. SAI-Challenger tests (DASH/test/SAI-Challenger.OCP/tests) folder replaced by DASH/test/test-cases/test_vector_example folder inside of container. Binded mount volume with DASH folder. +**`run-saic-client`**: Start Ixia-C and docker container `sc-client-thrift-run` from image built on `docker-saic-client` target. SAI-Challenger tests (`DASH/test/SAI-Challenger.OCP/tests`) folder replaced by `DASH/test/test-cases/test_vector_example` folder inside of container. Bound mount volume with DASH folder. -**kill-saic-client**: Stop Ixia-C and sc-client-thrift-run container. +**`kill-saic-client`**: Stop Ixia-C and `sc-client-thrift-run` container. -**run-saic-test-thrift**: Run test manually. This target may be triggerred with passing parameters, or with default parameters. -Run with default parameters(Setup file: sai_dpu_client_server_snappi.json; Test: test_sai_vnet_*.pys): +**`run-saic-test-thrift`**: Run test manually. This target may be triggered with passing parameters, or with default parameters. +Run with default parameters(Setup file: `sai_dpu_client_server_snappi.json`; Test: `test_sai_vnet_*.py`): ``` make run-saic-test-thrift ``` + Run with setup parameter and default test parameter (All tests): ``` make run-saic-test-thrift ``` + Run with setup parameter and test parameter: ``` make run-saic-test-thrift @@ -29,10 +31,9 @@ make run-saic-test-thrift ## os - install ubuntu 20.04 -## os depedencies +## os dependencies ``` apt install docker-compose - ``` ## Prepare repository @@ -66,13 +67,13 @@ Run all available VNET tests: make run-saic-tests ``` -Run tests in DASH config format with custom options: +Run tests in DASH configuration format with the custom options: ```sh make run-saic-tests sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py make run-saic-tests sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py ``` -Run tests in SAI config format with custom options: +Run tests in SAI configuration format with custom options: ```sh make run-saic-tests sai_dpu_client_server_snappi.json test_vnet_inbound.py make run-saic-tests sai_dpu_client_server_snappi.json test_vnet_outbound.py @@ -85,13 +86,13 @@ make run-saic-client docker exec dash-saichallenger-client-ubuntu-$USER ``` -And execute tests in DASH config format (inside the container): +And execute tests in DASH configuration format (inside the container): ```sh pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py ``` -Or in SAI config format: +Or in SAI configuration format: ```sh pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_inbound.py pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_outbound.py From 9e7707eecebd80762d5014e69ef517ee8aefab60 Mon Sep 17 00:00:00 2001 From: Maksym Prytoliuk Date: Mon, 3 Oct 2022 11:10:23 -0400 Subject: [PATCH 23/45] Add default .1Q bridge to bmv2 Signed-off-by: Maksym Prytoliuk --- dash-pipeline/SAI/templates/utils.cpp.j2 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dash-pipeline/SAI/templates/utils.cpp.j2 b/dash-pipeline/SAI/templates/utils.cpp.j2 index 2a59ac805..fe673a090 100644 --- a/dash-pipeline/SAI/templates/utils.cpp.j2 +++ b/dash-pipeline/SAI/templates/utils.cpp.j2 @@ -221,6 +221,7 @@ sai_status_t sai_create_switch_dummy( #define DASH_BMV2_NUM_PORTS 2 #define DASH_BMV2_DEFAULT_VLAN_ID (sai_object_id_t)((SAI_OBJECT_TYPE_VLAN<<48)+1) #define DASH_BMV2_DEFAULT_VRF_ID (sai_object_id_t)((SAI_OBJECT_TYPE_VIRTUAL_ROUTER<<48)+1) +#define DASH_BMV2_DEFAULT_1Q_BRIDGE_ID (sai_object_id_t)((SAI_OBJECT_TYPE_BRIDGE<<48)+1) sai_object_id_t port_list[DASH_BMV2_NUM_PORTS] = { (sai_object_id_t)((SAI_OBJECT_TYPE_PORT<<48) + 1), @@ -270,6 +271,11 @@ sai_status_t sai_get_switch_attribute( fprintf(stderr, " sai_get_switch_attribute() [0] attr %d SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID = %lx\n", attr->id, attr->value.oid); return SAI_STATUS_SUCCESS; + case SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID: + attr->value.oid = DASH_BMV2_DEFAULT_1Q_BRIDGE_ID; + fprintf(stderr, " sai_get_switch_attribute() [0] attr %d SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID = %lx\n", attr->id, attr->value.oid); + return SAI_STATUS_SUCCESS; + default: fprintf(stderr, " sai_get_switch_attribute() [0] attr %d is NOT SUPPORTED - returning SAI_STATUS_SUCCESS anyway\n", attr->id); return SAI_STATUS_NOT_SUPPORTED; From dd182557173e3df77ba718f11263112577471038 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Mon, 3 Oct 2022 09:21:05 +0000 Subject: [PATCH 24/45] Fixed SAI-Challenger user guide and file namings. Signed-off-by: Anton Putria --- ...l => dash-saichallenger-client-docker.yml} | 16 ++++----- dash-pipeline/Makefile | 23 +++++++----- ...client => Dockerfile.saichallenger-client} | 0 test/docs/dash-test-sai-challenger.md | 36 ++++++++----------- 4 files changed, 37 insertions(+), 38 deletions(-) rename .github/workflows/{dash-saic-client-docker.yml => dash-saichallenger-client-docker.yml} (69%) rename dash-pipeline/dockerfiles/{Dockerfile.saic-client => Dockerfile.saichallenger-client} (100%) diff --git a/.github/workflows/dash-saic-client-docker.yml b/.github/workflows/dash-saichallenger-client-docker.yml similarity index 69% rename from .github/workflows/dash-saic-client-docker.yml rename to .github/workflows/dash-saichallenger-client-docker.yml index 408d98be3..90a278f5b 100644 --- a/.github/workflows/dash-saic-client-docker.yml +++ b/.github/workflows/dash-saichallenger-client-docker.yml @@ -1,27 +1,27 @@ -name: DASH-docker-saic-client-image +name: DASH-docker-saichallenger-client-image on: push: branches: [ "**" ] paths: - - '.github/workflows/dash-saic-client-docker.yml' + - '.github/workflows/dash-saichallenger-client-docker.yml' - 'dash-pipeline/Makefile' - - 'dash-pipeline/dockerfiles/Dockerfile.saic-client' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' - 'dash-pipeline/.dockerignore' - 'dash-pipeline/dockerfiles/.dockerignore' pull_request: branches: [ "main" ] paths: - - '.github/workflows/dash-saic-client-docker.yml' + - '.github/workflows/dash-saichallenger-client-docker.yml' - 'dash-pipeline/Makefile' - - 'dash-pipeline/dockerfiles/Dockerfile.saic-client' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' - 'dash-pipeline/.dockerignore' - 'dash-pipeline/dockerfiles/.dockerignore' workflow_dispatch: jobs: build: - name: Build dash-saic-client-image + name: Build dash-saichallenger-client-image runs-on: ubuntu-20.04 env: docker_fg_flags: -u root --privileged @@ -41,7 +41,5 @@ jobs: run: DOCKER_FLAGS=$docker_fg_flags make sai - name: Generate SAI-Thrift client and server code and libs run: DOCKER_FLAGS=$docker_fg_flags make saithrift-server - - name: Build saithrift client docker image - run: DOCKER_FLAGS=$docker_fg_flags make docker-saithrift-client - name: Build SAI-Challenger client docker image - run: DOCKER_FLAGS=$docker_fg_flags make docker-saic-client + run: DOCKER_FLAGS=$docker_fg_flags make docker-saichallenger-client diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index d94ed43aa..0b0e8569a 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -11,7 +11,7 @@ run-saithrift-client-dev-tests: run-saithrift-dev-ptftests run-saithrift-dev-pyt clean: kill-all p4-clean sai-clean test-clean network-clean saithrift-server-clean rm -rf $(P4_OUTDIR) -kill-all: kill-saithrift-server kill-switch undeploy-ixiac kill-saic-client +kill-all: kill-saithrift-server kill-switch undeploy-ixiac kill-saichallenger-client PWD := $(shell pwd) DASH_USER ?=dashuser @@ -504,8 +504,8 @@ DOCKER_SAI_CHALLENGER_CLIENT = anton7811/dash-saichallenger-client:220920 CONTAINER_SAI_CHALLENGER_CLIENT_NAME = dash-saichallenger-client-$(USER) -# Add passing parameters to the run-saic-test-thrift target. -ifeq (run-saic-tests,$(firstword $(MAKECMDGOALS))) +# Add passing parameters to the run-saichallenger-tests target. +ifeq (run-saichallenger-tests,$(firstword $(MAKECMDGOALS))) SAI_CHALLENGER_SETUP_FILE := $(wordlist 2, 2, $(MAKECMDGOALS)) SAI_CHALLENGER_TEST := $(wordlist 3, 3, $(MAKECMDGOALS)) $(eval $(SAI_CHALLENGER_SETUP_FILE):;@:) @@ -520,10 +520,10 @@ ifeq ($(SAI_CHALLENGER_TEST),) SAI_CHALLENGER_TEST := test_sai_vnet_*.py endif -docker-saic-client: +docker-saichallenger-client: cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client docker build \ - -f dockerfiles/Dockerfile.saic-client \ + -f dockerfiles/Dockerfile.saichallenger-client \ -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ . @@ -537,16 +537,23 @@ DOCKER_RUN_SAI_CHALLENGER_CLEINT=docker run \ --network=host \ --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) -run-saic-client: deploy-ixiac +run-saichallenger-client: deploy-ixiac $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ -d \ --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ $(DOCKER_SAI_CHALLENGER_CLIENT) -kill-saic-client: +run-saichallenger-client-bash: deploy-ixiac + $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ + -d \ + --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ + $(DOCKER_SAI_CHALLENGER_CLIENT) \ + /bin/bash + +kill-saichallenger-client: -docker kill $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) -run-saic-tests: deploy-ixiac +run-saichallenger-tests: deploy-ixiac $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ -w /sai-challenger/tests \ $(DOCKER_FLAGS) \ diff --git a/dash-pipeline/dockerfiles/Dockerfile.saic-client b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client similarity index 100% rename from dash-pipeline/dockerfiles/Dockerfile.saic-client rename to dash-pipeline/dockerfiles/Dockerfile.saichallenger-client diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index 6bb5596fc..c3cddd99f 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -4,37 +4,32 @@ * Added test cases for SAI-Challenger by path: `DASH/test/test-cases/test_vector_example` # New make targets: -**`docker-saic-client`**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. +**`docker-saichallenger-client`**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. -**`run-saic-client`**: Start Ixia-C and docker container `sc-client-thrift-run` from image built on `docker-saic-client` target. SAI-Challenger tests (`DASH/test/SAI-Challenger.OCP/tests`) folder replaced by `DASH/test/test-cases/test_vector_example` folder inside of container. Bound mount volume with DASH folder. +**`run-saichallenger-client`**: Start Ixia-C and docker container `sc-client-thrift-run` from image built on `docker-saichallenger-client` target. SAI-Challenger tests (`DASH/test/SAI-Challenger.OCP/tests`) folder replaced by `DASH/test/test-cases/test_vector_example` folder inside of container. Bound mount volume with DASH folder. -**`kill-saic-client`**: Stop Ixia-C and `sc-client-thrift-run` container. +**`kill-saichallenger-client`**: Stop Ixia-C and `sc-client-thrift-run` container. -**`run-saic-test-thrift`**: Run test manually. This target may be triggered with passing parameters, or with default parameters. +**`run-saichallenger-tests`**: Run test manually. This target may be triggered with passing parameters, or with default parameters. Run with default parameters(Setup file: `sai_dpu_client_server_snappi.json`; Test: `test_sai_vnet_*.py`): ``` -make run-saic-test-thrift +make run-saichallenger-tests ``` Run with setup parameter and default test parameter (All tests): ``` -make run-saic-test-thrift +make run-saichallenger-tests ``` Run with setup parameter and test parameter: ``` -make run-saic-test-thrift +make run-saichallenger-tests ``` # How to start -## os -- install ubuntu 20.04 - -## os dependencies -``` -apt install docker-compose -``` +## Environment +Install dependencies listed [**here**](../../dash-pipeline/README.md#prerequisites). ## Prepare repository ``` @@ -64,26 +59,25 @@ Run in the 3 separate windows/tabs. ### Using make target Run all available VNET tests: ```sh -make run-saic-tests +make run-saichallenger-tests ``` Run tests in DASH configuration format with the custom options: ```sh -make run-saic-tests sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py -make run-saic-tests sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py ``` Run tests in SAI configuration format with custom options: ```sh -make run-saic-tests sai_dpu_client_server_snappi.json test_vnet_inbound.py -make run-saic-tests sai_dpu_client_server_snappi.json test_vnet_outbound.py +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_vnet_inbound.py +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_vnet_outbound.py ``` ### Manually from the docker (developers mode) Run the `dash-saichallenger-client-$USER` container. ```sh -make run-saic-client -docker exec dash-saichallenger-client-ubuntu-$USER +make run-saichallenger-client-bash ``` And execute tests in DASH configuration format (inside the container): From 04df302e1c32cd5ce398ef02dd54b88fc761e088 Mon Sep 17 00:00:00 2001 From: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Date: Tue, 11 Oct 2022 16:41:25 +0300 Subject: [PATCH 25/45] Scaled VNET outbound test using snappi and saigen. (1st edition) - Split scale and simple tests / jsons - Updated ixia controller version - Added dash_helper for traffic profile scaling. Signed-off-by: Maksym Hedeon --- dash-pipeline/Makefile | 8 +- test/SAI-Challenger.OCP | 2 +- .../test_vector_example/conftest.py | 6 +- .../dash_helper/vnet2vnet_helper.py | 234 +++++++++++ .../test_vector_example/run_vnet_tests.sh | 2 +- .../sai_dpu_client_server_snappi.json | 2 +- .../test_vector_example/test_dpu_basic.py | 5 - .../test_sai_vnet_inbound.py | 30 +- .../test_sai_vnet_outbound.py | 263 ------------- .../test_sai_vnet_outbound_scale.py | 241 ++++++++++++ .../test_sai_vnet_outbound_simple.py | 164 ++++++++ .../test_vector_example/test_vnet_inbound.py | 8 +- .../test_vnet_inbound_cleanup_commands.json | 38 -- .../test_vector_example/test_vnet_outbound.py | 13 +- .../test_vnet_outbound_cleanup_commands.json | 38 -- ....json => vnet_inbound_setup_commands.json} | 0 .../vnet_outbound_setup_commands_scale.json | 366 ++++++++++++++++++ ... vnet_outbound_setup_commands_simple.json} | 7 +- test/third-party/traffic_gen/deployment/.env | 2 +- 19 files changed, 1050 insertions(+), 379 deletions(-) create mode 100644 test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py delete mode 100644 test/test-cases/test_vector_example/test_dpu_basic.py delete mode 100644 test/test-cases/test_vector_example/test_sai_vnet_outbound.py create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py delete mode 100644 test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json delete mode 100644 test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json rename test/test-cases/test_vector_example/{test_vnet_inbound_setup_commands.json => vnet_inbound_setup_commands.json} (100%) create mode 100644 test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json rename test/test-cases/test_vector_example/{test_vnet_outbound_setup_commands.json => vnet_outbound_setup_commands_simple.json} (97%) diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 0b0e8569a..ae91b3826 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -529,7 +529,7 @@ docker-saichallenger-client: DOCKER_RUN_SAI_CHALLENGER_CLEINT=docker run \ -v $(SAI_CHALLENGER_PATH):/sai-challenger \ - -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/tests \ + -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/dash_tests \ -v $(PWD)/../:/dash \ --cap-add=NET_ADMIN \ --device /dev/net/tun:/dev/net/tun \ @@ -545,8 +545,8 @@ run-saichallenger-client: deploy-ixiac run-saichallenger-client-bash: deploy-ixiac $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ - -d \ - --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ + -w /sai-challenger/dash_tests \ + $(DOCKER_FLAGS) \ $(DOCKER_SAI_CHALLENGER_CLIENT) \ /bin/bash @@ -555,7 +555,7 @@ kill-saichallenger-client: run-saichallenger-tests: deploy-ixiac $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ - -w /sai-challenger/tests \ + -w /sai-challenger/dash_tests \ $(DOCKER_FLAGS) \ $(DOCKER_SAI_CHALLENGER_CLIENT) \ ./run_vnet_tests.sh --setup=$(SAI_CHALLENGER_SETUP_FILE) $(SAI_CHALLENGER_TEST) diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP index c1b44ba61..a714c5b12 160000 --- a/test/SAI-Challenger.OCP +++ b/test/SAI-Challenger.OCP @@ -1 +1 @@ -Subproject commit c1b44ba61d7267a5409bbc9c9838f1d327902d7a +Subproject commit a714c5b12535e4dfd05dd07f3ccb48a9a2710438 diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py index b51ff4301..3d90ca7c5 100644 --- a/test/test-cases/test_vector_example/conftest.py +++ b/test/test-cases/test_vector_example/conftest.py @@ -66,8 +66,10 @@ def generate(self): saigen.vnets.Vnets(self.params_dict), saigen.enis.Enis(self.params_dict), saigen.address_maps.AddressMaps(self.params_dict), - saigen.inbound_routing.InboundRouting(self.params_dict), - saigen.pa_validation.PaValidation(self.params_dict), + saigen.outbound_routing.OutboundRouting(self.params_dict), + saigen.outbound_ca_to_pa.OutboundCaToPa(self.params_dict), + # saigen.inbound_routing.InboundRouting(self.params_dict), + # saigen.pa_validation.PaValidation(self.params_dict), ] def items(self, reverse=False): diff --git a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py new file mode 100644 index 000000000..8c5dee29b --- /dev/null +++ b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py @@ -0,0 +1,234 @@ +import snappi +import saichallenger.dataplane.traffic_utils as tu +from collections import namedtuple + + +def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip): + """ + Define VNET Outbound routing flows + """ + + print("\nTest config:") + print(f"{vip}\n{dir_lookup}\n{ca_smac}\n{ca_dip}\n") + + print("Adding flows {} > {}:".format(sai_dp.configuration.ports[0].name, sai_dp.configuration.ports[1].name)) + vip_val = vip.start + for vip_number in range(0, vip.count): + dir_lookup_val = dir_lookup.start + print(f"\tVIP {vip_val}") + + ca_smac_portion = ca_smac.count // dir_lookup.count + for dir_lookup_number in range(0, dir_lookup.count): + print(f"\t\tDIR_LOOKUP VNI {dir_lookup_val}") + ca_smac_val = ca_smac.start + + ca_smac_start_index = dir_lookup_number * ca_smac_portion + for ca_smac_number in range(ca_smac_start_index, ca_smac_start_index + ca_smac_portion): + print(f"\t\t\tCA SMAC: {tu.get_next_mac(ca_smac_val, step=ca_smac.step, number=ca_smac_number)}") + print(f"\t\t\t\tCA DIP {ca_dip.start}, count: {ca_dip.count}, step: {ca_dip.step}") + + # Check that ca_mac differs on each iteration + flow = sai_dp.add_flow("flow {} > {} |vip#{}|dir_lookup#{}|ca_mac#{}|ca_dip#{}".format( + sai_dp.configuration.ports[0].name, sai_dp.configuration.ports[1].name, + vip_number, dir_lookup_number, ca_smac_number, ca_dip.start), + packet_count=ca_dip.count) + + sai_dp.add_ethernet_header(flow, dst_mac="00:00:02:03:04:05", src_mac="00:00:05:06:06:06") + sai_dp.add_ipv4_header(flow, dst_ip=vip_val, src_ip="172.16.1.1") + sai_dp.add_udp_header(flow, dst_port=80, src_port=11638) + sai_dp.add_vxlan_header(flow, vni=dir_lookup_val) + # sai_dp.add_ethernet_header(flow, dst_mac="02:02:02:02:02:02", src_mac=ca_smac_val) + sai_dp.add_ethernet_header(flow, dst_mac="02:02:02:02:02:02", + src_mac=tu.get_next_mac(ca_smac_val, step=ca_smac.step, number=ca_smac_number)) + + sai_dp.add_ipv4_header(flow, dst_ip=ca_dip.start, src_ip="10.1.1.10", + dst_step=ca_dip.step, dst_count=ca_dip.count, + dst_choice=snappi.PatternFlowIpv4Dst.INCREMENT) + sai_dp.add_udp_header(flow) + + dir_lookup_val += dir_lookup.step + + vip_val = tu.get_next_ip(vip_val, vip.step) + + print(f">>> FLOWS: {len(sai_dp.flows)}") + for flow in sai_dp.flows: + print(f">>>: {flow.name}") + + +def scale_vnet_outbound_flows(sai_dp, test_conf: dict): + """ + Get scale options and define VNET Outbound routing flows + """ + + vip_tup = namedtuple('VIP', 'count start step') + dir_lookup_tup = namedtuple('DIRECTION_LOOKUP', 'count start step') + ca_smac_tup = namedtuple('CA_SMAC', 'count start step') + ca_dip_tup = namedtuple('CA_DIP', 'count start step') + + def dict_helper(named_tup, conf, def_step): + if type(conf) != dict: + return named_tup(1, conf, def_step) + else: + return named_tup(conf.get('count', 1), conf.get('start', def_step), conf.get('step', def_step)) + + vip = dict_helper(vip_tup, test_conf['DASH_VIP']['vpe']['IPV4'], "0.0.0.1") + dir_lookup = dict_helper(dir_lookup_tup, test_conf['DASH_DIRECTION_LOOKUP']['dle']['VNI'], 1) + ca_smac = dict_helper(ca_smac_tup, test_conf['DASH_ENI_ETHER_ADDRESS_MAP']['eam']['MAC'], "00:00:00:00:00:01") + ca_dip = dict_helper(ca_dip_tup, test_conf['DASH_OUTBOUND_CA_TO_PA']['ocpe']['DIP'], "0.0.0.1") + + configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip) + + +def check_flows_all_packets_metrics(sai_dp, flows=[], name="Flow group", exp_tx=None, exp_rx=None, show=False): + if not flows: + print("Flows None or empty") + return False, None + if not exp_tx: + # check if all flows are fixed_packets + # sum of bool list == count of True in this list + if sum([flow.duration.choice == snappi.FlowDuration.FIXED_PACKETS for flow in flows]) == len(flows): + exp_tx = sum([flow.duration.fixed_packets.packets for flow in flows]) + else: + print("{}: some flow in flow group doesn't configured to {}.".format( \ + name, snappi.FlowDuration.FIXED_PACKETS)) + return False, None + if not exp_rx: + exp_rx = exp_tx + + act_tx = 0 + act_rx = 0 + success = 0 + + for flow in flows: + tmp = check_flow_packets_metrics(sai_dp, flow) + success += tmp[0] + act_tx += tmp[1]['TX'] + act_rx += tmp[1]['RX'] + + success = success == len(flows) + + if show: + # flow group name | exp tx | act tx | exp rx | act rx + print(f"{name} | exp tx:{exp_tx} - tx:{act_tx} | exp rx:{exp_rx} - rx:{act_rx}") + + return success, { 'TX': act_tx, 'RX': act_rx } + + +# exp = expected +# act = actual +# (bool, {'TX': int, 'RX': int}) +def check_flow_packets_metrics(sai_dp, flow: snappi.Flow, exp_tx=None, exp_rx=None, show=False): + if not exp_tx: + if flow.duration.choice == snappi.FlowDuration.FIXED_PACKETS: + exp_tx = flow.duration.fixed_packets.packets + else: + print("{}: check for packet count failed. Flow configured to {} instead of {}".format( \ + flow.name, flow.duration.choice, snappi.FlowDuration.FIXED_PACKETS)) + return False, None + if not exp_rx: + exp_rx = exp_tx + + req = sai_dp.api.metrics_request() + req.flow.flow_names = [ flow.name ] + req.flow.metric_names = [ snappi.FlowMetricsRequest.FRAMES_TX, snappi.FlowMetricsRequest.FRAMES_RX ] + res = sai_dp.api.get_metrics(req) + + act_tx = res.flow_metrics[0].frames_tx + act_rx = res.flow_metrics[0].frames_rx + + if show: + # flow name | exp tx | act tx | exp rx | act rx + print("{} | {} | {} | {} | {}".format(flow.name, exp_tx, act_tx, exp_rx, act_rx)) + + if exp_tx == act_tx and exp_rx == act_rx and \ + res.flow_metrics[0].transmit == snappi.FlowMetric.STOPPED: + return True, { 'TX': act_tx, 'RX': act_rx } + + return False, { 'TX': act_tx, 'RX': act_rx } + + +# TODO +def check_flows_all_seconds_metrics(sai_dp): + pass + + +def check_flow_seconds_metrics(sai_dp, flow: snappi.Flow, seconds=None, exp_tx=None, exp_rx=None, delta=None, show=False): + if not seconds: + if flow.duration.choice == snappi.FlowDuration.FIXED_SECONDS: + seconds = flow.duration.fixed_seconds.seconds + else: + print("{}: check for packet count failed. Flow configured to {} instead of {}".format( \ + flow.name, flow.duration.choice, snappi.FlowDuration.FIXED_SECONDS)) + return False, None + if not exp_tx: + exp_tx = flow.rate.pps * seconds + if not exp_rx: + exp_rx = exp_tx + if not delta: + # default delta is 10% of exp_tx. If it 0 (seconds < 10) then delta == pps + tmp_delta = int(exp_tx / 10) + delta = tmp_delta if tmp_delta > 0 else flow.rate.pps + + req = sai_dp.api.metrics_request() + req.flow.flow_names = [ flow.name ] + req.flow.metric_names = [ snappi.FlowMetricsRequest.FRAMES_TX, snappi.FlowMetricsRequest.FRAMES_RX ] + res = sai_dp.api.get_metrics(req) + + act_tx = res.flow_metrics[0].frames_tx + act_rx = res.flow_metrics[0].frames_rx + + if show: + # flow name | [exp tx - delta, ext_tx + delta] | act tx | [exp rx - delta, exp_rx + delta] | act rx + print("{} | [{}, {}] | {} | [{}, {}] | {}".format(flow.name, exp_tx - delta, exp_tx + delta, act_tx, \ + exp_rx - delta, exp_rx + delta, act_rx)) + + if act_tx in range(exp_tx - delta, exp_tx + delta) and \ + act_rx in range(exp_rx - delta, exp_rx + delta) and \ + res.flow_metrics[0].transmit == snappi.FlowMetric.STOPPED: + return True, { 'TX': act_tx, 'RX': act_rx } + + return False, { 'TX': act_tx, 'RX': act_rx } + + +# TODO +def check_flows_all_continuous_metrics(sai_dp): + pass + + +# TODO +def check_flow_continuous_metrics(sai_dp, flow: snappi.Flow): + pass + + +def add_simple_vxlan_packet(sai_dp, + flow: snappi.Flow, + outer_dst_mac, + outer_src_mac, + outer_dst_ip, + outer_src_ip, + dst_udp_port, + src_udp_port, + vni, + inner_dst_mac, + inner_src_mac, + inner_dst_ip, + inner_src_ip + ): + if flow == None: + print("flow is None") + return + + if flow.packet: + print("packet in flow") + return + + sai_dp.add_ethernet_header(flow, outer_dst_mac, outer_src_mac) + sai_dp.add_ipv4_header(flow, outer_dst_ip, outer_src_ip) + u = sai_dp.add_udp_header(flow, dst_udp_port, src_udp_port) + # TODO: report ixia bug (udp checksum still generated) + # u.checksum.choice = u.checksum.CUSTOM + # u.checksum.custom = 0 + sai_dp.add_vxlan_header(flow, vni) + sai_dp.add_ethernet_header(flow, inner_dst_mac, inner_src_mac) + sai_dp.add_ipv4_header(flow, inner_dst_ip, inner_src_ip) + sai_dp.add_udp_header(flow) diff --git a/test/test-cases/test_vector_example/run_vnet_tests.sh b/test/test-cases/test_vector_example/run_vnet_tests.sh index 90d4caf05..32eeaadda 100755 --- a/test/test-cases/test_vector_example/run_vnet_tests.sh +++ b/test/test-cases/test_vector_example/run_vnet_tests.sh @@ -1,3 +1,3 @@ #!/bin/bash -pytest -sv $@ +PYTHONPATH=. pytest -sv $@ diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json b/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json index 4477124ab..67abe70e4 100755 --- a/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json +++ b/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json @@ -28,7 +28,7 @@ "mode": "ixia_c", "controller": "https://127.0.0.1:443", "port_groups": [{"10G": "veth1", "init": "10G", "alias": 0}, - {"10G": "veth2", "init": "10G", "alias": 1} + {"10G": "veth3", "init": "10G", "alias": 1} ] } ], diff --git a/test/test-cases/test_vector_example/test_dpu_basic.py b/test/test-cases/test_vector_example/test_dpu_basic.py deleted file mode 100644 index b760e5dcd..000000000 --- a/test/test-cases/test_vector_example/test_dpu_basic.py +++ /dev/null @@ -1,5 +0,0 @@ -import pytest - -def test_dpu_basic(dpu, dataplane): - pass - #TODO diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py index c2a742349..11ad1957b 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py @@ -112,12 +112,12 @@ class TestSaiVnetInbound: def test_create_vnet_config(self, confgen, dpu, dataplane): - confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) - confgen.generate() - for item in confgen.items(): - pprint(item) + # confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) + # confgen.generate() + # for item in confgen.items(): + # pprint(item) - with (current_file_dir / 'test_vnet_inbound_setup_commands.json').open(mode='r') as config_file: + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: vnet_inbound_setup_commands = json.load(config_file) result = [*dpu.process_commands(vnet_inbound_setup_commands)] print("\n======= SAI commands RETURN values =======") @@ -168,16 +168,18 @@ def test_run_traffic_check(self, dpu, dataplane): def test_remove_vnet_config(self, confgen, dpu, dataplane): - confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) - confgen.generate() + # confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) + # confgen.generate() + # for item in confgen.items(): + # item['OP'] = 'remove' + # pprint(item) - for item in confgen.items(): - item['OP'] = 'remove' - pprint(item) + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + cleanup_commands = [] + for cmd in reversed(setup_commands): + cleanup_commands.append({'name': cmd['name'], 'op': 'remove'}) - with (current_file_dir / 'test_vnet_inbound_cleanup_commands.json').open(mode='r') as config_file: - vnet_inbound_cleanup_commands = json.load(config_file) - - result = [*dpu.process_commands(vnet_inbound_cleanup_commands)] + result = [*dpu.process_commands(cleanup_commands)] print("\n======= SAI commands RETURN values =======") pprint(result) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound.py deleted file mode 100644 index bb5849747..000000000 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound.py +++ /dev/null @@ -1,263 +0,0 @@ -import json -from pathlib import Path -from pprint import pprint - -import pytest -from saichallenger.dataplane.ptf_testutils import (send_packet, - simple_udp_packet, - simple_vxlan_packet, - verify_packet, - verify_no_other_packets) - -current_file_dir = Path(__file__).parent - -# Constants -SWITCH_ID = 5 -OUTBOUND_VNI = 60 -VNET_VNI = 100 -VM_VNI = 9 -ENI_MAC = "00:cc:cc:cc:cc:cc" -OUR_MAC = "00:00:02:03:04:05" -DST_CA_MAC = "00:dd:dd:dd:dd:dd" -VIP = "172.16.1.100" -OUTBOUND_VNI = 100 -DST_CA_IP = "10.1.2.50" -DST_PA_IP = "172.16.1.20" -SRC_VM_PA_IP = "172.16.1.1" -CA_PREFIX = "10.1.0.0/16" - -# Test Vector -TEST_VNET_OUTBOUND_CONFIG = { - - 'ACL_TABLE_COUNT': 1, - 'ENI_COUNT': 1, - 'ENI_START': 1, - 'IP_PER_ACL_RULE': 1, - 'IP_MAPPED_PER_ACL_RULE': 1, - 'IP_ROUTE_DIVIDER_PER_ACL_RULE': 8, - - 'DASH_VIP': [ - { 'vpe': - { 'SWITCH_ID': '$SWITCH_ID', - 'IPv4': VIP } - } - ], - - 'DASH_DIRECTION_LOOKUP': [ - { 'dle': - { 'SWITCH_ID': '$SWITCH_ID', - 'VNI': OUTBOUND_VNI, - 'ACTION': 'SET_OUTBOUND_DIRECTION' } - } - ], - - 'DASH_ACL_GROUP': [ - { 'in_acl_group_id': - { 'ADDR_FAMILY': 'IPv4' } - }, - { 'out_acl_group_id': - { 'ADDR_FAMILY': 'IPv4' } - } - ], - - 'DASH_VNET': [ - { 'vnet': - { 'VNI': VNET_VNI } - } - ], - - 'DASH_ENI': [ - { 'eni': - {'ACL_GROUP': { - 'INBOUND': [{ 'STAGE1': 0 }, - { 'STAGE2': 0 }, - { 'STAGE3': 0 }, - { 'STAGE4': 0 }, - { 'STAGE5': 0 } - ], - 'OUTBOUND': [{ 'STAGE1': 0 }, - { 'STAGE2': 0 }, - { 'STAGE3': 0 }, - { 'STAGE4': 0 }, - { 'STAGE5': 0 } - ] - }, - 'ADMIN_STATE': True, - 'CPS': 10000, - 'FLOWS': 10000, - 'PPS': 100000, - 'VM_UNDERLAY_DIP': SRC_VM_PA_IP, - 'VM_VNI': VM_VNI, - 'VNET_ID': '$vnet'} - } - ], - -# 'DASH_ACL_RULE': [ -# { 'out_acl_rule_id': -# { 'ACTION': 'PERMIT', -# 'DIP': DST_CA_IP, -# 'GID': '$out_acl_group_id', -# 'PRIORITY': 10 } -# } -# ], - - 'DASH_ENI_ETHER_ADDRESS_MAP': [ - { 'eam': - { 'SWITCH_ID': '$SWITCH_ID', - 'MAC': ENI_MAC, - 'ENI_ID': '$eni' } - } - ], - - 'DASH_OUTBOUND_ROUTING': [ - { 'ore': - { 'SWITCH_ID': '$SWITCH_ID', - 'ENI_ID': '$eni', - 'DESTINATION': CA_PREFIX, - 'ACTION': 'ROUTE_VNET', - 'DST_VNET_ID': '$vnet' } - } - ], - - 'DASH_OUTBOUND_CA_TO_PA': [ - { 'ocpe': - { 'SWITCH_ID': '$SWITCH_ID', - 'DST_VNET_ID': '$vnet', - 'DIP': DST_PA_IP, - 'UNDERLAY_DIP': DST_PA_IP, - 'OVERLAY_DMAC': DST_CA_MAC, - 'USE_DST_VNET_VNI': True } - } - ] -} - - -class TestSaiVnetOutbound: - - def test_create_vnet_config(self, confgen, dpu, dataplane): - - confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) - confgen.generate() - for item in confgen.items(): - pprint(item) - - with (current_file_dir / 'test_vnet_outbound_setup_commands.json').open(mode='r') as config_file: - setup_commands = json.load(config_file) - result = [*dpu.process_commands(setup_commands)] - print("\n======= SAI commands RETURN values =======") - pprint(result) - - def test_run_traffic_check(self, dpu, dataplane): - - SRC_VM_IP = "10.1.1.10" - OUTER_SMAC = "00:00:05:06:06:06" - INNER_SMAC = "00:00:04:06:06:06" - - # # check VIP drop - # WRONG_VIP = "172.16.100.100" - # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", - # eth_src=ENI_MAC, - # ip_dst=DST_CA_IP, - # ip_src=SRC_VM_IP) - # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - # eth_src=OUTER_SMAC, - # ip_dst=WRONG_VIP, - # ip_src=SRC_VM_PA_IP, - # udp_sport=11638, - # with_udp_chksum=False, - # vxlan_vni=OUTBOUND_VNI, - # inner_frame=inner_pkt) - # print("\n\nSending packet with wrong vip...\n\n", vxlan_pkt.__repr__()) - # send_packet(dataplane, 0, vxlan_pkt) - # print("\nVerifying drop...") - # verify_no_other_packets(dataplane) - - # # check routing drop - # WRONG_DST_CA = "10.200.2.50" - # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", - # eth_src=ENI_MAC, - # ip_dst=WRONG_DST_CA, - # ip_src=SRC_VM_IP) - # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - # eth_src=OUTER_SMAC, - # ip_dst=VIP, - # ip_src=SRC_VM_PA_IP, - # udp_sport=11638, - # with_udp_chksum=False, - # vxlan_vni=OUTBOUND_VNI, - # inner_frame=inner_pkt) - # print("\nSending packet with wrong dst CA IP to verify routing drop...\n\n", vxlan_pkt.__repr__()) - # send_packet(dataplane, 0, vxlan_pkt) - # print("\nVerifying drop...") - # verify_no_other_packets(dataplane) - - # # check mapping drop - # WRONG_DST_CA = "10.1.211.211" - # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", - # eth_src=ENI_MAC, - # ip_dst=WRONG_DST_CA, - # ip_src=SRC_VM_IP) - # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - # eth_src=OUTER_SMAC, - # ip_dst=VIP, - # ip_src=SRC_VM_PA_IP, - # udp_sport=11638, - # with_udp_chksum=False, - # vxlan_vni=OUTBOUND_VNI, - # inner_frame=inner_pkt) - # print("\nSending packet with wrong dst CA IP to verify mapping drop...\n\n", vxlan_pkt.__repr__()) - # send_packet(dataplane, 0, vxlan_pkt) - # print("\nVerifying drop...") - # verify_no_other_packets(dataplane) - - # check forwarding - inner_pkt = simple_udp_packet(eth_dst = "02:02:02:02:02:02", - eth_src = ENI_MAC, - ip_dst = DST_CA_IP, - ip_src = SRC_VM_IP) - vxlan_pkt = simple_vxlan_packet(eth_dst = OUR_MAC, - eth_src = OUTER_SMAC, - ip_dst = VIP, - ip_src = SRC_VM_PA_IP, - udp_sport = 11638, - with_udp_chksum = False, - vxlan_vni = OUTBOUND_VNI, - inner_frame = inner_pkt) - - inner_exp_pkt = simple_udp_packet(eth_dst=DST_CA_MAC, - eth_src=ENI_MAC, - ip_dst=DST_CA_IP, - ip_src=SRC_VM_IP) - vxlan_exp_pkt = simple_vxlan_packet(eth_dst="00:00:00:00:00:00", - eth_src="00:00:00:00:00:00", - ip_dst=DST_PA_IP, - ip_src=VIP, - udp_sport=0, # TODO: Fix sport in pipeline - with_udp_chksum=False, - vxlan_vni=VNET_VNI, - vxlan_flags=0, - inner_frame=inner_exp_pkt) - vxlan_exp_pkt['IP'].chksum = 0 - - self.pkt_exp = vxlan_exp_pkt - print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) - send_packet(dataplane, 0, vxlan_pkt) - print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) - verify_packet(dataplane, vxlan_exp_pkt, 0) - print ("test_sai_thrift_outbound_udp_pkt_test OK") - - def test_remove_vnet_config(self, confgen, dpu, dataplane): - - confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) - confgen.generate() - - for item in confgen.items(): - item['OP'] = 'remove' - pprint(item) - - with (current_file_dir / 'test_vnet_outbound_cleanup_commands.json').open(mode='r') as config_file: - cleanup_commands = json.load(config_file) - - result = [*dpu.process_commands(cleanup_commands)] - print("\n======= SAI commands RETURN values =======") - pprint(result) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py new file mode 100644 index 000000000..59dc8c93d --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py @@ -0,0 +1,241 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +import saichallenger.dataplane.snappi.snappi_traffic_utils as stu +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_no_other_packets, + verify_packet) + +import dash_helper.vnet2vnet_helper as dh + +current_file_dir = Path(__file__).parent + +# Constants for scale outbound +NUMBER_OF_VIP = 1 +NUMBER_OF_DLE = 2 +NUMBER_OF_ENI = 2 +NUMBER_OF_EAM = NUMBER_OF_ENI +NUMBER_OF_ORE = 2 # Per ENI +NUMBER_OF_OCPE = 2 # Per ORE +NUMBER_OF_VNET = NUMBER_OF_ENI + (NUMBER_OF_ORE * NUMBER_OF_ENI) # So far per ORE, but may be different +NUMBER_OF_IN_ACL_GROUP = 10 +NUMBER_OF_OUT_ACL_GROUP = 10 + +TEST_VNET_OUTBOUND_CONFIG_SCALE = { + + 'DASH_VIP': { + 'vpe': { + 'count': NUMBER_OF_VIP, + 'SWITCH_ID': '$SWITCH_ID', + 'IPV4': { + 'count': NUMBER_OF_VIP, + 'start': '172.16.1.100', + 'step': '0.1.0.0' + } + } + }, + + 'DASH_DIRECTION_LOOKUP': { + 'dle': { + 'count': NUMBER_OF_DLE, + 'SWITCH_ID': '$SWITCH_ID', + 'VNI': { + 'count': NUMBER_OF_DLE, + 'start': 5000, + 'step': 1000 + }, + 'ACTION': 'SET_OUTBOUND_DIRECTION' + } + }, + + 'DASH_ACL_GROUP': { + 'in_acl_group_id': { + 'count': NUMBER_OF_IN_ACL_GROUP, + 'ADDR_FAMILY': 'IPv4' + }, + 'out_acl_group_id': { + 'count': NUMBER_OF_OUT_ACL_GROUP, + 'ADDR_FAMILY': 'IPv4' + } + }, + + 'DASH_VNET': { + 'vnet': { + 'VNI': { + 'count': NUMBER_OF_VNET, + 'start': 1000, + 'step': 1000 + } + } + }, + + 'DASH_ENI': { + 'eni': { + 'count': NUMBER_OF_ENI, + 'ACL_GROUP': { + 'INBOUND': { + 'STAGE1': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE2': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE3': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE4': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE5': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + } + }, + 'OUTBOUND': { + 'STAGE1': 0, + 'STAGE2': 0, + 'STAGE3': 0, + 'STAGE4': 0, + 'STAGE5': 0 + } + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': { + 'count': NUMBER_OF_ENI, + 'start': '172.16.1.1', + 'step': '0.0.1.0' + }, + 'VM_VNI': { + 'count': NUMBER_OF_ENI, + 'start': 9 + }, + 'VNET_ID': { + 'count': NUMBER_OF_ENI, + 'start': '$vnet_#{4}' + } + } + }, + + 'DASH_ENI_ETHER_ADDRESS_MAP': { + 'eam': { + 'count': NUMBER_OF_EAM, + 'SWITCH_ID': '$SWITCH_ID', + 'MAC': { + 'count': NUMBER_OF_EAM, + 'start': '00:CC:CC:CC:00:00', + 'step': "00:00:00:00:00:01" + }, + 'ENI_ID': { + 'count': NUMBER_OF_ENI, + 'start': '$eni_#{0}' + } + } + }, + + 'DASH_OUTBOUND_ROUTING': { + 'ore': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, # Full count: OREs per ENI and VNET + 'SWITCH_ID': '$SWITCH_ID', + 'ACTION': 'ROUTE_VNET', + 'DESTINATION': { + 'count': NUMBER_OF_ORE, + 'start': '10.1.1.0/31', + 'step': '0.0.0.2' + }, + 'ENI_ID': { + 'count': NUMBER_OF_ENI, + 'start': '$eni_#{0}', + 'delay': NUMBER_OF_ORE + }, + 'DST_VNET_ID': { + 'count': NUMBER_OF_VNET, + 'start': '$vnet_#{0}', + 'delay': NUMBER_OF_ORE + } + } + }, + + 'DASH_OUTBOUND_CA_TO_PA': { + 'ocpe': { + 'count': (NUMBER_OF_ENI * NUMBER_OF_ORE) * NUMBER_OF_OCPE, # 2 Per ORE + 'SWITCH_ID': '$SWITCH_ID', + 'DIP': { + 'count': NUMBER_OF_ORE * NUMBER_OF_OCPE, + 'start': '10.1.1.0', + 'step': '0.0.0.1' + }, + 'DST_VNET_ID': { + 'count': NUMBER_OF_VNET, + 'start': '$vnet_#{0}', + 'delay': NUMBER_OF_ORE + }, + 'UNDERLAY_DIP': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, + 'start': '172.16.1.20', + 'step': '0.0.1.0' + }, + 'OVERLAY_DMAC': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, + 'start': '00:DD:DD:DD:00:00' + }, + 'USE_DST_VNET_VNI': True + } + } +} + + +class TestSaiVnetOutbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG_SCALE) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_scale.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + result = [*dpu.process_commands(setup_commands)] + # print("\n======= SAI commands RETURN values =======") + # for cmd, res in zip(setup_commands, result): + # print(cmd['name'], cmd['type'], res) + + @pytest.mark.snappi + def test_run_traffic_check(self, dpu, dataplane): + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE) + dataplane.set_config() + dataplane.start_traffic() + + stu.wait_for(lambda: dh.check_flows_all_packets_metrics(dataplane, dataplane.flows, + name="Custom flow group", show=True)[0], + "Test", timeout_seconds=2) + print("Test passed !") + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG_SCALE) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # item['op'] = 'remove' + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_scale.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + cleanup_commands = [] + for cmd in reversed(setup_commands): + cleanup_commands.append({'name': cmd['name'], 'op': 'remove'}) + + result = [*dpu.process_commands(cleanup_commands)] + # print("\n======= SAI commands RETURN values =======") + # for cmd, res in zip(cleanup_commands, result): + # print(cmd['name'], res) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py new file mode 100644 index 000000000..b934294f1 --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py @@ -0,0 +1,164 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +import saichallenger.dataplane.snappi.snappi_traffic_utils as stu +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_no_other_packets, + verify_packet) + +import dash_helper.vnet2vnet_helper as dh + +current_file_dir = Path(__file__).parent + +# Constants +SWITCH_ID = 5 + +TEST_VNET_OUTBOUND_CONFIG = { + + "ENI_COUNT": 1, + "ACL_RULES_NSG": 1, + "ACL_TABLE_COUNT": 1, + "IP_PER_ACL_RULE": 1, + "IP_MAPPED_PER_ACL_RULE": 1, + "IP_ROUTE_DIVIDER_PER_ACL_RULE": 1, + + 'DASH_VIP': { + 'vpe': { + 'SWITCH_ID': '$SWITCH_ID', + 'IPV4': "172.16.1.100" + } + }, + + 'DASH_DIRECTION_LOOKUP': { + 'dle': { + 'SWITCH_ID': '$SWITCH_ID', + 'VNI': 100, + 'ACTION': 'SET_OUTBOUND_DIRECTION' + } + }, + + 'DASH_ACL_GROUP': { + 'in_acl_group_id': { + 'ADDR_FAMILY': 'IPv4' + }, + 'out_acl_group_id': { + 'ADDR_FAMILY': 'IPv4' + } + }, + + 'DASH_VNET': { + 'vnet': { + 'VNI': 1000 + } + }, + + 'DASH_ENI': { + 'eni': { + 'ACL_GROUP': { + 'INBOUND': { + 'STAGE1': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE2': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE3': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE4': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE5': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'OUTBOUND': { + 'STAGE1': 0, + 'STAGE2': 0, + 'STAGE3': 0, + 'STAGE4': 0, + 'STAGE5': 0 + } + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': "172.16.1.1", + 'VM_VNI': 9, + 'VNET_ID': 'DASH_VNET#vnet#0' + } + }, + + 'DASH_ENI_ETHER_ADDRESS_MAP': { + 'eam': { + 'SWITCH_ID': '$SWITCH_ID', + 'MAC': "00:cc:cc:cc:00:00", + 'ENI_ID': 'DASH_ENI#eni#0' + } + }, + + 'DASH_OUTBOUND_ROUTING': { + 'ore': { + 'SWITCH_ID': '$SWITCH_ID', + 'ENI_ID': 'DASH_ENI#eni#0', + 'DESTINATION': "10.1.0.0/16", + 'ACTION': 'ROUTE_VNET', + 'DST_VNET_ID': 'DASH_VNET#vnet#0' + } + }, + + 'DASH_OUTBOUND_CA_TO_PA': { + 'ocpe': { + 'SWITCH_ID': '$SWITCH_ID', + 'DST_VNET_ID': 'DASH_VNET#vnet#0', + 'DIP': "10.1.2.50", + 'UNDERLAY_DIP': "172.16.1.20", + 'OVERLAY_DMAC': "00:DD:DD:DD:00:00", + 'USE_DST_VNET_VNI': True + } + } +} + +class TestSaiVnetOutbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_simple.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + result = [*dpu.process_commands(setup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) + + @pytest.mark.snappi + def test_simple_vxlan_packet(self, dpu, dataplane): + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG) + + dataplane.set_config() + dataplane.start_traffic() + + stu.wait_for(lambda: dh.check_flow_packets_metrics(dataplane, dataplane.flows[0], show=True)[0], + "Test", timeout_seconds=10) + + print("Test passed !") + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # item['op'] = 'remove' + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_simple.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + cleanup_commands = [] + for cmd in reversed(setup_commands): + cleanup_commands.append({'name': cmd['name'], 'op': 'remove'}) + + result = [*dpu.process_commands(cleanup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) diff --git a/test/test-cases/test_vector_example/test_vnet_inbound.py b/test/test-cases/test_vector_example/test_vnet_inbound.py index 7f3010d73..47ba7a9a4 100644 --- a/test/test-cases/test_vector_example/test_vnet_inbound.py +++ b/test/test-cases/test_vector_example/test_vnet_inbound.py @@ -5,12 +5,14 @@ def test_vnet_inbound(dpu, dataplane): - with (current_file_dir / 'test_vnet_inbound_setup_commands.json').open(mode='r') as config_file: + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: vnet_inbound_setup_commands = json.load(config_file) result = [*dpu.process_commands(vnet_inbound_setup_commands)] - with (current_file_dir / 'test_vnet_inbound_cleanup_commands.json').open(mode='r') as config_file: - vnet_inbound_cleanup_commands = json.load(config_file) + vnet_inbound_cleanup_commands = [] + for command in reversed(vnet_inbound_setup_commands): + command['op'] = 'remove' + vnet_inbound_cleanup_commands.append(command) result = [*dpu.process_commands(vnet_inbound_cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json b/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json deleted file mode 100644 index 409525e57..000000000 --- a/test/test-cases/test_vector_example/test_vnet_inbound_cleanup_commands.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "name": "pa_validation_entry", - "op": "remove" - }, - { - "name": "inbound_routing_entry", - "op": "remove" - }, - { - "name": "eni_ether_address_map_entry", - "op": "remove" - }, - { - "name": "eni_id", - "op": "remove" - }, - { - "name": "vnet_1", - "op": "remove" - }, - { - "name": "acl_out_1", - "op": "remove" - }, - { - "name": "acl_in_1", - "op": "remove" - }, - { - "name": "direction_lookup_entry", - "op": "remove" - }, - { - "name": "vip_entry", - "op": "remove" - } -] \ No newline at end of file diff --git a/test/test-cases/test_vector_example/test_vnet_outbound.py b/test/test-cases/test_vector_example/test_vnet_outbound.py index 5d1b0188b..6ae1a64c3 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound.py +++ b/test/test-cases/test_vector_example/test_vnet_outbound.py @@ -1,16 +1,21 @@ import json from pathlib import Path +import pytest + current_file_dir = Path(__file__).parent -def test_vnet_outbound(dpu, dataplane): - with (current_file_dir / 'test_vnet_outbound_setup_commands.json').open(mode='r') as config_file: +@pytest.mark.parametrize('cfg_type', ['simple', 'scale']) +def test_vnet_outbound_simple(dpu, cfg_type): + with (current_file_dir / f'vnet_outbound_setup_commands_{cfg_type}.json').open(mode='r') as config_file: setup_commands = json.load(config_file) result = [*dpu.process_commands(setup_commands)] - with (current_file_dir / 'test_vnet_outbound_cleanup_commands.json').open(mode='r') as config_file: - cleanup_commands = json.load(config_file) + cleanup_commands = [] + for command in reversed(setup_commands): + command['op'] = 'remove' + cleanup_commands.append(command) result = [*dpu.process_commands(cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json b/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json deleted file mode 100644 index 3a32ff45f..000000000 --- a/test/test-cases/test_vector_example/test_vnet_outbound_cleanup_commands.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "name": "ocpe", - "op": "remove" - }, - { - "name": "ore", - "op": "remove" - }, - { - "name": "eam", - "op": "remove" - }, - { - "name": "eni", - "op": "remove" - }, - { - "name": "vnet", - "op": "remove" - }, - { - "name": "out_acl_group_id", - "op": "remove" - }, - { - "name": "in_acl_group_id", - "op": "remove" - }, - { - "name": "dle", - "op": "remove" - }, - { - "name": "vpe", - "op": "remove" - } -] diff --git a/test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json similarity index 100% rename from test/test-cases/test_vector_example/test_vnet_inbound_setup_commands.json rename to test/test-cases/test_vector_example/vnet_inbound_setup_commands.json diff --git a/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json new file mode 100644 index 000000000..564e8798a --- /dev/null +++ b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json @@ -0,0 +1,366 @@ +[ + { + "name": "vpe_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.16.1.100" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "vpe_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.17.1.100" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "dle_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "5000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "dle_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "6000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "vnet_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "1000" + ] + }, + { + "name": "vnet_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "2000" + ] + }, + { + "name": "vnet_#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "3000" + ] + }, + { + "name": "vnet_#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "4000" + ] + }, + { + "name": "vnet_#4", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "5000" + ] + }, + { + "name": "vnet_#5", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "6000" + ] + }, + { + "name": "eni_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", "10000", + "SAI_ENI_ATTR_PPS", "100000", + "SAI_ENI_ATTR_FLOWS", "100000", + "SAI_ENI_ATTR_ADMIN_STATE", "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.1", + "SAI_ENI_ATTR_VM_VNI", "9", + "SAI_ENI_ATTR_VNET_ID", "$vnet_#4", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0" + ] + }, + { + "name": "eni_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", "10000", + "SAI_ENI_ATTR_PPS", "100000", + "SAI_ENI_ATTR_FLOWS", "100000", + "SAI_ENI_ATTR_ADMIN_STATE", "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.2.1", + "SAI_ENI_ATTR_VM_VNI", "10", + "SAI_ENI_ATTR_VNET_ID", "$vnet_#5", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0" + ] + }, + { + "name": "eam_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:CC:CC:CC:00:00" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni_#0" + ] + }, + { + "name": "eam_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:CC:CC:CC:00:01" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni_#1" + ] + }, + { + "name": "ore_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#0", + "destination": "10.1.1.0/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#0" + ] + }, + { + "name": "ore_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#0", + "destination": "10.1.1.2/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#1" + ] + }, + { + "name": "ore_#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#1", + "destination": "10.1.1.0/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#2" + ] + }, + { + "name": "ore_#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#1", + "destination": "10.1.1.2/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#3" + ] + }, + { + "name": "ocpe_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#0", + "dip": "10.1.1.0" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.1.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:00", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#0", + "dip": "10.1.1.1" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.2.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:01", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#1", + "dip": "10.1.1.2" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.3.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:02", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#1", + "dip": "10.1.1.3" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.4.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:03", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#4", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#2", + "dip": "10.1.1.0" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.5.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:04", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#5", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#2", + "dip": "10.1.1.1" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.6.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:05", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#6", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#3", + "dip": "10.1.1.2" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.7.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:06", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#7", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#3", + "dip": "10.1.1.3" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.8.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:07", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + } +] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json similarity index 97% rename from test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json rename to test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json index 1cf181ecb..087132275 100644 --- a/test/test-cases/test_vector_example/test_vnet_outbound_setup_commands.json +++ b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json @@ -44,7 +44,7 @@ "op": "create", "type": "SAI_OBJECT_TYPE_VNET", "attributes": [ - "SAI_VNET_ATTR_VNI", "100" + "SAI_VNET_ATTR_VNI", "1000" ] }, { @@ -87,7 +87,7 @@ "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", "key": { "switch_id": "$SWITCH_ID", - "address": "00:CC:CC:CC:CC:CC" + "address": "00:CC:CC:CC:00:00" }, "attributes": [ "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni" @@ -118,9 +118,8 @@ }, "attributes": [ "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.1.20", - "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:DD", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:00:00", "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" ] } ] - diff --git a/test/third-party/traffic_gen/deployment/.env b/test/third-party/traffic_gen/deployment/.env index 72ec4ae3b..8e3f592ed 100644 --- a/test/third-party/traffic_gen/deployment/.env +++ b/test/third-party/traffic_gen/deployment/.env @@ -1,5 +1,5 @@ DOCKER_REGISTRY=ghcr.io/open-traffic-generator -CONTROLLER_VERSION=0.0.1-3383 +CONTROLLER_VERSION=0.0.1-3423 TRAFFIC_ENGINE_VERSION=1.6.0.17 IFC1=veth1 IFC2=veth3 From de6a2007df1585afaba562fd0db330c26f4dc7dc Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:27:01 -0700 Subject: [PATCH 26/45] spellcheck --- .wordlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.wordlist.txt b/.wordlist.txt index f188cdd47..e69360d61 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -420,6 +420,7 @@ qos Radv rdpty reachability +reconvergence README READMEs README's From ce1852446a74f3226bed9c928107b2bf315b4f90 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:43:11 -0700 Subject: [PATCH 27/45] Move saichallenger client docker to ACR. --- .../dash-saichallenger-client-docker-acr.yml | 54 +++++++++++++++++++ .../dash-saichallenger-client-docker.yml | 2 +- .../dash-saithrift-client-bldr-docker-acr.yml | 2 +- dash-pipeline/Makefile | 26 +++++---- 4 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/dash-saichallenger-client-docker-acr.yml diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml new file mode 100644 index 000000000..034bdfd45 --- /dev/null +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -0,0 +1,54 @@ +name: DASH-docker-saichallenger-client-build-publish-acr + +on: + push: + branches: [ "**" ] + paths: + - '.github/workflows/dash-saichallenger-client-docker.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + pull_request: + branches: [ "main" ] + paths: + - '.github/workflows/dash-saichallenger-client-docker.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + workflow_dispatch: + +jobs: + build: + # Can only publish from within DASH repo (need credentials from secrets) + if: github.repository == 'Azure/DASH' + name: Build and publish dash-saichallenger-client-image + runs-on: ubuntu-20.04 + env: + docker_fg_flags: -u root --privileged + docker_bg_flags: -d -u root --privileged + defaults: + run: + working-directory: ./dash-pipeline + steps: + - uses: actions/checkout@v3 + - name: Pull docker p4c image + run: make docker-pull-dash-p4c + - name: Build P4 software switch (bmv2) and P4Info + run: DOCKER_FLAGS=$docker_fg_flags make p4 + - name: Install SAI submodule + run: git submodule update --init + - name: Generate SAI API + run: DOCKER_FLAGS=$docker_fg_flags make sai + - name: Generate SAI-Thrift client and server code and libs + run: DOCKER_FLAGS=$docker_fg_flags make saithrift-server + - uses: azure/docker-login@v1 + with: + login-server: sonicdash.azurecr.io + username: ${{ secrets.DASH_ACR_USERNAME }} + password: ${{ secrets.DASH_ACR_PASSWORD }} + - name: Build SAI-Challenger client docker image + run: DOCKER_FLAGS=$docker_fg_flags make docker-saichallenger-client + - name: Publish SAI-Challenger client docker image + run: make docker-publish-saichallenger-client \ No newline at end of file diff --git a/.github/workflows/dash-saichallenger-client-docker.yml b/.github/workflows/dash-saichallenger-client-docker.yml index 90a278f5b..0effadf42 100644 --- a/.github/workflows/dash-saichallenger-client-docker.yml +++ b/.github/workflows/dash-saichallenger-client-docker.yml @@ -1,4 +1,4 @@ -name: DASH-docker-saichallenger-client-image +name: DASH-docker-saichallenger-client-img on: push: diff --git a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml index eac589a5c..00ce811fd 100644 --- a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml +++ b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml @@ -53,4 +53,4 @@ jobs: - name: Build dash-saithrift-client-bldr image run: DOCKER_FLAGS=$docker_fg_flags make docker-saithrift-client-bldr - name: Publish dash-saithrift-client-bldr docker image - run: make docker-publish-saithrift-client-bldr + run: make docker-publish-saichallenger-client diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index fd6b04d3c..4f84ed096 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -49,6 +49,10 @@ include dockerfiles/DOCKER_SAITHRIFT_CLIENT_BLDR_IMG.env # TODO: consider some other tagging scheme DOCKER_SAITHRIFT_CLIENT_IMG ?= local/dash-saithrift-client:latest +# Base image with test frameworks, DASH client libs not installed +# include file defines DOCKER_SAI_CHALLENGER_CLIENT_IMG +include dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env + # Set differently in CI scripts as needed, e.g. run switch container in -d mode DOCKER_FLAGS ?=-it @@ -518,8 +522,6 @@ undeploy-ixiac: SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger.OCP -DOCKER_SAI_CHALLENGER_CLIENT = anton7811/dash-saichallenger-client:220920 - CONTAINER_SAI_CHALLENGER_CLIENT_NAME = dash-saichallenger-client-$(USER) # Add passing parameters to the run-saichallenger-tests target. @@ -542,10 +544,14 @@ docker-saichallenger-client: cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client docker build \ -f dockerfiles/Dockerfile.saichallenger-client \ - -t $(DOCKER_SAI_CHALLENGER_CLIENT) \ + -t $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ . -DOCKER_RUN_SAI_CHALLENGER_CLEINT=docker run \ +docker-publish-saithrift-client-bldr: + @echo "Publish $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) - requires credentials, can only do from DASH repo, not a fork" + docker push $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) + +DOCKER_RUN_SAI_CHALLENGER_CLIENT=docker run \ -v $(SAI_CHALLENGER_PATH):/sai-challenger \ -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/dash_tests \ -v $(PWD)/../:/dash \ @@ -556,26 +562,26 @@ DOCKER_RUN_SAI_CHALLENGER_CLEINT=docker run \ --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) run-saichallenger-client: deploy-ixiac - $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ + $(DOCKER_RUN_SAI_CHALLENGER_CLIENT) \ -d \ --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ - $(DOCKER_SAI_CHALLENGER_CLIENT) + $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) run-saichallenger-client-bash: deploy-ixiac - $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ + $(DOCKER_RUN_SAI_CHALLENGER_CLIENT) \ -w /sai-challenger/dash_tests \ $(DOCKER_FLAGS) \ - $(DOCKER_SAI_CHALLENGER_CLIENT) \ + $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ /bin/bash kill-saichallenger-client: -docker kill $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) run-saichallenger-tests: deploy-ixiac - $(DOCKER_RUN_SAI_CHALLENGER_CLEINT) \ + $(DOCKER_RUN_SAI_CHALLENGER_CLIENT) \ -w /sai-challenger/dash_tests \ $(DOCKER_FLAGS) \ - $(DOCKER_SAI_CHALLENGER_CLIENT) \ + $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ ./run_vnet_tests.sh --setup=$(SAI_CHALLENGER_SETUP_FILE) $(SAI_CHALLENGER_TEST) ############################### From 1b061c6880135c06e9c6fd0265ff7af71dfe46c2 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:46:22 -0700 Subject: [PATCH 28/45] Fix .yml formatting. --- .github/workflows/dash-saichallenger-client-docker-acr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml index 034bdfd45..4c9e4ed40 100644 --- a/.github/workflows/dash-saichallenger-client-docker-acr.yml +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -49,6 +49,6 @@ jobs: username: ${{ secrets.DASH_ACR_USERNAME }} password: ${{ secrets.DASH_ACR_PASSWORD }} - name: Build SAI-Challenger client docker image - run: DOCKER_FLAGS=$docker_fg_flags make docker-saichallenger-client + run: DOCKER_FLAGS=$docker_fg_flags make docker-saichallenger-client - name: Publish SAI-Challenger client docker image - run: make docker-publish-saichallenger-client \ No newline at end of file + run: make docker-publish-saichallenger-client \ No newline at end of file From 1f317ed108c04648bd74cf1f6bd32f78a2de0b09 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:48:13 -0700 Subject: [PATCH 29/45] Fix dependency in action file. --- .github/workflows/dash-saichallenger-client-docker-acr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml index 4c9e4ed40..b84ee19ed 100644 --- a/.github/workflows/dash-saichallenger-client-docker-acr.yml +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -4,7 +4,7 @@ on: push: branches: [ "**" ] paths: - - '.github/workflows/dash-saichallenger-client-docker.yml' + - '.github/workflows/dash-saichallenger-client-docker-acr.yml' - 'dash-pipeline/Makefile' - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' - 'dash-pipeline/.dockerignore' @@ -12,7 +12,7 @@ on: pull_request: branches: [ "main" ] paths: - - '.github/workflows/dash-saichallenger-client-docker.yml' + - '.github/workflows/dash-saichallenger-client-docker-acr.yml' - 'dash-pipeline/Makefile' - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' - 'dash-pipeline/.dockerignore' From f6965fe36b96c8c22ac856f571cfdf8f0ae71c05 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:53:02 -0700 Subject: [PATCH 30/45] Add missing .env file --- .../dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env diff --git a/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env new file mode 100644 index 000000000..95f3b2fe3 --- /dev/null +++ b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env @@ -0,0 +1,4 @@ +# Define docker image repo/name:tag +# Changing this will cause build/publish to occur in CI actions +export DASH_ACR_REGISTRY=sonicdash.azurecr.io +export DOCKER_SAI_CHALLENGER_CLIENT_IMG=anton7811/dash-saichallenger-client:220920 From 981a7e36661a8824572c66af11f6395c7066c24c Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:57:04 -0700 Subject: [PATCH 31/45] remove space in action script, add .env dependencies --- .github/workflows/dash-bmv2-ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dash-bmv2-ci.yml b/.github/workflows/dash-bmv2-ci.yml index 4aabd09b8..ce7aebe18 100644 --- a/.github/workflows/dash-bmv2-ci.yml +++ b/.github/workflows/dash-bmv2-ci.yml @@ -11,7 +11,8 @@ on: - 'test/**.sh' - 'test/**.yml' - 'dash-pipeline/**' - - '!dash-pipeline/docker files/Dockerfile.*' + - '!dash-pipeline/dockerfiles/Dockerfile.*' + - 'dash-pipeline/dockerfiles/*.env' - '!dash-pipeline/.dockerignore' - '!dash-pipeline/**.md' - '!dash-pipeline/**.svg' @@ -27,7 +28,8 @@ on: - 'test/**.sh' - 'test/**.yml' - 'dash-pipeline/**' - - '!dash-pipeline/docker files/Dockerfile.*' + - '!dash-pipeline/dockerfiles/Dockerfile.*' + - 'dash-pipeline/dockerfiles/*.env' - '!dash-pipeline/.dockerignore' - '!dash-pipeline/**.md' - '!dash-pipeline/**.svg' From c2983c242f934c2fb5f1efea584fefbd22f426b1 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 17:59:24 -0700 Subject: [PATCH 32/45] fix include path --- dash-pipeline/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 4f84ed096..a888a705e 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -51,7 +51,7 @@ DOCKER_SAITHRIFT_CLIENT_IMG ?= local/dash-saithrift-client:latest # Base image with test frameworks, DASH client libs not installed # include file defines DOCKER_SAI_CHALLENGER_CLIENT_IMG -include dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env +include dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env # Set differently in CI scripts as needed, e.g. run switch container in -d mode DOCKER_FLAGS ?=-it From c5fa177370d5b91bc802c0c9a06008bc0613c545 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 18:04:49 -0700 Subject: [PATCH 33/45] Add saichalleneger tests to run-all-tests and CI --- .github/workflows/dash-bmv2-ci.yml | 2 ++ dash-pipeline/Makefile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dash-bmv2-ci.yml b/.github/workflows/dash-bmv2-ci.yml index ce7aebe18..65971c75e 100644 --- a/.github/workflows/dash-bmv2-ci.yml +++ b/.github/workflows/dash-bmv2-ci.yml @@ -84,4 +84,6 @@ jobs: run: DOCKER_FLAGS=$docker_fg_flags make deploy-ixiac - name: Run Pytests run: DOCKER_FLAGS=$docker_fg_root_flags make run-saithrift-pytests + - name: Run SAI-Challenger Tests + run: DOCKER_FLAGS=$docker_fg_root_flags make run-saichallenger-tests diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index a888a705e..740bead66 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -6,7 +6,7 @@ mkfile_dir := $(dir $(mkfile_path)) # "All" type targets for convenience all:p4 sai saithrift-server docker-saithrift-client test -run-all-tests:run-libsai-test run-saithrift-client-tests +run-all-tests:run-libsai-test run-saithrift-client-tests run-saichallenger-tests run-saithrift-client-tests: run-saithrift-ptftests run-saithrift-pytests run-saithrift-client-dev-tests: run-saithrift-dev-ptftests run-saithrift-dev-pytests From a013ef7c786094884711a314334a547586c539a0 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 19:35:30 -0700 Subject: [PATCH 34/45] Fix docker image name. --- dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env index 95f3b2fe3..4af6e29d5 100644 --- a/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env +++ b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env @@ -1,4 +1,4 @@ # Define docker image repo/name:tag # Changing this will cause build/publish to occur in CI actions export DASH_ACR_REGISTRY=sonicdash.azurecr.io -export DOCKER_SAI_CHALLENGER_CLIENT_IMG=anton7811/dash-saichallenger-client:220920 +export DOCKER_SAI_CHALLENGER_CLIENT_IMG=${DASH_ACR_REGISTRY}/dash-saichallenger-client:220920 From d171622905d51e615290556c34140e6868b80570 Mon Sep 17 00:00:00 2001 From: Chris Sommers <31145757+chrispsommers@users.noreply.github.com> Date: Tue, 11 Oct 2022 19:42:27 -0700 Subject: [PATCH 35/45] Publish saic to acr (#252) * Added SAI-Challenger to CI setup. 1. Added SAI-Challenger submodule. 2. Added SAI-Challenger basic test. 3. Changed Makefile to build/start/stop SAI-Challenger. Signed-off-by: Maksym Hedeon * Added saithrift to SAI-Challenger client docker image - Added saithrift to SAI-Challenger client docker image - Changed SAI-C submodule branch Signed-off-by: Maksym Hedeon * Update example vnet test. 1. Added SAI-Challenger submodule. 2. Added SAI-Challenger basic test. 3. Changed Makefile to build/start/stop SAI-Challenger. Signed-off-by: Kostiantyn Goloveshko Co-authored-by: Maksym Hedeon * Add vnet outbound test based on SAI description. Signed-off-by: Maksym Prytoliuk * Fixup double network host usage for sai-challenger-client Signed-off-by: Konstantin Goloveshko * Kdt 17: Update docker environment (#8) * Added cgyang submodule * Updated docker env for thrift tests * Makefile refactor Signed-off-by: Maksym Hedeon * Fixup VNET inbound cleanup removals in test config. Signed-off-by: Konstantin Goloveshko * Update CA_TO_PA entry in outbound test Signed-off-by: Maksym Prytoliuk * Add vnet scenarios in DASH config format. * Added dash-style VNET inbound routing test * Added dash-style VNET outbound routing test * Read config from json (temp workaround) * Added JSON setup configs for testbed Signed-off-by: Anton Putria Co-authored-by: Maksym Prytoliuk * Fixed saigen links. Signed-off-by: Anton Putria * Fixes in test scanario. Signed-off-by: Anton Putria * Fixed path to saigen. Fixed inbound test. Signed-off-by: Anton Putria * Update submodule Signed-off-by: Anton Putria * Final test fixes to align with submodue version. Signed-off-by: Anton Putria * Fixed VNET outbound test scenario. Signed-off-by: Anton Putria * Outbound test passes with traffic Fixed configuration based on changes in main. Signed-off-by: Maksym Prytoliuk * Update documentation - Added dash-test-sai-challenger.md doc file under test/docs - Updated Makefile make run-saic-test-thrift target with passing parameters. Signed-off-by: Maksym Hedeon * Updated SAI-Challenger submodule. Signed-off-by: Anton Putria * Improvements to SAI-Challenger docker flows. - Use docker hub to pull images - Fixed make run-saic-tests to do not show errors - Updated manuals Signed-off-by: Anton Putria * Update dash-test-sai-challenger.md Signed-off-by: Mircea Dan Gheorghe * Add bmv2 SAI port attributes (num_active, port_list), dflt vlan, dflt vrf) * Added SAI-Challenger docker build verification to GitHub actions - Added SAI-Challenger docker verification action. - Fixed spellchecker and docker build issues. Signed-off-by: Anton Putria * Add default .1Q bridge to bmv2 Signed-off-by: Maksym Prytoliuk * Fixed SAI-Challenger user guide and file namings. Signed-off-by: Anton Putria * Scaled VNET outbound test using snappi and saigen. (1st edition) - Split scale and simple tests / jsons - Updated ixia controller version - Added dash_helper for traffic profile scaling. Signed-off-by: Maksym Hedeon * spellcheck * Move saichallenger client docker to ACR. * Fix .yml formatting. * Fix dependency in action file. * Add missing .env file * remove space in action script, add .env dependencies * fix include path * Add saichalleneger tests to run-all-tests and CI * Fix docker image name. Signed-off-by: Maksym Hedeon Signed-off-by: Kostiantyn Goloveshko Signed-off-by: Maksym Prytoliuk Signed-off-by: Konstantin Goloveshko Signed-off-by: Anton Putria Signed-off-by: Mircea Dan Gheorghe Co-authored-by: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Co-authored-by: Kostiantyn Goloveshko Co-authored-by: Maksym Hedeon Co-authored-by: Maksym Prytoliuk <71631949+maksym-prytoliuk-plv@users.noreply.github.com> Co-authored-by: Anton Putria Co-authored-by: Maksym Prytoliuk Co-authored-by: Anton Putria Co-authored-by: MirceaDan Co-authored-by: Chris Sommers --- .github/workflows/dash-bmv2-ci.yml | 8 +- .../dash-saichallenger-client-docker-acr.yml | 54 +++ .../dash-saichallenger-client-docker.yml | 45 +++ .../dash-saithrift-client-bldr-docker-acr.yml | 2 +- .gitmodules | 7 + .wordlist.txt | 3 + dash-pipeline/Makefile | 85 +++- dash-pipeline/SAI/templates/utils.cpp.j2 | 65 +++- dash-pipeline/cgyang | 1 + .../DOCKER_SAI_CHALLENGER_CLIENT_IMG.env | 4 + .../Dockerfile.saichallenger-client | 40 ++ .../tests/saithrift/pytest/pytest.ini | 1 + .../pytest/switch/test_saithrift_switch.py | 28 +- test/SAI-Challenger.OCP | 1 + test/docs/README.md | 9 +- test/docs/dash-test-sai-challenger.md | 96 +++++ .../test_vector_example/__init__.py | 0 .../test_vector_example/conftest.py | 82 ++++ .../dash_helper/vnet2vnet_helper.py | 234 +++++++++++ .../test_vector_example/run_vnet_tests.sh | 3 + .../sai_dpu_client_server_ptf.json | 41 ++ .../sai_dpu_client_server_snappi.json | 42 ++ .../test_sai_vnet_inbound.py | 185 +++++++++ .../test_sai_vnet_outbound_scale.py | 241 ++++++++++++ .../test_sai_vnet_outbound_simple.py | 164 ++++++++ .../test_vector_example/test_vnet_inbound.py | 18 + .../test_vector_example/test_vnet_outbound.py | 21 + .../vnet_inbound_setup_commands.json | 159 ++++++++ .../vnet_outbound_setup_commands_scale.json | 366 ++++++++++++++++++ .../vnet_outbound_setup_commands_simple.json | 125 ++++++ test/third-party/traffic_gen/deployment/.env | 2 +- 31 files changed, 2110 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/dash-saichallenger-client-docker-acr.yml create mode 100644 .github/workflows/dash-saichallenger-client-docker.yml create mode 160000 dash-pipeline/cgyang create mode 100644 dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env create mode 100644 dash-pipeline/dockerfiles/Dockerfile.saichallenger-client create mode 160000 test/SAI-Challenger.OCP create mode 100644 test/docs/dash-test-sai-challenger.md create mode 100644 test/test-cases/test_vector_example/__init__.py create mode 100644 test/test-cases/test_vector_example/conftest.py create mode 100644 test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py create mode 100755 test/test-cases/test_vector_example/run_vnet_tests.sh create mode 100755 test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json create mode 100755 test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_inbound.py create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py create mode 100644 test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py create mode 100644 test/test-cases/test_vector_example/test_vnet_inbound.py create mode 100644 test/test-cases/test_vector_example/test_vnet_outbound.py create mode 100644 test/test-cases/test_vector_example/vnet_inbound_setup_commands.json create mode 100644 test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json create mode 100644 test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json diff --git a/.github/workflows/dash-bmv2-ci.yml b/.github/workflows/dash-bmv2-ci.yml index 4aabd09b8..65971c75e 100644 --- a/.github/workflows/dash-bmv2-ci.yml +++ b/.github/workflows/dash-bmv2-ci.yml @@ -11,7 +11,8 @@ on: - 'test/**.sh' - 'test/**.yml' - 'dash-pipeline/**' - - '!dash-pipeline/docker files/Dockerfile.*' + - '!dash-pipeline/dockerfiles/Dockerfile.*' + - 'dash-pipeline/dockerfiles/*.env' - '!dash-pipeline/.dockerignore' - '!dash-pipeline/**.md' - '!dash-pipeline/**.svg' @@ -27,7 +28,8 @@ on: - 'test/**.sh' - 'test/**.yml' - 'dash-pipeline/**' - - '!dash-pipeline/docker files/Dockerfile.*' + - '!dash-pipeline/dockerfiles/Dockerfile.*' + - 'dash-pipeline/dockerfiles/*.env' - '!dash-pipeline/.dockerignore' - '!dash-pipeline/**.md' - '!dash-pipeline/**.svg' @@ -82,4 +84,6 @@ jobs: run: DOCKER_FLAGS=$docker_fg_flags make deploy-ixiac - name: Run Pytests run: DOCKER_FLAGS=$docker_fg_root_flags make run-saithrift-pytests + - name: Run SAI-Challenger Tests + run: DOCKER_FLAGS=$docker_fg_root_flags make run-saichallenger-tests diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml new file mode 100644 index 000000000..b84ee19ed --- /dev/null +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -0,0 +1,54 @@ +name: DASH-docker-saichallenger-client-build-publish-acr + +on: + push: + branches: [ "**" ] + paths: + - '.github/workflows/dash-saichallenger-client-docker-acr.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + pull_request: + branches: [ "main" ] + paths: + - '.github/workflows/dash-saichallenger-client-docker-acr.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + workflow_dispatch: + +jobs: + build: + # Can only publish from within DASH repo (need credentials from secrets) + if: github.repository == 'Azure/DASH' + name: Build and publish dash-saichallenger-client-image + runs-on: ubuntu-20.04 + env: + docker_fg_flags: -u root --privileged + docker_bg_flags: -d -u root --privileged + defaults: + run: + working-directory: ./dash-pipeline + steps: + - uses: actions/checkout@v3 + - name: Pull docker p4c image + run: make docker-pull-dash-p4c + - name: Build P4 software switch (bmv2) and P4Info + run: DOCKER_FLAGS=$docker_fg_flags make p4 + - name: Install SAI submodule + run: git submodule update --init + - name: Generate SAI API + run: DOCKER_FLAGS=$docker_fg_flags make sai + - name: Generate SAI-Thrift client and server code and libs + run: DOCKER_FLAGS=$docker_fg_flags make saithrift-server + - uses: azure/docker-login@v1 + with: + login-server: sonicdash.azurecr.io + username: ${{ secrets.DASH_ACR_USERNAME }} + password: ${{ secrets.DASH_ACR_PASSWORD }} + - name: Build SAI-Challenger client docker image + run: DOCKER_FLAGS=$docker_fg_flags make docker-saichallenger-client + - name: Publish SAI-Challenger client docker image + run: make docker-publish-saichallenger-client \ No newline at end of file diff --git a/.github/workflows/dash-saichallenger-client-docker.yml b/.github/workflows/dash-saichallenger-client-docker.yml new file mode 100644 index 000000000..0effadf42 --- /dev/null +++ b/.github/workflows/dash-saichallenger-client-docker.yml @@ -0,0 +1,45 @@ +name: DASH-docker-saichallenger-client-img + +on: + push: + branches: [ "**" ] + paths: + - '.github/workflows/dash-saichallenger-client-docker.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + pull_request: + branches: [ "main" ] + paths: + - '.github/workflows/dash-saichallenger-client-docker.yml' + - 'dash-pipeline/Makefile' + - 'dash-pipeline/dockerfiles/Dockerfile.saichallenger-client' + - 'dash-pipeline/.dockerignore' + - 'dash-pipeline/dockerfiles/.dockerignore' + workflow_dispatch: + +jobs: + build: + name: Build dash-saichallenger-client-image + runs-on: ubuntu-20.04 + env: + docker_fg_flags: -u root --privileged + docker_bg_flags: -d -u root --privileged + defaults: + run: + working-directory: ./dash-pipeline + steps: + - uses: actions/checkout@v3 + - name: Pull docker p4c image + run: make docker-pull-dash-p4c + - name: Build P4 software switch (bmv2) and P4Info + run: DOCKER_FLAGS=$docker_fg_flags make p4 + - name: Install SAI submodule + run: git submodule update --init + - name: Generate SAI API + run: DOCKER_FLAGS=$docker_fg_flags make sai + - name: Generate SAI-Thrift client and server code and libs + run: DOCKER_FLAGS=$docker_fg_flags make saithrift-server + - name: Build SAI-Challenger client docker image + run: DOCKER_FLAGS=$docker_fg_flags make docker-saichallenger-client diff --git a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml index eac589a5c..00ce811fd 100644 --- a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml +++ b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml @@ -53,4 +53,4 @@ jobs: - name: Build dash-saithrift-client-bldr image run: DOCKER_FLAGS=$docker_fg_flags make docker-saithrift-client-bldr - name: Publish dash-saithrift-client-bldr docker image - run: make docker-publish-saithrift-client-bldr + run: make docker-publish-saichallenger-client diff --git a/.gitmodules b/.gitmodules index cb32895b5..2e2092019 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,10 @@ path = dash-pipeline/SAI/SAI url = https://github.com/reshmaintel/SAI.git branch = dash-ptf-ci +[submodule "test/SAI-Challenger.OCP"] + path = test/SAI-Challenger.OCP + url = https://github.com/plvisiondevs/SAI-Challenger.OCP + branch = dash-testing +[submodule "dash-pipeline/cgyang"] + path = dash-pipeline/cgyang + url = https://github.com/mgheorghe/cgyang diff --git a/.wordlist.txt b/.wordlist.txt index 2b83ce91b..e69360d61 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -420,6 +420,7 @@ qos Radv rdpty reachability +reconvergence README READMEs README's @@ -450,12 +451,14 @@ runtime rx SAI sai +saigen sairedis SAIRPC saiserver saithrift sata scalability +scalable Scalable scapy Schemas diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 4ba85015c..740bead66 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -6,7 +6,7 @@ mkfile_dir := $(dir $(mkfile_path)) # "All" type targets for convenience all:p4 sai saithrift-server docker-saithrift-client test -run-all-tests:run-libsai-test run-saithrift-client-tests +run-all-tests:run-libsai-test run-saithrift-client-tests run-saichallenger-tests run-saithrift-client-tests: run-saithrift-ptftests run-saithrift-pytests run-saithrift-client-dev-tests: run-saithrift-dev-ptftests run-saithrift-dev-pytests @@ -14,7 +14,7 @@ run-saithrift-client-dev-tests: run-saithrift-dev-ptftests run-saithrift-dev-pyt clean: kill-all p4-clean sai-clean test-clean network-clean saithrift-server-clean rm -rf $(P4_OUTDIR) -kill-all: kill-saithrift-server kill-switch undeploy-ixiac +kill-all: kill-saithrift-server kill-switch undeploy-ixiac kill-saichallenger-client PWD := $(realpath $(mkfile_dir)) DASH_USER ?=dashuser @@ -49,6 +49,10 @@ include dockerfiles/DOCKER_SAITHRIFT_CLIENT_BLDR_IMG.env # TODO: consider some other tagging scheme DOCKER_SAITHRIFT_CLIENT_IMG ?= local/dash-saithrift-client:latest +# Base image with test frameworks, DASH client libs not installed +# include file defines DOCKER_SAI_CHALLENGER_CLIENT_IMG +include dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env + # Set differently in CI scripts as needed, e.g. run switch container in -d mode DOCKER_FLAGS ?=-it @@ -122,7 +126,7 @@ DOCKER_RUN_SAITHRIFT_BLDR =\ sai: sai-clean sai-headers sai-meta libsai -sai-headers: p4 | SAI/SAI +sai-headers: p4 | SAI/SAI @echo "Generate SAI library headers and implementation..." mkdir -p SAI/lib && chmod -R o+w SAI && \ $(DOCKER_RUN) \ @@ -131,7 +135,7 @@ sai-headers: p4 | SAI/SAI -w /SAI $(DOCKER_SAITHRIFT_BLDR_IMG) \ ./generate_dash_api.sh -sai-meta: +sai-meta: @echo "Generate SAI metadata..." # hack - remove scripts which cause Git ownership failures in CI pipelines # We don't need them, they're to check that SAI headers didn't experience enum changes etc. @@ -146,7 +150,7 @@ sai-meta: make # TODO - add SAI header dependencies -libsai: +libsai: @echo "build libsai.so..." $(DOCKER_RUN) \ $(DOCKER_FLAGS) \ @@ -155,7 +159,7 @@ libsai: $(DOCKER_BMV2_BLDR_IMG) \ make -libsai-clean: +libsai-clean: -rm -rf SAI/lib/* .PHONY:sai-clean @@ -354,7 +358,7 @@ docker-publish-saithrift-client-bldr: docker push $(DOCKER_SAITHRIFT_CLIENT_BLDR_IMG) ############################### - + # Client image, rebuild any time SAI interface changes # TODO - add sai header (inc/ and experimental) dependencies docker-saithrift-client: @@ -512,6 +516,73 @@ deploy-ixiac: undeploy-ixiac: cd ../test/third-party/traffic_gen && ./undeploy_ixiac.sh +############################### +# SAI-CHALLENGER TARGETS +############################### + +SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger.OCP + +CONTAINER_SAI_CHALLENGER_CLIENT_NAME = dash-saichallenger-client-$(USER) + +# Add passing parameters to the run-saichallenger-tests target. +ifeq (run-saichallenger-tests,$(firstword $(MAKECMDGOALS))) + SAI_CHALLENGER_SETUP_FILE := $(wordlist 2, 2, $(MAKECMDGOALS)) + SAI_CHALLENGER_TEST := $(wordlist 3, 3, $(MAKECMDGOALS)) + $(eval $(SAI_CHALLENGER_SETUP_FILE):;@:) + $(eval $(SAI_CHALLENGER_TEST):;@:) +endif +# If setup file's isn't passed, set it to the default. +ifeq ($(SAI_CHALLENGER_SETUP_FILE),) +SAI_CHALLENGER_SETUP_FILE := sai_dpu_client_server_snappi.json +endif +# If test's name isn't passed, set it to the default. +ifeq ($(SAI_CHALLENGER_TEST),) +SAI_CHALLENGER_TEST := test_sai_vnet_*.py +endif + +docker-saichallenger-client: + cd $(SAI_CHALLENGER_PATH) && ./build.sh -i client + docker build \ + -f dockerfiles/Dockerfile.saichallenger-client \ + -t $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ + . + +docker-publish-saithrift-client-bldr: + @echo "Publish $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) - requires credentials, can only do from DASH repo, not a fork" + docker push $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) + +DOCKER_RUN_SAI_CHALLENGER_CLIENT=docker run \ + -v $(SAI_CHALLENGER_PATH):/sai-challenger \ + -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/dash_tests \ + -v $(PWD)/../:/dash \ + --cap-add=NET_ADMIN \ + --device /dev/net/tun:/dev/net/tun \ + --rm \ + --network=host \ + --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) + +run-saichallenger-client: deploy-ixiac + $(DOCKER_RUN_SAI_CHALLENGER_CLIENT) \ + -d \ + --name $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) \ + $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) + +run-saichallenger-client-bash: deploy-ixiac + $(DOCKER_RUN_SAI_CHALLENGER_CLIENT) \ + -w /sai-challenger/dash_tests \ + $(DOCKER_FLAGS) \ + $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ + /bin/bash + +kill-saichallenger-client: + -docker kill $(CONTAINER_SAI_CHALLENGER_CLIENT_NAME) + +run-saichallenger-tests: deploy-ixiac + $(DOCKER_RUN_SAI_CHALLENGER_CLIENT) \ + -w /sai-challenger/dash_tests \ + $(DOCKER_FLAGS) \ + $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ + ./run_vnet_tests.sh --setup=$(SAI_CHALLENGER_SETUP_FILE) $(SAI_CHALLENGER_TEST) ############################### # ENVIRONMENT SETUP TARGETS diff --git a/dash-pipeline/SAI/templates/utils.cpp.j2 b/dash-pipeline/SAI/templates/utils.cpp.j2 index 683182933..fe673a090 100644 --- a/dash-pipeline/SAI/templates/utils.cpp.j2 +++ b/dash-pipeline/SAI/templates/utils.cpp.j2 @@ -218,20 +218,77 @@ sai_status_t sai_create_switch_dummy( return SAI_STATUS_SUCCESS; } -sai_status_t sai_get_switch_attribute_dummy( +#define DASH_BMV2_NUM_PORTS 2 +#define DASH_BMV2_DEFAULT_VLAN_ID (sai_object_id_t)((SAI_OBJECT_TYPE_VLAN<<48)+1) +#define DASH_BMV2_DEFAULT_VRF_ID (sai_object_id_t)((SAI_OBJECT_TYPE_VIRTUAL_ROUTER<<48)+1) +#define DASH_BMV2_DEFAULT_1Q_BRIDGE_ID (sai_object_id_t)((SAI_OBJECT_TYPE_BRIDGE<<48)+1) + +sai_object_id_t port_list[DASH_BMV2_NUM_PORTS] = { + (sai_object_id_t)((SAI_OBJECT_TYPE_PORT<<48) + 1), + (sai_object_id_t)((SAI_OBJECT_TYPE_PORT<<48) + 2) +}; + +sai_status_t sai_get_switch_attribute( _In_ sai_object_id_t switch_id, _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { - fprintf(stderr, "sai_get_switch_attribute_dummy()\n"); - return SAI_STATUS_SUCCESS; + fprintf(stderr, "sai_get_switch_attribute()\n"); + int i; + sai_attribute_t *attr = attr_list; + sai_object_list_t port_obj_list; + sai_object_id_t *objlist; + for (i = 0; i < attr_count ; i++, attr++) { + switch(attr->id) { + + case SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS: + attr->value.u32 = DASH_BMV2_NUM_PORTS; + fprintf(stderr, " sai_get_switch_attribute() [%d] attr %d SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS = %d\n", + i, attr->id, attr->value.u32); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_PORT_LIST: + // make a tmp port list, saiserver will free the memory + objlist = (sai_object_id_t *)malloc(sizeof(port_list)); + memcpy(objlist, port_list, sizeof(port_list)); + port_obj_list = { + .count = DASH_BMV2_NUM_PORTS, + .list = objlist + }; + attr->value.objlist = port_obj_list; + fprintf(stderr, " sai_get_switch_attribute() [%d] attr %d SAI_SWITCH_ATTR_PORT_LIST = [%d objids]\n", + i, attr->id, DASH_BMV2_NUM_PORTS); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_DEFAULT_VLAN_ID: + attr->value.oid = DASH_BMV2_DEFAULT_VLAN_ID; + fprintf(stderr, " sai_get_switch_attribute() [%d] attr %d SAI_SWITCH_ATTR_DEFAULT_VLAN_ID = %lx\n", + i, attr->id, attr->value.oid); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID: + attr->value.oid = DASH_BMV2_DEFAULT_VRF_ID; + fprintf(stderr, " sai_get_switch_attribute() [0] attr %d SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID = %lx\n", attr->id, attr->value.oid); + return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID: + attr->value.oid = DASH_BMV2_DEFAULT_1Q_BRIDGE_ID; + fprintf(stderr, " sai_get_switch_attribute() [0] attr %d SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID = %lx\n", attr->id, attr->value.oid); + return SAI_STATUS_SUCCESS; + + default: + fprintf(stderr, " sai_get_switch_attribute() [0] attr %d is NOT SUPPORTED - returning SAI_STATUS_SUCCESS anyway\n", attr->id); + return SAI_STATUS_NOT_SUPPORTED; + } + } + return SAI_STATUS_NOT_SUPPORTED; } sai_switch_api_t sai_switch_api_impl = { .create_switch = sai_create_switch_dummy, .remove_switch = (void *)0, .set_switch_attribute = (void *)0, - .get_switch_attribute = sai_get_switch_attribute_dummy, + .get_switch_attribute = sai_get_switch_attribute, .get_switch_stats = (void *)0, .get_switch_stats_ext = (void *)0, .clear_switch_stats = (void *)0, diff --git a/dash-pipeline/cgyang b/dash-pipeline/cgyang new file mode 160000 index 000000000..d1c65a161 --- /dev/null +++ b/dash-pipeline/cgyang @@ -0,0 +1 @@ +Subproject commit d1c65a16128003e05f05f0c138c15260abedacdd diff --git a/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env new file mode 100644 index 000000000..4af6e29d5 --- /dev/null +++ b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env @@ -0,0 +1,4 @@ +# Define docker image repo/name:tag +# Changing this will cause build/publish to occur in CI actions +export DASH_ACR_REGISTRY=sonicdash.azurecr.io +export DOCKER_SAI_CHALLENGER_CLIENT_IMG=${DASH_ACR_REGISTRY}/dash-saichallenger-client:220920 diff --git a/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client new file mode 100644 index 000000000..5230ca8c9 --- /dev/null +++ b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client @@ -0,0 +1,40 @@ +FROM sc-client + +ENV SAI_CHALLENGER_PATH /sai-challenger +ENV DASH_PATH /dash + +ADD tests/ /tests/ + +# Copy distro PTF submodule and tools from SAI repo +ADD SAI/SAI/test/ptf /SAI/test/ptf + +# Install PTF test framework & test-cases from SAI repo +ADD SAI/SAI/ptf /SAI/ptf/ + +# Copy thrift python distro +ADD SAI/rpc/thrift-0.11.0.tar.gz / + +# Copy autogenerated saithrift library built from SAI headers for DASH dataplane +ADD SAI/rpc/saithrift-0.9.tar.gz / + +# Install the python libraries +RUN python3 -m pip install -r /tests/requirements.txt && \ + pip3 install scapy \ + pysubnettree \ + macaddress \ + munch && \ + cd /saithrift-0.9 && \ + python3 setup.py install && \ + cd / && \ + rm -rf saithrift-0.9 &&\ + cd thrift-0.11.0 && \ + python3 setup.py install && \ + cd / &&\ + rm -rf thrift-0.11.0 && \ + cd /SAI/test/ptf && \ + python3 setup.py install && \ + ln -s ${SAI_CHALLENGER_PATH} /usr/local/lib/python3.7/dist-packages/saichallenger && \ + ln -s ${DASH_PATH}/test/test-cases/test_vector_example ${SAI_CHALLENGER_PATH}/test_vector_example && \ + ln -s ${DASH_PATH}/dash-pipeline/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen + +CMD ["/usr/bin/supervisord"] diff --git a/dash-pipeline/tests/saithrift/pytest/pytest.ini b/dash-pipeline/tests/saithrift/pytest/pytest.ini index 42107e96f..4443adf18 100644 --- a/dash-pipeline/tests/saithrift/pytest/pytest.ini +++ b/dash-pipeline/tests/saithrift/pytest/pytest.ini @@ -2,5 +2,6 @@ markers = bmv2: test DASH bmv2 model saithrift: test DASH using saithrift API + switch: test DASH SAI switch APIs vnet: test DASH vnet scenarios \ No newline at end of file diff --git a/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py b/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py index f36cb7012..5ef43afca 100644 --- a/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py +++ b/dash-pipeline/tests/saithrift/pytest/switch/test_saithrift_switch.py @@ -6,10 +6,32 @@ @pytest.mark.saithrift @pytest.mark.bmv2 -def test_sai_thrift_get_switch_attribute(saithrift_client): +@pytest.mark.switch +def test_sai_thrift_get_switch_attributes(saithrift_client): attr = sai_thrift_get_switch_attribute( saithrift_client, number_of_active_ports=True) - print ("switch_attributes = %s" % attr) - print ("test_sai_thrift_get_switch_attribute OK") + number_of_active_ports = attr['number_of_active_ports'] + print ("number_of_active_ports = %d" % number_of_active_ports) + assert(number_of_active_ports != 0) + attr = sai_thrift_get_switch_attribute( + saithrift_client, + port_list=sai_thrift_object_list_t(idlist=[], count=int(number_of_active_ports))) + assert(number_of_active_ports == attr['port_list'].count) + port_list = attr['port_list'].idlist + print ("port list = ", port_list) + + attr = sai_thrift_get_switch_attribute( + saithrift_client, default_vlan_id=True) + default_vlan_id = attr['default_vlan_id'] + print ("default_vlan_id = %d" % default_vlan_id) + assert(default_vlan_id != 0) + + attr = sai_thrift_get_switch_attribute( + saithrift_client, default_virtual_router_id=True) + default_virtual_router_id = attr['default_virtual_router_id'] + print ("default_virtual_router_id = %d" % default_virtual_router_id) + assert(default_virtual_router_id != 0) + + print ("test_sai_thrift_get_switch_attribute OK") \ No newline at end of file diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP new file mode 160000 index 000000000..a714c5b12 --- /dev/null +++ b/test/SAI-Challenger.OCP @@ -0,0 +1 @@ +Subproject commit a714c5b12535e4dfd05dd07f3ccb48a9a2710438 diff --git a/test/docs/README.md b/test/docs/README.md index c63dbe53a..e88335a61 100644 --- a/test/docs/README.md +++ b/test/docs/README.md @@ -2,13 +2,14 @@ | Document | Description | |----------|-------------| -| [High-Level Description (HLD) Test Specification](dash-test-HLD.md) | High-level design for the testing of devices which conform to the SONiC-DASH requirements.| -| [Dash Test Maturity Stages](dash-test-maturity-stages.md) | Describes a progressive approach to DASH testing.| +| [High-Level Description (HLD) Test Specification](dash-test-HLD.md) | High-level design for the testing of devices which conform to the SONiC-DASH requirements.| +| [Dash Test Maturity Stages](dash-test-maturity-stages.md) | Describes a progressive approach to DASH testing.| | [DASH SAI-Thrift Test Workflow](dash-test-workflow-saithrift.md) | DASH test workflow with SAI-thrift. | | [SAI PTF Design](https://github.com/reshmaintel/SAI/blob/dash-ptf/doc/SAI-Proposal-SAI-PTF.md) | SAI Thrift auto-generated Python based testing framework doc. | | [SAI PTF User Guide](https://github.com/opencomputeproject/SAI/blob/master/ptf/SAI_PTF_user-guide.md) | SAI Thrift Server User Guide to autogenerate test frame work. | | [DASH P4 SAI-Thrift Test Workflow](dash-test-workflow-p4-saithrift.md) | Use of P4-based simulators or SW data planes to verify DASH behavior, using saithrift API. | -| [Testbed](testbed/README.md) | Describes the setup and configuration of a DASH testbed.| +| [Testbed](testbed/README.md) | Describes the setup and configuration of a DASH testbed.| +| [snappi and SAI-Challenger based tests](dash-test-sai-challenger.md) | How to run scalable tests using SAI-Challenger and snappi. The scalability is achieved with additional DASH/SAI abstraction level in test code to simplify high scale DUT configuration. | -You can start with the [High-Level Description (HLD) Test Specification](dash-test-HLD.md). +You can start with the [High-Level Description (HLD) Test Specification](dash-test-HLD.md). diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md new file mode 100644 index 000000000..c3cddd99f --- /dev/null +++ b/test/docs/dash-test-sai-challenger.md @@ -0,0 +1,96 @@ +# General changes +* Added [SAI-Challenger](https://github.com/PLVision/SAI-Challenger.OCP) submodule by path: `DASH/test/SAI-Challenger.OCP`. +* Added [saigen](https://github.com/mgheorghe/cgyang) submodule by path: `DASH/test/third-party/cgyang/saigen`. +* Added test cases for SAI-Challenger by path: `DASH/test/test-cases/test_vector_example` + +# New make targets: +**`docker-saichallenger-client`**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. + +**`run-saichallenger-client`**: Start Ixia-C and docker container `sc-client-thrift-run` from image built on `docker-saichallenger-client` target. SAI-Challenger tests (`DASH/test/SAI-Challenger.OCP/tests`) folder replaced by `DASH/test/test-cases/test_vector_example` folder inside of container. Bound mount volume with DASH folder. + +**`kill-saichallenger-client`**: Stop Ixia-C and `sc-client-thrift-run` container. + +**`run-saichallenger-tests`**: Run test manually. This target may be triggered with passing parameters, or with default parameters. +Run with default parameters(Setup file: `sai_dpu_client_server_snappi.json`; Test: `test_sai_vnet_*.py`): +``` +make run-saichallenger-tests +``` + +Run with setup parameter and default test parameter (All tests): +``` +make run-saichallenger-tests +``` + +Run with setup parameter and test parameter: +``` +make run-saichallenger-tests +``` + +# How to start + +## Environment +Install dependencies listed [**here**](../../dash-pipeline/README.md#prerequisites). + +## Prepare repository +``` +git clone https://github.com/PLVision/DASH.git +cd DASH && git checkout test-framework-extension +git submodule update --init --recursive +``` + +## Build environment +``` +cd dash-pipeline +make clean ;# skip on a fresh setup as it will fail +make all + +pwd +``` + +## Start environment +Run in the 3 separate windows/tabs. +- take the output of `pwd` from previous step and do `cd ` in each window +- window 1: `make run-switch` +- window 2: `make run-saithrift-server` +- window 3: will be used to run the test as per instructions bellow + +## Run tests manually + +### Using make target +Run all available VNET tests: +```sh +make run-saichallenger-tests +``` + +Run tests in DASH configuration format with the custom options: +```sh +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py +``` + +Run tests in SAI configuration format with custom options: +```sh +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_vnet_inbound.py +make run-saichallenger-tests sai_dpu_client_server_snappi.json test_vnet_outbound.py +``` + +### Manually from the docker (developers mode) +Run the `dash-saichallenger-client-$USER` container. +```sh +make run-saichallenger-client-bash +``` + +And execute tests in DASH configuration format (inside the container): +```sh +pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_inbound.py +pytest -sv --setup=sai_dpu_client_server_snappi.json test_sai_vnet_outbound.py +``` + +Or in SAI configuration format: +```sh +pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_inbound.py +pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_outbound.py +``` + +# Known issues +* [Test Vector format tests ](#Test Vector format tests): traffic check will fail as expected diff --git a/test/test-cases/test_vector_example/__init__.py b/test/test-cases/test_vector_example/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py new file mode 100644 index 000000000..3d90ca7c5 --- /dev/null +++ b/test/test-cases/test_vector_example/conftest.py @@ -0,0 +1,82 @@ +import logging +import pytest + +import saigen +from saigen.confbase import ConfBase + +# import sys +# sys.path.insert(0, '/sai-challenger/common') # Needed for correct load_module + +from saichallenger.common.sai_dpu import SaiDpu +from saichallenger.common.sai_environment import init_setup + + +def pytest_addoption(parser): + parser.addoption("--traffic", action="store_true", default=False, help="run tests with traffic") + parser.addoption("--loglevel", action="store", default='NOTICE', help="syncd logging level") + parser.addoption("--setup", action="store", default=None, help="Setup description (Path to the json file).") + + +@pytest.fixture(scope="session") +def exec_params(request): + config_param = {} + config_param["setup"] = init_setup(request.config) + config_param["traffic"] = request.config.getoption("--traffic") + config_param["loglevel"] = request.config.getoption("--loglevel") + logging.getLogger().setLevel(getattr(logging, config_param["loglevel"].upper(), "INFO")) + return config_param + + +@pytest.fixture(scope="session") +def dpu(exec_params) -> SaiDpu: + dpu = exec_params["setup"]["DPU"][0] + if dpu is not None: + dpu.reset() + return dpu + + +@pytest.fixture(scope="session") +def dataplane_session(exec_params): + dataplane = exec_params["setup"]["DATAPLANE"][0] + # Set up the dataplane + dataplane.init() + yield dataplane + # Shutdown the dataplane + dataplane.remove() + + +@pytest.fixture(scope="function") +def dataplane(dataplane_session): + dataplane_session.setUp() + yield dataplane_session + dataplane_session.tearDown() + + +@pytest.fixture(scope="session") +def confgen(): + + class SaiConfig(ConfBase): + + def generate(self): + # Pass top-level params to sub-generrators. + self.configs = [ + saigen.vips.Vips(self.params_dict), + saigen.direction_lookup.DirectionLookup(self.params_dict), + saigen.acl_groups.AclGroups(self.params_dict), + saigen.vnets.Vnets(self.params_dict), + saigen.enis.Enis(self.params_dict), + saigen.address_maps.AddressMaps(self.params_dict), + saigen.outbound_routing.OutboundRouting(self.params_dict), + saigen.outbound_ca_to_pa.OutboundCaToPa(self.params_dict), + # saigen.inbound_routing.InboundRouting(self.params_dict), + # saigen.pa_validation.PaValidation(self.params_dict), + ] + + def items(self, reverse=False): + result = [] + for c in self.configs: + result.extend(c.items()) + return result + + return SaiConfig() + # return SaiConfig({}, saigen.simple_params.simple_params) diff --git a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py new file mode 100644 index 000000000..8c5dee29b --- /dev/null +++ b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py @@ -0,0 +1,234 @@ +import snappi +import saichallenger.dataplane.traffic_utils as tu +from collections import namedtuple + + +def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip): + """ + Define VNET Outbound routing flows + """ + + print("\nTest config:") + print(f"{vip}\n{dir_lookup}\n{ca_smac}\n{ca_dip}\n") + + print("Adding flows {} > {}:".format(sai_dp.configuration.ports[0].name, sai_dp.configuration.ports[1].name)) + vip_val = vip.start + for vip_number in range(0, vip.count): + dir_lookup_val = dir_lookup.start + print(f"\tVIP {vip_val}") + + ca_smac_portion = ca_smac.count // dir_lookup.count + for dir_lookup_number in range(0, dir_lookup.count): + print(f"\t\tDIR_LOOKUP VNI {dir_lookup_val}") + ca_smac_val = ca_smac.start + + ca_smac_start_index = dir_lookup_number * ca_smac_portion + for ca_smac_number in range(ca_smac_start_index, ca_smac_start_index + ca_smac_portion): + print(f"\t\t\tCA SMAC: {tu.get_next_mac(ca_smac_val, step=ca_smac.step, number=ca_smac_number)}") + print(f"\t\t\t\tCA DIP {ca_dip.start}, count: {ca_dip.count}, step: {ca_dip.step}") + + # Check that ca_mac differs on each iteration + flow = sai_dp.add_flow("flow {} > {} |vip#{}|dir_lookup#{}|ca_mac#{}|ca_dip#{}".format( + sai_dp.configuration.ports[0].name, sai_dp.configuration.ports[1].name, + vip_number, dir_lookup_number, ca_smac_number, ca_dip.start), + packet_count=ca_dip.count) + + sai_dp.add_ethernet_header(flow, dst_mac="00:00:02:03:04:05", src_mac="00:00:05:06:06:06") + sai_dp.add_ipv4_header(flow, dst_ip=vip_val, src_ip="172.16.1.1") + sai_dp.add_udp_header(flow, dst_port=80, src_port=11638) + sai_dp.add_vxlan_header(flow, vni=dir_lookup_val) + # sai_dp.add_ethernet_header(flow, dst_mac="02:02:02:02:02:02", src_mac=ca_smac_val) + sai_dp.add_ethernet_header(flow, dst_mac="02:02:02:02:02:02", + src_mac=tu.get_next_mac(ca_smac_val, step=ca_smac.step, number=ca_smac_number)) + + sai_dp.add_ipv4_header(flow, dst_ip=ca_dip.start, src_ip="10.1.1.10", + dst_step=ca_dip.step, dst_count=ca_dip.count, + dst_choice=snappi.PatternFlowIpv4Dst.INCREMENT) + sai_dp.add_udp_header(flow) + + dir_lookup_val += dir_lookup.step + + vip_val = tu.get_next_ip(vip_val, vip.step) + + print(f">>> FLOWS: {len(sai_dp.flows)}") + for flow in sai_dp.flows: + print(f">>>: {flow.name}") + + +def scale_vnet_outbound_flows(sai_dp, test_conf: dict): + """ + Get scale options and define VNET Outbound routing flows + """ + + vip_tup = namedtuple('VIP', 'count start step') + dir_lookup_tup = namedtuple('DIRECTION_LOOKUP', 'count start step') + ca_smac_tup = namedtuple('CA_SMAC', 'count start step') + ca_dip_tup = namedtuple('CA_DIP', 'count start step') + + def dict_helper(named_tup, conf, def_step): + if type(conf) != dict: + return named_tup(1, conf, def_step) + else: + return named_tup(conf.get('count', 1), conf.get('start', def_step), conf.get('step', def_step)) + + vip = dict_helper(vip_tup, test_conf['DASH_VIP']['vpe']['IPV4'], "0.0.0.1") + dir_lookup = dict_helper(dir_lookup_tup, test_conf['DASH_DIRECTION_LOOKUP']['dle']['VNI'], 1) + ca_smac = dict_helper(ca_smac_tup, test_conf['DASH_ENI_ETHER_ADDRESS_MAP']['eam']['MAC'], "00:00:00:00:00:01") + ca_dip = dict_helper(ca_dip_tup, test_conf['DASH_OUTBOUND_CA_TO_PA']['ocpe']['DIP'], "0.0.0.1") + + configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip) + + +def check_flows_all_packets_metrics(sai_dp, flows=[], name="Flow group", exp_tx=None, exp_rx=None, show=False): + if not flows: + print("Flows None or empty") + return False, None + if not exp_tx: + # check if all flows are fixed_packets + # sum of bool list == count of True in this list + if sum([flow.duration.choice == snappi.FlowDuration.FIXED_PACKETS for flow in flows]) == len(flows): + exp_tx = sum([flow.duration.fixed_packets.packets for flow in flows]) + else: + print("{}: some flow in flow group doesn't configured to {}.".format( \ + name, snappi.FlowDuration.FIXED_PACKETS)) + return False, None + if not exp_rx: + exp_rx = exp_tx + + act_tx = 0 + act_rx = 0 + success = 0 + + for flow in flows: + tmp = check_flow_packets_metrics(sai_dp, flow) + success += tmp[0] + act_tx += tmp[1]['TX'] + act_rx += tmp[1]['RX'] + + success = success == len(flows) + + if show: + # flow group name | exp tx | act tx | exp rx | act rx + print(f"{name} | exp tx:{exp_tx} - tx:{act_tx} | exp rx:{exp_rx} - rx:{act_rx}") + + return success, { 'TX': act_tx, 'RX': act_rx } + + +# exp = expected +# act = actual +# (bool, {'TX': int, 'RX': int}) +def check_flow_packets_metrics(sai_dp, flow: snappi.Flow, exp_tx=None, exp_rx=None, show=False): + if not exp_tx: + if flow.duration.choice == snappi.FlowDuration.FIXED_PACKETS: + exp_tx = flow.duration.fixed_packets.packets + else: + print("{}: check for packet count failed. Flow configured to {} instead of {}".format( \ + flow.name, flow.duration.choice, snappi.FlowDuration.FIXED_PACKETS)) + return False, None + if not exp_rx: + exp_rx = exp_tx + + req = sai_dp.api.metrics_request() + req.flow.flow_names = [ flow.name ] + req.flow.metric_names = [ snappi.FlowMetricsRequest.FRAMES_TX, snappi.FlowMetricsRequest.FRAMES_RX ] + res = sai_dp.api.get_metrics(req) + + act_tx = res.flow_metrics[0].frames_tx + act_rx = res.flow_metrics[0].frames_rx + + if show: + # flow name | exp tx | act tx | exp rx | act rx + print("{} | {} | {} | {} | {}".format(flow.name, exp_tx, act_tx, exp_rx, act_rx)) + + if exp_tx == act_tx and exp_rx == act_rx and \ + res.flow_metrics[0].transmit == snappi.FlowMetric.STOPPED: + return True, { 'TX': act_tx, 'RX': act_rx } + + return False, { 'TX': act_tx, 'RX': act_rx } + + +# TODO +def check_flows_all_seconds_metrics(sai_dp): + pass + + +def check_flow_seconds_metrics(sai_dp, flow: snappi.Flow, seconds=None, exp_tx=None, exp_rx=None, delta=None, show=False): + if not seconds: + if flow.duration.choice == snappi.FlowDuration.FIXED_SECONDS: + seconds = flow.duration.fixed_seconds.seconds + else: + print("{}: check for packet count failed. Flow configured to {} instead of {}".format( \ + flow.name, flow.duration.choice, snappi.FlowDuration.FIXED_SECONDS)) + return False, None + if not exp_tx: + exp_tx = flow.rate.pps * seconds + if not exp_rx: + exp_rx = exp_tx + if not delta: + # default delta is 10% of exp_tx. If it 0 (seconds < 10) then delta == pps + tmp_delta = int(exp_tx / 10) + delta = tmp_delta if tmp_delta > 0 else flow.rate.pps + + req = sai_dp.api.metrics_request() + req.flow.flow_names = [ flow.name ] + req.flow.metric_names = [ snappi.FlowMetricsRequest.FRAMES_TX, snappi.FlowMetricsRequest.FRAMES_RX ] + res = sai_dp.api.get_metrics(req) + + act_tx = res.flow_metrics[0].frames_tx + act_rx = res.flow_metrics[0].frames_rx + + if show: + # flow name | [exp tx - delta, ext_tx + delta] | act tx | [exp rx - delta, exp_rx + delta] | act rx + print("{} | [{}, {}] | {} | [{}, {}] | {}".format(flow.name, exp_tx - delta, exp_tx + delta, act_tx, \ + exp_rx - delta, exp_rx + delta, act_rx)) + + if act_tx in range(exp_tx - delta, exp_tx + delta) and \ + act_rx in range(exp_rx - delta, exp_rx + delta) and \ + res.flow_metrics[0].transmit == snappi.FlowMetric.STOPPED: + return True, { 'TX': act_tx, 'RX': act_rx } + + return False, { 'TX': act_tx, 'RX': act_rx } + + +# TODO +def check_flows_all_continuous_metrics(sai_dp): + pass + + +# TODO +def check_flow_continuous_metrics(sai_dp, flow: snappi.Flow): + pass + + +def add_simple_vxlan_packet(sai_dp, + flow: snappi.Flow, + outer_dst_mac, + outer_src_mac, + outer_dst_ip, + outer_src_ip, + dst_udp_port, + src_udp_port, + vni, + inner_dst_mac, + inner_src_mac, + inner_dst_ip, + inner_src_ip + ): + if flow == None: + print("flow is None") + return + + if flow.packet: + print("packet in flow") + return + + sai_dp.add_ethernet_header(flow, outer_dst_mac, outer_src_mac) + sai_dp.add_ipv4_header(flow, outer_dst_ip, outer_src_ip) + u = sai_dp.add_udp_header(flow, dst_udp_port, src_udp_port) + # TODO: report ixia bug (udp checksum still generated) + # u.checksum.choice = u.checksum.CUSTOM + # u.checksum.custom = 0 + sai_dp.add_vxlan_header(flow, vni) + sai_dp.add_ethernet_header(flow, inner_dst_mac, inner_src_mac) + sai_dp.add_ipv4_header(flow, inner_dst_ip, inner_src_ip) + sai_dp.add_udp_header(flow) diff --git a/test/test-cases/test_vector_example/run_vnet_tests.sh b/test/test-cases/test_vector_example/run_vnet_tests.sh new file mode 100755 index 000000000..32eeaadda --- /dev/null +++ b/test/test-cases/test_vector_example/run_vnet_tests.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +PYTHONPATH=. pytest -sv $@ diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json b/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json new file mode 100755 index 000000000..80c55496a --- /dev/null +++ b/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json @@ -0,0 +1,41 @@ +{"DPU": [ + { + "alias": "dash", + "asic": "generic", + "target": "bmv2", + "type": null, + "sku": null, + "mode": "client-server", + "sai_server_ip": "127.0.0.1", + "client": { + "type": "thrift", + "config": { + "ip": "127.0.0.1", + "port": "9092" + } + }, + "port_groups": [{"1x10G": "Ethernet0", "init": "1x10G", "alias": 0}, + {"1x10G": "Ethernet1", "init": "1x10G", "alias": 1} + ], + "sai_dataplane": "ptf_nn" + } +], + +"DATAPLANE": [ + { + "alias": "ptf", + "type": "ptf", + "mode": "eth", + "port_groups": [{"10G": "veth1", "init": "10G", "alias": 0}, + {"10G": "veth2", "init": "10G", "alias": 1} + ] + } +], + +"CONNECTIONS": { + "ptf->dash": [[0, 0], + [1, 1] + ] +} + +} diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json b/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json new file mode 100755 index 000000000..67abe70e4 --- /dev/null +++ b/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json @@ -0,0 +1,42 @@ +{"DPU": [ + { + "alias": "dash", + "asic": "generic", + "target": "bmv2", + "type": null, + "sku": null, + "mode": "client-server", + "sai_server_ip": "127.0.0.1", + "client": { + "type": "thrift", + "config": { + "ip": "127.0.0.1", + "port": "9092" + } + }, + "port_groups": [{"1x10G": "Ethernet0", "init": "1x10G", "alias": 0}, + {"1x10G": "Ethernet1", "init": "1x10G", "alias": 1} + ], + "sai_dataplane": "ptf_nn" + } +], + +"DATAPLANE": [ + { + "alias": "ixia", + "type": "snappi", + "mode": "ixia_c", + "controller": "https://127.0.0.1:443", + "port_groups": [{"10G": "veth1", "init": "10G", "alias": 0}, + {"10G": "veth3", "init": "10G", "alias": 1} + ] + } +], + +"CONNECTIONS": { + "ixia->dash": [[0, 0], + [1, 1] + ] +} + +} diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py new file mode 100644 index 000000000..11ad1957b --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py @@ -0,0 +1,185 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_packet) + +current_file_dir = Path(__file__).parent + +# Constants +VIP = "10.10.1.1" +SWITCH_ID = 1 +DIR_LOOKUP_VNI = 60 +VM_VNI = 9 +ENI_MAC = "00:00:00:09:03:14" +PA_VALIDATION_SIP = "10.10.2.10" +PA_VALIDATION_DIP = "10.10.2.20" +INBOUND_ROUTING_VNI = 2 +INNER_VM_IP = "172.19.1.100" +INNER_REMOTE_IP = "172.19.1.1" + +# Test Vector +TEST_VNET_INBOUND_CONFIG = { + + 'ACL_TABLE_COUNT': 1, + 'ENI_COUNT': 1, + 'ENI_START': 1, + 'IP_PER_ACL_RULE': 1, + 'IP_MAPPED_PER_ACL_RULE': 1, + 'IP_ROUTE_DIVIDER_PER_ACL_RULE': 8, + + 'DASH_VIP': [ + {'vip_1': {'IPv4': VIP}} + ], + + 'DASH_DIRECTION_LOOKUP': [ + {'direction_lookup': {'VNI': DIR_LOOKUP_VNI}} + ], + + 'DASH_ACL_GROUP': [ + {'acl_out_1': {'ADDR_FAMILY': 'IPv4'}} + ], + + 'DASH_ACL_RULE': [ + {'acl_rule_1': {'action': 'permit"', + 'dip': '10.0.0.1', + 'gid': '$acl_out_1', + 'priority': 10} + } + ], + + 'DASH_VNET': [ + {'vnet_1': {'VNI': DIR_LOOKUP_VNI}} + ], + + 'DASH_ENI': [ + {'eni_1': + {'ACL_GROUP': { + 'INBOUND': [{'STAGE1': '$acl_in_1'}, + {'STAGE2': '$acl_in_1'}, + {'STAGE3': '$acl_in_1'}, + {'STAGE4': '$acl_in_1'}, + {'STAGE5': '$acl_in_1'} + ], + 'OUTBOUND': [{'STAGE1': '$acl_out_1'}, + {'STAGE2': '$acl_out_1'}, + {'STAGE3': '$acl_out_1'}, + {'STAGE4': '$acl_out_1'}, + {'STAGE5': '$acl_out_1'} + ] + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': PA_VALIDATION_DIP, + 'VM_VNI': VM_VNI, + 'VNET_ID': '$vnet_1'} + } + ], + + 'DASH_ENI_ETHER_ADDRESS_MAP': [ + {'address_map_1': { + 'MAC': ENI_MAC, + 'VNI': INBOUND_ROUTING_VNI} + } + ], + + 'DASH_ROUTE_RULE_TABLE': [ + {'inbound_routing_1': { + 'VNI': INBOUND_ROUTING_VNI, + 'action_type': 'DECAP_PA_VALIDATE'} + } + ], + + 'DASH_PA_VALIDATION': [ + {'pa_validation_1': {'action': 'permit', + 'eni': '$eni_1', + 'sip': PA_VALIDATION_SIP, + 'switch_id': SWITCH_ID, + 'vni': INBOUND_ROUTING_VNI} + } + ] + +} + + +class TestSaiVnetInbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) + # confgen.generate() + # for item in confgen.items(): + # pprint(item) + + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: + vnet_inbound_setup_commands = json.load(config_file) + result = [*dpu.process_commands(vnet_inbound_setup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) + + def test_run_traffic_check(self, dpu, dataplane): + # Check forwarding + + outer_smac = "00:0a:05:06:06:06" + outer_dmac = "00:0b:05:06:06:06" + inner_smac = "00:0a:04:06:06:06" + inner_dmac = "00:0b:04:06:06:06" + + # PAcket to send + inner_pkt = simple_udp_packet(eth_dst=ENI_MAC, + eth_src=inner_smac, + ip_dst=INNER_VM_IP, + ip_src=INNER_REMOTE_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst=outer_dmac, + eth_src=outer_smac, + ip_dst=PA_VALIDATION_DIP, + ip_src=PA_VALIDATION_SIP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=DIR_LOOKUP_VNI, + inner_frame=inner_pkt) + + # Expected Packet to check + inner_exp_pkt = simple_udp_packet(eth_dst=inner_dmac, + eth_src=ENI_MAC, + ip_dst=INNER_VM_IP, + ip_src=INNER_REMOTE_IP) + vxlan_exp_pkt = simple_vxlan_packet(eth_dst="00:00:00:00:00:00", + eth_src="00:00:00:00:00:00", + ip_dst=PA_VALIDATION_DIP, + ip_src=PA_VALIDATION_SIP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=INBOUND_ROUTING_VNI, + inner_frame=inner_exp_pkt) + + # dataplane.start_capture() + print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) + send_packet(dataplane, 0, vxlan_pkt) + + print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) + verify_packet(dataplane, vxlan_exp_pkt, 1) + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) + # confgen.generate() + # for item in confgen.items(): + # item['OP'] = 'remove' + # pprint(item) + + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + cleanup_commands = [] + for cmd in reversed(setup_commands): + cleanup_commands.append({'name': cmd['name'], 'op': 'remove'}) + + result = [*dpu.process_commands(cleanup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py new file mode 100644 index 000000000..59dc8c93d --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py @@ -0,0 +1,241 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +import saichallenger.dataplane.snappi.snappi_traffic_utils as stu +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_no_other_packets, + verify_packet) + +import dash_helper.vnet2vnet_helper as dh + +current_file_dir = Path(__file__).parent + +# Constants for scale outbound +NUMBER_OF_VIP = 1 +NUMBER_OF_DLE = 2 +NUMBER_OF_ENI = 2 +NUMBER_OF_EAM = NUMBER_OF_ENI +NUMBER_OF_ORE = 2 # Per ENI +NUMBER_OF_OCPE = 2 # Per ORE +NUMBER_OF_VNET = NUMBER_OF_ENI + (NUMBER_OF_ORE * NUMBER_OF_ENI) # So far per ORE, but may be different +NUMBER_OF_IN_ACL_GROUP = 10 +NUMBER_OF_OUT_ACL_GROUP = 10 + +TEST_VNET_OUTBOUND_CONFIG_SCALE = { + + 'DASH_VIP': { + 'vpe': { + 'count': NUMBER_OF_VIP, + 'SWITCH_ID': '$SWITCH_ID', + 'IPV4': { + 'count': NUMBER_OF_VIP, + 'start': '172.16.1.100', + 'step': '0.1.0.0' + } + } + }, + + 'DASH_DIRECTION_LOOKUP': { + 'dle': { + 'count': NUMBER_OF_DLE, + 'SWITCH_ID': '$SWITCH_ID', + 'VNI': { + 'count': NUMBER_OF_DLE, + 'start': 5000, + 'step': 1000 + }, + 'ACTION': 'SET_OUTBOUND_DIRECTION' + } + }, + + 'DASH_ACL_GROUP': { + 'in_acl_group_id': { + 'count': NUMBER_OF_IN_ACL_GROUP, + 'ADDR_FAMILY': 'IPv4' + }, + 'out_acl_group_id': { + 'count': NUMBER_OF_OUT_ACL_GROUP, + 'ADDR_FAMILY': 'IPv4' + } + }, + + 'DASH_VNET': { + 'vnet': { + 'VNI': { + 'count': NUMBER_OF_VNET, + 'start': 1000, + 'step': 1000 + } + } + }, + + 'DASH_ENI': { + 'eni': { + 'count': NUMBER_OF_ENI, + 'ACL_GROUP': { + 'INBOUND': { + 'STAGE1': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE2': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE3': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE4': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'STAGE5': { + 'list': 'DASH_ACL_GROUP#in_acl_group_id#0' + } + }, + 'OUTBOUND': { + 'STAGE1': 0, + 'STAGE2': 0, + 'STAGE3': 0, + 'STAGE4': 0, + 'STAGE5': 0 + } + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': { + 'count': NUMBER_OF_ENI, + 'start': '172.16.1.1', + 'step': '0.0.1.0' + }, + 'VM_VNI': { + 'count': NUMBER_OF_ENI, + 'start': 9 + }, + 'VNET_ID': { + 'count': NUMBER_OF_ENI, + 'start': '$vnet_#{4}' + } + } + }, + + 'DASH_ENI_ETHER_ADDRESS_MAP': { + 'eam': { + 'count': NUMBER_OF_EAM, + 'SWITCH_ID': '$SWITCH_ID', + 'MAC': { + 'count': NUMBER_OF_EAM, + 'start': '00:CC:CC:CC:00:00', + 'step': "00:00:00:00:00:01" + }, + 'ENI_ID': { + 'count': NUMBER_OF_ENI, + 'start': '$eni_#{0}' + } + } + }, + + 'DASH_OUTBOUND_ROUTING': { + 'ore': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, # Full count: OREs per ENI and VNET + 'SWITCH_ID': '$SWITCH_ID', + 'ACTION': 'ROUTE_VNET', + 'DESTINATION': { + 'count': NUMBER_OF_ORE, + 'start': '10.1.1.0/31', + 'step': '0.0.0.2' + }, + 'ENI_ID': { + 'count': NUMBER_OF_ENI, + 'start': '$eni_#{0}', + 'delay': NUMBER_OF_ORE + }, + 'DST_VNET_ID': { + 'count': NUMBER_OF_VNET, + 'start': '$vnet_#{0}', + 'delay': NUMBER_OF_ORE + } + } + }, + + 'DASH_OUTBOUND_CA_TO_PA': { + 'ocpe': { + 'count': (NUMBER_OF_ENI * NUMBER_OF_ORE) * NUMBER_OF_OCPE, # 2 Per ORE + 'SWITCH_ID': '$SWITCH_ID', + 'DIP': { + 'count': NUMBER_OF_ORE * NUMBER_OF_OCPE, + 'start': '10.1.1.0', + 'step': '0.0.0.1' + }, + 'DST_VNET_ID': { + 'count': NUMBER_OF_VNET, + 'start': '$vnet_#{0}', + 'delay': NUMBER_OF_ORE + }, + 'UNDERLAY_DIP': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, + 'start': '172.16.1.20', + 'step': '0.0.1.0' + }, + 'OVERLAY_DMAC': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, + 'start': '00:DD:DD:DD:00:00' + }, + 'USE_DST_VNET_VNI': True + } + } +} + + +class TestSaiVnetOutbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG_SCALE) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_scale.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + result = [*dpu.process_commands(setup_commands)] + # print("\n======= SAI commands RETURN values =======") + # for cmd, res in zip(setup_commands, result): + # print(cmd['name'], cmd['type'], res) + + @pytest.mark.snappi + def test_run_traffic_check(self, dpu, dataplane): + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE) + dataplane.set_config() + dataplane.start_traffic() + + stu.wait_for(lambda: dh.check_flows_all_packets_metrics(dataplane, dataplane.flows, + name="Custom flow group", show=True)[0], + "Test", timeout_seconds=2) + print("Test passed !") + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG_SCALE) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # item['op'] = 'remove' + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_scale.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + cleanup_commands = [] + for cmd in reversed(setup_commands): + cleanup_commands.append({'name': cmd['name'], 'op': 'remove'}) + + result = [*dpu.process_commands(cleanup_commands)] + # print("\n======= SAI commands RETURN values =======") + # for cmd, res in zip(cleanup_commands, result): + # print(cmd['name'], res) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py new file mode 100644 index 000000000..b934294f1 --- /dev/null +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py @@ -0,0 +1,164 @@ +import json +from pathlib import Path +from pprint import pprint + +import pytest +import saichallenger.dataplane.snappi.snappi_traffic_utils as stu +from saichallenger.dataplane.ptf_testutils import (send_packet, + simple_udp_packet, + simple_vxlan_packet, + verify_no_other_packets, + verify_packet) + +import dash_helper.vnet2vnet_helper as dh + +current_file_dir = Path(__file__).parent + +# Constants +SWITCH_ID = 5 + +TEST_VNET_OUTBOUND_CONFIG = { + + "ENI_COUNT": 1, + "ACL_RULES_NSG": 1, + "ACL_TABLE_COUNT": 1, + "IP_PER_ACL_RULE": 1, + "IP_MAPPED_PER_ACL_RULE": 1, + "IP_ROUTE_DIVIDER_PER_ACL_RULE": 1, + + 'DASH_VIP': { + 'vpe': { + 'SWITCH_ID': '$SWITCH_ID', + 'IPV4': "172.16.1.100" + } + }, + + 'DASH_DIRECTION_LOOKUP': { + 'dle': { + 'SWITCH_ID': '$SWITCH_ID', + 'VNI': 100, + 'ACTION': 'SET_OUTBOUND_DIRECTION' + } + }, + + 'DASH_ACL_GROUP': { + 'in_acl_group_id': { + 'ADDR_FAMILY': 'IPv4' + }, + 'out_acl_group_id': { + 'ADDR_FAMILY': 'IPv4' + } + }, + + 'DASH_VNET': { + 'vnet': { + 'VNI': 1000 + } + }, + + 'DASH_ENI': { + 'eni': { + 'ACL_GROUP': { + 'INBOUND': { + 'STAGE1': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE2': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE3': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE4': 'DASH_ACL_GROUP#in_acl_group_id#0', + 'STAGE5': 'DASH_ACL_GROUP#in_acl_group_id#0' + }, + 'OUTBOUND': { + 'STAGE1': 0, + 'STAGE2': 0, + 'STAGE3': 0, + 'STAGE4': 0, + 'STAGE5': 0 + } + }, + 'ADMIN_STATE': True, + 'CPS': 10000, + 'FLOWS': 10000, + 'PPS': 100000, + 'VM_UNDERLAY_DIP': "172.16.1.1", + 'VM_VNI': 9, + 'VNET_ID': 'DASH_VNET#vnet#0' + } + }, + + 'DASH_ENI_ETHER_ADDRESS_MAP': { + 'eam': { + 'SWITCH_ID': '$SWITCH_ID', + 'MAC': "00:cc:cc:cc:00:00", + 'ENI_ID': 'DASH_ENI#eni#0' + } + }, + + 'DASH_OUTBOUND_ROUTING': { + 'ore': { + 'SWITCH_ID': '$SWITCH_ID', + 'ENI_ID': 'DASH_ENI#eni#0', + 'DESTINATION': "10.1.0.0/16", + 'ACTION': 'ROUTE_VNET', + 'DST_VNET_ID': 'DASH_VNET#vnet#0' + } + }, + + 'DASH_OUTBOUND_CA_TO_PA': { + 'ocpe': { + 'SWITCH_ID': '$SWITCH_ID', + 'DST_VNET_ID': 'DASH_VNET#vnet#0', + 'DIP': "10.1.2.50", + 'UNDERLAY_DIP': "172.16.1.20", + 'OVERLAY_DMAC': "00:DD:DD:DD:00:00", + 'USE_DST_VNET_VNI': True + } + } +} + +class TestSaiVnetOutbound: + + def test_create_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_simple.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + result = [*dpu.process_commands(setup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) + + @pytest.mark.snappi + def test_simple_vxlan_packet(self, dpu, dataplane): + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG) + + dataplane.set_config() + dataplane.start_traffic() + + stu.wait_for(lambda: dh.check_flow_packets_metrics(dataplane, dataplane.flows[0], show=True)[0], + "Test", timeout_seconds=10) + + print("Test passed !") + + def test_remove_vnet_config(self, confgen, dpu, dataplane): + + # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) + # confgen.generate() + # results = [] + # for item in confgen.items(): + # item['op'] = 'remove' + # pprint(item) + # results.append(dpu.command_processor.process_command(item)) + + with (current_file_dir / 'vnet_outbound_setup_commands_simple.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + cleanup_commands = [] + for cmd in reversed(setup_commands): + cleanup_commands.append({'name': cmd['name'], 'op': 'remove'}) + + result = [*dpu.process_commands(cleanup_commands)] + print("\n======= SAI commands RETURN values =======") + pprint(result) diff --git a/test/test-cases/test_vector_example/test_vnet_inbound.py b/test/test-cases/test_vector_example/test_vnet_inbound.py new file mode 100644 index 000000000..47ba7a9a4 --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_inbound.py @@ -0,0 +1,18 @@ +import json +from pathlib import Path + +current_file_dir = Path(__file__).parent + + +def test_vnet_inbound(dpu, dataplane): + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: + vnet_inbound_setup_commands = json.load(config_file) + + result = [*dpu.process_commands(vnet_inbound_setup_commands)] + + vnet_inbound_cleanup_commands = [] + for command in reversed(vnet_inbound_setup_commands): + command['op'] = 'remove' + vnet_inbound_cleanup_commands.append(command) + + result = [*dpu.process_commands(vnet_inbound_cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound.py b/test/test-cases/test_vector_example/test_vnet_outbound.py new file mode 100644 index 000000000..6ae1a64c3 --- /dev/null +++ b/test/test-cases/test_vector_example/test_vnet_outbound.py @@ -0,0 +1,21 @@ +import json +from pathlib import Path + +import pytest + +current_file_dir = Path(__file__).parent + + +@pytest.mark.parametrize('cfg_type', ['simple', 'scale']) +def test_vnet_outbound_simple(dpu, cfg_type): + with (current_file_dir / f'vnet_outbound_setup_commands_{cfg_type}.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + + result = [*dpu.process_commands(setup_commands)] + + cleanup_commands = [] + for command in reversed(setup_commands): + command['op'] = 'remove' + cleanup_commands.append(command) + + result = [*dpu.process_commands(cleanup_commands)] diff --git a/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json new file mode 100644 index 000000000..b9fe9d4de --- /dev/null +++ b/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json @@ -0,0 +1,159 @@ +[ + { + "name": "vip_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "192.168.0.1" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", + "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "direction_lookup_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "2000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", + "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "acl_in_1", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", + "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "acl_out_1", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", + "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "vnet_1", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", + "2000" + ] + }, + { + "name": "eni_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", + "10000", + "SAI_ENI_ATTR_PPS", + "100000", + "SAI_ENI_ATTR_FLOWS", + "100000", + "SAI_ENI_ATTR_ADMIN_STATE", + "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", + "10.10.2.10", + "SAI_ENI_ATTR_VM_VNI", + "9", + "SAI_ENI_ATTR_VNET_ID", + "$vnet_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", + "$acl_in_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", + "$acl_out_1", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", + "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", + "0" + ] + }, + { + "name": "eni_ether_address_map_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:AA:AA:AA:AA:00" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", + "$eni_id" + ] + }, + { + "name": "inbound_routing_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_id", + "vni": "1000" + }, + "attributes": [ + "SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION", + "SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE", + "SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID", + "$vnet_1" + ] + }, + { + "name": "pa_validation_entry", + "op": "create", + "type": "SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "sip": "10.10.2.10", + "vnet_id": "$vnet_1" + }, + "attributes": [ + "SAI_PA_VALIDATION_ENTRY_ATTR_ACTION", + "SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT" + ] + } +] diff --git a/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json new file mode 100644 index 000000000..564e8798a --- /dev/null +++ b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json @@ -0,0 +1,366 @@ +[ + { + "name": "vpe_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.16.1.100" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "vpe_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.17.1.100" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "dle_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "5000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "dle_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "6000" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "vnet_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "1000" + ] + }, + { + "name": "vnet_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "2000" + ] + }, + { + "name": "vnet_#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "3000" + ] + }, + { + "name": "vnet_#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "4000" + ] + }, + { + "name": "vnet_#4", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "5000" + ] + }, + { + "name": "vnet_#5", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "6000" + ] + }, + { + "name": "eni_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", "10000", + "SAI_ENI_ATTR_PPS", "100000", + "SAI_ENI_ATTR_FLOWS", "100000", + "SAI_ENI_ATTR_ADMIN_STATE", "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.1", + "SAI_ENI_ATTR_VM_VNI", "9", + "SAI_ENI_ATTR_VNET_ID", "$vnet_#4", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0" + ] + }, + { + "name": "eni_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", "10000", + "SAI_ENI_ATTR_PPS", "100000", + "SAI_ENI_ATTR_FLOWS", "100000", + "SAI_ENI_ATTR_ADMIN_STATE", "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.2.1", + "SAI_ENI_ATTR_VM_VNI", "10", + "SAI_ENI_ATTR_VNET_ID", "$vnet_#5", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0" + ] + }, + { + "name": "eam_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:CC:CC:CC:00:00" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni_#0" + ] + }, + { + "name": "eam_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:CC:CC:CC:00:01" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni_#1" + ] + }, + { + "name": "ore_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#0", + "destination": "10.1.1.0/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#0" + ] + }, + { + "name": "ore_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#0", + "destination": "10.1.1.2/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#1" + ] + }, + { + "name": "ore_#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#1", + "destination": "10.1.1.0/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#2" + ] + }, + { + "name": "ore_#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni_#1", + "destination": "10.1.1.2/31" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet_#3" + ] + }, + { + "name": "ocpe_#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#0", + "dip": "10.1.1.0" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.1.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:00", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#0", + "dip": "10.1.1.1" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.2.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:01", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#1", + "dip": "10.1.1.2" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.3.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:02", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#1", + "dip": "10.1.1.3" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.4.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:03", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#4", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#2", + "dip": "10.1.1.0" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.5.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:04", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#5", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#2", + "dip": "10.1.1.1" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.6.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:05", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#6", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#3", + "dip": "10.1.1.2" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.7.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:06", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + }, + { + "name": "ocpe_#7", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet_#3", + "dip": "10.1.1.3" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.8.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:DD:07", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + } +] diff --git a/test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json new file mode 100644 index 000000000..087132275 --- /dev/null +++ b/test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json @@ -0,0 +1,125 @@ +[ + { + "name": "vpe", + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.16.1.100" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + }, + { + "name": "dle", + "op": "create", + "type": "SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "vni": "100" + }, + "attributes": [ + "SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION", "SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION" + ] + }, + { + "name": "in_acl_group_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "out_acl_group_id", + "op": "create", + "type": "SAI_OBJECT_TYPE_DASH_ACL_GROUP", + "attributes": [ + "SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY", "SAI_IP_ADDR_FAMILY_IPV4" + ] + }, + { + "name": "vnet", + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "attributes": [ + "SAI_VNET_ATTR_VNI", "1000" + ] + }, + { + "name": "eni", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI", + "attributes": [ + "SAI_ENI_ATTR_CPS", "10000", + "SAI_ENI_ATTR_PPS", "100000", + "SAI_ENI_ATTR_FLOWS", "100000", + "SAI_ENI_ATTR_ADMIN_STATE", "True", + "SAI_ENI_ATTR_VM_UNDERLAY_DIP", "172.16.1.1", + "SAI_ENI_ATTR_VM_VNI", "9", + "SAI_ENI_ATTR_VNET_ID", "$vnet", + "SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID", "0", + "SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID", "0" + ] + }, + { + "name": "eam", + "op": "create", + "type": "SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "address": "00:CC:CC:CC:00:00" + }, + "attributes": [ + "SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID", "$eni" + ] + }, + { + "name": "ore", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$eni", + "destination": "10.1.0.0/16" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$vnet" + ] + }, + { + "name": "ocpe", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "dst_vnet_id": "$vnet", + "dip": "10.1.2.50" + }, + "attributes": [ + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP", "172.16.1.20", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC", "00:DD:DD:DD:00:00", + "SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI", "True" + ] + } +] diff --git a/test/third-party/traffic_gen/deployment/.env b/test/third-party/traffic_gen/deployment/.env index 72ec4ae3b..8e3f592ed 100644 --- a/test/third-party/traffic_gen/deployment/.env +++ b/test/third-party/traffic_gen/deployment/.env @@ -1,5 +1,5 @@ DOCKER_REGISTRY=ghcr.io/open-traffic-generator -CONTROLLER_VERSION=0.0.1-3383 +CONTROLLER_VERSION=0.0.1-3423 TRAFFIC_ENGINE_VERSION=1.6.0.17 IFC1=veth1 IFC2=veth3 From aa3033adcb3ffdd204fe3958c0a1b85e32d77ec7 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 20:35:27 -0700 Subject: [PATCH 36/45] Correct mixup in image names. --- .github/workflows/dash-saithrift-client-bldr-docker-acr.yml | 2 +- dash-pipeline/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml index 00ce811fd..eac589a5c 100644 --- a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml +++ b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml @@ -53,4 +53,4 @@ jobs: - name: Build dash-saithrift-client-bldr image run: DOCKER_FLAGS=$docker_fg_flags make docker-saithrift-client-bldr - name: Publish dash-saithrift-client-bldr docker image - run: make docker-publish-saichallenger-client + run: make docker-publish-saithrift-client-bldr diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 740bead66..ad866e9f5 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -547,7 +547,7 @@ docker-saichallenger-client: -t $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ . -docker-publish-saithrift-client-bldr: +docker-publish-saichallenger-client: @echo "Publish $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) - requires credentials, can only do from DASH repo, not a fork" docker push $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) From cffc5061682ee0fc0cbad3b6d3901e5c8f581242 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 20:48:09 -0700 Subject: [PATCH 37/45] Remove stray hyphen --- .github/workflows/dash-saichallenger-client-docker-acr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml index b84ee19ed..6b58cb713 100644 --- a/.github/workflows/dash-saichallenger-client-docker-acr.yml +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -23,7 +23,7 @@ jobs: build: # Can only publish from within DASH repo (need credentials from secrets) if: github.repository == 'Azure/DASH' - name: Build and publish dash-saichallenger-client-image + name: Build and publish dash-saichallenger-client image runs-on: ubuntu-20.04 env: docker_fg_flags: -u root --privileged From f225dc49bb4b3794328fe31c8b9d85568c88efcb Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 11 Oct 2022 20:50:20 -0700 Subject: [PATCH 38/45] Run saichallenger workflows on any branch PR. --- .github/workflows/dash-saichallenger-client-docker-acr.yml | 2 +- .github/workflows/dash-saichallenger-client-docker.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml index 6b58cb713..7e867cba4 100644 --- a/.github/workflows/dash-saichallenger-client-docker-acr.yml +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -10,7 +10,7 @@ on: - 'dash-pipeline/.dockerignore' - 'dash-pipeline/dockerfiles/.dockerignore' pull_request: - branches: [ "main" ] + branches: [ "**" ] paths: - '.github/workflows/dash-saichallenger-client-docker-acr.yml' - 'dash-pipeline/Makefile' diff --git a/.github/workflows/dash-saichallenger-client-docker.yml b/.github/workflows/dash-saichallenger-client-docker.yml index 0effadf42..77ce64d02 100644 --- a/.github/workflows/dash-saichallenger-client-docker.yml +++ b/.github/workflows/dash-saichallenger-client-docker.yml @@ -10,7 +10,7 @@ on: - 'dash-pipeline/.dockerignore' - 'dash-pipeline/dockerfiles/.dockerignore' pull_request: - branches: [ "main" ] + branches: [ "**" ] paths: - '.github/workflows/dash-saichallenger-client-docker.yml' - 'dash-pipeline/Makefile' From 7bfb9bc9eb3676942c71fca1485d70f4bcf35f61 Mon Sep 17 00:00:00 2001 From: Chris Sommers <31145757+chrispsommers@users.noreply.github.com> Date: Tue, 11 Oct 2022 20:58:41 -0700 Subject: [PATCH 39/45] Publish saic to acr (#253) * Added SAI-Challenger to CI setup. 1. Added SAI-Challenger submodule. 2. Added SAI-Challenger basic test. 3. Changed Makefile to build/start/stop SAI-Challenger. Signed-off-by: Maksym Hedeon * Added saithrift to SAI-Challenger client docker image - Added saithrift to SAI-Challenger client docker image - Changed SAI-C submodule branch Signed-off-by: Maksym Hedeon * Update example vnet test. 1. Added SAI-Challenger submodule. 2. Added SAI-Challenger basic test. 3. Changed Makefile to build/start/stop SAI-Challenger. Signed-off-by: Kostiantyn Goloveshko Co-authored-by: Maksym Hedeon * Add vnet outbound test based on SAI description. Signed-off-by: Maksym Prytoliuk * Fixup double network host usage for sai-challenger-client Signed-off-by: Konstantin Goloveshko * Kdt 17: Update docker environment (#8) * Added cgyang submodule * Updated docker env for thrift tests * Makefile refactor Signed-off-by: Maksym Hedeon * Fixup VNET inbound cleanup removals in test config. Signed-off-by: Konstantin Goloveshko * Update CA_TO_PA entry in outbound test Signed-off-by: Maksym Prytoliuk * Add vnet scenarios in DASH config format. * Added dash-style VNET inbound routing test * Added dash-style VNET outbound routing test * Read config from json (temp workaround) * Added JSON setup configs for testbed Signed-off-by: Anton Putria Co-authored-by: Maksym Prytoliuk * Fixed saigen links. Signed-off-by: Anton Putria * Fixes in test scanario. Signed-off-by: Anton Putria * Fixed path to saigen. Fixed inbound test. Signed-off-by: Anton Putria * Update submodule Signed-off-by: Anton Putria * Final test fixes to align with submodue version. Signed-off-by: Anton Putria * Fixed VNET outbound test scenario. Signed-off-by: Anton Putria * Outbound test passes with traffic Fixed configuration based on changes in main. Signed-off-by: Maksym Prytoliuk * Update documentation - Added dash-test-sai-challenger.md doc file under test/docs - Updated Makefile make run-saic-test-thrift target with passing parameters. Signed-off-by: Maksym Hedeon * Updated SAI-Challenger submodule. Signed-off-by: Anton Putria * Improvements to SAI-Challenger docker flows. - Use docker hub to pull images - Fixed make run-saic-tests to do not show errors - Updated manuals Signed-off-by: Anton Putria * Update dash-test-sai-challenger.md Signed-off-by: Mircea Dan Gheorghe * Add bmv2 SAI port attributes (num_active, port_list), dflt vlan, dflt vrf) * Added SAI-Challenger docker build verification to GitHub actions - Added SAI-Challenger docker verification action. - Fixed spellchecker and docker build issues. Signed-off-by: Anton Putria * Add default .1Q bridge to bmv2 Signed-off-by: Maksym Prytoliuk * Fixed SAI-Challenger user guide and file namings. Signed-off-by: Anton Putria * Scaled VNET outbound test using snappi and saigen. (1st edition) - Split scale and simple tests / jsons - Updated ixia controller version - Added dash_helper for traffic profile scaling. Signed-off-by: Maksym Hedeon * spellcheck * Move saichallenger client docker to ACR. * Fix .yml formatting. * Fix dependency in action file. * Add missing .env file * remove space in action script, add .env dependencies * fix include path * Add saichalleneger tests to run-all-tests and CI * Fix docker image name. * Correct mixup in image names. * Remove stray hyphen * Run saichallenger workflows on any branch PR. Signed-off-by: Maksym Hedeon Signed-off-by: Kostiantyn Goloveshko Signed-off-by: Maksym Prytoliuk Signed-off-by: Konstantin Goloveshko Signed-off-by: Anton Putria Signed-off-by: Mircea Dan Gheorghe Co-authored-by: Maksym Hedeon <106111454+maksymhedeon@users.noreply.github.com> Co-authored-by: Kostiantyn Goloveshko Co-authored-by: Maksym Hedeon Co-authored-by: Maksym Prytoliuk <71631949+maksym-prytoliuk-plv@users.noreply.github.com> Co-authored-by: Anton Putria Co-authored-by: Maksym Prytoliuk Co-authored-by: Anton Putria Co-authored-by: MirceaDan Co-authored-by: Chris Sommers --- .github/workflows/dash-saichallenger-client-docker-acr.yml | 4 ++-- .github/workflows/dash-saichallenger-client-docker.yml | 2 +- dash-pipeline/Makefile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dash-saichallenger-client-docker-acr.yml b/.github/workflows/dash-saichallenger-client-docker-acr.yml index b84ee19ed..7e867cba4 100644 --- a/.github/workflows/dash-saichallenger-client-docker-acr.yml +++ b/.github/workflows/dash-saichallenger-client-docker-acr.yml @@ -10,7 +10,7 @@ on: - 'dash-pipeline/.dockerignore' - 'dash-pipeline/dockerfiles/.dockerignore' pull_request: - branches: [ "main" ] + branches: [ "**" ] paths: - '.github/workflows/dash-saichallenger-client-docker-acr.yml' - 'dash-pipeline/Makefile' @@ -23,7 +23,7 @@ jobs: build: # Can only publish from within DASH repo (need credentials from secrets) if: github.repository == 'Azure/DASH' - name: Build and publish dash-saichallenger-client-image + name: Build and publish dash-saichallenger-client image runs-on: ubuntu-20.04 env: docker_fg_flags: -u root --privileged diff --git a/.github/workflows/dash-saichallenger-client-docker.yml b/.github/workflows/dash-saichallenger-client-docker.yml index 0effadf42..77ce64d02 100644 --- a/.github/workflows/dash-saichallenger-client-docker.yml +++ b/.github/workflows/dash-saichallenger-client-docker.yml @@ -10,7 +10,7 @@ on: - 'dash-pipeline/.dockerignore' - 'dash-pipeline/dockerfiles/.dockerignore' pull_request: - branches: [ "main" ] + branches: [ "**" ] paths: - '.github/workflows/dash-saichallenger-client-docker.yml' - 'dash-pipeline/Makefile' diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index 740bead66..ad866e9f5 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -547,7 +547,7 @@ docker-saichallenger-client: -t $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) \ . -docker-publish-saithrift-client-bldr: +docker-publish-saichallenger-client: @echo "Publish $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) - requires credentials, can only do from DASH repo, not a fork" docker push $(DOCKER_SAI_CHALLENGER_CLIENT_IMG) From 46461fd049bf81561a62e42b2420d8d23ef19a66 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Wed, 12 Oct 2022 17:13:46 +0300 Subject: [PATCH 40/45] Added few more VNET scenario examples. - Extended VNET traffic scenarios. - Added docstrings for helper methods. - Removed unused code. Signed-off-by: Anton Putria Co-authored-by: Maksym Hedeon --- .../dash_helper/vnet2vnet_helper.py | 205 ++++++++++++------ .../test_sai_vnet_outbound_scale.py | 22 +- .../test_sai_vnet_outbound_simple.py | 133 ++++++++++-- 3 files changed, 274 insertions(+), 86 deletions(-) diff --git a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py index 8c5dee29b..b4e03bc7e 100644 --- a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py +++ b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py @@ -3,9 +3,19 @@ from collections import namedtuple -def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip): +def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip, pkt_count=1, pps=50, duration=0): """ - Define VNET Outbound routing flows + Define VNET Outbound routing flows. + + Parameters: + sai_dp: sai_dataplane. + vip (namedtuple(name, 'count start step')): DASH VIP. + dir_lookup (namedtuple(name, 'count start step')): direction lookup vni. + ca_smac (namedtuple(name, 'count start step')): client source MAC. + ca_dip (namedtuple(name, 'count start step')): client destination IP. + pkt_count (int): count of packets to send per each flow. Default is 1. + pps (int): packet per second for each flow. Default is 50. + duration (int): count in seconds to generate traffic for each flow. Default is 0. """ print("\nTest config:") @@ -26,18 +36,15 @@ def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_di for ca_smac_number in range(ca_smac_start_index, ca_smac_start_index + ca_smac_portion): print(f"\t\t\tCA SMAC: {tu.get_next_mac(ca_smac_val, step=ca_smac.step, number=ca_smac_number)}") print(f"\t\t\t\tCA DIP {ca_dip.start}, count: {ca_dip.count}, step: {ca_dip.step}") - - # Check that ca_mac differs on each iteration flow = sai_dp.add_flow("flow {} > {} |vip#{}|dir_lookup#{}|ca_mac#{}|ca_dip#{}".format( sai_dp.configuration.ports[0].name, sai_dp.configuration.ports[1].name, vip_number, dir_lookup_number, ca_smac_number, ca_dip.start), - packet_count=ca_dip.count) + packet_count=ca_dip.count * pkt_count, pps=pps, seconds_count=duration) sai_dp.add_ethernet_header(flow, dst_mac="00:00:02:03:04:05", src_mac="00:00:05:06:06:06") sai_dp.add_ipv4_header(flow, dst_ip=vip_val, src_ip="172.16.1.1") sai_dp.add_udp_header(flow, dst_port=80, src_port=11638) sai_dp.add_vxlan_header(flow, vni=dir_lookup_val) - # sai_dp.add_ethernet_header(flow, dst_mac="02:02:02:02:02:02", src_mac=ca_smac_val) sai_dp.add_ethernet_header(flow, dst_mac="02:02:02:02:02:02", src_mac=tu.get_next_mac(ca_smac_val, step=ca_smac.step, number=ca_smac_number)) @@ -55,9 +62,16 @@ def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_di print(f">>>: {flow.name}") -def scale_vnet_outbound_flows(sai_dp, test_conf: dict): +def scale_vnet_outbound_flows(sai_dp, test_conf: dict, packets_per_flow=1, pps_per_flow=10, flow_duration=0): """ - Get scale options and define VNET Outbound routing flows + Get scale options and define VNET Outbound routing flows. + + Parameters: + sai_dp: sai_dataplane. + test_conf (dict): test config. + packets_per_flow (int): count of packets to send per each flow. Default is 1. + pps_per_flow (int): packet per second for each flow. Default is 10. + flow_duration (int): count in seconds to generate traffic for each flow. Default is 0. """ vip_tup = namedtuple('VIP', 'count start step') @@ -76,10 +90,27 @@ def dict_helper(named_tup, conf, def_step): ca_smac = dict_helper(ca_smac_tup, test_conf['DASH_ENI_ETHER_ADDRESS_MAP']['eam']['MAC'], "00:00:00:00:00:01") ca_dip = dict_helper(ca_dip_tup, test_conf['DASH_OUTBOUND_CA_TO_PA']['ocpe']['DIP'], "0.0.0.1") - configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip) + configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_dip, + pkt_count=packets_per_flow, pps=pps_per_flow, duration=flow_duration) + +def check_flows_all_packets_metrics(sai_dp, flows, name="Flow group", exp_tx=None, exp_rx=None, show=False): + """ + Get packet count metrics on list of flows. + + Parameters: + sai_dp: sai_dataplane. + flows: list of flows to check. + name (str): flow list's name. Default is "Flow group". + exp_tx (int): expected count of TX packets. + exp_rx (int): expected count of RX packets. + show (bool): flag to show metrics. Default is False. + + Return: + tuple(bool, { int, int }): bool is True if all flow metrics are OK. First int is for + sum of TX packets from all flows. Second int is for sum of RX packets from all flows. + """ -def check_flows_all_packets_metrics(sai_dp, flows=[], name="Flow group", exp_tx=None, exp_rx=None, show=False): if not flows: print("Flows None or empty") return False, None @@ -108,16 +139,28 @@ def check_flows_all_packets_metrics(sai_dp, flows=[], name="Flow group", exp_tx= success = success == len(flows) if show: - # flow group name | exp tx | act tx | exp rx | act rx + # flow group name | exp tx - act tx | exp rx - act rx print(f"{name} | exp tx:{exp_tx} - tx:{act_tx} | exp rx:{exp_rx} - rx:{act_rx}") return success, { 'TX': act_tx, 'RX': act_rx } -# exp = expected -# act = actual -# (bool, {'TX': int, 'RX': int}) def check_flow_packets_metrics(sai_dp, flow: snappi.Flow, exp_tx=None, exp_rx=None, show=False): + """ + Get packet count metrics on flow. + + Parameters: + sai_dp: sai_dataplane. + flow (snappi.Flow): flow to check. + exp_tx (int): expected count of TX packets. + exp_rx (int): expected count of RX packets. + show (bool): flag to show metrics. Default is False. + + Return: + tuple(bool, { int, int }): bool is result of metrics. First int is for TX packets, + second int is for RX packets. + """ + if not exp_tx: if flow.duration.choice == snappi.FlowDuration.FIXED_PACKETS: exp_tx = flow.duration.fixed_packets.packets @@ -137,8 +180,8 @@ def check_flow_packets_metrics(sai_dp, flow: snappi.Flow, exp_tx=None, exp_rx=No act_rx = res.flow_metrics[0].frames_rx if show: - # flow name | exp tx | act tx | exp rx | act rx - print("{} | {} | {} | {} | {}".format(flow.name, exp_tx, act_tx, exp_rx, act_rx)) + # flow group name | exp tx - act tx | exp rx - act rx + print(f"{flow.name} | exp tx:{exp_tx} - tx:{act_tx} | exp rx:{exp_rx} - rx:{act_rx}") if exp_tx == act_tx and exp_rx == act_rx and \ res.flow_metrics[0].transmit == snappi.FlowMetric.STOPPED: @@ -147,17 +190,87 @@ def check_flow_packets_metrics(sai_dp, flow: snappi.Flow, exp_tx=None, exp_rx=No return False, { 'TX': act_tx, 'RX': act_rx } -# TODO -def check_flows_all_seconds_metrics(sai_dp): - pass +def check_flows_all_seconds_metrics(sai_dp, flows, name="Flow group", seconds=None, exp_tx=None, exp_rx=None, delta=None, show=False): + """ + Get packet count metrics per given time on list of flows. + + Parameters: + sai_dp: sai dataplane. + flows: list of flow to check. + name (str): name of flow group. Default is "Flow group". + seconds (int): duration of traffic generating. + exp_tx (int): expected count of TX packets. + exp_rx (int): expected count of RX packets. + delta (int): permissible error in the calculation of TX/RX packets. + show (bool): flag to show metrics. Default is False. + + Return: + tuple(bool, { int, int }): bool is True if all flow metrics are OK. First int is for + sum of TX packets from all flows. Second int is for sum of RX packets from all flows. + """ + + if not flows: + print("Flows None or empty") + return False, None + if not seconds: + if sum([flow.duration.choice == snappi.FlowDuration.FIXED_SECONDS for flow in flows]) == len(flows): + seconds = sum([flow.duration.fixed_seconds.seconds for flow in flows]) // len(flows) + else: + print("{}: some flow in flow group doesn't configured to {}".format( + flow.name, snappi.FlowDuration.FIXED_SECONDS)) + return False, None + if not exp_tx: + exp_tx = sum([flow.rate.pps for flow in flows]) // len(flows) * seconds * len(flows) + if not exp_rx: + exp_rx = exp_tx + if not delta: + # default delta is 10% of exp_tx. If it 0 (seconds < 10) then delta == pps + tmp_delta = exp_tx // 10 + delta = tmp_delta if tmp_delta > 0 else (sum([flow.rate.pps for flow in flows]) // len(flows)) + + act_tx = 0 + act_rx = 0 + success = 0 + + for flow in flows: + tmp = check_flow_seconds_metrics(sai_dp, flow) + success += tmp[0] + act_tx += tmp[1]['TX'] + act_rx += tmp[1]['RX'] + + success = success == len(flows) + + if show: + # flow group name | [exp tx +-delta] - act tx | [exp rx +-delta] - act rx + print(f"{name} | exp tx:[{exp_tx - delta}, {exp_tx + delta}] - tx:{act_tx} | \ +exp rx:[{exp_rx - delta}, {exp_rx + delta}] - rx:{act_rx}") + + return success, { 'TX': act_tx, 'RX': act_rx } def check_flow_seconds_metrics(sai_dp, flow: snappi.Flow, seconds=None, exp_tx=None, exp_rx=None, delta=None, show=False): + """ + Get packet count metrics per given time on flow. + + Parameters: + sai_dp: sai dataplane. + flow (snappi.Flow): flow to check. + seconds (int): duration of traffic generating. + exp_tx (int): expected count of TX packets. + exp_rx (int): expected count of RX packets. + delta (int): permissible error in the calculation of TX/RX packets. + show (bool): flag to show metrics. Default is False. + + Return: + tuple(bool, { int, int }): bool is result of metrics. First int is for TX packets, + second int is for RX packets. + """ + if not seconds: if flow.duration.choice == snappi.FlowDuration.FIXED_SECONDS: seconds = flow.duration.fixed_seconds.seconds else: - print("{}: check for packet count failed. Flow configured to {} instead of {}".format( \ + print("{}: check for packet count failed. Flow configured to {} instead of {}".format( flow.name, flow.duration.choice, snappi.FlowDuration.FIXED_SECONDS)) return False, None if not exp_tx: @@ -166,7 +279,7 @@ def check_flow_seconds_metrics(sai_dp, flow: snappi.Flow, seconds=None, exp_tx=N exp_rx = exp_tx if not delta: # default delta is 10% of exp_tx. If it 0 (seconds < 10) then delta == pps - tmp_delta = int(exp_tx / 10) + tmp_delta = exp_tx // 10 delta = tmp_delta if tmp_delta > 0 else flow.rate.pps req = sai_dp.api.metrics_request() @@ -178,9 +291,9 @@ def check_flow_seconds_metrics(sai_dp, flow: snappi.Flow, seconds=None, exp_tx=N act_rx = res.flow_metrics[0].frames_rx if show: - # flow name | [exp tx - delta, ext_tx + delta] | act tx | [exp rx - delta, exp_rx + delta] | act rx - print("{} | [{}, {}] | {} | [{}, {}] | {}".format(flow.name, exp_tx - delta, exp_tx + delta, act_tx, \ - exp_rx - delta, exp_rx + delta, act_rx)) + # flow group name | [exp tx +-delta] - act tx | [exp rx +-delta] - act rx + print(f"{flow.name} | exp tx:[{exp_tx - delta}, {exp_tx + delta}] - tx:{act_tx} | \ +exp rx:[{exp_rx - delta}, {exp_rx + delta}] - rx:{act_rx}") if act_tx in range(exp_tx - delta, exp_tx + delta) and \ act_rx in range(exp_rx - delta, exp_rx + delta) and \ @@ -188,47 +301,3 @@ def check_flow_seconds_metrics(sai_dp, flow: snappi.Flow, seconds=None, exp_tx=N return True, { 'TX': act_tx, 'RX': act_rx } return False, { 'TX': act_tx, 'RX': act_rx } - - -# TODO -def check_flows_all_continuous_metrics(sai_dp): - pass - - -# TODO -def check_flow_continuous_metrics(sai_dp, flow: snappi.Flow): - pass - - -def add_simple_vxlan_packet(sai_dp, - flow: snappi.Flow, - outer_dst_mac, - outer_src_mac, - outer_dst_ip, - outer_src_ip, - dst_udp_port, - src_udp_port, - vni, - inner_dst_mac, - inner_src_mac, - inner_dst_ip, - inner_src_ip - ): - if flow == None: - print("flow is None") - return - - if flow.packet: - print("packet in flow") - return - - sai_dp.add_ethernet_header(flow, outer_dst_mac, outer_src_mac) - sai_dp.add_ipv4_header(flow, outer_dst_ip, outer_src_ip) - u = sai_dp.add_udp_header(flow, dst_udp_port, src_udp_port) - # TODO: report ixia bug (udp checksum still generated) - # u.checksum.choice = u.checksum.CUSTOM - # u.checksum.custom = 0 - sai_dp.add_vxlan_header(flow, vni) - sai_dp.add_ethernet_header(flow, inner_dst_mac, inner_src_mac) - sai_dp.add_ipv4_header(flow, inner_dst_ip, inner_src_ip) - sai_dp.add_udp_header(flow) diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py index 59dc8c93d..739fb02f6 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py @@ -209,14 +209,26 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): # print(cmd['name'], cmd['type'], res) @pytest.mark.snappi - def test_run_traffic_check(self, dpu, dataplane): - dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE) + def test_run_traffic_check_fixed_packets(self, dpu, dataplane): + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE, + packets_per_flow=10, flow_duration=0, pps_per_flow=10) dataplane.set_config() dataplane.start_traffic() - stu.wait_for(lambda: dh.check_flows_all_packets_metrics(dataplane, dataplane.flows, - name="Custom flow group", show=True)[0], - "Test", timeout_seconds=2) + name="Custom flow group", show=True)[0], + "Test", timeout_seconds=5) + print("Test passed !") + + @pytest.mark.snappi + def test_run_traffic_check_fixed_duration(self, dpu, dataplane): + TEST_DURATION = 10 + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE, + packets_per_flow=0, flow_duration=TEST_DURATION, pps_per_flow=10) + dataplane.set_config() + dataplane.start_traffic() + stu.wait_for(lambda: dh.check_flows_all_seconds_metrics(dataplane, dataplane.flows, + name="Custom flow group", show=True)[0], + "Test", timeout_seconds=TEST_DURATION + 1) print("Test passed !") def test_remove_vnet_config(self, confgen, dpu, dataplane): diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py index b934294f1..fb33ae1ae 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py @@ -1,4 +1,5 @@ import json +import time from pathlib import Path from pprint import pprint @@ -60,11 +61,11 @@ 'eni': { 'ACL_GROUP': { 'INBOUND': { - 'STAGE1': 'DASH_ACL_GROUP#in_acl_group_id#0', - 'STAGE2': 'DASH_ACL_GROUP#in_acl_group_id#0', - 'STAGE3': 'DASH_ACL_GROUP#in_acl_group_id#0', - 'STAGE4': 'DASH_ACL_GROUP#in_acl_group_id#0', - 'STAGE5': 'DASH_ACL_GROUP#in_acl_group_id#0' + 'STAGE1': '$in_acl_group_id_#{0}', + 'STAGE2': '$in_acl_group_id_#{0}', + 'STAGE3': '$in_acl_group_id_#{0}}', + 'STAGE4': '$in_acl_group_id_#{0}}', + 'STAGE5': '$in_acl_group_id_#{0}}' }, 'OUTBOUND': { 'STAGE1': 0, @@ -80,7 +81,7 @@ 'PPS': 100000, 'VM_UNDERLAY_DIP': "172.16.1.1", 'VM_VNI': 9, - 'VNET_ID': 'DASH_VNET#vnet#0' + 'VNET_ID': '$vnet_#{0}' } }, @@ -88,24 +89,24 @@ 'eam': { 'SWITCH_ID': '$SWITCH_ID', 'MAC': "00:cc:cc:cc:00:00", - 'ENI_ID': 'DASH_ENI#eni#0' + 'ENI_ID': '$eni_#{0}' } }, 'DASH_OUTBOUND_ROUTING': { 'ore': { 'SWITCH_ID': '$SWITCH_ID', - 'ENI_ID': 'DASH_ENI#eni#0', + 'ENI_ID': '$eni_#{0}', 'DESTINATION': "10.1.0.0/16", 'ACTION': 'ROUTE_VNET', - 'DST_VNET_ID': 'DASH_VNET#vnet#0' + 'DST_VNET_ID': '$vnet_#{0}' } }, 'DASH_OUTBOUND_CA_TO_PA': { 'ocpe': { 'SWITCH_ID': '$SWITCH_ID', - 'DST_VNET_ID': 'DASH_VNET#vnet#0', + 'DST_VNET_ID': '$vnet_#{0}', 'DIP': "10.1.2.50", 'UNDERLAY_DIP': "172.16.1.20", 'OVERLAY_DMAC': "00:DD:DD:DD:00:00", @@ -114,6 +115,7 @@ } } + class TestSaiVnetOutbound: def test_create_vnet_config(self, confgen, dpu, dataplane): @@ -131,18 +133,123 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): print("\n======= SAI commands RETURN values =======") pprint(result) + @pytest.mark.ptf + def test_run_packets_check(self, dpu, dataplane): + + SRC_VM_IP = "10.1.1.10" + OUTER_SMAC = "00:00:05:06:06:06" + OUR_MAC = "00:00:02:03:04:05" + + VIP = TEST_VNET_OUTBOUND_CONFIG['DASH_VIP']['vpe']['IPV4'] + VNET_VNI = TEST_VNET_OUTBOUND_CONFIG['DASH_VNET']['vnet']['VNI'] + DIR_LOOKUP_VNI = TEST_VNET_OUTBOUND_CONFIG['DASH_DIRECTION_LOOKUP']['dle']['VNI'] + SRC_VM_PA_IP = TEST_VNET_OUTBOUND_CONFIG['DASH_ENI']['eni']['VM_UNDERLAY_DIP'] + ENI_MAC = TEST_VNET_OUTBOUND_CONFIG['DASH_ENI_ETHER_ADDRESS_MAP']['eam']['MAC'] + DST_CA_IP = TEST_VNET_OUTBOUND_CONFIG['DASH_OUTBOUND_CA_TO_PA']['ocpe']['DIP'] + DST_PA_IP = TEST_VNET_OUTBOUND_CONFIG['DASH_OUTBOUND_CA_TO_PA']['ocpe']["UNDERLAY_DIP"] + DST_CA_MAC = TEST_VNET_OUTBOUND_CONFIG['DASH_OUTBOUND_CA_TO_PA']['ocpe']["OVERLAY_DMAC"] + + # # check VIP drop + # WRONG_VIP = "172.16.100.100" + # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + # eth_src=ENI_MAC, + # ip_dst=DST_CA_IP, + # ip_src=SRC_VM_IP) + # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + # eth_src=OUTER_SMAC, + # ip_dst=WRONG_VIP, + # ip_src=SRC_VM_PA_IP, + # udp_sport=11638, + # with_udp_chksum=False, + # vxlan_vni=OUTBOUND_VNI, + # inner_frame=inner_pkt) + # print("\n\nSending packet with wrong vip...\n\n", vxlan_pkt.__repr__()) + # send_packet(dataplane, 0, vxlan_pkt) + # print("\nVerifying drop...") + # verify_no_other_packets(dataplane) + + # # check routing drop + # WRONG_DST_CA = "10.200.2.50" + # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + # eth_src=ENI_MAC, + # ip_dst=WRONG_DST_CA, + # ip_src=SRC_VM_IP) + # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + # eth_src=OUTER_SMAC, + # ip_dst=VIP, + # ip_src=SRC_VM_PA_IP, + # udp_sport=11638, + # with_udp_chksum=False, + # vxlan_vni=OUTBOUND_VNI, + # inner_frame=inner_pkt) + # print("\nSending packet with wrong dst CA IP to verify routing drop...\n\n", vxlan_pkt.__repr__()) + # send_packet(dataplane, 0, vxlan_pkt) + # print("\nVerifying drop...") + # verify_no_other_packets(dataplane) + + # # check mapping drop + # WRONG_DST_CA = "10.1.211.211" + # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + # eth_src=ENI_MAC, + # ip_dst=WRONG_DST_CA, + # ip_src=SRC_VM_IP) + # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + # eth_src=OUTER_SMAC, + # ip_dst=VIP, + # ip_src=SRC_VM_PA_IP, + # udp_sport=11638, + # with_udp_chksum=False, + # vxlan_vni=OUTBOUND_VNI, + # inner_frame=inner_pkt) + # print("\nSending packet with wrong dst CA IP to verify mapping drop...\n\n", vxlan_pkt.__repr__()) + # send_packet(dataplane, 0, vxlan_pkt) + # print("\nVerifying drop...") + # verify_no_other_packets(dataplane) + + # check forwarding + inner_pkt = simple_udp_packet(eth_dst = "02:02:02:02:02:02", + eth_src = ENI_MAC, + ip_dst = DST_CA_IP, + ip_src = SRC_VM_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst = OUR_MAC, + eth_src = OUTER_SMAC, + ip_dst = VIP, + ip_src = SRC_VM_PA_IP, + udp_sport = 11638, + with_udp_chksum = False, + vxlan_vni = DIR_LOOKUP_VNI, + inner_frame = inner_pkt) + + inner_exp_pkt = simple_udp_packet(eth_dst = DST_CA_MAC, + eth_src = ENI_MAC, + ip_dst = DST_CA_IP, + ip_src = SRC_VM_IP) + vxlan_exp_pkt = simple_vxlan_packet(eth_dst = "00:00:00:00:00:00", + eth_src = "00:00:00:00:00:00", + ip_dst = DST_PA_IP, + ip_src = VIP, + udp_sport = 0, # TODO: Fix sport in pipeline + with_udp_chksum = False, + vxlan_vni = VNET_VNI, + vxlan_flags = 0, + inner_frame = inner_exp_pkt) + vxlan_exp_pkt['IP'].chksum = 0 + + print("\nSending outbound packet...\n\n", vxlan_pkt.__repr__()) + send_packet(dataplane, 0, vxlan_pkt) + time.sleep(0.5) + print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) + verify_packet(dataplane, vxlan_exp_pkt, 0) + @pytest.mark.snappi def test_simple_vxlan_packet(self, dpu, dataplane): dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG) - dataplane.set_config() dataplane.start_traffic() stu.wait_for(lambda: dh.check_flow_packets_metrics(dataplane, dataplane.flows[0], show=True)[0], "Test", timeout_seconds=10) - print("Test passed !") - def test_remove_vnet_config(self, confgen, dpu, dataplane): # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) From b0aca69fd806b12a651b54b9c2502f2361461c21 Mon Sep 17 00:00:00 2001 From: Maksym Prytoliuk Date: Thu, 13 Oct 2022 05:37:20 -0400 Subject: [PATCH 41/45] Add outbound diagram Signed-off-by: Maksym Prytoliuk --- .../images/outbound_scenario_explained.svg | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 test/test-cases/test_vector_example/images/outbound_scenario_explained.svg diff --git a/test/test-cases/test_vector_example/images/outbound_scenario_explained.svg b/test/test-cases/test_vector_example/images/outbound_scenario_explained.svg new file mode 100644 index 000000000..737e39685 --- /dev/null +++ b/test/test-cases/test_vector_example/images/outbound_scenario_explained.svg @@ -0,0 +1,4 @@ + + + +
VIP

vip: 172.16.1.100
action: ACCEPT
VIP...
DIRECTION LOOKUP

vni: 100
action: SET_OUTBOUND_DIRECTION
DIRECTION LOOKUP...
VNET

vni:  1000
VNET...
ENI

vm_underlay_dip: 172.16.1.1
vm_vni: 9
vnet_id: $vnet
ENI...
ENI_MAC

address: 00:CC:CC:CC:CC:CC
eni_id: $eni
ENI_MAC...
OUTBOUND ROUTING

eni_id: $eni
destination: 10.1.0.0/16
action: ROUTE_VNET
vnet_id: $vnet
OUTBOUND ROUTING...
OUTBOUND CA TO PA

dip: 10.1.2.50
dst_vnet_id: $vnet
underlay_dip: 172.16.1.20
overlay_dmac: 00:DD:DD:DD:DD:DD
use_dst_vnet_vni: True
OUTBOUND CA TO PA...
00:DD:DD:DD:DD:DD
00:DD:DD:DD:DD:DD
00:CC:CC:CC:CC:CC
00:CC:CC:CC:CC:CC
10.1.1.10
10.1.1.10
10.1.2.50
10.1.2.50
00:00:00:00:00:00
00:00:00:00:00:00
00:00:00:00:00:00
00:00:00:00:00:00
172.16.1.100
172.16.1.100
172.16.1.20
172.16.1.20
1000
1000
02:02:02:02:02:02
02:02:02:02:02:02
00:CC:CC:CC:CC:CC
00:CC:CC:CC:CC:CC
10.1.1.10
10.1.1.10
10.1.2.50
10.1.2.50
00:00:02:03:04:05
00:00:02:03:04:05
00:00:05:06:06:06
00:00:05:06:06:06
172.16.1.1
172.16.1.1
172.16.1.100
172.16.1.100
100
100
DMAC
DMAC
SMAC
SMAC
SIP
SIP
DIP
DIP
VNI
VNI
DMAC
DMAC
SMAC
SMAC
SIP
SIP
DIP
DIP
DMAC
DMAC
SMAC
SMAC
SIP
SIP
DIP
DIP
VNI
VNI
DMAC
DMAC
SMAC
SMAC
SIP
SIP
DIP
DIP
match: ODIP
action: accept
match: ODIP...
match: VNI
action: set_outbound_direction
match: VNI...
match: ISMAC
action: set $eni
match: ISMAC...
match: $eni
action: set $eni attrs
match: $eni...
match: $eni, destination (IDIP)
action: set $vnet
match: $eni, destination (ID...
match: $vnet, IDIP
action: set_tunnel_mapping
match: $vnet, IDIP...
match: VNET
action: set vni
match: VNET...
Text is not SVG - cannot display
From e5055086f262c93374184ca7c63847008f4d7b7d Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Thu, 13 Oct 2022 12:44:36 +0300 Subject: [PATCH 42/45] Added inbound to xfail test results. (#44) - Marked VNET Inbound Routing with xfail - Added pytest.ini with marks definitions. - Decreased duration of tests. Signed-off-by: Anton Putria --- test/test-cases/test_vector_example/pytest.ini | 4 ++++ .../test-cases/test_vector_example/test_sai_vnet_inbound.py | 3 ++- .../test_vector_example/test_sai_vnet_outbound_scale.py | 6 +++--- .../test_vector_example/vnet_inbound_setup_commands.json | 5 ++++- 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 test/test-cases/test_vector_example/pytest.ini diff --git a/test/test-cases/test_vector_example/pytest.ini b/test/test-cases/test_vector_example/pytest.ini new file mode 100644 index 000000000..f9eb33c53 --- /dev/null +++ b/test/test-cases/test_vector_example/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +markers = + ptf: traffic tests supported by PTF. snappi should work as well. + snappi: traffic tests that requires snappi only. \ No newline at end of file diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py index 11ad1957b..bb0760044 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py @@ -22,7 +22,7 @@ INNER_VM_IP = "172.19.1.100" INNER_REMOTE_IP = "172.19.1.1" -# Test Vector +# TODO: Fix configuration once issue is addressed: https://github.com/Azure/DASH/issues/233 TEST_VNET_INBOUND_CONFIG = { 'ACL_TABLE_COUNT': 1, @@ -123,6 +123,7 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): print("\n======= SAI commands RETURN values =======") pprint(result) + @pytest.mark.xfail(reason="https://github.com/Azure/DASH/issues/233") def test_run_traffic_check(self, dpu, dataplane): # Check forwarding diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py index 739fb02f6..cfce1abae 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py @@ -211,7 +211,7 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): @pytest.mark.snappi def test_run_traffic_check_fixed_packets(self, dpu, dataplane): dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE, - packets_per_flow=10, flow_duration=0, pps_per_flow=10) + packets_per_flow=1, flow_duration=0, pps_per_flow=10) dataplane.set_config() dataplane.start_traffic() stu.wait_for(lambda: dh.check_flows_all_packets_metrics(dataplane, dataplane.flows, @@ -221,9 +221,9 @@ def test_run_traffic_check_fixed_packets(self, dpu, dataplane): @pytest.mark.snappi def test_run_traffic_check_fixed_duration(self, dpu, dataplane): - TEST_DURATION = 10 + TEST_DURATION = 5 dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE, - packets_per_flow=0, flow_duration=TEST_DURATION, pps_per_flow=10) + packets_per_flow=0, flow_duration=TEST_DURATION, pps_per_flow=5) dataplane.set_config() dataplane.start_traffic() stu.wait_for(lambda: dh.check_flows_all_seconds_metrics(dataplane, dataplane.flows, diff --git a/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json b/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json index b9fe9d4de..e43e09c09 100644 --- a/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json +++ b/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json @@ -133,7 +133,10 @@ "key": { "switch_id": "$SWITCH_ID", "eni_id": "$eni_id", - "vni": "1000" + "vni": "1000", + "sip": "10.10.2.0", + "sip_mask": "255.255.255.0", + "priority": 0 }, "attributes": [ "SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION", From 6513dca8948d556062ae1f8a5553be516fd26367 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Fri, 14 Oct 2022 11:31:44 +0300 Subject: [PATCH 43/45] Scaling test configuration documentation - Added scaling approach documentation. - Vnet2vnet traffic scaling scenario description. - Added docstring to the test cases. - Added more test examples. Signed-off-by: Anton Putria Co-authored-by: Maksym Hedeon Co-authored-by: Maksym Prytoliuk --- .wordlist.txt | 2 + test/docs/dash-test-sai-challenger.md | 1 - test/test-cases/test_vector_example/README.md | 550 ++++++++++++++++++ .../test_vector_example/conftest.py | 2 +- .../dash_helper/vnet2vnet_helper.py | 2 +- .../vnet2vnet_outbound_traffic_scaling.svg | 4 + .../test_config_vnet_inbound.py | 48 ++ .../test_config_vnet_outbound.py | 37 ++ .../test_sai_vnet_inbound.py | 15 +- .../test_sai_vnet_outbound_scale.py | 36 +- .../test_sai_vnet_outbound_simple.py | 38 +- .../test_vector_example/test_vnet_inbound.py | 18 - .../test_vector_example/test_vnet_outbound.py | 21 - 13 files changed, 715 insertions(+), 59 deletions(-) create mode 100644 test/test-cases/test_vector_example/README.md create mode 100644 test/test-cases/test_vector_example/images/vnet2vnet_outbound_traffic_scaling.svg create mode 100644 test/test-cases/test_vector_example/test_config_vnet_inbound.py create mode 100644 test/test-cases/test_vector_example/test_config_vnet_outbound.py delete mode 100644 test/test-cases/test_vector_example/test_vnet_inbound.py delete mode 100644 test/test-cases/test_vector_example/test_vnet_outbound.py diff --git a/.wordlist.txt b/.wordlist.txt index e69360d61..8963d3fc1 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -295,6 +295,7 @@ LLDP lldp loadbalancer lookups +LOOKUPs loopback LPM lts @@ -303,6 +304,7 @@ makefile Makefile Makefiles makefiles +MAPs MatchedHalfOpenFlow MatchedOtherFlow MatchedTcpFlow diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index c3cddd99f..f927b8cd0 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -93,4 +93,3 @@ pytest -sv --setup=sai_dpu_client_server_snappi.json test_vnet_outbound.py ``` # Known issues -* [Test Vector format tests ](#Test Vector format tests): traffic check will fail as expected diff --git a/test/test-cases/test_vector_example/README.md b/test/test-cases/test_vector_example/README.md new file mode 100644 index 000000000..da69cdc66 --- /dev/null +++ b/test/test-cases/test_vector_example/README.md @@ -0,0 +1,550 @@ + +# DASH configuration specification + +1. [Generator input format](#generator-input-format) + - [Sequence generator](#sequence-generator) + - [Example of generator output using scale configuration](#example-of-generator-output-using-scale-configuration) + - [Known issues](#known-issues) +1. [Generator output format (Unified SAI format)](#generator-output-format-unified-sai-format) + - [General description](#general-description) + - [Unified SAI commands examples](#unified-sai-commands-examples) +1. [Traffic scaling](#traffic-scaling) + - [VNET Outbound Routing scenario explanation](#vnet-outbound-routing-scenario-explanation) + - [DASH and traffic configuration visualization](#dash-and-traffic-configuration-visualization) + - [Resulting traffic configuration examples](#resulting-traffic-configuration-examples) + + +# Generator input format + +In general a DASH config consists of such entries: + +``` +DASH_OBJECT_TYPE: + object_name: + count: NUMBER_OF_OBJECTS + attribute_name: CONST_OR_GENERATOR +``` + +Where, +* `DASH_OBJECT_TYPE` - Can be **DASH_VNET**, **DASH_VIP**, **DASH_ENI**, etc. +* `object_name` - Name of the object +* `NUMBER_OF_OBJECTS` - Number of such objects to create +* `attribute_name` - Specific attributes of every object. Depend on `DASH_OBJECT_TYPE`. +* `CONST_OR_GENERATOR` - The value of the attribute. Could be a constant value or a sequence generator expression. + +If `NUMBER_OF_OBJECTS` is greater than the number of values generated by the sequence generator - after reaching the last value generator must produce values from the start again. + +If number of values generated by the sequence generator is greater than `NUMBER_OF_OBJECTS` - only first `NUMBER_OF_OBJECTS` values of the sequence generator should be used. + +## Sequence generator + +For scaling purposes sequence generator could be used for creating big number of objects. It produces a range of values according to the given attributes. + +### Sequence generator attributes: + +* `count` - The number of entries (default is 1) +* `start` - The first entry (no default values) +* `step` - Increment step (default is 1) +* `delay`[1](#known-issues) - Delay increment for `delay` iterations (default is 1, which means increment at every iteration) +* `list` - Use this specific list of values instead of the generated values. If this attribute is present `start`, `step`, `delay` must be ignored. `count` still will be used. + +### Sequence generator expressions examples: + +#### Integers + +```JSON +{ count: 4, start: 100, step: 10 } => 100, 110, 120, 130 +{ count: 4, start: 100, step: 5 } => 100, 105, 110, 115 +{ count: 4, start: 100, step: 10, delay: 2} => 100, 100, 105, 105 +{ count: 4, start: 100 } => 100, 101, 102, 103 +{ start: 100 } => 100 +``` + +#### IP-addresses and IP-prefixes + +```JSON +{ count: 4, start: "10.0.0.1", step: "0.0.0.1" } => "10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4" +{ count: 4, start: "10.0.0.1", step: "0.0.1.0" } => "10.0.0.1", "10.0.1.1", "10.0.2.1", "10.0.3.1" +{ count: 4, start: "10.0.0.1", step: "0.0.1.0", delay: 2 } => "10.0.0.1", "10.0.0.1", "10.0.1.1", "10.0.1.1" +{ count: 4, start: "10.0.0.1" } => "10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4" +{ start: "10.0.0.1" } => "10.0.0.1" + +{ count: 4, start: "10.0.0.0/24", step: "0.0.1.0" } => "10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24" +{ count: 4, start: "10.0.0.0/24", step: "0.1.1.0" } => "10.0.0.0/24", "10.1.1.0/24", "10.2.2.0/24", "10.3.3.0/24" +{ count: 4, start: "10.0.0.0/24", step: "0.1.1.0", delay: 2 } => "10.0.0.0/24", "10.0.0.0/24", "10.2.2.0/24", "10.2.2.0/24" +{ start: "10.0.0.1/24" } => "10.0.0.1/24" +``` + +#### MAC-addresses + +```JSON +{ count: 4, start: "00:CC:CC:CC:CC:00", step: "00:00:00:00:00:01" } => "00:CC:CC:CC:CC:00", "00:CC:CC:CC:CC:01", "00:CC:CC:CC:CC:02", "00:CC:CC:CC:CC:03" +{ count: 4, start: "00:CC:CC:CC:CC:00", step: "00:00:00:00:00:10" } => "00:CC:CC:CC:CC:00", "00:CC:CC:CC:CC:10", "00:CC:CC:CC:CC:20", "00:CC:CC:CC:CC:30" +{ count: 4, start: "00:CC:CC:CC:CC:00", step: "00:00:00:00:00:10", delay: 2 } => "00:CC:CC:CC:CC:00", "00:CC:CC:CC:CC:00", "00:CC:CC:CC:CC:10", "00:CC:CC:CC:CC:10" +{ count: 4, start: "00:CC:CC:CC:CC:00" } => "00:CC:CC:CC:CC:00", "00:CC:CC:CC:CC:01", "00:CC:CC:CC:CC:02", "00:CC:CC:CC:CC:03" +{ start: "00:CC:CC:CC:CC:00" } => "00:CC:CC:CC:CC:00" +``` + +#### Object IDs + +```JSON +{ count: 4, start: "DASH_VNET#vnet#0", step: 1 } => "$DASH_VNET#vnet#0", "$DASH_VNET#vnet#1", "$DASH_VNET#vnet#2", "$DASH_VNET#vnet#3" +{ count: 4, start: "DASH_VNET#vnet#0", step: 2 } => "$DASH_VNET#vnet#0", "$DASH_VNET#vnet#2", "$DASH_VNET#vnet#4", "$DASH_VNET#vnet#6" +{ count: 4, start: "DASH_VNET#vnet#0", step: 2, delay: 2} => "$DASH_VNET#vnet#0", "$DASH_VNET#vnet#0", "$DASH_VNET#vnet#2", "$DASH_VNET#vnet#2" +{ count: 4, start: "DASH_VNET#vnet#0"} => "$DASH_VNET#vnet#0", "$DASH_VNET#vnet#1", "$DASH_VNET#vnet#2", "$DASH_VNET#vnet#3" +{ start: "DASH_VNET#vnet#0"} => "$DASH_VNET#vnet#0" +``` + +#### Lists + +```JSON +{ count: 4, start: 100, step: 10, list: [3, 5, 7, 9] } => 3, 5, 7, 9 +{ count: 4, list: [3, 5, 7, 9] } => 3, 5, 7, 9 +{ count: 2, list: [3, 5, 7, 9] } => 3, 5 +{ count: 6, list: [3, 5, 7, 9] } => 3, 5, 7, 9, 3, 5 +``` + +## Example of generator output using scale configuration + +Here is an example of DASH_OUTBOUND_ROUTING scale configuration using DASH config + +### Input: + +```yaml +NUMBER_OF_ORE: 5 +NUMBER_OF_ENI: 4 +NUMBER_OF_DST: 3 +NUMBER_OF_VNET: 10 + +DASH_OUTBOUND_ROUTING: + ore: + count: NUMBER_OF_ORE + SWITCH_ID: $SWITCH_ID + ENI_ID: + count: NUMBER_OF_ENI + start: "$eni_#0" + delay: NUMBER_OF_DST + DESTINATION: + count: NUMBER_OF_DST + start: "10.1.0.0/24" + step: "0.0.1.0" + ACTION: ROUTE_VNET + DST_VNET_ID: + count: NUMBER_OF_VNET + start: "$vnet_#0" +``` + +### Output: + +```json + { + "name": "DASH_OUTBOUND_ROUTING#ore#0", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$DASH_ENI#eni#0", + "destination": "10.1.0.0/24" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$DASH_VNET#vnet#0" + ] + }, + { + "name": "DASH_OUTBOUND_ROUTING#ore#1", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$DASH_ENI#eni#0", + "destination": "10.1.1.0/24" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$DASH_VNET#vnet#1" + ] + }, + { + "name": "DASH_OUTBOUND_ROUTING#ore#2", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$DASH_ENI#eni#0", + "destination": "10.1.2.0/24" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$DASH_VNET#vnet#2" + ] + }, + { + "name": "DASH_OUTBOUND_ROUTING#ore#3", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$DASH_ENI#eni#1", + "destination": "10.0.1.0/24" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$DASH_VNET#vnet#3" + ] + }, + { + "name": "DASH_OUTBOUND_ROUTING#ore#4", + "op": "create", + "type": "SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY", + "key": { + "switch_id": "$SWITCH_ID", + "eni_id": "$DASH_ENI#eni#1", + "destination": "10.1.1.0/24" + }, + "attributes": [ + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION", "SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET", + "SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID", "$DASH_VNET#vnet#4" + ] + } +``` + +## Outbound DASH config example + +```YAML +NUMBER_OF_VIP: 3 +NUMBER_OF_DLE: 3 +NUMBER_OF_IN_ACL_GROUP: 10 +NUMBER_OF_OUT_ACL_GROUP: 10 +NUMBER_OF_VNET: 50 +NUMBER_OF_ENI: 10 +NUMBER_OF_EAM: NUMBER_OF_ENI * 2 +NUMBER_OF_ORE: 5 +NUMBER_OF_DST: 10 +NUMBER_OF_OCPE: 5 + +DASH_VIP: + vpe: NUMBER_OF_VIP + SWITCH_ID: $SWITCH_ID + IPv4: { count: NUMBER_OF_VIP, start: "172.1.0.100", step: "0.1.0.0" } + +DASH_DIRECTION_LOOKUP: + dle: NUMBER_OF_DLE + SWITCH_ID: $SWITCH_ID + VNI: { count: NUMBER_OF_DLE, start: 100, step: 100 } + ACTION: SET_OUTBOUND_DIRECTION + +DASH_ACL_GROUP: + in_acl_group_id: NUMBER_OF_IN_ACL_GROUP + ADDR_FAMILY: IPv4 + out_acl_group_id: NUMBER_OF_OUT_ACL_GROUP + ADDR_FAMILY: IPv4 + +DASH_VNET: + vnet: NUMBER_OF_VNET + VNI: { count: NUMBER_OF_VNET, start: 1000, step: 10 } + +DASH_ENI: + eni: NUMBER_OF_ENI + ACL_GROUP: + INBOUND: + STAGE1: { list: "DASH_ACL_GROUP#in_acl_group_id#0" } + STAGE2: { list: "DASH_ACL_GROUP#in_acl_group_id#0" } + STAGE3: { list: "DASH_ACL_GROUP#in_acl_group_id#0" } + STAGE4: { list: "DASH_ACL_GROUP#in_acl_group_id#0" } + STAGE5: { list: "DASH_ACL_GROUP#in_acl_group_id#0" } + OUTBOUND: + STAGE1: 0 + STAGE2: 0 + STAGE3: 0 + STAGE4: 0 + STAGE5: 0 + ADMIN_STATE: True + CPS: 10000 + FLOWS: 10000 + PPS: 100000 + VM_UNDERLAY_DIP: { count: NUMBER_OF_ENI, start: "172.16.1.0", step: "0.0.1.0" } + VM_VNI: { count: NUMBER_OF_ENI, start: 50 } + VNET_ID: { count: NUMBER_OF_ENI, start: "DASH_VNET#vnet#0" } + +DASH_ENI_ETHER_ADDRESS_MAP: + eam: NUMBER_OF_EAM + SWITCH_ID: $SWITCH_ID + MAC: { count: NUMBER_OF_EAM, start: "00:CC:CC:CC:00:00" } + ENI_ID: { count: NUMBER_OF_ENI, start: "DASH_ENI#eni#0" } + +DASH_OUTBOUND_ROUTING: + ore: NUMBER_OF_ORE + SWITCH_ID: $SWITCH_ID + ENI_ID: { count: NUMBER_OF_ENI, start: "DASH_ENI#eni#0", delay: NUMBER_OF_DST } + DESTINATION: { count: NUMBER_OF_DST, start: "10.1.0.0/24", step: "0.0.1.0" } + ACTION: ROUTE_VNET + DST_VNET_ID: { count: NUMBER_OF_VNET, start: "DASH_VNET#vnet#0" } + +DASH_OUTBOUND_CA_TO_PA: + ocpe: NUMBER_OF_OCPE + SWITCH_ID: $SWITCH_ID + DST_VNET_ID: { count: NUMBER_OF_VNET, start: "DASH_VNET#vnet#0" } + DIP: { count: NUMBER_OF_OCPE, start: "10.1.2.50", step: "0.0.1.0" } + UNDERLAY_DIP: { count: NUMBER_OF_OCPE, start: "172.16.1.20", step: "0.0.1.0" } + OVERLAY_DMAC: { count: NUMBER_OF_OCPE, start: "00:DD:DD:DD:00:00" } + USE_DST_VNET_VNI: True +``` + + +## Known issues + +1. "duration" key might be replaced with nested loops approach. + +# Generator output format (Unified SAI format) + +## General description + +Config generator generates a list of commands that should be applied to SAI. These commands consist of the following fields: + +- `op` - operation. (mandatory) +- `type` - object type. See *sai_object_type_t*. (mandatory when op is "create" or "bulk_create") +- `name` - name of the object. (mandatory when "op" is "remove", "bulk_remove" or "set") +- `key` - key of the specific object. Not all objects have key. See SAI headers for more information. (mandatory for some object types) +- `attributes` - a list of attributes and their values. See SAI headers for more information. (optional) + +Possible operations (`op`): +- create +- remove +- get +- set +- bulk_create *(currently not supported)* +- bulk_remove *(currently not supported)* + +If `op` is "bulk_create" or "bulk_remove" SAI expects `name` and `key` to be lists of values and `attributes` to be a list of lists. + +If you need to refer to some object in `attributes` or `key` you should use its name with a '$' sign at the beginning. Example: "$vnet". + +## Unified SAI commands examples + +Create an object without a key: + +```JSON + { + "op": "create", + "type": "SAI_OBJECT_TYPE_VNET", + "name": "vnet", + "attributes": [ + "SAI_VNET_ATTR_VNI", "100" + ] + } +``` + +Create an object with key: + +```JSON + { + "op": "create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "name": "vpe", + "key": { + "switch_id": "$SWITCH_ID", + "vip": "172.16.1.100" + }, + "attributes": [ + "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" + ] + } +``` + +Remove object: +```JSON + { + "name": "vnet", + "op": "remove" + } +``` +NOTE: For removal it's enough to provide only name and skip attributes. + +Bulk create: +```JSON + { + "op": "bulk_create", + "type": "SAI_OBJECT_TYPE_VIP_ENTRY", + "name": [ "vpe#0", "vpe#1" ], + "key": [ + { "switch_id": "$SWITCH_ID", + "vip": "172.16.1.100" }, + { "switch_id": "$SWITCH_ID", + "vip": "172.16.1.200" } + ], + "attributes": [ + [ "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" ], + [ "SAI_VIP_ENTRY_ATTR_ACTION", "SAI_VIP_ENTRY_ACTION_ACCEPT" ] + ] + } +``` + +Bulk remove: +```JSON + { + "name": [ "vpe#0", "vpe#1" ], + "op": "bulk_remove" + } +``` + +# Traffic scaling + +**Scalable traffic configuration uses the same DASH config format and the same entities as it is described above.** + + +## VNET Outbound Routing scenario explanation + +The following picture explains: +1. Relations between packet and configuration parameters +1. Packet transformation + +![Outbound scenario explanation](images/outbound_scenario_explained.svg) + + +## DASH and traffic configuration visualization + +The following picture depicts configuration used in [test_sai_vnet_outbound_scale.py](./test_sai_vnet_outbound_scale.py) + +![Visualization of traffic scaling](images/vnet2vnet_outbound_traffic_scaling.svg) + + +For simplicity DIRECTION_LOOKUPs are mapped to ENIs as **one-to-one**. +ENIs are mapped to ENI_ETHER_ADDRESS_MAPs as one-to-one by design. + +VIPs are completely standalone entities. If user increases count of VIPs, the rest of configuration stays as is, but the traffic will by multiplied on number of underlay destination IPs. + +ENI scales to OUTBOUND_ROUTING in the ratio: two OUTBOUND_ROUTING entries per one ENI. + +OUTBOUND_ROUTING scales to OUTBOUND_CA_TO_PA in the ratio: two OUTBOUND_CA_TO_PA entries per one OUTBOUND_ROUTING. + + +### DASH configuration based on the picture above: +```python +NUMBER_OF_VIP = 1 +NUMBER_OF_DLE = 2 +NUMBER_OF_ENI = 2 +NUMBER_OF_EAM = NUMBER_OF_ENI +NUMBER_OF_ORE = 2 # Per ENI +NUMBER_OF_OCPE = 2 # Per ORE +NUMBER_OF_VNET = NUMBER_OF_ENI + (NUMBER_OF_ORE * NUMBER_OF_ENI) # Per ORE + +TEST_VNET_OUTBOUND_CONFIG_SCALE = { + + 'DASH_VIP': { + 'vpe': { + 'count': NUMBER_OF_VIP, + ... + } + }, + + 'DASH_DIRECTION_LOOKUP': { + 'dle': { + 'count': NUMBER_OF_DLE, + ... + } + }, + + 'DASH_VNET': { + 'vnet': { + 'VNI': { + 'count': NUMBER_OF_VNET, + ... + } + }, + + 'DASH_ENI': { + 'eni': { + 'count': NUMBER_OF_ENI, + ... + } + }, + + 'DASH_ENI_ETHER_ADDRESS_MAP': { + 'eam': { + 'count': NUMBER_OF_EAM, + ... + } + }, + + 'DASH_OUTBOUND_ROUTING': { + 'ore': { + 'count': NUMBER_OF_ENI * NUMBER_OF_ORE, # Full count: OREs per ENI and VNET + ... + } + }, + + 'DASH_OUTBOUND_CA_TO_PA': { + 'ocpe': { + 'count': (NUMBER_OF_ENI * NUMBER_OF_ORE) * NUMBER_OF_OCPE, # 2 Per ORE + ... + } + } +} +``` + +## Resulting traffic configuration examples + +These short snippets are applicable with [this config example](#dash-configuration-based-on-the-picture-above). + +#### **Example #1** + +Each DIRECTION_LOOKUP refers to a single ENI_ETHER_MAP. +```python +NUMBER_OF_DLE = 2 +NUMBER_OF_ENI = 2 +``` + +Resulting traffic flows configuration: +```YAML +VIP "172.16.1.100" + DIR_LOOKUP VNI 5000 + CA SMAC: "00:CC:CC:CC:00:00" + DIR_LOOKUP VNI 6000 + CA SMAC: "00:CC:CC:CC:00:01" +``` +This means that 2 flows will be send with the following properties: +1. Underlay DIP: 172.16.1.100, VNI: 5000, Overlay SRC MAC: "00:CC:CC:CC:00:00" +1. Underlay DIP: 172.16.1.100, VNI: 6000, Overlay SRC MAC: "00:CC:CC:CC:00:01" + +#### **Example #2** +Each DIRECTION_LOOKUP refers to two ENI_ETHER_MAP. +```python +NUMBER_OF_DLE = 2 +NUMBER_OF_ENI = 4 +``` + +Resulting traffic flows configuration (4 flows in total): +```YAML +VIP "172.16.1.100" + DIR_LOOKUP VNI 5000 + CA SMAC: "00:CC:CC:CC:00:00" + CA SMAC: "00:CC:CC:CC:00:01" + DIR_LOOKUP VNI 6000 + CA SMAC: "00:CC:CC:CC:00:02" + CA SMAC: "00:CC:CC:CC:00:03" +``` + +## **Example #3** + +According to the [scheme](#dash-and-traffic-configuration-visualization) +```python +NUMBER_OF_VIP = 1 +NUMBER_OF_DLE = 2 +NUMBER_OF_ENI = 2 +NUMBER_OF_EAM = NUMBER_OF_ENI +NUMBER_OF_ORE = 2 # Per ENI +NUMBER_OF_OCPE = 2 # Per ORE +NUMBER_OF_VNET = NUMBER_OF_ENI + (NUMBER_OF_ORE * NUMBER_OF_ENI) +``` + +Resulting traffic profile includes 2 flows each of 4 "sub-flows" for each possible CA DIP. +```YAML +VIP 172.16.1.100 + DIR_LOOKUP VNI 5000 + CA SMAC: 00:CC:CC:CC:00:00 + CA DIP 10.1.1.0, count: 4, step: 0.0.0.1 + DIR_LOOKUP VNI 6000 + CA SMAC: 00:CC:CC:CC:00:01 + CA DIP 10.1.1.0, count: 4, step: 0.0.0.1 +``` diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/test_vector_example/conftest.py index 3d90ca7c5..8cb0a5260 100644 --- a/test/test-cases/test_vector_example/conftest.py +++ b/test/test-cases/test_vector_example/conftest.py @@ -58,7 +58,7 @@ def confgen(): class SaiConfig(ConfBase): def generate(self): - # Pass top-level params to sub-generrators. + # Pass top-level params to sub-generators. self.configs = [ saigen.vips.Vips(self.params_dict), saigen.direction_lookup.DirectionLookup(self.params_dict), diff --git a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py index b4e03bc7e..d7cb53ce4 100644 --- a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py +++ b/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py @@ -62,7 +62,7 @@ def configure_vnet_outbound_packet_flows(sai_dp, vip, dir_lookup, ca_smac, ca_di print(f">>>: {flow.name}") -def scale_vnet_outbound_flows(sai_dp, test_conf: dict, packets_per_flow=1, pps_per_flow=10, flow_duration=0): +def scale_vnet_outbound_flows(sai_dp, test_conf: dict, packets_per_flow=1, pps_per_flow=0, flow_duration=0): """ Get scale options and define VNET Outbound routing flows. diff --git a/test/test-cases/test_vector_example/images/vnet2vnet_outbound_traffic_scaling.svg b/test/test-cases/test_vector_example/images/vnet2vnet_outbound_traffic_scaling.svg new file mode 100644 index 000000000..0d418a221 --- /dev/null +++ b/test/test-cases/test_vector_example/images/vnet2vnet_outbound_traffic_scaling.svg @@ -0,0 +1,4 @@ + + + +
VIP #1
VIP #1
ENI #1
ENI #1
ENI MAC MAP #1
ENI MAC MAP #1
ENI #2
ENI #2
ENI MAC MAP #2
ENI MAC MAP #2
DIRECTION LOOKUP #1
DIRECTION LOOKUP #1
OUTBOUND ROUTING #1
OUTBOUND ROUTING #1
OUTBOUND ROUTING #2
OUTBOUND ROUTING #2
OUTBOUND ROUTING #3
OUTBOUND ROUTING #3
OUTBOUND ROUTING #4
OUTBOUND ROUTING #4
CA TO PA #1
CA TO PA #1
CA TO PA #2
CA TO PA #2
CA TO PA #3
CA TO PA #3
CA TO PA #4
CA TO PA #4
DIRECTION LOOKUP #2
DIRECTION LOOKUP #2
VNET #X
VNET #X
VNET #X
VNET #X
VNET #X
VNET #X
VNET #Y
VNET #Y
VNET #X
VNET #X
VNET #X
VNET #X
CA TO PA #5
CA TO PA #5
CA TO PA #6
CA TO PA #6
CA TO PA #7
CA TO PA #7
CA TO PA #8
CA TO PA #8
Text is not SVG - cannot display
\ No newline at end of file diff --git a/test/test-cases/test_vector_example/test_config_vnet_inbound.py b/test/test-cases/test_vector_example/test_config_vnet_inbound.py new file mode 100644 index 000000000..22b4c74f9 --- /dev/null +++ b/test/test-cases/test_vector_example/test_config_vnet_inbound.py @@ -0,0 +1,48 @@ +""" +Test module with an example of loading unified SAI config format from the file +""" + +import json +from pathlib import Path + +import pytest + + +class TestConfigVnetInboundRouting: + + @pytest.fixture(scope="class") + def vnet_in_config(self): + """ + Fixture returns the content of the file with SAI configuration commands. + scope=class - The file is loaded once for the whole test class + """ + current_file_dir = Path(__file__).parent + with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: + vnet_inbound_setup_commands = json.load(config_file) + return vnet_inbound_setup_commands + + def test_config_vnet_inbound_create(self, dpu, vnet_in_config): + """ + Apply configuration that is loaded from the file. + """ + + result = [*dpu.process_commands(vnet_in_config)] + # User may want to verify result. + + def test_config_vnet_inbound_remove(self, dpu, vnet_in_config): + """ + Remove configuration that is loaded from the file. + """ + # NOTE: vnet_in_config contains op="create". + # In the following loop "create" is replaced with "remove" + # Note that the order is reversed. + vnet_inbound_cleanup_commands = [] + for command in reversed(vnet_in_config): + command['op'] = 'remove' + vnet_inbound_cleanup_commands.append(command) + + # Another example of applying commands one by one. + # Extremely useful when you have a generator instead of the list + result = [] + for command in vnet_inbound_cleanup_commands: + result.append(dpu.command_processor.process_command(command)) diff --git a/test/test-cases/test_vector_example/test_config_vnet_outbound.py b/test/test-cases/test_vector_example/test_config_vnet_outbound.py new file mode 100644 index 000000000..9480b16c1 --- /dev/null +++ b/test/test-cases/test_vector_example/test_config_vnet_outbound.py @@ -0,0 +1,37 @@ +""" +Test module with an example of parametrized test case +""" +import json +from pathlib import Path + +import pytest + + +# The following test function will be executed twice - against each cfg_type: simple and scale +@pytest.mark.parametrize('cfg_type', ['simple', 'scale']) +def test_config_vnet_outbound_parametrized(dpu, cfg_type): + + # Loading unified SAI commands from file based on cfg_type + current_file_dir = Path(__file__).parent + with (current_file_dir / f'vnet_outbound_setup_commands_{cfg_type}.json').open(mode='r') as config_file: + setup_commands = json.load(config_file) + + try: + # Execute all commands in one shot + result = [*dpu.process_commands(setup_commands)] + + finally: + # The idea of finally here to try remove something if apply failed in the middle... + # In other test suites remove is a part of the separate test case and is always executed. + # This specific function executes a different configuration on each iteration and it's important + # to keep remove commands next to the create ones. + + # Replace op="create" to op="remove" + # Note that the order is reversed. + cleanup_commands = [] + for command in reversed(setup_commands): + command['op'] = 'remove' + cleanup_commands.append(command) + + # Execute all remove commands + result = [*dpu.process_commands(cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py index bb0760044..3ac8dc3f2 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_inbound.py @@ -1,3 +1,7 @@ +""" +Verify VNET Inbound Routing scenario +""" + import json from pathlib import Path from pprint import pprint @@ -110,7 +114,8 @@ class TestSaiVnetInbound: - def test_create_vnet_config(self, confgen, dpu, dataplane): + def test_vnet_inbound_create(self, confgen, dpu): + """Test configuration create""" # confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) # confgen.generate() @@ -123,9 +128,10 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): print("\n======= SAI commands RETURN values =======") pprint(result) + @pytest.mark.ptf @pytest.mark.xfail(reason="https://github.com/Azure/DASH/issues/233") - def test_run_traffic_check(self, dpu, dataplane): - # Check forwarding + def test_vnet_inbound_traffic_check(self, dpu, dataplane): + """Verify traffic forwarding in PTF style""" outer_smac = "00:0a:05:06:06:06" outer_dmac = "00:0b:05:06:06:06" @@ -167,7 +173,8 @@ def test_run_traffic_check(self, dpu, dataplane): print("\nVerifying packet...\n", vxlan_exp_pkt.__repr__()) verify_packet(dataplane, vxlan_exp_pkt, 1) - def test_remove_vnet_config(self, confgen, dpu, dataplane): + def test_vnet_inbound_remove(self, confgen, dpu): + """Test configuration remove""" # confgen.mergeParams(TEST_VNET_INBOUND_CONFIG) # confgen.generate() diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py index cfce1abae..2661221dd 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py @@ -14,7 +14,7 @@ current_file_dir = Path(__file__).parent -# Constants for scale outbound +# Constants for scale VNET outbound routing configuration NUMBER_OF_VIP = 1 NUMBER_OF_DLE = 2 NUMBER_OF_ENI = 2 @@ -25,6 +25,10 @@ NUMBER_OF_IN_ACL_GROUP = 10 NUMBER_OF_OUT_ACL_GROUP = 10 + +# Scaled configuration +# Pay attention to the 'count', 'start', 'step' keywords. +# See README.md for details. TEST_VNET_OUTBOUND_CONFIG_SCALE = { 'DASH_VIP': { @@ -192,7 +196,8 @@ class TestSaiVnetOutbound: - def test_create_vnet_config(self, confgen, dpu, dataplane): + def test_create_vnet_config(self, confgen, dpu): + """Generate and apply configuration""" # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG_SCALE) # confgen.generate() @@ -210,28 +215,45 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): @pytest.mark.snappi def test_run_traffic_check_fixed_packets(self, dpu, dataplane): + """ + Test with the fixed number of packets to send. + packets_per_flow=1 means that each possible packet path will be verified using a single packet. + NOTE: This test does not verify the correctness of the packets transformation. + """ + + #Generate traffic configuration, apply it and run. dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE, packets_per_flow=1, flow_duration=0, pps_per_flow=10) dataplane.set_config() dataplane.start_traffic() + + # The following function waits for expected counters and fail if no success during time out. stu.wait_for(lambda: dh.check_flows_all_packets_metrics(dataplane, dataplane.flows, name="Custom flow group", show=True)[0], "Test", timeout_seconds=5) - print("Test passed !") @pytest.mark.snappi def test_run_traffic_check_fixed_duration(self, dpu, dataplane): - TEST_DURATION = 5 + """ + Test with the fixed traffic duration to send. + flow_duration sets the total duration of traffic. Number of packets is limited by PPS. + For the HW PPS may be omitted and then it will send traffic on a line rate. + NOTE: This test does not verify the correctness of the packets transformation. + """ + test_duration = 5 dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG_SCALE, - packets_per_flow=0, flow_duration=TEST_DURATION, pps_per_flow=5) + packets_per_flow=0, flow_duration=test_duration, pps_per_flow=5) dataplane.set_config() dataplane.start_traffic() stu.wait_for(lambda: dh.check_flows_all_seconds_metrics(dataplane, dataplane.flows, name="Custom flow group", show=True)[0], - "Test", timeout_seconds=TEST_DURATION + 1) - print("Test passed !") + "Test", timeout_seconds=test_duration + 1) def test_remove_vnet_config(self, confgen, dpu, dataplane): + """ + Generate and remove configuration + We generate configuration on remove stage as well to avoid storing giant objects in memory. + """ # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG_SCALE) # confgen.generate() diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py index fb33ae1ae..82d73383d 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py +++ b/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py @@ -18,6 +18,8 @@ # Constants SWITCH_ID = 5 +# Simple, non-scaled configuration. +# See README.md for details. TEST_VNET_OUTBOUND_CONFIG = { "ENI_COUNT": 1, @@ -118,7 +120,8 @@ class TestSaiVnetOutbound: - def test_create_vnet_config(self, confgen, dpu, dataplane): + def test_vnet_inbound_simple_create(self, confgen, dpu): + """Generate and apply configuration""" # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) # confgen.generate() @@ -134,7 +137,8 @@ def test_create_vnet_config(self, confgen, dpu, dataplane): pprint(result) @pytest.mark.ptf - def test_run_packets_check(self, dpu, dataplane): + def test_vnet_inbound_simple_packet_modification(self, dpu, dataplane): + """Verify proper packet transformation.""" SRC_VM_IP = "10.1.1.10" OUTER_SMAC = "00:00:05:06:06:06" @@ -242,15 +246,37 @@ def test_run_packets_check(self, dpu, dataplane): verify_packet(dataplane, vxlan_exp_pkt, 0) @pytest.mark.snappi - def test_simple_vxlan_packet(self, dpu, dataplane): - dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG) + def test_vnet_inbound_simple_traffic_fixed_packets(self, dpu, dataplane): + """ + Verify same config with high-rate traffic. + packets_per_flow=10 means that each possible packet path will be verified using 10 packet. + NOTE: For BMv2 we keep here PPS limitation + """ + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG, packets_per_flow=10, pps_per_flow=10) dataplane.set_config() dataplane.start_traffic() - stu.wait_for(lambda: dh.check_flow_packets_metrics(dataplane, dataplane.flows[0], show=True)[0], "Test", timeout_seconds=10) - def test_remove_vnet_config(self, confgen, dpu, dataplane): + @pytest.mark.snappi + def test_vnet_inbound_simple_traffic_fixed_duration(self, dpu, dataplane): + """ + Test with the fixed traffic duration to send. + flow_duration sets the total duration of traffic. Number of packets is limited by PPS. + For the HW PPS may be omitted and then it will send traffic on a line rate. + NOTE: This test does not verify the correctness of the packets transformation. + """ + test_duration = 5 + dh.scale_vnet_outbound_flows(dataplane, TEST_VNET_OUTBOUND_CONFIG, + packets_per_flow=0, flow_duration=test_duration, pps_per_flow=5) + dataplane.set_config() + dataplane.start_traffic() + stu.wait_for(lambda: dh.check_flows_all_seconds_metrics(dataplane, dataplane.flows, + name="Custom flow group", show=True)[0], + "Test", timeout_seconds=test_duration + 1) + + def test_vnet_inbound_simple_remove(self, confgen, dpu): + """Verify configuration removal""" # confgen.mergeParams(TEST_VNET_OUTBOUND_CONFIG) # confgen.generate() diff --git a/test/test-cases/test_vector_example/test_vnet_inbound.py b/test/test-cases/test_vector_example/test_vnet_inbound.py deleted file mode 100644 index 47ba7a9a4..000000000 --- a/test/test-cases/test_vector_example/test_vnet_inbound.py +++ /dev/null @@ -1,18 +0,0 @@ -import json -from pathlib import Path - -current_file_dir = Path(__file__).parent - - -def test_vnet_inbound(dpu, dataplane): - with (current_file_dir / 'vnet_inbound_setup_commands.json').open(mode='r') as config_file: - vnet_inbound_setup_commands = json.load(config_file) - - result = [*dpu.process_commands(vnet_inbound_setup_commands)] - - vnet_inbound_cleanup_commands = [] - for command in reversed(vnet_inbound_setup_commands): - command['op'] = 'remove' - vnet_inbound_cleanup_commands.append(command) - - result = [*dpu.process_commands(vnet_inbound_cleanup_commands)] diff --git a/test/test-cases/test_vector_example/test_vnet_outbound.py b/test/test-cases/test_vector_example/test_vnet_outbound.py deleted file mode 100644 index 6ae1a64c3..000000000 --- a/test/test-cases/test_vector_example/test_vnet_outbound.py +++ /dev/null @@ -1,21 +0,0 @@ -import json -from pathlib import Path - -import pytest - -current_file_dir = Path(__file__).parent - - -@pytest.mark.parametrize('cfg_type', ['simple', 'scale']) -def test_vnet_outbound_simple(dpu, cfg_type): - with (current_file_dir / f'vnet_outbound_setup_commands_{cfg_type}.json').open(mode='r') as config_file: - setup_commands = json.load(config_file) - - result = [*dpu.process_commands(setup_commands)] - - cleanup_commands = [] - for command in reversed(setup_commands): - command['op'] = 'remove' - cleanup_commands.append(command) - - result = [*dpu.process_commands(cleanup_commands)] From 4481a6e6c394fe8d40e3fdb2825381d3621f9789 Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Mon, 17 Oct 2022 19:20:27 +0300 Subject: [PATCH 44/45] Submodule update and rename * Rename and update the SAI-Challenger submodule * Enabled additional tests based on the fixes in the SAI-Challenger. * Renamed test folder. Signed-off-by: Anton Putria --- .gitmodules | 8 +- dash-pipeline/Makefile | 4 +- .../Dockerfile.saichallenger-client | 2 +- test/SAI-Challenger | 1 + test/SAI-Challenger.OCP | 1 - test/docs/dash-test-sai-challenger.md | 6 +- .../saic}/README.md | 0 .../saic}/__init__.py | 0 .../saic}/conftest.py | 0 .../saic}/dash_helper/vnet2vnet_helper.py | 0 .../images/outbound_scenario_explained.svg | 0 .../vnet2vnet_outbound_traffic_scaling.svg | 0 .../saic}/pytest.ini | 0 .../saic}/run_vnet_tests.sh | 0 .../saic}/sai_dpu_client_server_ptf.json | 0 .../saic}/sai_dpu_client_server_snappi.json | 0 .../saic}/test_config_vnet_inbound.py | 0 .../saic}/test_config_vnet_outbound.py | 0 .../saic}/test_sai_vnet_inbound.py | 0 .../saic}/test_sai_vnet_outbound_scale.py | 0 .../saic}/test_sai_vnet_outbound_simple.py | 110 +++++++++--------- .../saic}/vnet_inbound_setup_commands.json | 0 .../vnet_outbound_setup_commands_scale.json | 0 .../vnet_outbound_setup_commands_simple.json | 0 24 files changed, 66 insertions(+), 66 deletions(-) create mode 160000 test/SAI-Challenger delete mode 160000 test/SAI-Challenger.OCP rename test/test-cases/{test_vector_example => scale/saic}/README.md (100%) rename test/test-cases/{test_vector_example => scale/saic}/__init__.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/conftest.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/dash_helper/vnet2vnet_helper.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/images/outbound_scenario_explained.svg (100%) rename test/test-cases/{test_vector_example => scale/saic}/images/vnet2vnet_outbound_traffic_scaling.svg (100%) rename test/test-cases/{test_vector_example => scale/saic}/pytest.ini (100%) rename test/test-cases/{test_vector_example => scale/saic}/run_vnet_tests.sh (100%) rename test/test-cases/{test_vector_example => scale/saic}/sai_dpu_client_server_ptf.json (100%) rename test/test-cases/{test_vector_example => scale/saic}/sai_dpu_client_server_snappi.json (100%) rename test/test-cases/{test_vector_example => scale/saic}/test_config_vnet_inbound.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/test_config_vnet_outbound.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/test_sai_vnet_inbound.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/test_sai_vnet_outbound_scale.py (100%) rename test/test-cases/{test_vector_example => scale/saic}/test_sai_vnet_outbound_simple.py (74%) rename test/test-cases/{test_vector_example => scale/saic}/vnet_inbound_setup_commands.json (100%) rename test/test-cases/{test_vector_example => scale/saic}/vnet_outbound_setup_commands_scale.json (100%) rename test/test-cases/{test_vector_example => scale/saic}/vnet_outbound_setup_commands_simple.json (100%) diff --git a/.gitmodules b/.gitmodules index 2e2092019..9fa8a0a63 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,10 +2,10 @@ path = dash-pipeline/SAI/SAI url = https://github.com/reshmaintel/SAI.git branch = dash-ptf-ci -[submodule "test/SAI-Challenger.OCP"] - path = test/SAI-Challenger.OCP - url = https://github.com/plvisiondevs/SAI-Challenger.OCP - branch = dash-testing +[submodule "test/SAI-Challenger"] + path = test/SAI-Challenger + url = https://github.com/opencomputeproject/SAI-Challenger + branch = multiple-api-support [submodule "dash-pipeline/cgyang"] path = dash-pipeline/cgyang url = https://github.com/mgheorghe/cgyang diff --git a/dash-pipeline/Makefile b/dash-pipeline/Makefile index ad866e9f5..fd0590b8a 100644 --- a/dash-pipeline/Makefile +++ b/dash-pipeline/Makefile @@ -520,7 +520,7 @@ undeploy-ixiac: # SAI-CHALLENGER TARGETS ############################### -SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger.OCP +SAI_CHALLENGER_PATH = $(PWD)/../test/SAI-Challenger CONTAINER_SAI_CHALLENGER_CLIENT_NAME = dash-saichallenger-client-$(USER) @@ -553,7 +553,7 @@ docker-publish-saichallenger-client: DOCKER_RUN_SAI_CHALLENGER_CLIENT=docker run \ -v $(SAI_CHALLENGER_PATH):/sai-challenger \ - -v $(SAI_CHALLENGER_PATH)/../test-cases/test_vector_example/:/sai-challenger/dash_tests \ + -v $(SAI_CHALLENGER_PATH)/../test-cases/scale/saic/:/sai-challenger/dash_tests \ -v $(PWD)/../:/dash \ --cap-add=NET_ADMIN \ --device /dev/net/tun:/dev/net/tun \ diff --git a/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client index 5230ca8c9..a59000064 100644 --- a/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client +++ b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client @@ -34,7 +34,7 @@ RUN python3 -m pip install -r /tests/requirements.txt && \ cd /SAI/test/ptf && \ python3 setup.py install && \ ln -s ${SAI_CHALLENGER_PATH} /usr/local/lib/python3.7/dist-packages/saichallenger && \ - ln -s ${DASH_PATH}/test/test-cases/test_vector_example ${SAI_CHALLENGER_PATH}/test_vector_example && \ + ln -s ${DASH_PATH}/test/test-cases/scale/saic ${SAI_CHALLENGER_PATH}/dash_tests && \ ln -s ${DASH_PATH}/dash-pipeline/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen CMD ["/usr/bin/supervisord"] diff --git a/test/SAI-Challenger b/test/SAI-Challenger new file mode 160000 index 000000000..e1f1d5bac --- /dev/null +++ b/test/SAI-Challenger @@ -0,0 +1 @@ +Subproject commit e1f1d5bac518f92dae4d0700931e65a280c7bb99 diff --git a/test/SAI-Challenger.OCP b/test/SAI-Challenger.OCP deleted file mode 160000 index a714c5b12..000000000 --- a/test/SAI-Challenger.OCP +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a714c5b12535e4dfd05dd07f3ccb48a9a2710438 diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index f927b8cd0..985ad8a2a 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -1,12 +1,12 @@ # General changes -* Added [SAI-Challenger](https://github.com/PLVision/SAI-Challenger.OCP) submodule by path: `DASH/test/SAI-Challenger.OCP`. +* Added [SAI-Challenger](https://github.com/opencomputeproject/SAI-Challenger.OCP) submodule by path: `DASH/test/SAI-Challenger`. * Added [saigen](https://github.com/mgheorghe/cgyang) submodule by path: `DASH/test/third-party/cgyang/saigen`. -* Added test cases for SAI-Challenger by path: `DASH/test/test-cases/test_vector_example` +* Added test cases for SAI-Challenger by path: `DASH/test/test-cases/scale/saic` # New make targets: **`docker-saichallenger-client`**: Build SAI-Challenger docker image and docker image based on SAI-Challenger client docker image with sai_thrift, saigen and DASH files. -**`run-saichallenger-client`**: Start Ixia-C and docker container `sc-client-thrift-run` from image built on `docker-saichallenger-client` target. SAI-Challenger tests (`DASH/test/SAI-Challenger.OCP/tests`) folder replaced by `DASH/test/test-cases/test_vector_example` folder inside of container. Bound mount volume with DASH folder. +**`run-saichallenger-client`**: Start Ixia-C and docker container `sc-client-thrift-run` from image built on `docker-saichallenger-client` target. To the original SAI-Challenger tests (`DASH/test/SAI-Challenger/tests`) folder a new folder `dash_tests` mounted from `DASH/test/test-cases/scale/saic` folder inside of container. Bound mount volume with DASH folder. **`kill-saichallenger-client`**: Stop Ixia-C and `sc-client-thrift-run` container. diff --git a/test/test-cases/test_vector_example/README.md b/test/test-cases/scale/saic/README.md similarity index 100% rename from test/test-cases/test_vector_example/README.md rename to test/test-cases/scale/saic/README.md diff --git a/test/test-cases/test_vector_example/__init__.py b/test/test-cases/scale/saic/__init__.py similarity index 100% rename from test/test-cases/test_vector_example/__init__.py rename to test/test-cases/scale/saic/__init__.py diff --git a/test/test-cases/test_vector_example/conftest.py b/test/test-cases/scale/saic/conftest.py similarity index 100% rename from test/test-cases/test_vector_example/conftest.py rename to test/test-cases/scale/saic/conftest.py diff --git a/test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py b/test/test-cases/scale/saic/dash_helper/vnet2vnet_helper.py similarity index 100% rename from test/test-cases/test_vector_example/dash_helper/vnet2vnet_helper.py rename to test/test-cases/scale/saic/dash_helper/vnet2vnet_helper.py diff --git a/test/test-cases/test_vector_example/images/outbound_scenario_explained.svg b/test/test-cases/scale/saic/images/outbound_scenario_explained.svg similarity index 100% rename from test/test-cases/test_vector_example/images/outbound_scenario_explained.svg rename to test/test-cases/scale/saic/images/outbound_scenario_explained.svg diff --git a/test/test-cases/test_vector_example/images/vnet2vnet_outbound_traffic_scaling.svg b/test/test-cases/scale/saic/images/vnet2vnet_outbound_traffic_scaling.svg similarity index 100% rename from test/test-cases/test_vector_example/images/vnet2vnet_outbound_traffic_scaling.svg rename to test/test-cases/scale/saic/images/vnet2vnet_outbound_traffic_scaling.svg diff --git a/test/test-cases/test_vector_example/pytest.ini b/test/test-cases/scale/saic/pytest.ini similarity index 100% rename from test/test-cases/test_vector_example/pytest.ini rename to test/test-cases/scale/saic/pytest.ini diff --git a/test/test-cases/test_vector_example/run_vnet_tests.sh b/test/test-cases/scale/saic/run_vnet_tests.sh similarity index 100% rename from test/test-cases/test_vector_example/run_vnet_tests.sh rename to test/test-cases/scale/saic/run_vnet_tests.sh diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json b/test/test-cases/scale/saic/sai_dpu_client_server_ptf.json similarity index 100% rename from test/test-cases/test_vector_example/sai_dpu_client_server_ptf.json rename to test/test-cases/scale/saic/sai_dpu_client_server_ptf.json diff --git a/test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json b/test/test-cases/scale/saic/sai_dpu_client_server_snappi.json similarity index 100% rename from test/test-cases/test_vector_example/sai_dpu_client_server_snappi.json rename to test/test-cases/scale/saic/sai_dpu_client_server_snappi.json diff --git a/test/test-cases/test_vector_example/test_config_vnet_inbound.py b/test/test-cases/scale/saic/test_config_vnet_inbound.py similarity index 100% rename from test/test-cases/test_vector_example/test_config_vnet_inbound.py rename to test/test-cases/scale/saic/test_config_vnet_inbound.py diff --git a/test/test-cases/test_vector_example/test_config_vnet_outbound.py b/test/test-cases/scale/saic/test_config_vnet_outbound.py similarity index 100% rename from test/test-cases/test_vector_example/test_config_vnet_outbound.py rename to test/test-cases/scale/saic/test_config_vnet_outbound.py diff --git a/test/test-cases/test_vector_example/test_sai_vnet_inbound.py b/test/test-cases/scale/saic/test_sai_vnet_inbound.py similarity index 100% rename from test/test-cases/test_vector_example/test_sai_vnet_inbound.py rename to test/test-cases/scale/saic/test_sai_vnet_inbound.py diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py b/test/test-cases/scale/saic/test_sai_vnet_outbound_scale.py similarity index 100% rename from test/test-cases/test_vector_example/test_sai_vnet_outbound_scale.py rename to test/test-cases/scale/saic/test_sai_vnet_outbound_scale.py diff --git a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py b/test/test-cases/scale/saic/test_sai_vnet_outbound_simple.py similarity index 74% rename from test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py rename to test/test-cases/scale/saic/test_sai_vnet_outbound_simple.py index 82d73383d..6cc1a1e74 100644 --- a/test/test-cases/test_vector_example/test_sai_vnet_outbound_simple.py +++ b/test/test-cases/scale/saic/test_sai_vnet_outbound_simple.py @@ -154,61 +154,61 @@ def test_vnet_inbound_simple_packet_modification(self, dpu, dataplane): DST_CA_MAC = TEST_VNET_OUTBOUND_CONFIG['DASH_OUTBOUND_CA_TO_PA']['ocpe']["OVERLAY_DMAC"] # # check VIP drop - # WRONG_VIP = "172.16.100.100" - # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", - # eth_src=ENI_MAC, - # ip_dst=DST_CA_IP, - # ip_src=SRC_VM_IP) - # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - # eth_src=OUTER_SMAC, - # ip_dst=WRONG_VIP, - # ip_src=SRC_VM_PA_IP, - # udp_sport=11638, - # with_udp_chksum=False, - # vxlan_vni=OUTBOUND_VNI, - # inner_frame=inner_pkt) - # print("\n\nSending packet with wrong vip...\n\n", vxlan_pkt.__repr__()) - # send_packet(dataplane, 0, vxlan_pkt) - # print("\nVerifying drop...") - # verify_no_other_packets(dataplane) - - # # check routing drop - # WRONG_DST_CA = "10.200.2.50" - # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", - # eth_src=ENI_MAC, - # ip_dst=WRONG_DST_CA, - # ip_src=SRC_VM_IP) - # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - # eth_src=OUTER_SMAC, - # ip_dst=VIP, - # ip_src=SRC_VM_PA_IP, - # udp_sport=11638, - # with_udp_chksum=False, - # vxlan_vni=OUTBOUND_VNI, - # inner_frame=inner_pkt) - # print("\nSending packet with wrong dst CA IP to verify routing drop...\n\n", vxlan_pkt.__repr__()) - # send_packet(dataplane, 0, vxlan_pkt) - # print("\nVerifying drop...") - # verify_no_other_packets(dataplane) - - # # check mapping drop - # WRONG_DST_CA = "10.1.211.211" - # inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", - # eth_src=ENI_MAC, - # ip_dst=WRONG_DST_CA, - # ip_src=SRC_VM_IP) - # vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, - # eth_src=OUTER_SMAC, - # ip_dst=VIP, - # ip_src=SRC_VM_PA_IP, - # udp_sport=11638, - # with_udp_chksum=False, - # vxlan_vni=OUTBOUND_VNI, - # inner_frame=inner_pkt) - # print("\nSending packet with wrong dst CA IP to verify mapping drop...\n\n", vxlan_pkt.__repr__()) - # send_packet(dataplane, 0, vxlan_pkt) - # print("\nVerifying drop...") - # verify_no_other_packets(dataplane) + WRONG_VIP = "172.16.100.100" + inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + eth_src=ENI_MAC, + ip_dst=DST_CA_IP, + ip_src=SRC_VM_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + eth_src=OUTER_SMAC, + ip_dst=WRONG_VIP, + ip_src=SRC_VM_PA_IP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=VNET_VNI, + inner_frame=inner_pkt) + print("\n\nSending packet with wrong vip...\n\n", vxlan_pkt.__repr__()) + send_packet(dataplane, 0, vxlan_pkt) + print("\nVerifying drop...") + verify_no_other_packets(dataplane) + + # check routing drop + WRONG_DST_CA = "10.200.2.50" + inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + eth_src=ENI_MAC, + ip_dst=WRONG_DST_CA, + ip_src=SRC_VM_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + eth_src=OUTER_SMAC, + ip_dst=VIP, + ip_src=SRC_VM_PA_IP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=VNET_VNI, + inner_frame=inner_pkt) + print("\nSending packet with wrong dst CA IP to verify routing drop...\n\n", vxlan_pkt.__repr__()) + send_packet(dataplane, 0, vxlan_pkt) + print("\nVerifying drop...") + verify_no_other_packets(dataplane) + + # check mapping drop + WRONG_DST_CA = "10.1.211.211" + inner_pkt = simple_udp_packet(eth_dst="02:02:02:02:02:02", + eth_src=ENI_MAC, + ip_dst=WRONG_DST_CA, + ip_src=SRC_VM_IP) + vxlan_pkt = simple_vxlan_packet(eth_dst=OUR_MAC, + eth_src=OUTER_SMAC, + ip_dst=VIP, + ip_src=SRC_VM_PA_IP, + udp_sport=11638, + with_udp_chksum=False, + vxlan_vni=VNET_VNI, + inner_frame=inner_pkt) + print("\nSending packet with wrong dst CA IP to verify mapping drop...\n\n", vxlan_pkt.__repr__()) + send_packet(dataplane, 0, vxlan_pkt) + print("\nVerifying drop...") + verify_no_other_packets(dataplane) # check forwarding inner_pkt = simple_udp_packet(eth_dst = "02:02:02:02:02:02", diff --git a/test/test-cases/test_vector_example/vnet_inbound_setup_commands.json b/test/test-cases/scale/saic/vnet_inbound_setup_commands.json similarity index 100% rename from test/test-cases/test_vector_example/vnet_inbound_setup_commands.json rename to test/test-cases/scale/saic/vnet_inbound_setup_commands.json diff --git a/test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json b/test/test-cases/scale/saic/vnet_outbound_setup_commands_scale.json similarity index 100% rename from test/test-cases/test_vector_example/vnet_outbound_setup_commands_scale.json rename to test/test-cases/scale/saic/vnet_outbound_setup_commands_scale.json diff --git a/test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json b/test/test-cases/scale/saic/vnet_outbound_setup_commands_simple.json similarity index 100% rename from test/test-cases/test_vector_example/vnet_outbound_setup_commands_simple.json rename to test/test-cases/scale/saic/vnet_outbound_setup_commands_simple.json From 6157fa219b6635e59c246fcd6cd2efeb409d1e0f Mon Sep 17 00:00:00 2001 From: Anton Putria Date: Fri, 4 Nov 2022 17:17:50 +0000 Subject: [PATCH 45/45] Replaced submodule with PyPI package. Upgraded Ixia-C version. Signed-off-by: Anton Putria --- .github/workflows/dash-saithrift-client-bldr-docker-acr.yml | 6 +++--- .gitmodules | 3 --- dash-pipeline/cgyang | 1 - .../dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env | 2 +- dash-pipeline/dockerfiles/Dockerfile.saichallenger-client | 4 ++-- test/docs/dash-test-sai-challenger.md | 1 - test/test-cases/scale/saic/conftest.py | 4 ++-- test/third-party/traffic_gen/deployment/.env | 4 ++-- 8 files changed, 10 insertions(+), 15 deletions(-) delete mode 160000 dash-pipeline/cgyang diff --git a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml index 00ce811fd..30b3244cf 100644 --- a/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml +++ b/.github/workflows/dash-saithrift-client-bldr-docker-acr.yml @@ -49,8 +49,8 @@ jobs: with: login-server: sonicdash.azurecr.io username: ${{ secrets.DASH_ACR_USERNAME }} - password: ${{ secrets.DASH_ACR_PASSWORD }} - - name: Build dash-saithrift-client-bldr image + password: ${{ secrets.DASH_ACR_PASSWORD }} + - name: Build dash-saithrift-client-bldr image run: DOCKER_FLAGS=$docker_fg_flags make docker-saithrift-client-bldr - name: Publish dash-saithrift-client-bldr docker image - run: make docker-publish-saichallenger-client + run: make docker-publish-saithrift-client-bldr diff --git a/.gitmodules b/.gitmodules index 9fa8a0a63..f10d24641 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,6 +6,3 @@ path = test/SAI-Challenger url = https://github.com/opencomputeproject/SAI-Challenger branch = multiple-api-support -[submodule "dash-pipeline/cgyang"] - path = dash-pipeline/cgyang - url = https://github.com/mgheorghe/cgyang diff --git a/dash-pipeline/cgyang b/dash-pipeline/cgyang deleted file mode 160000 index d1c65a161..000000000 --- a/dash-pipeline/cgyang +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d1c65a16128003e05f05f0c138c15260abedacdd diff --git a/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env index 4af6e29d5..3f8abcca8 100644 --- a/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env +++ b/dash-pipeline/dockerfiles/DOCKER_SAI_CHALLENGER_CLIENT_IMG.env @@ -1,4 +1,4 @@ # Define docker image repo/name:tag # Changing this will cause build/publish to occur in CI actions export DASH_ACR_REGISTRY=sonicdash.azurecr.io -export DOCKER_SAI_CHALLENGER_CLIENT_IMG=${DASH_ACR_REGISTRY}/dash-saichallenger-client:220920 +export DOCKER_SAI_CHALLENGER_CLIENT_IMG=${DASH_ACR_REGISTRY}/dash-saichallenger-client:221104 diff --git a/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client index a59000064..251ae9be1 100644 --- a/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client +++ b/dash-pipeline/dockerfiles/Dockerfile.saichallenger-client @@ -20,6 +20,7 @@ ADD SAI/rpc/saithrift-0.9.tar.gz / # Install the python libraries RUN python3 -m pip install -r /tests/requirements.txt && \ pip3 install scapy \ + dpugen>=0.0.3 \ pysubnettree \ macaddress \ munch && \ @@ -34,7 +35,6 @@ RUN python3 -m pip install -r /tests/requirements.txt && \ cd /SAI/test/ptf && \ python3 setup.py install && \ ln -s ${SAI_CHALLENGER_PATH} /usr/local/lib/python3.7/dist-packages/saichallenger && \ - ln -s ${DASH_PATH}/test/test-cases/scale/saic ${SAI_CHALLENGER_PATH}/dash_tests && \ - ln -s ${DASH_PATH}/dash-pipeline/cgyang/saigen /usr/local/lib/python3.7/dist-packages/saigen + ln -s ${DASH_PATH}/test/test-cases/scale/saic ${SAI_CHALLENGER_PATH}/dash_tests CMD ["/usr/bin/supervisord"] diff --git a/test/docs/dash-test-sai-challenger.md b/test/docs/dash-test-sai-challenger.md index 985ad8a2a..910d69e95 100644 --- a/test/docs/dash-test-sai-challenger.md +++ b/test/docs/dash-test-sai-challenger.md @@ -1,6 +1,5 @@ # General changes * Added [SAI-Challenger](https://github.com/opencomputeproject/SAI-Challenger.OCP) submodule by path: `DASH/test/SAI-Challenger`. -* Added [saigen](https://github.com/mgheorghe/cgyang) submodule by path: `DASH/test/third-party/cgyang/saigen`. * Added test cases for SAI-Challenger by path: `DASH/test/test-cases/scale/saic` # New make targets: diff --git a/test/test-cases/scale/saic/conftest.py b/test/test-cases/scale/saic/conftest.py index 8cb0a5260..42855c716 100644 --- a/test/test-cases/scale/saic/conftest.py +++ b/test/test-cases/scale/saic/conftest.py @@ -1,8 +1,8 @@ import logging import pytest -import saigen -from saigen.confbase import ConfBase +from dpugen import saigen +from dpugen.saigen.confbase import ConfBase # import sys # sys.path.insert(0, '/sai-challenger/common') # Needed for correct load_module diff --git a/test/third-party/traffic_gen/deployment/.env b/test/third-party/traffic_gen/deployment/.env index 8e3f592ed..a15c34c10 100644 --- a/test/third-party/traffic_gen/deployment/.env +++ b/test/third-party/traffic_gen/deployment/.env @@ -1,6 +1,6 @@ DOCKER_REGISTRY=ghcr.io/open-traffic-generator -CONTROLLER_VERSION=0.0.1-3423 -TRAFFIC_ENGINE_VERSION=1.6.0.17 +CONTROLLER_VERSION=0.0.1-3587 +TRAFFIC_ENGINE_VERSION=1.6.0.19 IFC1=veth1 IFC2=veth3 TCP_PORT_IFC1=5555