Commits (2)
# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
descriptors_real.json
import grpc from 'k6/net/grpc';
import exec from "k6/execution";
import { check, sleep } from 'k6';
const client = new grpc.Client();
client.load(['../proto'], 'policy.proto');
export const data = [];
for (let i = 1; i < 2; i++) {
data.push(
{
"serviceId": {
"context_id": {
"context_uuid": {"uuid": "admin"}
},
"service_uuid": {
"uuid": "6942d780-cfa9-4dea-a946-a8a0b3f7eab2"
}
},
"policyRuleBasic": {
"policyRuleId": {"uuid": {"uuid": i.toString()}},
"policyRuleState": {"policyRuleState": "POLICY_UNDEFINED"},
"priority": 0,
"conditionList": [{"kpiId": {"kpi_id": {"uuid": "1"}},
"numericalOperator": "POLICYRULE_CONDITION_NUMERICAL_EQUAL",
"kpiValue": {"boolVal": false}
}],
"actionList": [{}],
"booleanOperator": "POLICYRULE_CONDITION_BOOLEAN_UNDEFINED"
}
}
);
};
export const options = {
scenarios :{
"AddPolicy-scenario": {
executor: "shared-iterations",
vus: 1,
iterations: data.length,
maxDuration: "1h"
}
}
};
export default () => {
client.connect('10.1.255.198:6060', {
plaintext: true,
// timeout: 10000
});
var item = data[exec.scenario.iterationInInstance];
const response = client.invoke('policy.PolicyService/PolicyAddService', item);
check(response, {
'status is OK': (r) => r && r.status === grpc.StatusOK,
});
console.log(JSON.stringify(response.message));
client.close();
sleep(1);
};
export function handleSummary(data) {
return {
'summary_add_1.json': JSON.stringify(data.metrics.grpc_req_duration.values), //the default data object
};
}
import grpc from 'k6/net/grpc';
import exec from "k6/execution";
import { check, sleep } from 'k6';
const client = new grpc.Client();
client.load(['../proto'], 'policy.proto');
export const data = [];
for (let i = 1; i < 2; i++) {
data.push(
{
"uuid": {"uuid": i.toString()}
}
);
};
export const options = {
scenarios :{
"AddPolicy-scenario": {
executor: "shared-iterations",
vus: 1,
iterations: data.length,
maxDuration: "1h"
}
}
};
export default () => {
client.connect('10.1.255.198:6060', {
plaintext: true,
// timeout: 10000
});
var item = data[exec.scenario.iterationInInstance];
const response = client.invoke('policy.PolicyService/PolicyDelete', item);
check(response, {
'status is OK': (r) => r && r.status === grpc.StatusOK,
});
console.log(JSON.stringify(response.message));
client.close();
sleep(1);
};
export function handleSummary(data) {
return {
'summary_delete_1.json': JSON.stringify(data.metrics.grpc_req_duration.values), //the default data object
};
}
import grpc from 'k6/net/grpc';
import exec from "k6/execution";
import { check, sleep } from 'k6';
const client = new grpc.Client();
client.load(['../proto'], 'policy.proto');
export const data = [];
for (let i = 1; i < 2; i++) {
data.push(
{
"serviceId": {
"context_id": {
"context_uuid": {"uuid": "admin"}
},
"service_uuid": {
"uuid": "6942d780-cfa9-4dea-a946-a8a0b3f7eab2"
}
},
"policyRuleBasic": {
"policyRuleId": {"uuid": {"uuid": i.toString()}},
"policyRuleState": {"policyRuleState": "POLICY_UNDEFINED"},
"priority": 0,
"conditionList": [{"kpiId": {"kpi_id": {"uuid": "1"}},
"numericalOperator": "POLICYRULE_CONDITION_NUMERICAL_EQUAL",
"kpiValue": {"boolVal": false}
}],
"actionList": [{}],
"booleanOperator": "POLICYRULE_CONDITION_BOOLEAN_UNDEFINED"
}
}
);
};
export const options = {
scenarios :{
"AddPolicy-scenario": {
executor: "shared-iterations",
vus: 1,
iterations: data.length,
maxDuration: "1h"
}
}
};
export default () => {
client.connect('10.1.255.198:6060', {
plaintext: true,
// timeout: 10000
});
var item = data[exec.scenario.iterationInInstance];
const response = client.invoke('policy.PolicyService/PolicyUpdateService', item);
check(response, {
'status is OK': (r) => r && r.status === grpc.StatusOK,
});
console.log(JSON.stringify(response.message));
client.close();
sleep(1);
};
export function handleSummary(data) {
return {
'summary_add_1.json': JSON.stringify(data.metrics.grpc_req_duration.values), //the default data object
};
}
# Grafana k6 load testing tool
# K6 Installation Instructions on Ubuntu
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
Or install k6 via snap:
sudo apt install snapd
sudo snap install k6
# Running K6
k6 run script.js
\ No newline at end of file
# 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.
# Set the URL of your local Docker registry where the images will be uploaded to.
export TFS_REGISTRY_IMAGE="http://localhost:32000/tfs/"
# Set the list of components, separated by spaces, you want to build images for, and deploy.
# Supported components are:
# context device automation policy service compute monitoring webui
# interdomain slice pathcomp dlt
# dbscanserving opticalattackmitigator opticalattackdetector
# l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector
export TFS_COMPONENTS="context device automation monitoring pathcomp service slice compute webui"
# Set the tag you want to use for your images.
export TFS_IMAGE_TAG="dev"
# Set the name of the Kubernetes namespace to deploy to.
export TFS_K8S_NAMESPACE="tfs"
# Set additional manifest files to be applied after the deployment
export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
# Set the new Grafana admin password
export TFS_GRAFANA_PASSWORD="admin123+"
# If not already set, disable skip-build flag.
# If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used.
export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""}
{
"contexts": [
{
"context_id": {"context_uuid": {"uuid": "admin"}},
"topology_ids": [],
"service_ids": []
}
],
"topologies": [
{
"topology_id": {"topology_uuid": {"uuid": "admin"}, "context_id": {"context_uuid": {"uuid": "admin"}}},
"device_ids": [
{"device_uuid": {"uuid": "R1-EMU"}},
{"device_uuid": {"uuid": "R2-EMU"}},
{"device_uuid": {"uuid": "R3-EMU"}},
{"device_uuid": {"uuid": "R4-EMU"}},
{"device_uuid": {"uuid": "O1-OLS"}}
],
"link_ids": [
{"link_uuid": {"uuid": "R1-EMU/13/0/0==O1-OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}},
{"link_uuid": {"uuid": "R2-EMU/13/0/0==O1-OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}},
{"link_uuid": {"uuid": "R3-EMU/13/0/0==O1-OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}},
{"link_uuid": {"uuid": "R4-EMU/13/0/0==O1-OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}
]
}
],
"devices": [
{
"device_id": {"device_uuid": {"uuid": "R1-EMU"}}, "device_type": "emu-packet-router",
"device_operational_status": 1, "device_drivers": [0], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "13/0/0", "type": "optical", "sample_types": []},
{"uuid": "13/1/2", "type": "copper", "sample_types": [101, 102, 201, 202]}
]}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "R2-EMU"}}, "device_type": "emu-packet-router",
"device_operational_status": 1, "device_drivers": [0], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "13/0/0", "type": "optical", "sample_types": []},
{"uuid": "13/1/2", "type": "copper", "sample_types": [101, 102, 201, 202]}
]}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "R3-EMU"}}, "device_type": "emu-packet-router",
"device_operational_status": 1, "device_drivers": [0], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "13/0/0", "type": "optical", "sample_types": []},
{"uuid": "13/1/2", "type": "copper", "sample_types": [101, 102, 201, 202]}
]}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "R4-EMU"}}, "device_type": "emu-packet-router",
"device_operational_status": 1, "device_drivers": [0], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "13/0/0", "type": "optical", "sample_types": []},
{"uuid": "13/1/2", "type": "copper", "sample_types": [101, 102, 201, 202]}
]}}}
]}
},
{
"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "device_type": "emu-open-line-system",
"device_operational_status": 1, "device_drivers": [0], "device_endpoints": [],
"device_config": {"config_rules": [
{"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}},
{"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}},
{"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [
{"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870", "type": "optical", "sample_types": []},
{"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418", "type": "optical", "sample_types": []},
{"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513", "type": "optical", "sample_types": []},
{"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec", "type": "optical", "sample_types": []}
]}}}
]}
}
],
"links": [
{
"link_id": {"link_uuid": {"uuid": "R1-EMU/13/0/0==O1-OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "R1-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
{"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "R2-EMU/13/0/0==O1-OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "R2-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
{"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "R3-EMU/13/0/0==O1-OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "R3-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
{"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}
]
},
{
"link_id": {"link_uuid": {"uuid": "R4-EMU/13/0/0==O1-OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}},
"link_endpoint_ids": [
{"device_id": {"device_uuid": {"uuid": "R4-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
{"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}
]
}
]
}
\ No newline at end of file
#!/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.
source tfs_runtime_env_vars.sh
pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/benchmark/policy/tests/test_functional_bootstrap.py
#!/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.
source tfs_runtime_env_vars.sh
pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/benchmark/policy/tests/test_functional_create_service.py
#!/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.
source tfs_runtime_env_vars.sh
pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/benchmark/policy/tests/test_functional_delete_service.py
#!/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.
source tfs_runtime_env_vars.sh
pytest --verbose --log-level=INFO -o log_cli=true -o log_cli_level=INFO src/tests/benchmark/policy/tests/test_functional_cleanup.py
# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
Credentials.py
# 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, logging
from common.Settings import get_setting
from tests.tools.mock_osm.Constants import WIM_PASSWORD, WIM_USERNAME
from tests.tools.mock_osm.MockOSM import MockOSM
from .Objects import WIM_MAPPING
LOGGER = logging.getLogger(__name__)
@pytest.fixture(scope='session')
def osm_wim():
wim_url = 'http://{:s}:{:s}'.format(
get_setting('COMPUTESERVICE_SERVICE_HOST'), str(get_setting('COMPUTESERVICE_SERVICE_PORT_HTTP')))
LOGGER.info('WIM_MAPPING = {:s}'.format(str(WIM_MAPPING)))
return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
# 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.tools.object_factory.Device import json_device_id
from common.tools.object_factory.EndPoint import json_endpoint_id
from tests.tools.mock_osm.Tools import connection_point, wim_mapping
# ----- WIM Service Settings -------------------------------------------------------------------------------------------
WIM_DC1_SITE_ID = '1'
WIM_DC1_DEVICE_ID = json_device_id('R1-EMU')
WIM_DC1_ENDPOINT_ID = json_endpoint_id(WIM_DC1_DEVICE_ID, '13/1/2')
WIM_DC2_SITE_ID = '2'
WIM_DC2_DEVICE_ID = json_device_id('R3-EMU')
WIM_DC2_ENDPOINT_ID = json_endpoint_id(WIM_DC2_DEVICE_ID, '13/1/2')
WIM_SEP_DC1, WIM_MAP_DC1 = wim_mapping(WIM_DC1_SITE_ID, WIM_DC1_ENDPOINT_ID)
WIM_SEP_DC2, WIM_MAP_DC2 = wim_mapping(WIM_DC2_SITE_ID, WIM_DC2_ENDPOINT_ID)
WIM_MAPPING = [WIM_MAP_DC1, WIM_MAP_DC2]
WIM_SRV_VLAN_ID = 300
WIM_SERVICE_TYPE = 'ELINE'
WIM_SERVICE_CONNECTION_POINTS = [
connection_point(WIM_SEP_DC1, 'dot1q', WIM_SRV_VLAN_ID),
connection_point(WIM_SEP_DC2, 'dot1q', WIM_SRV_VLAN_ID),
]
# 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, time
from common.proto.context_pb2 import ContextId, Empty
from common.proto.monitoring_pb2 import KpiDescriptorList
from common.tests.LoadScenario import load_scenario_from_descriptor
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.object_factory.Context import json_context_id
from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient
from monitoring.client.MonitoringClient import MonitoringClient
from tests.Fixtures import context_client, device_client, monitoring_client # pylint: disable=unused-import
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json'
def test_scenario_bootstrap(
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
) -> None:
# ----- List entities - Ensure database is empty -------------------------------------------------------------------
response = context_client.ListContexts(Empty())
assert len(response.contexts) == 0
response = context_client.ListDevices(Empty())
assert len(response.devices) == 0
response = context_client.ListLinks(Empty())
assert len(response.links) == 0
# ----- Load Scenario ----------------------------------------------------------------------------------------------
descriptor_loader = load_scenario_from_descriptor(
DESCRIPTOR_FILE, context_client, device_client, None, None)
# ----- List entities - Ensure scenario is ready -------------------------------------------------------------------
response = context_client.ListContexts(Empty())
assert len(response.contexts) == descriptor_loader.num_contexts
for context_uuid, num_topologies in descriptor_loader.num_topologies.items():
response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid)))
assert len(response.topologies) == num_topologies
response = context_client.ListDevices(Empty())
assert len(response.devices) == descriptor_loader.num_devices
response = context_client.ListLinks(Empty())
assert len(response.links) == descriptor_loader.num_links
for context_uuid, _ in descriptor_loader.num_services.items():
response = context_client.ListServices(ContextId(**json_context_id(context_uuid)))
assert len(response.services) == 0
def test_scenario_kpis_created(
context_client : ContextClient, # pylint: disable=redefined-outer-name
monitoring_client: MonitoringClient, # pylint: disable=redefined-outer-name
) -> None:
"""
This test validates that KPIs related to the service/device/endpoint were created
during the service creation process.
"""
response = context_client.ListDevices(Empty())
kpis_expected = set()
for device in response.devices:
device_uuid = device.device_id.device_uuid.uuid
for endpoint in device.device_endpoints:
endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
for kpi_sample_type in endpoint.kpi_sample_types:
kpis_expected.add((device_uuid, endpoint_uuid, kpi_sample_type))
num_kpis_expected = len(kpis_expected)
LOGGER.info('Num KPIs expected: {:d}'.format(num_kpis_expected))
num_kpis_created, num_retry = 0, 0
while (num_kpis_created != num_kpis_expected) and (num_retry < 5):
response: KpiDescriptorList = monitoring_client.GetKpiDescriptorList(Empty())
num_kpis_created = len(response.kpi_descriptor_list)
LOGGER.info('Num KPIs created: {:d}'.format(num_kpis_created))
time.sleep(0.5)
num_retry += 1
assert num_kpis_created == num_kpis_expected
# 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
from common.tools.descriptor.Loader import DescriptorLoader
from common.tools.object_factory.Context import json_context_id
from common.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId
from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient
from tests.Fixtures import context_client, device_client # pylint: disable=unused-import
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json'
def test_services_removed(
context_client : ContextClient, # pylint: disable=redefined-outer-name
device_client : DeviceClient, # pylint: disable=redefined-outer-name
) -> None:
# ----- List entities - Ensure service is removed ------------------------------------------------------------------
with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f:
descriptors = f.read()
descriptor_loader = DescriptorLoader(descriptors)
response = context_client.ListContexts(Empty())
assert len(response.contexts) == descriptor_loader.num_contexts
for context_uuid, num_topologies in descriptor_loader.num_topologies.items():
response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid)))
assert len(response.topologies) == num_topologies
response = context_client.ListDevices(Empty())
assert len(response.devices) == descriptor_loader.num_devices
response = context_client.ListLinks(Empty())
assert len(response.links) == descriptor_loader.num_links
for context_uuid, _ in descriptor_loader.num_services.items():
response = context_client.ListServices(ContextId(**json_context_id(context_uuid)))
assert len(response.services) == 0
# ----- Delete Links, Devices, Topologies, Contexts ----------------------------------------------------------------
for link in descriptor_loader.links:
context_client.RemoveLink(LinkId(**link['link_id']))
for device in descriptor_loader.devices:
device_client .DeleteDevice(DeviceId(**device['device_id']))
for context_uuid, topology_list in descriptor_loader.topologies.items():
for topology in topology_list:
context_client.RemoveTopology(TopologyId(**topology['topology_id']))
for context in descriptor_loader.contexts:
context_client.RemoveContext(ContextId(**context['context_id']))
# ----- List entities - Ensure database is empty again -------------------------------------------------------------
response = context_client.ListContexts(Empty())
assert len(response.contexts) == 0
response = context_client.ListDevices(Empty())
assert len(response.devices) == 0
response = context_client.ListLinks(Empty())
assert len(response.links) == 0
# 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, random
from common.DeviceTypes import DeviceTypeEnum
from common.proto.context_pb2 import ContextId, Empty
from common.proto.kpi_sample_types_pb2 import KpiSampleType
from common.tools.descriptor.Loader import DescriptorLoader
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.object_factory.Context import json_context_id
from context.client.ContextClient import ContextClient
from monitoring.client.MonitoringClient import MonitoringClient
from tests.Fixtures import context_client, device_client, monitoring_client # pylint: disable=unused-import
from tests.tools.mock_osm.MockOSM import MockOSM
from .Fixtures import osm_wim # pylint: disable=unused-import
from .Objects import WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
DEVTYPE_EMU_PR = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json'
def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
# ----- List entities - Ensure scenario is ready -------------------------------------------------------------------
with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f:
descriptors = f.read()
descriptor_loader = DescriptorLoader(descriptors)
response = context_client.ListContexts(Empty())
assert len(response.contexts) == descriptor_loader.num_contexts
for context_uuid, num_topologies in descriptor_loader.num_topologies.items():
response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid)))
assert len(response.topologies) == num_topologies
response = context_client.ListDevices(Empty())
assert len(response.devices) == descriptor_loader.num_devices
response = context_client.ListLinks(Empty())
assert len(response.links) == descriptor_loader.num_links
for context_uuid, num_services in descriptor_loader.num_services.items():
response = context_client.ListServices(ContextId(**json_context_id(context_uuid)))
assert len(response.services) == 0
# ----- Create Service ---------------------------------------------------------------------------------------------
service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
osm_wim.get_connectivity_service_status(service_uuid)
# ----- List entities - Ensure service is created ------------------------------------------------------------------
response = context_client.ListContexts(Empty())
assert len(response.contexts) == descriptor_loader.num_contexts
for context_uuid, num_topologies in descriptor_loader.num_topologies.items():
response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid)))
assert len(response.topologies) == num_topologies
response = context_client.ListDevices(Empty())
assert len(response.devices) == descriptor_loader.num_devices
response = context_client.ListLinks(Empty())
assert len(response.links) == descriptor_loader.num_links
for context_uuid, num_services in descriptor_loader.num_services.items():
response = context_client.ListServices(ContextId(**json_context_id(context_uuid)))
LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
assert len(response.services) == 2*num_services # OLS & L3NM => (L3NM + TAPI)
for service in response.services:
service_id = service.service_id
response = context_client.ListConnections(service_id)
LOGGER.info(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format(
grpc_message_to_json_string(service_id), len(response.connections),
grpc_message_to_json_string(response)))
assert len(response.connections) == 1 # one connection per service
def test_scenario_kpi_values_created(
monitoring_client: MonitoringClient, # pylint: disable=redefined-outer-name
) -> None:
"""
This test validates that KPI values have been inserted into the monitoring database.
We short k KPI descriptors to test.
"""
response = monitoring_client.GetKpiDescriptorList(Empty())
kpi_descriptors = random.choices(response.kpi_descriptor_list, k=2)
for kpi_descriptor in kpi_descriptors:
MSG = 'KPI(kpi_uuid={:s}, device_uuid={:s}, endpoint_uuid={:s}, service_uuid={:s}, kpi_sample_type={:s})...'
LOGGER.info(MSG.format(
str(kpi_descriptor.kpi_id.kpi_id.uuid), str(kpi_descriptor.device_id.device_uuid.uuid),
str(kpi_descriptor.endpoint_id.endpoint_uuid.uuid), str(kpi_descriptor.service_id.service_uuid.uuid),
str(KpiSampleType.Name(kpi_descriptor.kpi_sample_type))))
response = monitoring_client.GetInstantKpi(kpi_descriptor.kpi_id)
kpi_uuid = response.kpi_id.kpi_id.uuid
assert kpi_uuid == kpi_descriptor.kpi_id.kpi_id.uuid
kpi_value_type = response.kpi_value.WhichOneof('value')
if kpi_value_type is None:
MSG = ' KPI({:s}): No instant value found'
LOGGER.warning(MSG.format(str(kpi_uuid)))
else:
kpi_timestamp = response.timestamp.timestamp
assert kpi_timestamp > 0
assert kpi_value_type == 'floatVal'
kpi_value = getattr(response.kpi_value, kpi_value_type)
MSG = ' KPI({:s}): timestamp={:s} value_type={:s} value={:s}'
LOGGER.info(MSG.format(str(kpi_uuid), str(kpi_timestamp), str(kpi_value_type), str(kpi_value)))
# 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
from common.Constants import DEFAULT_CONTEXT_UUID
from common.DeviceTypes import DeviceTypeEnum
from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum
from common.tools.descriptor.Loader import DescriptorLoader
from common.tools.object_factory.Context import json_context_id
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient
from tests.Fixtures import context_client # pylint: disable=unused-import
from tests.tools.mock_osm.MockOSM import MockOSM
from .Fixtures import osm_wim # pylint: disable=unused-import
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
DEVTYPE_EMU_PR = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPEN_LINE_SYSTEM.value
DESCRIPTOR_FILE = 'ofc22/descriptors_emulated.json'
def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
# ----- List entities - Ensure service is created ------------------------------------------------------------------
with open(DESCRIPTOR_FILE, 'r', encoding='UTF-8') as f:
descriptors = f.read()
descriptor_loader = DescriptorLoader(descriptors)
response = context_client.ListContexts(Empty())
assert len(response.contexts) == descriptor_loader.num_contexts
for context_uuid, num_topologies in descriptor_loader.num_topologies.items():
response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid)))
assert len(response.topologies) == num_topologies
response = context_client.ListDevices(Empty())
assert len(response.devices) == descriptor_loader.num_devices
response = context_client.ListLinks(Empty())
assert len(response.links) == descriptor_loader.num_links
l3nm_service_uuids = set()
response = context_client.ListServices(ContextId(**json_context_id(DEFAULT_CONTEXT_UUID)))
assert len(response.services) == 2 # OLS & L3NM => (L3NM + TAPI)
for service in response.services:
service_id = service.service_id
if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM:
service_uuid = service_id.service_uuid.uuid
l3nm_service_uuids.add(service_uuid)
osm_wim.conn_info[service_uuid] = {}
response = context_client.ListConnections(service_id)
LOGGER.info(' ServiceId[{:s}] => Connections[{:d}] = {:s}'.format(
grpc_message_to_json_string(service_id), len(response.connections),
grpc_message_to_json_string(response)))
assert len(response.connections) == 1 # one connection per service
# Identify service to delete
assert len(l3nm_service_uuids) == 1 # assume a single L3NM service has been created
l3nm_service_uuid = set(l3nm_service_uuids).pop()
# ----- Delete Service ---------------------------------------------------------------------------------------------
osm_wim.delete_connectivity_service(l3nm_service_uuid)
# ----- List entities - Ensure service is removed ------------------------------------------------------------------
response = context_client.ListContexts(Empty())
assert len(response.contexts) == descriptor_loader.num_contexts
for context_uuid, num_topologies in descriptor_loader.num_topologies.items():
response = context_client.ListTopologies(ContextId(**json_context_id(context_uuid)))
assert len(response.topologies) == num_topologies
response = context_client.ListDevices(Empty())
assert len(response.devices) == descriptor_loader.num_devices
response = context_client.ListLinks(Empty())
assert len(response.links) == descriptor_loader.num_links
for context_uuid, num_services in descriptor_loader.num_services.items():
response = context_client.ListServices(ContextId(**json_context_id(context_uuid)))
assert len(response.services) == 0