From 14db9b7c6317d021d29c88541593eb716a1804cf Mon Sep 17 00:00:00 2001 From: gifrerenom <lluis.gifre@cttc.es> Date: Thu, 11 Apr 2024 15:46:01 +0000 Subject: [PATCH] OFC'24 test: - Corrected tests create/delete service unidir/bidir - Added run-tests-locally.sh script - Removed unneeded README.md file --- src/tests/ofc24/README.md | 21 ----- src/tests/ofc24/run-tests-locally.sh | 22 ++++++ .../test_functional_create_service_bidir.py | 30 ++++---- .../test_functional_create_service_unidir.py | 30 ++++---- .../test_functional_delete_service_bidir.py | 76 ++++++++----------- .../test_functional_delete_service_unidir.py | 76 ++++++++----------- 6 files changed, 116 insertions(+), 139 deletions(-) delete mode 100644 src/tests/ofc24/README.md create mode 100755 src/tests/ofc24/run-tests-locally.sh diff --git a/src/tests/ofc24/README.md b/src/tests/ofc24/README.md deleted file mode 100644 index 93e95fc64..000000000 --- a/src/tests/ofc24/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# OFC'24 - Test scenario - -## Start Topology -Topology is composed of 2 transponders managed through OpenConfig and 2 Multi-granular ROAMDS -Strat the topology executing the following command: -```bash -sudo ./start_topo.sh -``` - -## Populate the TFS context and topology -Pushing the JSON files following the file indexes, i.e, 1, 2, 3, ... -The last JSON file with ID 7 is the service. -To check the service is onboarded successfully go into the TFS WebUI and check the `Service` tab. - -## Check configuration in devices -Check if the devices are configured properly. -To check that, run, for each device (X={1, 2, 3, 4}): -```bash -screen -r tX -``` -To release the terminal, press `Ctrl + A + D` diff --git a/src/tests/ofc24/run-tests-locally.sh b/src/tests/ofc24/run-tests-locally.sh new file mode 100755 index 000000000..14cf78500 --- /dev/null +++ b/src/tests/ofc24/run-tests-locally.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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-ctrl/tfs_runtime_env_vars.sh +pytest --verbose --log-level=INFO ~/tfs-ctrl/ofc24/tests/test_functional_bootstrap.py +pytest --verbose --log-level=INFO ~/tfs-ctrl/ofc24/tests/test_functional_create_service_unidir.py +pytest --verbose --log-level=INFO ~/tfs-ctrl/ofc24/tests/test_functional_delete_service_unidir.py +pytest --verbose --log-level=INFO ~/tfs-ctrl/ofc24/tests/test_functional_create_service_bidir.py +pytest --verbose --log-level=INFO ~/tfs-ctrl/ofc24/tests/test_functional_delete_service_bidir.py +pytest --verbose --log-level=INFO ~/tfs-ctrl/ofc24/tests/test_functional_cleanup.py diff --git a/src/tests/ofc24/tests/test_functional_create_service_bidir.py b/src/tests/ofc24/tests/test_functional_create_service_bidir.py index 82408eaa5..e910c946d 100644 --- a/src/tests/ofc24/tests/test_functional_create_service_bidir.py +++ b/src/tests/ofc24/tests/test_functional_create_service_bidir.py @@ -14,7 +14,7 @@ import logging, os from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import ContextId, ServiceTypeEnum +from common.proto.context_pb2 import ContextId, ServiceStatusEnum, ServiceTypeEnum from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id @@ -41,32 +41,32 @@ def test_service_creation_bidir( ) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) - descriptor_loader.validate() - # Verify the scenario has no services/slices + # Verify the scenario has 1 service and 0 slices response = context_client.GetContext(ADMIN_CONTEXT_ID) - #assert len(response.service_ids) == 0 - #assert len(response.slice_ids) == 0 + assert len(response.service_ids) == 1 + assert len(response.slice_ids) == 0 - # Ensure slices and services are created + # Check there are no slices response = context_client.ListSlices(ADMIN_CONTEXT_ID) LOGGER.warning('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response))) - #assert len(response.slices) == 1 # OSM slice + assert len(response.slices) == 0 + # Check there is 1 service response = context_client.ListServices(ADMIN_CONTEXT_ID) LOGGER.warning('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) - #assert len(response.services) == 2 # 1xL3NM + 1xTAPI + assert len(response.services) == 1 for service in response.services: service_id = service.service_id + assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE + response = context_client.ListConnections(service_id) LOGGER.warning(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) - #if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: - # assert len(response.connections) == 1 # 1 connection per service - #elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: - # assert len(response.connections) == 1 # 1 connection per service - #else: - # str_service = grpc_message_to_json_string(service) - # raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) + if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: + assert len(response.connections) == 2 + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) diff --git a/src/tests/ofc24/tests/test_functional_create_service_unidir.py b/src/tests/ofc24/tests/test_functional_create_service_unidir.py index 1cc0f43ce..5b2550ae1 100644 --- a/src/tests/ofc24/tests/test_functional_create_service_unidir.py +++ b/src/tests/ofc24/tests/test_functional_create_service_unidir.py @@ -14,7 +14,7 @@ import logging, os from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import ContextId, ServiceTypeEnum +from common.proto.context_pb2 import ContextId, ServiceStatusEnum, ServiceTypeEnum from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id @@ -41,32 +41,32 @@ def test_service_creation_unidir( ) results = descriptor_loader.process() check_descriptor_load_results(results, descriptor_loader) - descriptor_loader.validate() - # Verify the scenario has no services/slices + # Verify the scenario has 1 service and 0 slices response = context_client.GetContext(ADMIN_CONTEXT_ID) - #assert len(response.service_ids) == 0 - #assert len(response.slice_ids) == 0 + assert len(response.service_ids) == 1 + assert len(response.slice_ids) == 0 - # Ensure slices and services are created + # Check there are no slices response = context_client.ListSlices(ADMIN_CONTEXT_ID) LOGGER.warning('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response))) - #assert len(response.slices) == 1 # OSM slice + assert len(response.slices) == 0 + # Check there is 1 service response = context_client.ListServices(ADMIN_CONTEXT_ID) LOGGER.warning('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) - #assert len(response.services) == 2 # 1xL3NM + 1xTAPI + assert len(response.services) == 1 for service in response.services: service_id = service.service_id + assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE + response = context_client.ListConnections(service_id) LOGGER.warning(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) - #if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: - # assert len(response.connections) == 1 # 1 connection per service - #elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: - # assert len(response.connections) == 1 # 1 connection per service - #else: - # str_service = grpc_message_to_json_string(service) - # raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) + if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: + assert len(response.connections) == 2 + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) diff --git a/src/tests/ofc24/tests/test_functional_delete_service_bidir.py b/src/tests/ofc24/tests/test_functional_delete_service_bidir.py index ee0572df2..a337336a8 100644 --- a/src/tests/ofc24/tests/test_functional_delete_service_bidir.py +++ b/src/tests/ofc24/tests/test_functional_delete_service_bidir.py @@ -12,79 +12,67 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, os +import logging +from typing import Set, Tuple from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import ContextId, ServiceId, ServiceTypeEnum -from common.tools.descriptor.Loader import DescriptorLoader +from common.proto.context_pb2 import ContextId, ServiceId, ServiceStatusEnum, ServiceTypeEnum from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id +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.Fixtures import context_client, service_client # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors', 'service-bidir.json') ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def test_service_removal_bidir( context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name service_client : ServiceClient, # pylint: disable=redefined-outer-name ): - # Load descriptors and validate the base scenario - descriptor_loader = DescriptorLoader( - descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client, - service_client=service_client - ) - descriptor_loader.validate() - - # Verify the scenario has no services/slices + # Verify the scenario has 1 service and 0 slices response = context_client.GetContext(ADMIN_CONTEXT_ID) - #assert len(response.service_ids) == 0 - #assert len(response.slice_ids) == 0 + assert len(response.service_ids) == 1 + assert len(response.slice_ids) == 0 - # Ensure slices and services are created + # Check there are no slices response = context_client.ListSlices(ADMIN_CONTEXT_ID) LOGGER.warning('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response))) - #assert len(response.slices) == 1 # OSM slice + assert len(response.slices) == 0 + # Check there is 1 service response = context_client.ListServices(ADMIN_CONTEXT_ID) LOGGER.warning('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) - #assert len(response.services) == 2 # 1xL3NM + 1xTAPI + assert len(response.services) == 1 - #service_uuids = set() + context_service_uuids : Set[Tuple[str, str]] = set() for service in response.services: service_id = service.service_id + assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE + response = context_client.ListConnections(service_id) LOGGER.warning(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) - #if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: - # assert len(response.connections) == 1 # 1 connection per service - # service_uuid = service_id.service_uuid.uuid - # service_uuids.add(service_uuid) - # osm_wim.conn_info[service_uuid] = {} - #elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: - # assert len(response.connections) == 1 # 1 connection per service - #else: - # str_service = grpc_message_to_json_string(service) - # raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) + if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: + assert len(response.connections) == 2 + context_uuid = service_id.context_id.context_uuid.uuid + service_uuid = service_id.service_uuid.uuid + context_service_uuids.add((context_uuid, service_uuid)) + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) - ## Identify service to delete - #assert len(service_uuids) == 1 # assume a single L3NM service has been created - #service_uuid = set(service_uuids).pop() + # Identify service to delete + assert len(context_service_uuids) == 1 + context_uuid, service_uuid = set(context_service_uuids).pop() - ## Delete Service - #service_client.DeleteService(ServiceId(json_service_id(service_uuid, context_uuid))) + # Delete Service + service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid)))) - ## Verify the scenario has no services/slices - #response = context_client.GetContext(ADMIN_CONTEXT_ID) - #assert len(response.service_ids) == 0 - #assert len(response.slice_ids) == 0 - - ## Load descriptors and validate the base scenario - #descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client) - #descriptor_loader.validate() + # Verify the scenario has no services/slices + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 diff --git a/src/tests/ofc24/tests/test_functional_delete_service_unidir.py b/src/tests/ofc24/tests/test_functional_delete_service_unidir.py index 0861b103c..9b0381c49 100644 --- a/src/tests/ofc24/tests/test_functional_delete_service_unidir.py +++ b/src/tests/ofc24/tests/test_functional_delete_service_unidir.py @@ -12,79 +12,67 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging, os +import logging +from typing import Set, Tuple from common.Constants import DEFAULT_CONTEXT_NAME -from common.proto.context_pb2 import ContextId, ServiceId, ServiceTypeEnum -from common.tools.descriptor.Loader import DescriptorLoader +from common.proto.context_pb2 import ContextId, ServiceId, ServiceStatusEnum, ServiceTypeEnum from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.object_factory.Context import json_context_id +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.Fixtures import context_client, service_client # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors', 'service-unidir.json') ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def test_service_removal_unidir( context_client : ContextClient, # pylint: disable=redefined-outer-name - device_client : DeviceClient, # pylint: disable=redefined-outer-name service_client : ServiceClient, # pylint: disable=redefined-outer-name ): - # Load descriptors and validate the base scenario - descriptor_loader = DescriptorLoader( - descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client, - service_client=service_client - ) - descriptor_loader.validate() - - # Verify the scenario has no services/slices + # Verify the scenario has 1 service and 0 slices response = context_client.GetContext(ADMIN_CONTEXT_ID) - #assert len(response.service_ids) == 0 - #assert len(response.slice_ids) == 0 + assert len(response.service_ids) == 1 + assert len(response.slice_ids) == 0 - # Ensure slices and services are created + # Check there are no slices response = context_client.ListSlices(ADMIN_CONTEXT_ID) LOGGER.warning('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response))) - #assert len(response.slices) == 1 # OSM slice + assert len(response.slices) == 0 + # Check there is 1 service response = context_client.ListServices(ADMIN_CONTEXT_ID) LOGGER.warning('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response))) - #assert len(response.services) == 2 # 1xL3NM + 1xTAPI + assert len(response.services) == 1 - #service_uuids = set() + context_service_uuids : Set[Tuple[str, str]] = set() for service in response.services: service_id = service.service_id + assert service.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE + response = context_client.ListConnections(service_id) LOGGER.warning(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format( grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response))) - #if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM: - # assert len(response.connections) == 1 # 1 connection per service - # service_uuid = service_id.service_uuid.uuid - # service_uuids.add(service_uuid) - # osm_wim.conn_info[service_uuid] = {} - #elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE: - # assert len(response.connections) == 1 # 1 connection per service - #else: - # str_service = grpc_message_to_json_string(service) - # raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) + if service.service_type == ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY: + assert len(response.connections) == 2 + context_uuid = service_id.context_id.context_uuid.uuid + service_uuid = service_id.service_uuid.uuid + context_service_uuids.add((context_uuid, service_uuid)) + else: + str_service = grpc_message_to_json_string(service) + raise Exception('Unexpected ServiceType: {:s}'.format(str_service)) - ## Identify service to delete - #assert len(service_uuids) == 1 # assume a single L3NM service has been created - #service_uuid = set(service_uuids).pop() + # Identify service to delete + assert len(context_service_uuids) == 1 + context_uuid, service_uuid = set(context_service_uuids).pop() - ## Delete Service - #service_client.DeleteService(ServiceId(json_service_id(service_uuid, context_uuid))) + # Delete Service + service_client.DeleteService(ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid)))) - ## Verify the scenario has no services/slices - #response = context_client.GetContext(ADMIN_CONTEXT_ID) - #assert len(response.service_ids) == 0 - #assert len(response.slice_ids) == 0 - - ## Load descriptors and validate the base scenario - #descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client) - #descriptor_loader.validate() + # Verify the scenario has no services/slices + response = context_client.GetContext(ADMIN_CONTEXT_ID) + assert len(response.service_ids) == 0 + assert len(response.slice_ids) == 0 -- GitLab