Skip to content
Snippets Groups Projects
Commit b51eac16 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

PathComp component:

- initial skeleton (not functional)
parent fee580ca
No related branches found
No related tags found
1 merge request!54Release 2.0.0
grpcio==1.43.0
grpcio-health-checking==1.43.0
prometheus-client==0.13.0
protobuf==3.19.3
pytest==6.2.5
pytest-benchmark==3.4.1
python-json-logger==2.0.2
requests==2.27.1
coverage==6.3
# 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.
from common.Constants import ServiceNameEnum
from common.Settings import get_service_port_grpc
from common.tools.service.GenericGrpcService import GenericGrpcService
from pathcomp.proto.pathcomp_pb2_grpc import add_PathCompServiceServicer_to_server
from .PathCompServiceServicerImpl import PathCompServiceServicerImpl
class PathCompService(GenericGrpcService):
def __init__(self, cls_name: str = __name__) -> None:
port = get_service_port_grpc(ServiceNameEnum.PATHCOMP)
super().__init__(port, cls_name=cls_name)
self.pathcomp_servicer = PathCompServiceServicerImpl()
def install_servicers(self):
add_PathCompServiceServicer_to_server(self.pathcomp_servicer, self.server)
# 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.
import grpc, logging
from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient
from pathcomp.proto.pathcomp_pb2 import PathCompReply, PathCompRequest
from pathcomp.proto.pathcomp_pb2_grpc import PathCompServiceServicer
LOGGER = logging.getLogger(__name__)
SERVICE_NAME = 'PathComp'
METHOD_NAMES = ['Compute']
METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
class PathCompServiceServicerImpl(PathCompServiceServicer):
def __init__(self) -> None:
LOGGER.debug('Creating Servicer...')
self.context_client = ContextClient()
LOGGER.debug('Servicer Created')
@safe_and_metered_rpc_method(METRICS, LOGGER)
def Compute(self, request : PathCompRequest, context : grpc.ServicerContext) -> PathCompReply:
LOGGER.info('[Compute] begin ; request = {:s}'.format(grpc_message_to_json_string(request)))
return PathCompReply()
# 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.
# 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.
import logging, signal, sys, threading
from prometheus_client import start_http_server
from common.Constants import ServiceNameEnum
from common.Settings import (
ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
wait_for_environment_variables)
from .PathCompService import PathCompService
terminate = threading.Event()
LOGGER : logging.Logger = None
def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
LOGGER.warning('Terminate signal received')
terminate.set()
def main():
global LOGGER # pylint: disable=global-statement
log_level = get_log_level()
logging.basicConfig(level=log_level)
LOGGER = logging.getLogger(__name__)
wait_for_environment_variables([
get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
])
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
LOGGER.info('Starting...')
# Start metrics server
metrics_port = get_metrics_port()
start_http_server(metrics_port)
# Starting service service
grpc_service = PathCompService()
grpc_service.start()
# Wait for Ctrl+C or termination signal
while not terminate.wait(timeout=0.1): pass
LOGGER.info('Terminating...')
grpc_service.stop()
LOGGER.info('Bye')
return 0
if __name__ == '__main__':
sys.exit(main())
# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
# 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.
import os
from typing import Union
from common.Constants import ServiceNameEnum
from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name
from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
from common.tools.service.GenericGrpcService import GenericGrpcService
from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
LOCAL_HOST = '127.0.0.1'
SERVICE_CONTEXT = ServiceNameEnum.CONTEXT
class MockService_Dependencies(GenericGrpcService):
# Mock Service implementing Context to simplify unitary tests of PathComp
def __init__(self, bind_port: Union[str, int]) -> None:
super().__init__(bind_port, LOCAL_HOST, enable_health_servicer=False, cls_name='MockService')
# pylint: disable=attribute-defined-outside-init
def install_servicers(self):
self.context_servicer = MockServicerImpl_Context()
add_ContextServiceServicer_to_server(self.context_servicer, self.server)
def configure_env_vars(self):
os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_HOST )] = str(self.bind_address)
os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
# 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.
from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
from common.tools.object_factory.Constraint import json_constraint
from common.tools.object_factory.Context import json_context, json_context_id
from common.tools.object_factory.Device import json_device_emulated_packet_router_disabled, json_device_id
from common.tools.object_factory.EndPoint import json_endpoints
from common.tools.object_factory.Link import get_link_uuid, json_link, json_link_id
from common.tools.object_factory.Service import get_service_uuid, json_service_l3nm_planned
from common.tools.object_factory.Topology import json_topology, json_topology_id
def compose_device(device_uuid, endpoint_uuids):
device_id = json_device_id(device_uuid)
endpoints = [(endpoint_uuid, 'copper') for endpoint_uuid in endpoint_uuids]
endpoints = json_endpoints(device_id, endpoints, topology_id=TOPOLOGY_A_ID)
device = json_device_emulated_packet_router_disabled(device_uuid, endpoints=endpoints)
return device_id, endpoints, device
def compose_link(endpoint_a_id, endpoint_z_id):
link_uuid = get_link_uuid(endpoint_a_id, endpoint_z_id)
link_id = json_link_id(link_uuid)
link = json_link(link_uuid, [endpoint_a_id, endpoint_z_id])
return link_id, link
def compose_service(endpoint_a_id, endpoint_z_id, constraints=[]):
service_uuid = get_service_uuid(endpoint_a_id, endpoint_z_id)
endpoint_ids = [endpoint_a_id, endpoint_z_id]
service = json_service_l3nm_planned(service_uuid, endpoint_ids=endpoint_ids, constraints=constraints)
return service
# ----- Context --------------------------------------------------------------------------------------------------------
CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
CONTEXT = json_context(DEFAULT_CONTEXT_UUID)
# ----- Domains --------------------------------------------------------------------------------------------------------
TOPOLOGY_ADMIN_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID)
TOPOLOGY_ADMIN = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=CONTEXT_ID)
TOPOLOGY_A_ID = json_topology_id('A', context_id=CONTEXT_ID)
TOPOLOGY_A = json_topology('A', context_id=CONTEXT_ID)
TOPOLOGY_B_ID = json_topology_id('B', context_id=CONTEXT_ID)
TOPOLOGY_B = json_topology('B', context_id=CONTEXT_ID)
TOPOLOGY_C_ID = json_topology_id('C', context_id=CONTEXT_ID)
TOPOLOGY_C = json_topology('C', context_id=CONTEXT_ID)
# ----- Devices Domain A -----------------------------------------------------------------------------------------------
DEVICE_A1_ID, DEVICE_A1_ENDPOINTS, DEVICE_A1 = compose_device('A1', ['1', '2', '2000'])
DEVICE_A2_ID, DEVICE_A2_ENDPOINTS, DEVICE_A2 = compose_device('A2', ['1', '2', '1001'])
DEVICE_A3_ID, DEVICE_A3_ENDPOINTS, DEVICE_A3 = compose_device('A3', ['1', '2'])
# ----- Devices Domain B -----------------------------------------------------------------------------------------------
DEVICE_B1_ID, DEVICE_B1_ENDPOINTS, DEVICE_B1 = compose_device('B1', ['1', '2', '2000'])
DEVICE_B2_ID, DEVICE_B2_ENDPOINTS, DEVICE_B2 = compose_device('B2', ['1', '2', '1002'])
DEVICE_B3_ID, DEVICE_B3_ENDPOINTS, DEVICE_B3 = compose_device('B3', ['1', '2'])
# ----- Devices Domain C -----------------------------------------------------------------------------------------------
DEVICE_C1_ID, DEVICE_C1_ENDPOINTS, DEVICE_C1 = compose_device('C1', ['1', '2', '1001'])
DEVICE_C2_ID, DEVICE_C2_ENDPOINTS, DEVICE_C2 = compose_device('C2', ['1', '2'])
DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', '1002'])
# ----- InterDomain Links ----------------------------------------------------------------------------------------------
LINK_A2_C3_ID, LINK_A2_C3 = compose_link(DEVICE_A2_ENDPOINTS[2], DEVICE_C3_ENDPOINTS[2])
LINK_C1_B2_ID, LINK_C1_B2 = compose_link(DEVICE_C1_ENDPOINTS[2], DEVICE_B2_ENDPOINTS[2])
# ----- IntraDomain A Links --------------------------------------------------------------------------------------------
LINK_A1_A2_ID, LINK_A1_A2 = compose_link(DEVICE_A1_ENDPOINTS[0], DEVICE_A2_ENDPOINTS[0])
LINK_A1_A3_ID, LINK_A1_A3 = compose_link(DEVICE_A1_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[0])
LINK_A2_A3_ID, LINK_A2_A3 = compose_link(DEVICE_A2_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[1])
# ----- IntraDomain B Links --------------------------------------------------------------------------------------------
LINK_B1_B2_ID, LINK_B1_B2 = compose_link(DEVICE_B1_ENDPOINTS[0], DEVICE_B2_ENDPOINTS[0])
LINK_B1_B3_ID, LINK_B1_B3 = compose_link(DEVICE_B1_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[0])
LINK_B2_B3_ID, LINK_B2_B3 = compose_link(DEVICE_B2_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[1])
# ----- IntraDomain C Links --------------------------------------------------------------------------------------------
LINK_C1_C2_ID, LINK_C1_C2 = compose_link(DEVICE_C1_ENDPOINTS[0], DEVICE_C2_ENDPOINTS[0])
LINK_C1_C3_ID, LINK_C1_C3 = compose_link(DEVICE_C1_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[0])
LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[1])
# ----- Service --------------------------------------------------------------------------------------------------------
SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[
json_constraint('bandwidth', 10.0),
json_constraint('latency_ms', 5.0)
])
# ----- Containers -----------------------------------------------------------------------------------------------------
CONTEXTS = [CONTEXT],
TOPOLOGIES = [TOPOLOGY_ADMIN, TOPOLOGY_A, TOPOLOGY_B, TOPOLOGY_C],
DEVICES = [ DEVICE_A1, DEVICE_A2, DEVICE_A3,
DEVICE_B1, DEVICE_B2, DEVICE_B3,
DEVICE_C1, DEVICE_C2, DEVICE_C3, ],
LINKS = [ LINK_A2_C3, LINK_C1_B2,
LINK_A1_A2, LINK_A1_A3, LINK_A2_A3,
LINK_B1_B2, LINK_B1_B3, LINK_B2_B3,
LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, ],
SERVICES = [SERVICE_A1_B1]
# 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.
import pytest, os
from common.Constants import ServiceNameEnum
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 service.client.ServiceClient import ServiceClient
from service.service.ServiceService import ServiceService
from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
from service.service.service_handlers import SERVICE_HANDLERS
from service.tests.MockService_Dependencies import MockService_Dependencies
LOCAL_HOST = '127.0.0.1'
MOCKSERVICE_PORT = 10000
SERVICE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.SERVICE) # avoid privileged ports
os.environ[get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_HOST )] = str(LOCAL_HOST)
os.environ[get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(SERVICE_SERVICE_PORT)
@pytest.fixture(scope='session')
def mock_service():
_service = MockService_Dependencies(MOCKSERVICE_PORT)
_service.configure_env_vars()
_service.start()
yield _service
_service.stop()
@pytest.fixture(scope='session')
def context_client(mock_service : MockService_Dependencies): # pylint: disable=redefined-outer-name
_client = ContextClient()
yield _client
_client.close()
@pytest.fixture(scope='session')
def device_client(mock_service : MockService_Dependencies): # pylint: disable=redefined-outer-name
_client = DeviceClient()
yield _client
_client.close()
@pytest.fixture(scope='session')
def service_service(
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient): # pylint: disable=redefined-outer-name
_service_handler_factory = ServiceHandlerFactory(SERVICE_HANDLERS)
_service = ServiceService(_service_handler_factory)
_service.start()
yield _service
_service.stop()
@pytest.fixture(scope='session')
def service_client(service_service : ServiceService): # pylint: disable=redefined-outer-name
_client = ServiceClient()
yield _client
_client.close()
# 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.
# 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.
import copy, grpc, logging, pytest
from common.tests.PytestGenerateTests import pytest_generate_tests # (required) pylint: disable=unused-import
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient
from context.proto.context_pb2 import Context, ContextId, DeviceId, Link, LinkId, Topology, Device, TopologyId
from device.client.DeviceClient import DeviceClient
from service.client.ServiceClient import ServiceClient
from service.proto.context_pb2 import Service, ServiceId
from .PrepareTestScenario import ( # pylint: disable=unused-import
# be careful, order of symbols is important here!
mock_service, service_service, context_client, device_client, service_client)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
try:
from .ServiceHandlersToTest import SERVICE_HANDLERS_TO_TEST
except ImportError:
LOGGER.exception('Unable to load service handlers, nothing will be tested.')
SERVICE_HANDLERS_TO_TEST = []
class TestServiceHandlers:
scenarios = SERVICE_HANDLERS_TO_TEST
def test_prepare_environment(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
for context in contexts: context_client.SetContext(Context(**context))
for topology in topologies: context_client.SetTopology(Topology(**topology))
for device in devices: device_client.AddDevice(Device(**device))
for link in links: context_client.SetLink(Link(**link))
def test_service_create_error_cases(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
with pytest.raises(grpc.RpcError) as e:
service_with_endpoints = copy.deepcopy(service_descriptor)
service_with_endpoints['service_endpoint_ids'].extend(service_endpoint_ids)
service_client.CreateService(Service(**service_with_endpoints))
assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
msg_head = 'service.service_endpoint_ids(['
msg_tail = ']) is invalid; RPC method CreateService does not accept Endpoints. '\
'Endpoints should be configured after creating the service.'
except_msg = str(e.value.details())
assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
with pytest.raises(grpc.RpcError) as e:
service_with_config_rules = copy.deepcopy(service_descriptor)
service_with_config_rules['service_config']['config_rules'].extend(service_config_rules)
service_client.CreateService(Service(**service_with_config_rules))
assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
msg_head = 'service.service_config.config_rules(['
msg_tail = ']) is invalid; RPC method CreateService does not accept Config Rules. '\
'Config Rules should be configured after creating the service.'
except_msg = str(e.value.details())
assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
with pytest.raises(grpc.RpcError) as e:
service_with_constraints = copy.deepcopy(service_descriptor)
service_with_constraints['service_constraints'].extend(service_constraints)
service_client.CreateService(Service(**service_with_constraints))
assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
msg_head = 'service.service_constraints(['
msg_tail = ']) is invalid; RPC method CreateService does not accept Constraints. '\
'Constraints should be configured after creating the service.'
except_msg = str(e.value.details())
assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
def test_service_create_correct(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
service_client.CreateService(Service(**service_descriptor))
def test_service_get_created(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
service_data = context_client.GetService(ServiceId(**service_id))
LOGGER.info('service_data = {:s}'.format(grpc_message_to_json_string(service_data)))
def test_service_update_configure(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
service_with_settings = copy.deepcopy(service_descriptor)
service_with_settings['service_endpoint_ids'].extend(service_endpoint_ids)
service_with_settings['service_config']['config_rules'].extend(service_config_rules)
service_with_settings['service_constraints'].extend(service_constraints)
service_client.UpdateService(Service(**service_with_settings))
for endpoint_id in service_endpoint_ids:
device_id = endpoint_id['device_id']
device_data = context_client.GetDevice(DeviceId(**device_id))
for i,config_rule in enumerate(device_data.device_config.config_rules):
LOGGER.info('device_data[{:s}][#{:d}] => {:s}'.format(
str(device_id), i, grpc_message_to_json_string(config_rule)))
def test_service_update_deconfigure(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
service_with_settings = copy.deepcopy(service_descriptor)
service_with_settings['service_endpoint_ids'].extend([]) # remove endpoints
service_client.UpdateService(Service(**service_with_settings))
for endpoint_id in service_endpoint_ids:
device_id = endpoint_id['device_id']
device_data = context_client.GetDevice(DeviceId(**device_id))
for i,config_rule in enumerate(device_data.device_config.config_rules):
LOGGER.info('device_data[{:s}][#{:d}] => {:s}'.format(
str(device_id), i, grpc_message_to_json_string(config_rule)))
def test_service_get_updated(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
service_data = context_client.GetService(ServiceId(**service_id))
LOGGER.info('service_data = {:s}'.format(grpc_message_to_json_string(service_data)))
def test_service_delete(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
service_client.DeleteService(ServiceId(**service_id))
def test_cleanup_environment(
self, service_id, service_descriptor, service_endpoint_ids, service_config_rules, service_constraints,
contexts, topologies, devices, links,
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
service_client : ServiceClient): # pylint: disable=redefined-outer-name
for link in links: context_client.RemoveLink(LinkId(**link['link_id']))
for device in devices: device_client.DeleteDevice(DeviceId(**device['device_id']))
for topology in topologies: context_client.RemoveTopology(TopologyId(**topology['topology_id']))
for context in contexts: context_client.RemoveContext(ContextId(**context['context_id']))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment