From c9cbd9fa09a2710673b5dfe8d075cb609bb1670a Mon Sep 17 00:00:00 2001 From: "Georgios P. Katsikas" <gkatsikas@ubitech.eu> Date: Sat, 22 Mar 2025 08:09:29 +0000 Subject: [PATCH] fix: refactoring of p4 fabric tna testing suite --- .../service/service_handlers/__init__.py | 4 +- .../{p4_l1 => p4_dummy_l1}/__init__.py | 0 .../p4_dummy_l1_service_handler.py} | 4 +- .../README.md | 40 ++-- .../__init__.py | 0 .../descriptors/sbi-rules-insert-acl.json | 0 .../descriptors/sbi-rules-insert-int-b1.json | 0 .../descriptors/sbi-rules-insert-int-b2.json | 0 .../descriptors/sbi-rules-insert-int-b3.json | 0 .../sbi-rules-insert-routing-corp.json | 0 .../sbi-rules-insert-routing-edge.json | 0 .../descriptors/sbi-rules-remove.json | 0 .../descriptors/topology.json | 0 .../p4src/README.md | 0 .../p4src/_pp.p4 | 0 .../p4src/bmv2.json | 0 .../p4src/p4info.txt | 0 .../run_test_01_bootstrap.sh | 2 +- ...n_test_02a_sbi_provision_int_l2_l3_acl.sh} | 2 +- ..._test_02b_sbi_deprovision_int_l2_l3_acl.sh | 17 ++ .../run_test_07_cleanup.sh} | 2 +- .../run_test_08_purge.sh} | 2 +- .../setup.sh | 4 +- .../test_functional_sbi_rules_deprovision.py | 2 +- .../test_functional_sbi_rules_provision.py | 2 +- .../tests-setup}/test_functional_bootstrap.py | 2 +- .../tests-setup}/test_functional_cleanup.py | 5 +- .../tests-setup/test_functional_purge.py | 81 +++++++++ .../topology/README.md | 0 .../topology/p4-switch-conf-common.sh | 0 .../topology/p4-switch-setup.sh | 0 .../topology/p4-switch-tear-down.sh | 0 ...witch-three-port-chassis-config-phy.pb.txt | 0 .../topology/run-stratum.sh | 0 src/tests/p4-int-routing-acl/test_common.py | 116 ------------ src/tests/tools/test_tools_p4.py | 172 ++++++++++++++++++ 36 files changed, 309 insertions(+), 148 deletions(-) rename src/service/service/service_handlers/{p4_l1 => p4_dummy_l1}/__init__.py (100%) rename src/service/service/service_handlers/{p4_l1/p4_l1_service_handler.py => p4_dummy_l1/p4_dummy_l1_service_handler.py} (99%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/README.md (73%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/__init__.py (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-acl.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-int-b1.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-int-b2.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-int-b3.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-routing-corp.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-insert-routing-edge.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/sbi-rules-remove.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/descriptors/topology.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/README.md (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/_pp.p4 (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/bmv2.json (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/p4src/p4info.txt (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/run_test_01_bootstrap.sh (89%) rename src/tests/{p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh => p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh} (86%) create mode 100755 src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh rename src/tests/{p4-int-routing-acl/run_test_02_sbi_rules_provision.sh => p4-fabric-tna/run_test_07_cleanup.sh} (87%) rename src/tests/{p4-int-routing-acl/run_test_06_cleanup.sh => p4-fabric-tna/run_test_08_purge.sh} (88%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/setup.sh (80%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-sbi}/test_functional_sbi_rules_deprovision.py (99%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-sbi}/test_functional_sbi_rules_provision.py (99%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-setup}/test_functional_bootstrap.py (98%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna/tests-setup}/test_functional_cleanup.py (94%) create mode 100644 src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/README.md (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-conf-common.sh (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-setup.sh (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-tear-down.sh (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/p4-switch-three-port-chassis-config-phy.pb.txt (100%) rename src/tests/{p4-int-routing-acl => p4-fabric-tna}/topology/run-stratum.sh (100%) delete mode 100644 src/tests/p4-int-routing-acl/test_common.py create mode 100644 src/tests/tools/test_tools_p4.py diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py index ccf821b2f..bddc8ee6e 100644 --- a/src/service/service/service_handlers/__init__.py +++ b/src/service/service/service_handlers/__init__.py @@ -25,7 +25,7 @@ from .l3nm_ietf_actn.L3NMIetfActnServiceHandler import L3NMIetfActnServiceHandle from .l3nm_nce.L3NMNCEServiceHandler import L3NMNCEServiceHandler from .l3slice_ietfslice.L3SliceIETFSliceServiceHandler import L3NMSliceIETFSliceServiceHandler from .microwave.MicrowaveServiceHandler import MicrowaveServiceHandler -from .p4_l1.p4_l1_service_handler import P4L1ServiceHandler +from .p4_dummy_l1.p4_dummy_l1_service_handler import P4DummyL1ServiceHandler from .tapi_tapi.TapiServiceHandler import TapiServiceHandler from .tapi_xr.TapiXrServiceHandler import TapiXrServiceHandler from .e2e_orch.E2EOrchestratorServiceHandler import E2EOrchestratorServiceHandler @@ -105,7 +105,7 @@ SERVICE_HANDLERS = [ FilterFieldEnum.DEVICE_DRIVER : [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY, DeviceDriverEnum.DEVICEDRIVER_ONF_TR_532], } ]), - (P4L1ServiceHandler, [ + (P4DummyL1ServiceHandler, [ { FilterFieldEnum.SERVICE_TYPE: ServiceTypeEnum.SERVICETYPE_L1NM, FilterFieldEnum.DEVICE_DRIVER: DeviceDriverEnum.DEVICEDRIVER_P4, diff --git a/src/service/service/service_handlers/p4_l1/__init__.py b/src/service/service/service_handlers/p4_dummy_l1/__init__.py similarity index 100% rename from src/service/service/service_handlers/p4_l1/__init__.py rename to src/service/service/service_handlers/p4_dummy_l1/__init__.py diff --git a/src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py b/src/service/service/service_handlers/p4_dummy_l1/p4_dummy_l1_service_handler.py similarity index 99% rename from src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py rename to src/service/service/service_handlers/p4_dummy_l1/p4_dummy_l1_service_handler.py index b1ff9c600..6e9141caf 100644 --- a/src/service/service/service_handlers/p4_l1/p4_l1_service_handler.py +++ b/src/service/service/service_handlers/p4_dummy_l1/p4_dummy_l1_service_handler.py @@ -29,7 +29,7 @@ from service.service.task_scheduler.TaskExecutor import TaskExecutor LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_l1'}) +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'p4_dummy_l1'}) def create_rule_set(endpoint_a, endpoint_b): return json_config_rule_set( @@ -83,7 +83,7 @@ def find_names(uuid_a, uuid_b, device_endpoints): return (endpoint_a, endpoint_b) -class P4L1ServiceHandler(_ServiceHandler): +class P4DummyL1ServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called self, service : Service, task_executor : TaskExecutor, **settings ) -> None: diff --git a/src/tests/p4-int-routing-acl/README.md b/src/tests/p4-fabric-tna/README.md similarity index 73% rename from src/tests/p4-int-routing-acl/README.md rename to src/tests/p4-fabric-tna/README.md index fa935e1b2..fc49276a9 100644 --- a/src/tests/p4-int-routing-acl/README.md +++ b/src/tests/p4-fabric-tna/README.md @@ -1,6 +1,7 @@ # Tests for P4 routing, ACL, and In-Band Network Telemetry functions -This directory contains the necessary scripts and configurations to run tests atop a Stratum-based P4 whitebox that performs a set of network functions, including routing, access control list (ACL), and In-Band Network Telemetry (INT). +This directory contains the necessary scripts and configurations to run tests atop a Stratum-based P4 whitebox that performs a set of network functions, including forwarding (L2), routing (L3), L3/L4 access control list (ACL), and In-Band Network Telemetry (INT). +The P4 data plane is based on ONF's SD-Fabric implementation, titled [fabric-tna](https://github.com/stratum/fabric-tna) ## Prerequisites @@ -16,6 +17,7 @@ pip3 install grpcio-tools ``` The versions used for this test are: + - `protobuf` 3.20.3 - `grpclib` 0.4.4 - `grpcio` 1.47.5 @@ -29,11 +31,11 @@ First we copy it to /usr/local/bin/: ``` Then, we include this path to the PYTHONPATH: + ```shell export PYTHONPATH="${PYTHONPATH}:/usr/local/bin/protoc-gen-grpclib_python" ``` - You need to build and deploy a software-based Stratum switch, before being able to use TFS to control it. To do so, follow the instructions in the `./topology` folder. @@ -41,7 +43,7 @@ To do so, follow the instructions in the `./topology` folder. To conduct this test, follow the steps below. -### TFS re-deploy +### Deploy TFS ```shell cd ~/tfs-ctrl/ @@ -67,7 +69,7 @@ The `./setup.sh` script copies from this directory. If you need to change the P4 ## Tests -The following tests are implemented. +A set of tests is implemented, each focusing on different aspects of TFS. For each of these tests, an auxiliary bash script allows to run it with less typing. | Test | Bash Runner | Purpose | @@ -80,7 +82,7 @@ For each of these tests, an auxiliary bash script allows to run it with less typ Each of the tests above is described in detail below. -### Step 1: Copy the necessary P4 artifacts into the TFS SBI service pod +### Step 0: Copy the necessary P4 artifacts into the TFS SBI service pod The setup script copies the necessary artifacts to the SBI service pod. It should be run just once, after a fresh install of TFS. @@ -89,34 +91,33 @@ If you `deploy/all.sh` again, you need to repeat this step. ```shell cd ~/tfs-ctrl/ source my_deploy.sh && source tfs_runtime_env_vars.sh -bash src/tests/p4-int-routing-acl/setup.sh +bash src/tests/p4-fabric-tna/setup.sh ``` -### Step 2: Bootstrap topology +### Step 1: Bootstrap topology The bootstrap script registers the context, topology, links, and devices to TFS. ```shell cd ~/tfs-ctrl/ -bash src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh +bash src/tests/p4-fabric-tna/run_test_01_bootstrap.sh ``` -### Step 3: Provision rules via the SBI API +### Step 2: Manage L2, L3, ACL, and INT via the SBI API (rules) -Implement routing, ACL, and INT functions by installing P4 rules to the Stratum switch via the TFS SBI API. +Implement forwarding, routing, ACL, and INT network functions by installing P4 rules to the Stratum switch via the TFS SBI API. +In this test, these rules are installed in batches, as the switch cannot digest all these rules at once. ```shell cd ~/tfs-ctrl/ -bash src/tests/p4-int-routing-acl/run_test_02_rules_provision.sh +bash src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh ``` -### Step 4: Deprovision rules via the SBI API - -Deprovision the routing, ACL, and INT network functions by removing the previously installed P4 rules (via the TFS SBI API) from the Stratum switch. +Deprovision forwarding, routing, ACL, and INT network functions by removing the previously installed P4 rules (via the TFS SBI API) from the Stratum switch. ```shell cd ~/tfs-ctrl/ -bash src/tests/p4-int-routing-acl/run_test_03_rules_deprovision.sh +bash src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh ``` ### Step 4: Deprovision topology @@ -125,5 +126,12 @@ Delete all the objects (context, topology, links, devices) from TFS: ```shell cd ~/tfs-ctrl/ -bash src/tests/p4-int-routing-acl/run_test_04_cleanup.sh +bash src/tests/p4-fabric-tna/run_test_07_cleanup.sh +``` + +Alternatively, a purge test is implemented; this test removes services, links, devices, topology, and context in this order. + +```shell +cd ~/tfs-ctrl/ +bash src/tests/p4-fabric-tna/run_test_08_purge.sh ``` diff --git a/src/tests/p4-int-routing-acl/__init__.py b/src/tests/p4-fabric-tna/__init__.py similarity index 100% rename from src/tests/p4-int-routing-acl/__init__.py rename to src/tests/p4-fabric-tna/__init__.py diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-acl.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-acl.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-acl.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-acl.json diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b1.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b1.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b1.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b1.json diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b2.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b2.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b2.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b2.json diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b3.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b3.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-int-b3.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-int-b3.json diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-corp.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-corp.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-corp.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-corp.json diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-edge.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-edge.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-insert-routing-edge.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-insert-routing-edge.json diff --git a/src/tests/p4-int-routing-acl/descriptors/sbi-rules-remove.json b/src/tests/p4-fabric-tna/descriptors/sbi-rules-remove.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/sbi-rules-remove.json rename to src/tests/p4-fabric-tna/descriptors/sbi-rules-remove.json diff --git a/src/tests/p4-int-routing-acl/descriptors/topology.json b/src/tests/p4-fabric-tna/descriptors/topology.json similarity index 100% rename from src/tests/p4-int-routing-acl/descriptors/topology.json rename to src/tests/p4-fabric-tna/descriptors/topology.json diff --git a/src/tests/p4-int-routing-acl/p4src/README.md b/src/tests/p4-fabric-tna/p4src/README.md similarity index 100% rename from src/tests/p4-int-routing-acl/p4src/README.md rename to src/tests/p4-fabric-tna/p4src/README.md diff --git a/src/tests/p4-int-routing-acl/p4src/_pp.p4 b/src/tests/p4-fabric-tna/p4src/_pp.p4 similarity index 100% rename from src/tests/p4-int-routing-acl/p4src/_pp.p4 rename to src/tests/p4-fabric-tna/p4src/_pp.p4 diff --git a/src/tests/p4-int-routing-acl/p4src/bmv2.json b/src/tests/p4-fabric-tna/p4src/bmv2.json similarity index 100% rename from src/tests/p4-int-routing-acl/p4src/bmv2.json rename to src/tests/p4-fabric-tna/p4src/bmv2.json diff --git a/src/tests/p4-int-routing-acl/p4src/p4info.txt b/src/tests/p4-fabric-tna/p4src/p4info.txt similarity index 100% rename from src/tests/p4-int-routing-acl/p4src/p4info.txt rename to src/tests/p4-fabric-tna/p4src/p4info.txt diff --git a/src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh b/src/tests/p4-fabric-tna/run_test_01_bootstrap.sh similarity index 89% rename from src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh rename to src/tests/p4-fabric-tna/run_test_01_bootstrap.sh index 76469ca55..81d87476e 100755 --- a/src/tests/p4-int-routing-acl/run_test_01_bootstrap.sh +++ b/src/tests/p4-fabric-tna/run_test_01_bootstrap.sh @@ -18,4 +18,4 @@ # - tfs_runtime_env_vars.sh source tfs_runtime_env_vars.sh -python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_bootstrap.py +python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py diff --git a/src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh b/src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh similarity index 86% rename from src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh rename to src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh index 4032c01df..a3ab51c22 100755 --- a/src/tests/p4-int-routing-acl/run_test_03_sbi_rules_deprovision.sh +++ b/src/tests/p4-fabric-tna/run_test_02a_sbi_provision_int_l2_l3_acl.sh @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py +python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py diff --git a/src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh b/src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh new file mode 100755 index 000000000..49a686638 --- /dev/null +++ b/src/tests/p4-fabric-tna/run_test_02b_sbi_deprovision_int_l2_l3_acl.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source tfs_runtime_env_vars.sh +python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py diff --git a/src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh b/src/tests/p4-fabric-tna/run_test_07_cleanup.sh similarity index 87% rename from src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh rename to src/tests/p4-fabric-tna/run_test_07_cleanup.sh index 7c485d401..c7b829168 100755 --- a/src/tests/p4-int-routing-acl/run_test_02_sbi_rules_provision.sh +++ b/src/tests/p4-fabric-tna/run_test_07_cleanup.sh @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py +python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py diff --git a/src/tests/p4-int-routing-acl/run_test_06_cleanup.sh b/src/tests/p4-fabric-tna/run_test_08_purge.sh similarity index 88% rename from src/tests/p4-int-routing-acl/run_test_06_cleanup.sh rename to src/tests/p4-fabric-tna/run_test_08_purge.sh index 917a2af2d..9aef079f1 100755 --- a/src/tests/p4-int-routing-acl/run_test_06_cleanup.sh +++ b/src/tests/p4-fabric-tna/run_test_08_purge.sh @@ -14,4 +14,4 @@ # limitations under the License. source tfs_runtime_env_vars.sh -python3 -m pytest --verbose src/tests/p4-int-routing-acl/test_functional_cleanup.py +python3 -m pytest --verbose src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py diff --git a/src/tests/p4-int-routing-acl/setup.sh b/src/tests/p4-fabric-tna/setup.sh similarity index 80% rename from src/tests/p4-int-routing-acl/setup.sh rename to src/tests/p4-fabric-tna/setup.sh index c77164276..9418ac3d7 100755 --- a/src/tests/p4-int-routing-acl/setup.sh +++ b/src/tests/p4-fabric-tna/setup.sh @@ -18,5 +18,5 @@ export POD_NAME=$(kubectl get pods -n=tfs | grep device | awk '{print $1}') kubectl exec ${POD_NAME} -n=tfs -c=server -- mkdir -p /root/p4 -kubectl cp src/tests/p4-int-routing-acl/p4src/p4info.txt tfs/${POD_NAME}:/root/p4 -c=server -kubectl cp src/tests/p4-int-routing-acl/p4src/bmv2.json tfs/${POD_NAME}:/root/p4 -c=server +kubectl cp src/tests/p4-fabric-tna/p4src/p4info.txt tfs/${POD_NAME}:/root/p4 -c=server +kubectl cp src/tests/p4-fabric-tna/p4src/bmv2.json tfs/${POD_NAME}:/root/p4 -c=server diff --git a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py similarity index 99% rename from src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py rename to src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py index 2d54ae908..6d5f7dfd2 100644 --- a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_deprovision.py +++ b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_deprovision.py @@ -18,7 +18,7 @@ from common.tools.grpc.Tools import grpc_message_to_json_string from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from tests.Fixtures import context_client, device_client # pylint: disable=unused-import -from test_common import * +from tests.tools.test_tools_p4 import * LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) diff --git a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py similarity index 99% rename from src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py rename to src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py index 86a82d212..49d9aba4d 100644 --- a/src/tests/p4-int-routing-acl/test_functional_sbi_rules_provision.py +++ b/src/tests/p4-fabric-tna/tests-sbi/test_functional_sbi_rules_provision.py @@ -18,7 +18,7 @@ from common.tools.grpc.Tools import grpc_message_to_json_string from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from tests.Fixtures import context_client, device_client # pylint: disable=unused-import -from test_common import * +from tests.tools.test_tools_p4 import * LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) diff --git a/src/tests/p4-int-routing-acl/test_functional_bootstrap.py b/src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py similarity index 98% rename from src/tests/p4-int-routing-acl/test_functional_bootstrap.py rename to src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py index b5b72cc33..2f9130ad0 100644 --- a/src/tests/p4-int-routing-acl/test_functional_bootstrap.py +++ b/src/tests/p4-fabric-tna/tests-setup/test_functional_bootstrap.py @@ -19,7 +19,7 @@ from common.tools.descriptor.Loader import DescriptorLoader, \ from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from tests.Fixtures import context_client, device_client # pylint: disable=unused-import -from test_common import * +from tests.tools.test_tools_p4 import * LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) diff --git a/src/tests/p4-int-routing-acl/test_functional_cleanup.py b/src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py similarity index 94% rename from src/tests/p4-int-routing-acl/test_functional_cleanup.py rename to src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py index fc29be24d..4d98c9e05 100644 --- a/src/tests/p4-int-routing-acl/test_functional_cleanup.py +++ b/src/tests/p4-fabric-tna/tests-setup/test_functional_cleanup.py @@ -12,13 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, os -from common.Constants import DEFAULT_CONTEXT_NAME +import logging from common.tools.descriptor.Loader import DescriptorLoader, validate_empty_scenario from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from tests.Fixtures import context_client, device_client # pylint: disable=unused-import -from test_common import * +from tests.tools.test_tools_p4 import * LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) diff --git a/src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py b/src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py new file mode 100644 index 000000000..ba37fbd89 --- /dev/null +++ b/src/tests/p4-fabric-tna/tests-setup/test_functional_purge.py @@ -0,0 +1,81 @@ +# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +from common.proto.context_pb2 import ServiceId, DeviceId, LinkId, ServiceStatusEnum, ServiceTypeEnum +from common.tools.grpc.Tools import grpc_message_to_json_string +from common.tools.object_factory.Service import json_service_id +from context.client.ContextClient import ContextClient +from device.client.DeviceClient import DeviceClient +from service.client.ServiceClient import ServiceClient +from tests.Fixtures import context_client, device_client, service_client # pylint: disable=unused-import +from tests.tools.test_tools_p4 import * + +LOGGER = logging.getLogger(__name__) +LOGGER.setLevel(logging.DEBUG) + +def test_clean_services( + context_client : ContextClient, # pylint: disable=redefined-outer-name + service_client : ServiceClient # pylint: disable=redefined-outer-name +) -> None: + response = context_client.ListServices(ADMIN_CONTEXT_ID) + LOGGER.warning('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) + + for service in response.services: + service_id = service.service_id + assert service_id + + service_uuid = service_id.service_uuid.uuid + context_uuid = service_id.context_id.context_uuid.uuid + assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE + assert service.service_type == ServiceTypeEnum.SERVICETYPE_INT + + # Delete service + service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid)))) + +def test_clean_links( + context_client : ContextClient, # pylint: disable=redefined-outer-name +) -> None: + response = context_client.ListLinks(ADMIN_CONTEXT_ID) + + for link in response.links: + link_id = link.link_id + + # Delete link + context_client.RemoveLink(LinkId(**link_id)) + +def test_clean_devices( + context_client : ContextClient, # pylint: disable=redefined-outer-name + device_client : DeviceClient # pylint: disable=redefined-outer-name +) -> None: + response = context_client.ListDevices(ADMIN_CONTEXT_ID) + LOGGER.warning('Devices[{:d}] = {:s}'.format(len(response.devices), grpc_message_to_json_string(response))) + + for device in response.devices: + device_id = device.device_id + + # Delete device + device_client.DeleteDevice(DeviceId(**device_id)) + +def test_clean_context( + context_client : ContextClient # pylint: disable=redefined-outer-name +) -> None: + # Verify the scenario has no services/slices + response = context_client.ListTopologies(ADMIN_CONTEXT_ID) + + for topology in response.topologies: + topology_id = topology.topology_id + response = context_client.RemoveTopology(topology_id) + + response = context_client.RemoveContext(ADMIN_CONTEXT_ID) diff --git a/src/tests/p4-int-routing-acl/topology/README.md b/src/tests/p4-fabric-tna/topology/README.md similarity index 100% rename from src/tests/p4-int-routing-acl/topology/README.md rename to src/tests/p4-fabric-tna/topology/README.md diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-conf-common.sh b/src/tests/p4-fabric-tna/topology/p4-switch-conf-common.sh similarity index 100% rename from src/tests/p4-int-routing-acl/topology/p4-switch-conf-common.sh rename to src/tests/p4-fabric-tna/topology/p4-switch-conf-common.sh diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-setup.sh b/src/tests/p4-fabric-tna/topology/p4-switch-setup.sh similarity index 100% rename from src/tests/p4-int-routing-acl/topology/p4-switch-setup.sh rename to src/tests/p4-fabric-tna/topology/p4-switch-setup.sh diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-tear-down.sh b/src/tests/p4-fabric-tna/topology/p4-switch-tear-down.sh similarity index 100% rename from src/tests/p4-int-routing-acl/topology/p4-switch-tear-down.sh rename to src/tests/p4-fabric-tna/topology/p4-switch-tear-down.sh diff --git a/src/tests/p4-int-routing-acl/topology/p4-switch-three-port-chassis-config-phy.pb.txt b/src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt similarity index 100% rename from src/tests/p4-int-routing-acl/topology/p4-switch-three-port-chassis-config-phy.pb.txt rename to src/tests/p4-fabric-tna/topology/p4-switch-three-port-chassis-config-phy.pb.txt diff --git a/src/tests/p4-int-routing-acl/topology/run-stratum.sh b/src/tests/p4-fabric-tna/topology/run-stratum.sh similarity index 100% rename from src/tests/p4-int-routing-acl/topology/run-stratum.sh rename to src/tests/p4-fabric-tna/topology/run-stratum.sh diff --git a/src/tests/p4-int-routing-acl/test_common.py b/src/tests/p4-int-routing-acl/test_common.py deleted file mode 100644 index f2d00f1dc..000000000 --- a/src/tests/p4-int-routing-acl/test_common.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum -from common.tools.object_factory.Context import json_context_id - -# Context info -CONTEXT_NAME_P4 = DEFAULT_CONTEXT_NAME -ADMIN_CONTEXT_ID = ContextId(**json_context_id(CONTEXT_NAME_P4)) - -# Device and rule cardinality variables -DEV_NB = 4 -CONNECTION_RULES = 3 -ENDPOINT_RULES = 3 -DATAPLANE_RULES_NB_INT_B1 = 5 -DATAPLANE_RULES_NB_INT_B2 = 6 -DATAPLANE_RULES_NB_INT_B3 = 8 -DATAPLANE_RULES_NB_RT_EDGE = 7 -DATAPLANE_RULES_NB_RT_CORP = 7 -DATAPLANE_RULES_NB_ACL = 1 -DATAPLANE_RULES_NB_TOT = \ - DATAPLANE_RULES_NB_INT_B1 +\ - DATAPLANE_RULES_NB_INT_B2 +\ - DATAPLANE_RULES_NB_INT_B3 +\ - DATAPLANE_RULES_NB_RT_EDGE +\ - DATAPLANE_RULES_NB_RT_CORP +\ - DATAPLANE_RULES_NB_ACL - -# Service-related variables -SVC_NB = 1 -NO_SERVICES = 0 -NO_SLICES = 0 - -# Topology descriptor -DESC_TOPO = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'topology.json' -) - -# SBI rule insertion descriptors -# The switch cannot digest all rules at once, hence we insert in batches -DESC_FILE_RULES_INSERT_INT_B1 = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-insert-int-b1.json' -) -DESC_FILE_RULES_INSERT_INT_B2 = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-insert-int-b2.json' -) -DESC_FILE_RULES_INSERT_INT_B3 = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-insert-int-b3.json' -) -DESC_FILE_RULES_INSERT_ROUTING_EDGE = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-insert-routing-edge.json' -) -DESC_FILE_RULES_INSERT_ROUTING_CORP = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-insert-routing-corp.json' -) -DESC_FILE_RULES_INSERT_ACL = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-insert-acl.json' -) - -# SBI rule deletion descriptor -DESC_FILE_RULES_DELETE_ALL = os.path.join( - os.path.dirname( - os.path.abspath(__file__) - ), - 'descriptors', 'sbi-rules-remove.json' -) - -def verify_number_of_rules(devices, desired_rules_nb): - # Iterate all devices - for device in devices: - # Skip non-P4 devices - if device.device_type != "p4-switch": continue - - # We want the device to be active - assert \ - device.device_operational_status == DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED - - # Get the configuration rules of this device - config_rules = device.device_config.config_rules - - # Expected rule cardinality - assert len(config_rules) == desired_rules_nb diff --git a/src/tests/tools/test_tools_p4.py b/src/tests/tools/test_tools_p4.py new file mode 100644 index 000000000..4557fef61 --- /dev/null +++ b/src/tests/tools/test_tools_p4.py @@ -0,0 +1,172 @@ +# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from common.Constants import DEFAULT_CONTEXT_NAME +from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum,\ + DeviceDriverEnum, ServiceTypeEnum, ServiceStatusEnum +from common.tools.object_factory.Context import json_context_id + +# Context info +CONTEXT_NAME_P4 = DEFAULT_CONTEXT_NAME +ADMIN_CONTEXT_ID = ContextId(**json_context_id(CONTEXT_NAME_P4)) + +# Device and rule cardinality variables +DEV_NB = 4 +P4_DEV_NB = 1 +CONNECTION_RULES = 3 +ENDPOINT_RULES = 3 +INT_RULES = 19 +L2_RULES = 8 +L3_RULES = 8 +ACL_RULES = 1 + +DATAPLANE_RULES_NB_INT_B1 = 5 +DATAPLANE_RULES_NB_INT_B2 = 6 +DATAPLANE_RULES_NB_INT_B3 = 8 +DATAPLANE_RULES_NB_RT_EDGE = 7 +DATAPLANE_RULES_NB_RT_CORP = 7 +DATAPLANE_RULES_NB_ACL = 1 +DATAPLANE_RULES_NB_TOT = \ + DATAPLANE_RULES_NB_INT_B1 +\ + DATAPLANE_RULES_NB_INT_B2 +\ + DATAPLANE_RULES_NB_INT_B3 +\ + DATAPLANE_RULES_NB_RT_EDGE +\ + DATAPLANE_RULES_NB_RT_CORP +\ + DATAPLANE_RULES_NB_ACL + +# Service-related variables +SVC_NB = 1 +NO_SERVICES = 0 +NO_SLICES = 0 + +TEST_PATH = os.path.join( + os.path.dirname(os.path.dirname( + os.path.abspath(__file__) + )) + '/p4-fabric-tna/descriptors') +assert os.path.exists(TEST_PATH), "Invalid path to P4 SD-Fabric tests" + +# Topology descriptor +DESC_TOPO = os.path.join(TEST_PATH, 'topology.json') +assert os.path.exists(DESC_TOPO), "Invalid path to the SD-Fabric topology descriptor" + +# SBI descriptors +# The switch cannot digest all rules at once, hence we insert in batches +DESC_FILE_RULES_INSERT_INT_B1 = os.path.join(TEST_PATH, 'sbi-rules-insert-int-b1.json') +assert os.path.exists(DESC_FILE_RULES_INSERT_INT_B1),\ + "Invalid path to the SD-Fabric INT SBI descriptor (batch #1)" + +DESC_FILE_RULES_INSERT_INT_B2 = os.path.join(TEST_PATH, 'sbi-rules-insert-int-b2.json') +assert os.path.exists(DESC_FILE_RULES_INSERT_INT_B2),\ + "Invalid path to the SD-Fabric INT SBI descriptor (batch #2)" + +DESC_FILE_RULES_INSERT_INT_B3 = os.path.join(TEST_PATH, 'sbi-rules-insert-int-b3.json') +assert os.path.exists(DESC_FILE_RULES_INSERT_INT_B3),\ + "Invalid path to the SD-Fabric INT SBI descriptor (batch #3)" + +DESC_FILE_RULES_INSERT_ROUTING_EDGE = os.path.join(TEST_PATH, 'sbi-rules-insert-routing-edge.json') +assert os.path.exists(DESC_FILE_RULES_INSERT_ROUTING_EDGE),\ + "Invalid path to the SD-Fabric routing SBI descriptor (domain1-side)" + +DESC_FILE_RULES_INSERT_ROUTING_CORP = os.path.join(TEST_PATH, 'sbi-rules-insert-routing-corp.json') +assert os.path.exists(DESC_FILE_RULES_INSERT_ROUTING_CORP),\ + "Invalid path to the SD-Fabric routing SBI descriptor (domain2-side)" + +DESC_FILE_RULES_INSERT_ACL = os.path.join(TEST_PATH, 'sbi-rules-insert-acl.json') +assert os.path.exists(DESC_FILE_RULES_INSERT_ACL),\ + "Invalid path to the SD-Fabric ACL SBI descriptor" + +DESC_FILE_RULES_DELETE_ALL = os.path.join(TEST_PATH, 'sbi-rules-remove.json') +assert os.path.exists(DESC_FILE_RULES_DELETE_ALL),\ + "Invalid path to the SD-Fabric rule removal SBI descriptor" + +# Service descriptors +DESC_FILE_SERVICE_CREATE_INT = os.path.join(TEST_PATH, 'service-create-int.json') +assert os.path.exists(DESC_FILE_SERVICE_CREATE_INT),\ + "Invalid path to the SD-Fabric INT service descriptor" + +DESC_FILE_SERVICE_CREATE_L2 = os.path.join(TEST_PATH, 'service-create-l2.json') +assert os.path.exists(DESC_FILE_SERVICE_CREATE_L2),\ + "Invalid path to the SD-Fabric L2 service descriptor" + +DESC_FILE_SERVICE_CREATE_L3 = os.path.join(TEST_PATH, 'service-create-l3.json') +assert os.path.exists(DESC_FILE_SERVICE_CREATE_L3),\ + "Invalid path to the SD-Fabric L3 service descriptor" + +DESC_FILE_SERVICE_CREATE_ACL = os.path.join(TEST_PATH, 'service-create-acl.json') +assert os.path.exists(DESC_FILE_SERVICE_CREATE_ACL),\ + "Invalid path to the SD-Fabric ACL service descriptor" + +def identify_number_of_p4_devices(devices) -> int: + p4_dev_no = 0 + + # Iterate all devices + for device in devices: + # Skip non-P4 devices + if not DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: continue + + p4_dev_no += 1 + + return p4_dev_no + +def get_number_of_rules(devices) -> int: + total_rules_no = 0 + + # Iterate all devices + for device in devices: + # Skip non-P4 devices + if not DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: continue + + # We want the device to be active + assert device.device_operational_status == \ + DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + + # Get the configuration rules of this device + config_rules = device.device_config.config_rules + + # Expected rule cardinality + total_rules_no += len(config_rules) + + return total_rules_no + +def verify_number_of_rules(devices, desired_rules_nb : int) -> None: + # Iterate all devices + for device in devices: + # Skip non-P4 devices + if not DeviceDriverEnum.DEVICEDRIVER_P4 in device.device_drivers: continue + + # We want the device to be active + assert device.device_operational_status == \ + DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED + + # Get the configuration rules of this device + config_rules = device.device_config.config_rules + + # Expected rule cardinality + assert len(config_rules) == desired_rules_nb + +def verify_active_service_type(services, target_service_type : ServiceTypeEnum) -> bool: # type: ignore + # Iterate all services + for service in services: + # Ignore services of other types + if service.service_type != target_service_type: + continue + + service_id = service.service_id + assert service_id + assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE + assert service.service_config + return True + + return False -- GitLab