diff --git a/src/tests/ofc24/README.md b/src/tests/ofc24/README.md deleted file mode 100644 index 93e95fc642273bf852c829d6fae14cddf8ccba96..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..14cf78500d7d61789129b89cdfffe0f28e793aa5 --- /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 82408eaa5603a11cf3512ce9a4ed0939121f3ac8..e910c946d509a814415019c01a19b1058934e47a 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 1cc0f43ce3b1c080e82b206e8c7cdb338c82aa46..5b2550ae1e6f7ea9d51aec70af7af7b5c1360dc4 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 ee0572df2833477b81eb181ae450e874e8b9ed12..a337336a87535a89aa6ca176d56e40d33dcb1aca 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 0861b103cf0581ee5aa8d8962f1a36a98c1e006e..9b0381c492bd1c0783aaf9872037bfefdd25fa37 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