From ef420f23695e30fe42ea19a7f489afb714c267a5 Mon Sep 17 00:00:00 2001 From: Lluis Gifre <lluis.gifre@cttc.es> Date: Tue, 26 Jul 2022 14:36:54 +0200 Subject: [PATCH] PathComp component: Common: - added helper scripts FrontEnd: - corrected import paths - added missing parameters in test - refined creation of backend request --- ...=> run_tests_locally-pathcomp-frontend.sh} | 2 +- src/pathcomp/backend/Dockerfile-gdb | 37 +++++++++ .../service/PathCompServiceServicerImpl.py | 3 + .../frontend/service/tools/ComposeRequest.py | 77 ++++++++----------- .../frontend/tests/PrepareTestScenario.py | 6 +- src/pathcomp/frontend/tests/test_unitary.py | 4 + src/pathcomp/test-deploy.sh | 1 + src/pathcomp/test-run.sh | 29 +++++++ 8 files changed, 111 insertions(+), 48 deletions(-) rename scripts/{run_tests_locally-pathcomp.sh => run_tests_locally-pathcomp-frontend.sh} (95%) create mode 100644 src/pathcomp/backend/Dockerfile-gdb create mode 100644 src/pathcomp/test-run.sh diff --git a/scripts/run_tests_locally-pathcomp.sh b/scripts/run_tests_locally-pathcomp-frontend.sh similarity index 95% rename from scripts/run_tests_locally-pathcomp.sh rename to scripts/run_tests_locally-pathcomp-frontend.sh index f56f47a8b..1bcf5e7f3 100755 --- a/scripts/run_tests_locally-pathcomp.sh +++ b/scripts/run_tests_locally-pathcomp-frontend.sh @@ -25,4 +25,4 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc #-o log_cli=true -o log_file=service.log -o log_file_level=DEBUG coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ - pathcomp/tests/test_unitary.py + pathcomp/frontend/tests/test_unitary.py diff --git a/src/pathcomp/backend/Dockerfile-gdb b/src/pathcomp/backend/Dockerfile-gdb new file mode 100644 index 000000000..13af33006 --- /dev/null +++ b/src/pathcomp/backend/Dockerfile-gdb @@ -0,0 +1,37 @@ +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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. + +# Multi-stage Docker image build + +# Stage 1 +FROM ubuntu:20.04 AS builder +ARG DEBIAN_FRONTEND=noninteractive + +# Install build software +RUN apt-get update -y && apt-get install build-essential libglib2.0-dev -y +RUN apt-get install gdb gdbserver -y + +# mkdir +RUN mkdir -p /var/teraflow + +# Define working directory +WORKDIR /var/teraflow + +# Copy every file in working directory +COPY src/pathcomp/backend/. ./ +RUN make + +EXPOSE 8081 + +ENTRYPOINT [ "gdb", "--args", "./pathComp", "config/pathcomp.conf", "pathcomp.log" ] diff --git a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py index a86405195..2ec045c27 100644 --- a/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py +++ b/src/pathcomp/frontend/service/PathCompServiceServicerImpl.py @@ -84,6 +84,9 @@ class PathCompServiceServicerImpl(PathCompServiceServicer): 'linkList' : link_list, } + #with open('pc-req.json', 'w', encoding='UTF-8') as f: + # f.write(json.dumps(request, sort_keys=True, indent=4)) + backend_url = BACKEND_URL.format(BACKEND_HOST, BACKEND_PORT) reply = requests.post(backend_url, json=request) if reply.status_code not in {requests.codes.ok}: diff --git a/src/pathcomp/frontend/service/tools/ComposeRequest.py b/src/pathcomp/frontend/service/tools/ComposeRequest.py index 0b8e5e13c..2cd4185f0 100644 --- a/src/pathcomp/frontend/service/tools/ComposeRequest.py +++ b/src/pathcomp/frontend/service/tools/ComposeRequest.py @@ -14,7 +14,7 @@ from enum import IntEnum from typing import Dict -from common.proto.context_pb2 import Device, Link, Service +from common.proto.context_pb2 import Constraint, Device, EndPointId, Link, Service, ServiceId, TopologyId from common.tools.grpc.Tools import grpc_message_to_json_string class CapacityUnit(IntEnum): @@ -55,13 +55,20 @@ class LinkForwardingDirection(IntEnum): UNIDIRECTIONAL = 1 UNKNOWN = 2 -def compose_topology_id(context_uuid : str, topology_uuid : str) -> Dict: +def compose_topology_id(topology_id : TopologyId) -> Dict: + context_uuid = topology_id.context_id.context_uuid.uuid + topology_uuid = topology_id.topology_uuid.uuid return {'contextId': context_uuid, 'topology_uuid': topology_uuid} -def compose_service_id(context_uuid : str, service_uuid : str) -> Dict: +def compose_service_id(service_id : ServiceId) -> Dict: + context_uuid = service_id.context_id.context_uuid.uuid + service_uuid = service_id.service_uuid.uuid return {'contextId': context_uuid, 'service_uuid': service_uuid} -def compose_endpoint_id(topology_id : Dict, device_uuid : str, endpoint_uuid : str) -> Dict: +def compose_endpoint_id(endpoint_id : EndPointId) -> Dict: + topology_id = compose_topology_id(endpoint_id.topology_id) + device_uuid = endpoint_id.device_id.device_uuid.uuid + endpoint_uuid = endpoint_id.endpoint_uuid.uuid return {'topology_id': topology_id, 'device_id': device_uuid, 'endpoint_uuid': endpoint_uuid} def compose_capacity(value : str, unit : str) -> Dict: @@ -83,7 +90,13 @@ def compose_cost_characteristics(cost_name : str, cost_value : str, cost_algorit def compose_latency_characteristics(fixed_latency_characteristic : str) -> Dict: return {'fixed-latency-characteristic': fixed_latency_characteristic} -def compose_constraint(constraint_type : str, constraint_value : str) -> Dict: +def compose_constraint(constraint : Constraint) -> Dict: + if constraint.WhichOneof('constraint') != 'custom': + MSG = 'Constraint({:s}) not supported' + str_constraint = grpc_message_to_json_string(constraint) + raise NotImplementedError(MSG.format(str_constraint)) + constraint_type = constraint.custom.constraint_type + constraint_value = constraint.custom.constraint_value return {'constraint_type': constraint_type, 'constraint_value': constraint_value} def compose_device(grpc_device : Device) -> Dict: @@ -92,14 +105,8 @@ def compose_device(grpc_device : Device) -> Dict: endpoints = [] for device_endpoint in grpc_device.device_endpoints: - context_uuid = device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid - topology_uuid = device_endpoint.endpoint_id.topology_id.topology_uuid.uuid - endpoint_uuid = device_endpoint.endpoint_id.endpoint_uuid.uuid + endpoint_id = compose_endpoint_id(device_endpoint.endpoint_id) endpoint_type = device_endpoint.endpoint_type - - topology_id = compose_topology_id(context_uuid, topology_uuid) - endpoint_id = compose_endpoint_id(topology_id, device_uuid, endpoint_uuid) - link_port_direction = LinkPortDirection.BIDIRECTIONAL.value termination_direction = TerminationDirection.BIDIRECTIONAL.value termination_state = TerminationState.TERMINATED_BIDIRECTIONAL.value @@ -115,15 +122,10 @@ def compose_device(grpc_device : Device) -> Dict: def compose_link(grpc_link : Link) -> Dict: link_uuid = grpc_link.link_id.link_uuid.uuid - endpoint_ids = [] - for link_endpoint_id in grpc_link.link_endpoint_ids: - context_uuid = link_endpoint_id.topology_id.context_id.context_uuid.uuid - topology_uuid = link_endpoint_id.topology_id.topology_uuid.uuid - device_uuid = link_endpoint_id.device_id.device_uuid.uuid - endpoint_uuid = link_endpoint_id.endpoint_uuid.uuid - topology_id = compose_topology_id(context_uuid, topology_uuid) - endpoint_id = compose_endpoint_id(topology_id, device_uuid, endpoint_uuid) - endpoint_ids.append({'endpoint_id' : endpoint_id}) + endpoint_ids = [ + {'endpoint_id' : compose_endpoint_id(link_endpoint_id)} + for link_endpoint_id in grpc_link.link_endpoint_ids + ] forwarding_direction = LinkForwardingDirection.UNIDIRECTIONAL.value total_potential_capacity = compose_capacity(200, CapacityUnit.MBPS.value) @@ -138,31 +140,18 @@ def compose_link(grpc_link : Link) -> Dict: } def compose_service(grpc_service : Service, algorithm : Dict) -> Dict: - context_uuid = grpc_service.service_id.service_id.context_id.context_uuid.uuid - service_uuid = grpc_service.service_id.service_id.service_uuid.uuid - - service_id = compose_service_id(context_uuid, service_uuid) + service_id = compose_service_id(grpc_service.service_id) service_type = grpc_service.service_type - endpoint_ids = [] - for service_endpoint_id in grpc_service.service_endpoint_ids: - context_uuid = service_endpoint_id.topology_id.context_id.context_uuid.uuid - topology_uuid = service_endpoint_id.topology_id.topology_uuid.uuid - device_uuid = service_endpoint_id.device_id.device_uuid.uuid - endpoint_uuid = service_endpoint_id.endpoint_uuid.uuid - topology_id = compose_topology_id(context_uuid, topology_uuid) - endpoint_id = compose_endpoint_id(topology_id, device_uuid, endpoint_uuid) - endpoint_ids.append(endpoint_id) - - constraints = [] - for service_constraint in grpc_service.service_constraints: - if service_constraint.WhichOneof('constraint') != 'custom': - MSG = 'Constraint({:s}) not supported' - str_constraint = grpc_message_to_json_string(service_constraint) - raise NotImplementedError(MSG.format(str_constraint)) - constraint_type = service_constraint.custom.constraint_type - constraint_value = service_constraint.custom.constraint_value - constraints.append(compose_constraint(constraint_type, constraint_value)) + endpoint_ids = [ + compose_endpoint_id(service_endpoint_id) + for service_endpoint_id in grpc_service.service_endpoint_ids + ] + + constraints = [ + compose_constraint(service_constraint) + for service_constraint in grpc_service.service_constraints + ] # algorithm to be executed algorithm_id = algorithm.get('id', 'SP') diff --git a/src/pathcomp/frontend/tests/PrepareTestScenario.py b/src/pathcomp/frontend/tests/PrepareTestScenario.py index a4efcbdbf..9fb57e41b 100644 --- a/src/pathcomp/frontend/tests/PrepareTestScenario.py +++ b/src/pathcomp/frontend/tests/PrepareTestScenario.py @@ -18,9 +18,9 @@ from common.Settings import ( ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc) from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient -from pathcomp.client.PathCompClient import PathCompClient -from pathcomp.service.PathCompService import PathCompService -from pathcomp.tests.MockService_Dependencies import MockService_Dependencies +from pathcomp.frontend.client.PathCompClient import PathCompClient +from pathcomp.frontend.service.PathCompService import PathCompService +from pathcomp.frontend.tests.MockService_Dependencies import MockService_Dependencies LOCAL_HOST = '127.0.0.1' MOCKSERVICE_PORT = 10000 diff --git a/src/pathcomp/frontend/tests/test_unitary.py b/src/pathcomp/frontend/tests/test_unitary.py index 43a4a577d..90d31bf0a 100644 --- a/src/pathcomp/frontend/tests/test_unitary.py +++ b/src/pathcomp/frontend/tests/test_unitary.py @@ -43,7 +43,11 @@ def test_request_service( request_services = SERVICES pathcomp_request = PathCompRequest(services=request_services) + pathcomp_request.k_shortest_path.k_inspection = 2 #pylint: disable=no-member + pathcomp_request.k_shortest_path.k_return = 2 #pylint: disable=no-member + pathcomp_reply = pathcomp_client.Compute(pathcomp_request) + pathcomp_reply = grpc_message_to_json(pathcomp_reply) reply_services = pathcomp_reply['services'] reply_connections = pathcomp_reply['connections'] diff --git a/src/pathcomp/test-deploy.sh b/src/pathcomp/test-deploy.sh index 2c14511db..9414fabf7 100644 --- a/src/pathcomp/test-deploy.sh +++ b/src/pathcomp/test-deploy.sh @@ -15,6 +15,7 @@ docker build -t "pathcomp-frontend:latest" -f ./src/pathcomp/frontend/Dockerfile . docker build -t "pathcomp-backend:latest" -f ./src/pathcomp/backend/Dockerfile . +docker build -t "pathcomp-backend:gdb" -f ./src/pathcomp/backend/Dockerfile-gdb . docker network create --driver=bridge --subnet=172.28.0.0/24 --gateway=172.28.0.254 tfbr diff --git a/src/pathcomp/test-run.sh b/src/pathcomp/test-run.sh new file mode 100644 index 000000000..2c14511db --- /dev/null +++ b/src/pathcomp/test-run.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) +# +# 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. + +docker build -t "pathcomp-frontend:latest" -f ./src/pathcomp/frontend/Dockerfile . +docker build -t "pathcomp-backend:latest" -f ./src/pathcomp/backend/Dockerfile . + +docker network create --driver=bridge --subnet=172.28.0.0/24 --gateway=172.28.0.254 tfbr + +docker run --name pathcomp-frontend -d --network=tfbr --ip 172.28.0.1 pathcomp-frontend:latest +docker run --name pathcomp-backend -d --network=tfbr --ip 172.28.0.2 pathcomp-backend:latest + +docker rm -f pathcomp-frontend pathcomp-backend +docker network rm teraflowbridge + +docker images --filter="dangling=true" --quiet | xargs -r docker rmi + +docker exec -i pathcomp bash -c "pytest --log-level=INFO --verbose pathcomp/tests/test_unitary.py" -- GitLab