From ab7a87456538e561d60d209fe534c175ddd0269c Mon Sep 17 00:00:00 2001 From: Sastry Isukapalli Date: Wed, 28 Mar 2018 22:21:30 -0400 Subject: Functest scripts, simulators, and payloads osdf/adapters/policy/utils.py: Removed duplicated code (group_policies and group_policies_gen are very similar, and group_policies seems to be not used osdf/optimizers/placementopt/conductor/api_builder.py: changed param name from "grouped_policies" to "flat_policies" tox.ini added starup and shutdown of simulators (flask app with mock payloads) in tox tests rest all files/changes in "test/" folder quite a few payload files Patch set 2: removed a "print()" statement from simulator code Issue-ID: OPTFRA-22 Change-Id: I0006c577fc459c7c884b55e8316c689afd151780 Signed-off-by: Sastry Isukapalli --- osdf/adapters/policy/utils.py | 31 ----- .../placementopt/conductor/api_builder.py | 3 +- .../optimizers/placementopt/conductor/conductor.py | 6 +- test/conductor/test_conductor_calls.py | 49 +++++++ test/functest/scripts/sanity-check-simulators.sh | 11 ++ test/functest/scripts/start-simulators.sh | 50 +++++++ test/functest/scripts/stop-simulators.sh | 37 ++++++ .../flow1-success-simple/main.json | 13 ++ .../flow1-success-simple/status-done.json | 64 +++++++++ .../flow1-success-simple/status-solving.json | 17 +++ .../flow2-error-right-away/main.json | 18 +++ .../has-api/response-payloads/orig/README.md | 2 + .../response-payloads/orig/status-done.json | 64 +++++++++ .../response-payloads/orig/status-error.json | 18 +++ .../response-payloads/orig/status-solving.json | 17 +++ .../response-payloads/orig/status-template.json | 13 ++ .../simulators/oof_dependencies_simulators.py | 84 ++++++++++++ .../simulators/policy/response-payloads/README.md | 1 + .../pdp-has-vcpe-good/Affinity_vCPE_1.json | 22 ++++ .../pdp-has-vcpe-good/Capacity_vGMuxInfra.json | 22 ++++ .../pdp-has-vcpe-good/Capacity_vG_1.json | 22 ++++ .../pdp-has-vcpe-good/Distance_vGMuxInfra_1.json | 22 ++++ .../pdp-has-vcpe-good/Distance_vG_1.json | 22 ++++ .../Placement_Optimization_1.json | 36 ++++++ .../pdp-has-vcpe-good/QueryPolicy_vCPE.json | 23 ++++ .../pdp-has-vcpe-good/QueryPolicy_vCPE_2.json | 23 ++++ .../response-payloads/pdp-has-vcpe-good/README.md | 1 + .../pdp-has-vcpe-good/hpa_policy_vGMuxInfra_1.json | 144 +++++++++++++++++++++ .../pdp-has-vcpe-good/hpa_policy_vG_1.json | 144 +++++++++++++++++++++ .../pdp-has-vcpe-good/subscriber_policy.json | 22 ++++ .../pdp-has-vcpe-good/vnfPolicy_vG.json | 32 +++++ .../pdp-has-vcpe-good/vnfPolicy_vGMuxInfra.json | 32 +++++ .../simulators/simulated-config/common_config.yaml | 63 +++++++++ .../simulators/simulated-config/has_config.yaml | 24 ++++ .../simulators/simulated-config/osdf_config.yaml | 34 +++++ .../simulators/simulated-config/simulated-config | 1 + .../has_policies_r2/meta-valid-policies.txt | 14 -- test/test_PolicyCalls.py | 48 ++++--- tox.ini | 2 + 39 files changed, 1176 insertions(+), 75 deletions(-) create mode 100644 test/conductor/test_conductor_calls.py create mode 100644 test/functest/scripts/sanity-check-simulators.sh create mode 100755 test/functest/scripts/start-simulators.sh create mode 100755 test/functest/scripts/stop-simulators.sh create mode 100644 test/functest/simulators/has-api/response-payloads/flow1-success-simple/main.json create mode 100644 test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-done.json create mode 100644 test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-solving.json create mode 100644 test/functest/simulators/has-api/response-payloads/flow2-error-right-away/main.json create mode 100644 test/functest/simulators/has-api/response-payloads/orig/README.md create mode 100644 test/functest/simulators/has-api/response-payloads/orig/status-done.json create mode 100644 test/functest/simulators/has-api/response-payloads/orig/status-error.json create mode 100644 test/functest/simulators/has-api/response-payloads/orig/status-solving.json create mode 100644 test/functest/simulators/has-api/response-payloads/orig/status-template.json create mode 100755 test/functest/simulators/oof_dependencies_simulators.py create mode 100644 test/functest/simulators/policy/response-payloads/README.md create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Affinity_vCPE_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vGMuxInfra.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vG_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vGMuxInfra_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vG_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Placement_Optimization_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE_2.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/README.md create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vGMuxInfra_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vG_1.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/subscriber_policy.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vG.json create mode 100644 test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vGMuxInfra.json create mode 100644 test/functest/simulators/simulated-config/common_config.yaml create mode 100644 test/functest/simulators/simulated-config/has_config.yaml create mode 100755 test/functest/simulators/simulated-config/osdf_config.yaml create mode 120000 test/functest/simulators/simulated-config/simulated-config delete mode 100644 test/policy-local-files/has_policies_r2/meta-valid-policies.txt diff --git a/osdf/adapters/policy/utils.py b/osdf/adapters/policy/utils.py index f165079..2f873af 100644 --- a/osdf/adapters/policy/utils.py +++ b/osdf/adapters/policy/utils.py @@ -23,37 +23,6 @@ import itertools from osdf.utils.programming_utils import dot_notation, list_flatten -def group_policies(flat_policies): - """Filter policies using the following steps: - 1. Apply prioritization among the policies that are sharing the same policy type and resource type - 2. Remove redundant policies that may applicable across different types of resource - 3. Filter policies based on type and return - :param flat_policies: list of flat policies - :return: Filtered policies - """ - filtered_policies = defaultdict(list) - policy_name = [] - policies = [x for x in flat_policies if x['content'].get('policyType')] # drop ones without 'policy_type' - policy_types = set([x['content'].get('policyType') for x in policies]) - aggregated_policies = dict((x, defaultdict(list)) for x in policy_types) - - for policy in policies: - policy_type = policy['content'].get('policyType') - for resource in policy['content'].get('resources', []): - aggregated_policies[policy_type][resource].append(policy) - - for policy_type in aggregated_policies: - for resource in aggregated_policies[policy_type]: - if aggregated_policies[policy_type][resource]: - aggregated_policies[policy_type][resource].sort(key=lambda x: x['priority'], reverse=True) - prioritized_policy = aggregated_policies[policy_type][resource][0] - if prioritized_policy['policyName'] not in policy_name: - # TODO: Check logic here... should policy appear only once across all groups? - filtered_policies[prioritized_policy['content']['policyType']].append(prioritized_policy) - policy_name.append(prioritized_policy['policyName']) - return filtered_policies - - def group_policies_gen(flat_policies, config): """Filter policies using the following steps: 1. Apply prioritization among the policies that are sharing the same policy type and resource type diff --git a/osdf/optimizers/placementopt/conductor/api_builder.py b/osdf/optimizers/placementopt/conductor/api_builder.py index e359500..b2a5bf7 100644 --- a/osdf/optimizers/placementopt/conductor/api_builder.py +++ b/osdf/optimizers/placementopt/conductor/api_builder.py @@ -25,7 +25,8 @@ from osdf.adapters.policy.utils import group_policies_gen from osdf.utils.programming_utils import list_flatten -def conductor_api_builder(request_json, flat_policies: list, local_config, template="templates/conductor_interface.json"): +def conductor_api_builder(request_json, flat_policies: list, local_config, + template="osdf/templates/conductor_interface.json"): """Build an OSDF southbound API call for HAS-Conductor/Placement optimization :param request_json: parameter data received from a client :param flat_policies: policy data received from the policy platform (flat policies) diff --git a/osdf/optimizers/placementopt/conductor/conductor.py b/osdf/optimizers/placementopt/conductor/conductor.py index 41b901c..663857b 100644 --- a/osdf/optimizers/placementopt/conductor/conductor.py +++ b/osdf/optimizers/placementopt/conductor/conductor.py @@ -32,12 +32,12 @@ from osdf.utils.interfaces import RestClient from osdf.operation.exceptions import BusinessException -def request(req_object, osdf_config, grouped_policies): +def request(req_object, osdf_config, flat_policies): """ Process a placement request from a Client (build Conductor API call, make the call, return result) :param req_object: Request parameters from the client :param osdf_config: Configuration specific to SNIRO application (core + deployment) - :param grouped_policies: policies related to placement (fetched based on request, and grouped by policy type) + :param flat_policies: policies related to placement (fetched based on request) :param prov_status: provStatus retrieved from Subscriber policy :return: response from Conductor (accounting for redirects from Conductor service """ @@ -53,7 +53,7 @@ def request(req_object, osdf_config, grouped_policies): ping_wait_time = config.get('conductorPingWaitTime', 60) rc = RestClient(userid=uid, passwd=passwd, method="GET", log_func=debug_log.debug, headers=headers) - conductor_req_json_str = conductor_api_builder(req_object, grouped_policies, local_config) + conductor_req_json_str = conductor_api_builder(req_object, flat_policies, local_config) conductor_req_json = json.loads(conductor_req_json_str) debug_log.debug("Sending first Conductor request for request_id {}".format(req_id)) diff --git a/test/conductor/test_conductor_calls.py b/test/conductor/test_conductor_calls.py new file mode 100644 index 0000000..1a96da7 --- /dev/null +++ b/test/conductor/test_conductor_calls.py @@ -0,0 +1,49 @@ +# ------------------------------------------------------------------------- +# Copyright (c) 2018 AT&T Intellectual Property +# +# 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 unittest + +from osdf.optimizers.placementopt.conductor import conductor +import osdf.config.loader as config_loader +from osdf.utils.interfaces import json_from_file +from osdf.utils.programming_utils import DotDict +from osdf.adapters.policy import interface as pol + + +class TestConductorCalls(unittest.TestCase): + + def setUp(self): + self.config_spec = { + "deployment": "test/functest/simulators/simulated-config/osdf_config.yaml", + "core": "test/functest/simulators/simulated-config/common_config.yaml" + } + self.osdf_config = DotDict(config_loader.all_configs(**self.config_spec)) + self.lp = self.osdf_config.core.get('osdf_temp', {}).get('local_policies', {} + ).get('placement_policy_files_vcpe') + + def tearDown(self): + pass + + def test_request(self): + req_json = json_from_file("./test/placement-tests/request.json") + policies = pol.get_local_policies("test/policy-local-files/", self.lp) + conductor.request(req_json, self.osdf_config, policies) + + +if __name__ == "__main__": + unittest.main() + diff --git a/test/functest/scripts/sanity-check-simulators.sh b/test/functest/scripts/sanity-check-simulators.sh new file mode 100644 index 0000000..93c5372 --- /dev/null +++ b/test/functest/scripts/sanity-check-simulators.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +for x in policy has-api so-callback; do + curl http://localhost:5000/simulated/healthy/$x + curl http://localhost:5000/simulated/unhealthy/$x + curl http://localhost:5000/simulated/ERROR/$x + curl http://localhost:5000/simulated/success/$x +done + +curl -d '{"A1": "B1"}' http://localhost:5000/simulated/policy/pdp-has-vcpe-good/getConfig +curl -d '{"A1": "B1"}' http://localhost:5000/simulated/oof/has-api/flow1-success-simple/main.json diff --git a/test/functest/scripts/start-simulators.sh b/test/functest/scripts/start-simulators.sh new file mode 100755 index 0000000..11767e0 --- /dev/null +++ b/test/functest/scripts/start-simulators.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# ------------------------------------------------------------------------- +# Copyright (c) 2015-2017 AT&T Intellectual Property +# +# 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. +# +# ------------------------------------------------------------------------- +# + +# This script is in osdf/test/functest/scripts/ + +SCRIPTDIR=$(dirname $(readlink -f $0)) +FUNC_TEST_DIR=$(dirname $SCRIPTDIR) +TEST_DIR=$(dirname $FUNC_TEST_DIR) +OSDF_DIR=$(dirname $TEST_DIR) +SIMULATORS_DIR=$FUNC_TEST_DIR/simulators + +# Copy policy files from $TEST_DIR/policy-local-files into $SIMULATORS_DIR/policy/response-payloads +( + cd $SIMULATORS_DIR + cp $TEST_DIR/policy-local-files/*.json $SIMULATORS_DIR/policy/response-payloads/pdp-has-vcpe-good +) + + +# start the flask application after linking the code location and config folder +( + cd $SIMULATORS_DIR + ln -s $OSDF_DIR/osdf . + ln -s $SIMULATORS_DIR/simulated-config config + + XPID=$(ps -x | grep "python oof_dependencies_simulators.py" | grep -v grep | awk '{print $1}') + if [ -z "$XPID" ]; then + python oof_dependencies_simulators.py > simulator-logs 2>&1 & + sleep 5 + fi +) + + + diff --git a/test/functest/scripts/stop-simulators.sh b/test/functest/scripts/stop-simulators.sh new file mode 100755 index 0000000..c9dd126 --- /dev/null +++ b/test/functest/scripts/stop-simulators.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# ------------------------------------------------------------------------- +# Copyright (c) 2015-2017 AT&T Intellectual Property +# +# 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. +# +# ------------------------------------------------------------------------- +# + +# This script is in osdf/test/functest/scripts/ + +# We don't need all the directory names here and the "cd", but it may be needed later on +# Also, it will be a guard against some bad config where the directory doesn't exist + +SCRIPTDIR=$(dirname $(readlink -f $0)) +FUNC_TEST_DIR=$(dirname $SCRIPTDIR) +TEST_DIR=$(dirname $FUNC_TEST_DIR) +OSDF_DIR=$(dirname $TEST_DIR) +SIMULATORS_DIR=$FUNC_TEST_DIR/simulators + +cd $SIMULATORS_DIR + +XPID=$(ps -x | grep "python oof_dependencies_simulators.py" | grep -v grep | awk '{print $1}') +if [ -n "$XPID" ]; then + kill $XPID +fi diff --git a/test/functest/simulators/has-api/response-payloads/flow1-success-simple/main.json b/test/functest/simulators/has-api/response-payloads/flow1-success-simple/main.json new file mode 100644 index 0000000..a56840a --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/flow1-success-simple/main.json @@ -0,0 +1,13 @@ +{ + "status": "template", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://localhost:5000/simulated/oof/has-api/flow1-success-simple/status-solving.json", + "rel": "self" + } + ] + ], + "id": "plan_id" +} diff --git a/test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-done.json b/test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-done.json new file mode 100644 index 0000000..3944b8c --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-done.json @@ -0,0 +1,64 @@ +{ + "plans": [ + { + "status": "done", + "id": "plan_id", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://conductor:8091/v1/plans/plan_id", + "rel": "self" + } + ] + ], + "recommendations": [ + { + "vG": { + "inventory_provider": "aai", + "candidate": { + "candidate_id": "DLLSTX1A", + "cloud_owner": "CloudOwner1", + "inventory_type": "cloud", + "location_id": "DLLSTX1A", + "location_type": "openstack-cloud" + }, + "attributes": { + "flavors": { + "flavor_label_1": "vim_flavor_X", + "flavor_label_2": "vim_flavor_Y" + }, + "cloud_owner": "CloudOwner1", + "physical-location-id": "DLLSTX1A", + "cloud_version": "3.0", + "vim-id": "CloudOwner1_DLLSTX1A" + } + } + }, + { + "vGMuxInfra": { + "attributes": { + "host_id": "vgmux_host_name", + "cloud_owner": "CloudOwner1", + "physical-location-id": "DLLSTX1A", + "service_instance_id": "21d5f3e8-e714-4383-8f99-cc480144505a", + "cloud_version": "3.0", + "vim-id": "CloudOwner1_DLLSTX1A" + }, + "inventory_provider": "aai", + "service_resource_id": "12345", + "candidate": { + "is_rehome": "false", + "location_id": "DLLSTX1A", + "inventory_type": "service", + "candidate_id": "21d5f3e8-e714-4383-8f99-cc480144505a", + "host_id": "vgmux_host_name", + "cloud_owner": "CloudOwner1", + "location_type": "openstack-cloud" + } + } + } + ] + } + ] +} diff --git a/test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-solving.json b/test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-solving.json new file mode 100644 index 0000000..8bb074f --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/flow1-success-simple/status-solving.json @@ -0,0 +1,17 @@ +{ + "plans": [ + { + "status": "solving", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://localhost:5000/simulated/oof/has-api/flow1-success-simple/status-done.json", + "rel": "self" + } + ] + ], + "id": "plan_id" + } + ] +} diff --git a/test/functest/simulators/has-api/response-payloads/flow2-error-right-away/main.json b/test/functest/simulators/has-api/response-payloads/flow2-error-right-away/main.json new file mode 100644 index 0000000..95a9750 --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/flow2-error-right-away/main.json @@ -0,0 +1,18 @@ +{ + "plans": [ + { + "status": "error", + "message": "Some error message", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://conductor:8091/v1/plans/plan_id", + "rel": "self" + } + ] + ], + "id": "plan_id" + } + ] +} diff --git a/test/functest/simulators/has-api/response-payloads/orig/README.md b/test/functest/simulators/has-api/response-payloads/orig/README.md new file mode 100644 index 0000000..212be9c --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/orig/README.md @@ -0,0 +1,2 @@ +Policies from HAS page: https://wiki.onap.org/display/DW/vCPE+Homing+Use+Case +Retrieved 2018-03-28 diff --git a/test/functest/simulators/has-api/response-payloads/orig/status-done.json b/test/functest/simulators/has-api/response-payloads/orig/status-done.json new file mode 100644 index 0000000..3944b8c --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/orig/status-done.json @@ -0,0 +1,64 @@ +{ + "plans": [ + { + "status": "done", + "id": "plan_id", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://conductor:8091/v1/plans/plan_id", + "rel": "self" + } + ] + ], + "recommendations": [ + { + "vG": { + "inventory_provider": "aai", + "candidate": { + "candidate_id": "DLLSTX1A", + "cloud_owner": "CloudOwner1", + "inventory_type": "cloud", + "location_id": "DLLSTX1A", + "location_type": "openstack-cloud" + }, + "attributes": { + "flavors": { + "flavor_label_1": "vim_flavor_X", + "flavor_label_2": "vim_flavor_Y" + }, + "cloud_owner": "CloudOwner1", + "physical-location-id": "DLLSTX1A", + "cloud_version": "3.0", + "vim-id": "CloudOwner1_DLLSTX1A" + } + } + }, + { + "vGMuxInfra": { + "attributes": { + "host_id": "vgmux_host_name", + "cloud_owner": "CloudOwner1", + "physical-location-id": "DLLSTX1A", + "service_instance_id": "21d5f3e8-e714-4383-8f99-cc480144505a", + "cloud_version": "3.0", + "vim-id": "CloudOwner1_DLLSTX1A" + }, + "inventory_provider": "aai", + "service_resource_id": "12345", + "candidate": { + "is_rehome": "false", + "location_id": "DLLSTX1A", + "inventory_type": "service", + "candidate_id": "21d5f3e8-e714-4383-8f99-cc480144505a", + "host_id": "vgmux_host_name", + "cloud_owner": "CloudOwner1", + "location_type": "openstack-cloud" + } + } + } + ] + } + ] +} diff --git a/test/functest/simulators/has-api/response-payloads/orig/status-error.json b/test/functest/simulators/has-api/response-payloads/orig/status-error.json new file mode 100644 index 0000000..95a9750 --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/orig/status-error.json @@ -0,0 +1,18 @@ +{ + "plans": [ + { + "status": "error", + "message": "Some error message", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://conductor:8091/v1/plans/plan_id", + "rel": "self" + } + ] + ], + "id": "plan_id" + } + ] +} diff --git a/test/functest/simulators/has-api/response-payloads/orig/status-solving.json b/test/functest/simulators/has-api/response-payloads/orig/status-solving.json new file mode 100644 index 0000000..7868830 --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/orig/status-solving.json @@ -0,0 +1,17 @@ +{ + "plans": [ + { + "status": "solving", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://conductor:8091/v1/plans/plan_id", + "rel": "self" + } + ] + ], + "id": "plan_id" + } + ] +} diff --git a/test/functest/simulators/has-api/response-payloads/orig/status-template.json b/test/functest/simulators/has-api/response-payloads/orig/status-template.json new file mode 100644 index 0000000..6f20309 --- /dev/null +++ b/test/functest/simulators/has-api/response-payloads/orig/status-template.json @@ -0,0 +1,13 @@ +{ + "status": "template", + "name": "Plan Name 1", + "links": [ + [ + { + "href": "http://conductor:8091/v1/plans/plan_id", + "rel": "self" + } + ] + ], + "id": "plan_id" +} diff --git a/test/functest/simulators/oof_dependencies_simulators.py b/test/functest/simulators/oof_dependencies_simulators.py new file mode 100755 index 0000000..bdb552d --- /dev/null +++ b/test/functest/simulators/oof_dependencies_simulators.py @@ -0,0 +1,84 @@ +# ------------------------------------------------------------------------- +# Copyright (c) 2018 AT&T Intellectual Property +# +# 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. +# +# ------------------------------------------------------------------------- +# + +""" +Simulators for dependencies of OSDF (e.g. HAS-API, Policy, SO-callback, etc.) +""" +import glob + +from osdf.utils.interfaces import json_from_file +from flask import Flask, jsonify, request + +app = Flask(__name__) + + +@app.route("/simulated/ERROR/", methods=["GET", "POST"]) +@app.route("/simulated/unhealthy/", methods=["GET", "POST"]) +def error_for_component(component): + """Send an HTTP error for component""" + return jsonify({"error": "{} error".format(component)}), 503 + + +@app.route("/simulated/healthy/", methods=["GET", "POST"]) +def healthy_status_for_component(component): + """Send a health-OK response for component""" + return jsonify({"success": "Passed Health Check for Component {}".format(component)}) + + +@app.route("/simulated/success/", methods=["GET", "POST"]) +def successful_call_for_component(component): + """Send a message about successful call to component""" + return jsonify({"success": "made a call to Component: {}".format(component)}) + + +@app.route("/simulated/oof/has-api/", methods=["GET", "POST"]) +def has_api_calls(mainpath): + data, status = get_payload_for_simulated_component('has-api', mainpath) + if not status: + return jsonify(data) + return jsonify(data), 503 + + +def get_payload_for_simulated_component(component, mainpath): + """ + Get the payload for the given path for the given component + :param component: Component we are using (e.g. HAS-API, Policy, SO-callback, etc.) + :param mainpath: path within the URL (e.g. /main/X1/y1/) + :return: Content if file exists, or else 503 error + """ + file_name = "{}/response-payloads/{}".format(component, mainpath) + data = json_from_file(file_name) + if not data: + return {"Error": "Unable to read File {}".format(file_name)}, 503 + return data, None + + +@app.route("/simulated/policy//getConfig", methods=["POST"]) +def get_policies(sub_component): + """ + Get all policies for this folder + :param sub_component: The folder we are interested in (e.g. "pdp-has-vcpe-good", "pdp-has-vcpe-bad") + :return: A list of policies as a json object (each element is one policy) + """ + main_dir = "policy/response-payloads/" + sub_component + files = glob.glob("{}/*.json".format(main_dir)) + return jsonify([json_from_file(x) for x in files]) + + +if __name__ == "__main__": + app.run(debug=True) diff --git a/test/functest/simulators/policy/response-payloads/README.md b/test/functest/simulators/policy/response-payloads/README.md new file mode 100644 index 0000000..2ae3965 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/README.md @@ -0,0 +1 @@ +All policy local files will come here diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Affinity_vCPE_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Affinity_vCPE_1.json new file mode 100644 index 0000000..4a3e086 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Affinity_vCPE_1.json @@ -0,0 +1,22 @@ +{ + "service": "affinityPolicy", + "policyName": "oofBeijing.affinityPolicy_vcpe", + "description": "Affinity policy for vCPE", + "templateVersion": "1702.03", + "version": "oofBeijing", + "priority": "5", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "identity": "affinity_vCPE", + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG"], + "affinityProperty": { + "qualifier": "different", + "category": "complex" + }, + "policyType": "zone", + "resources": ["vGMuxInfra", "vG"], + "applicableResources": "all" + } +} \ No newline at end of file diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vGMuxInfra.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vGMuxInfra.json new file mode 100644 index 0000000..0225d40 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vGMuxInfra.json @@ -0,0 +1,22 @@ +{ + "service": "capacityPolicy", + "policyName": "oofBeijing.capacityPolicy_vGMuxInfra", + "description": "Capacity policy for vGMuxInfra", + "templateVersion": "1702.03", + "version": "oofBeijing", + "priority": "5", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "identity": "capacity_vGMuxInfra", + "policyScope": ["VCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vim_fit"], + "resources": ["vGMuxInfra"], + "capacityProperty": { + "controller": "multicloud", + "request": "{\"vCPU\": 10, \"Memory\": {\"quantity\": 16, \"unit\": \"GB\"}, \"Storage\": {\"quantity\": 40, \"unit\": \"GB\"}}" + }, + "policyType": "vim_fit", + "applicableResources": "any" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vG_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vG_1.json new file mode 100644 index 0000000..f311650 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vG_1.json @@ -0,0 +1,22 @@ +{ + "service": "capacityPolicy", + "policyName": "oofBeijing.capacityPolicy_vG", + "description": "Capacity policy for vG", + "templateVersion": "1702.03", + "version": "oofBeijing", + "priority": "5", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "identity": "capacity_vG", + "policyScope": ["VCPE", "US", "INTERNATIONAL", "ip", "vG", "vim_fit"], + "resources": ["vG"], + "capacityProperty": { + "controller": "multicloud", + "request": "{\"vCPU\": 10, \"Memory\": {\"quantity\": 16, \"unit\": \"GB\"}, \"Storage\": {\"quantity\": 40, \"unit\": \"GB\"}}" + }, + "policyType": "vim_fit", + "applicableResources": "any" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vGMuxInfra_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vGMuxInfra_1.json new file mode 100644 index 0000000..992e9ec --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vGMuxInfra_1.json @@ -0,0 +1,22 @@ +{ + "service": "distancePolicy", + "policyName": "oofBeijing.distancePolicy_vGMuxInfra", + "description": "Distance Policy for vGMuxInfra", + "templateVersion": "0.0.1", + "version": "oofBeijing", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "distanceProperties": { + "locationInfo": "customer_location", + "distance": { "value": "500", "operator": "<", "unit": "km" } + }, + "identity": "distance-vGMuxInfra", + "resources": ["vGMuxInfra"], + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "distancePolicy"], + "policyType": "distance_to_location", + "applicableResources": "any" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vG_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vG_1.json new file mode 100644 index 0000000..07baabd --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vG_1.json @@ -0,0 +1,22 @@ +{ + "service": "distancePolicy", + "policyName": "oofBeijing.distancePolicy_vG", + "description": "Distance Policy for vG", + "templateVersion": "0.0.1", + "version": "oofBeijing", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "distanceProperties": { + "locationInfo": "customer_location", + "distance": { "value": "1500", "operator": "<", "unit": "km" } + }, + "identity": "distance-vG", + "resources": ["vG"], + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vG", "distancePolicy"], + "policyType": "distance_to_location", + "applicableResources": "any" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Placement_Optimization_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Placement_Optimization_1.json new file mode 100644 index 0000000..6d09b82 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Placement_Optimization_1.json @@ -0,0 +1,36 @@ +{ + "service": "PlacementOptimizationPolicy", + "policyName": "oofBeijing.PlacementOptimizationPolicy_vGMuxInfra", + "description": "Placement Optimization Policy for vGMuxInfra", + "templateVersion": "1702.03", + "version": "oofBeijing", + "priority": "5", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "objectiveParameter": { + "parameterAttributes": [ + { + "resources": ["vGMuxInfra"], + "customerLocationInfo": "customer_loc", + "parameter": "distance", + "weight": "1", + "operator": "product" + }, + { + "resources": ["vG"], + "customerLocationInfo": "customer_loc", + "parameter": "distance", + "weight": "1", + "operator": "product" + } + ], + "operator": "sum" + }, + "identity": "optimization", + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG", "placementOptimization"], + "policyType": "placementOptimization", + "objective": "minimize" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE.json new file mode 100644 index 0000000..03c457e --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE.json @@ -0,0 +1,23 @@ +{ + "service": "optimizationQueryPolicy", + "policyName": "oofBeijing.queryPolicy_vCPE", + "description": "Optimization query policy for vCPE", + "templateVersion": "0.0.1", + "version": "oofBeijing", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "queryProperties": [ + {"attribute":"locationId", "attribute_location": "customerLocation", "value": ""}, + {"attribute":"id", "attribute_location": "vpnInfo.vpnId", "value": ""}, + {"attribute":"upstreamBW", "attribute_location": "vpnInfo.upstreamBW", "value": ""}, + {"attribute":"customerLatitude", "attribute_location": "customerLatitude", "value": 32.89748}, + {"attribute":"customerLongitude", "attribute_location": "customerLongitude", "value": -97.040443} + ], + "serviceName": "vCPE", + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG", "optimizationQueryPolicy"], + "policyType": "optimizationQueryPolicy" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE_2.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE_2.json new file mode 100644 index 0000000..7f1db83 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE_2.json @@ -0,0 +1,23 @@ +{ + "service": "optimizationQueryPolicy", + "policyName": "oofBeijing.queryPolicy_vCPE", + "description": "Optimization query policy for vCPE", + "templateVersion": "0.0.1", + "version": "oofBeijing", + "priority": "5", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "queryProperties": [ + {"attribute":"locationId", "attribute_location": "customerLocation", "value": ""}, + {"attribute":"id", "attribute_location": "vpnInfo.vpnId", "value": ""}, + {"attribute":"upstreamBW", "attribute_location": "vpnInfo.upstreamBW", "value": ""}, + {"attribute":"customerLatitude", "attribute_location": "customerLatitude", "value": 1.1}, + {"attribute":"customerLongitude", "attribute_location": "customerLongitude", "value": 2.2} + ], + "serviceName": "vCPE", + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG", "optimizationQueryPolicy"], + "policyType": "optimizationQueryPolicy" + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/README.md b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/README.md new file mode 100644 index 0000000..58c5cb5 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/README.md @@ -0,0 +1 @@ +All HAS-related policy local files will come here diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vGMuxInfra_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vGMuxInfra_1.json new file mode 100644 index 0000000..a3403f0 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vGMuxInfra_1.json @@ -0,0 +1,144 @@ +{ + "service": "hpaPolicy", + "policyName": "oofBeijing.hpaPolicy_vGMuxInfra", + "description": "HPA policy for vGMuxInfra", + "templateVersion": "0.0.1", + "version": "1.0", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "resources": ["vGMuxInfra"], + "identity": "hpaPolicy_vGMuxInfra", + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "hpaPolicy"], + "policyType": "hpa", + "flavorFeatures": [ + { + "flavorLabel": "flavor_label_vm_01", + "flavorProperties":[ + { + "hpa-feature" : "cpuTopology", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"numCpuSockets", "hpa-attribute-value": "2","operator": ">=", "unit": ""}, + {"hpa-attribute-key":"numCpuSockets", "hpa-attribute-value": "4","operator": "<=", "unit": ""}, + {"hpa-attribute-key":"numCpuCores", "hpa-attribute-value": "2", "operator":">=", "unit": ""}, + {"hpa-attribute-key":"numCpuCores", "hpa-attribute-value": "4", "operator":"<=", "unit": ""}, + {"hpa-attribute-key":"numCpuThreads", "hpa-attribute-value": "4", "operator":">=", "unit": ""}, + {"hpa-attribute-key":"numCpuThreads", "hpa-attribute-value": "8", "operator":"<=", "unit": ""} + ] + }, + { + "hpa-feature" : "basicCapabilities", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numVirtualCpu", "hpa-attribute-value": "6", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "virtualMemSize", "hpa-attribute-value":"6", "operator": "=", "unit": "GB"} + ] + }, + { + "hpa-feature" : "ovsDpdk", + "mandatory" : "False", + "score" : "3", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"dataProcessingAccelerationLibrary", "hpa-attribute-value":"ovsDpdk_version", "operator": "=", "unit":""} + ] + }, + { + "hpa-feature" : "cpuInstructionSetExtensions", + "mandatory" : "True", + "architecture": "INTEL-64", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"instructionSetExtensions", "hpa-attribute-value":["", ""], "operator": "ALL", "unit":""} + ] + } + ] + }, + { + "flavorLabel": "flavor_label_vm_02", + "flavorProperties":[ + { + "hpa-feature" : "cpuPinningy", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"logicalCpuThreadPinningPolicy", "hpa-attribute-value":"", "operator": "=", "unit":""}, + {"hpa-attribute-key":"logicalCpuPinningPolicy", "hpa-attribute-value": "","operator": "=", "unit":""} + ] + }, + { + "hpa-feature" : "basicCapabilities", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numVirtualCpu", "hpa-attribute-value": "6", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "virtualMemSize", "hpa-attribute-value":"6", "operator": "=", "unit": "GB"} + ] + }, + { + "hpa-feature" : "localStorage", + "mandatory" : "False", + "score" : "5", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "diskSize", "hpa-attribute-value": "2", "operator": "=", "unit": "GB"}, + {"hpa-attribute-key": "ephemeralDiskSize", "hpa-attribute-value": "2", "operator": "=", "unit": "GB"}, + {"hpa-attribute-key": "swapMemSize", "hpa-attribute-value":"16", "operator": "=", "unit": "MB"} + ] + }, + { + "hpa-feature" : "pcie", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "pciCount", "hpa-attribute-value": "2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "pciVendorId", "hpa-attribute-value":"8086", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "pciDeviceId", "hpa-attribute-value": "2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "functionType", "hpa-attribute-value": "","operator": "=", "unit": ""} + ] + } + ] + }, + { + "flavorLabel": "flavor_label_vm_03", + "flavorProperties":[ + { + "hpa-feature" : "numa", + "mandatory" : "False", + "score" : "5", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numaNodes", "hpa-attribute-value": "2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "numaCpu-0", "hpa-attribute-value":"2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "numaMem-0", "hpa-attribute-value": "2048", "operator": "=", "unit": "MB"}, + {"hpa-attribute-key": "numaCpu-1", "hpa-attribute-value":"4", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "numaMem-1", "value": "4096", "operator": "=", "unit": "MB"} + ] + }, + { + "hpa-feature" : "basicCapabilities", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numVirtualCpu", "hpa-attribute-value": "6", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "virtualMemSize", "hpa-attribute-value":"6", "operator": "=", "unit": "GB"} + ] + }, + { + "hpa-feature" : "hugePages", + "mandatory" : "False", + "score" : "7", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "memoryPageSize", "hpa-attribute-value": "", "operator": "=", "unit": ""} + ] + } + ] + } + ] + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vG_1.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vG_1.json new file mode 100644 index 0000000..9b832f6 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vG_1.json @@ -0,0 +1,144 @@ +{ + "service": "hpaPolicy", + "policyName": "oofBeijing.hpaPolicy_vG", + "description": "HPA policy for vG", + "templateVersion": "0.0.1", + "version": "1.0", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "resources": ["vG"], + "identity": "hpaPolicy_vG", + "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vG", "hpaPolicy"], + "policyType": "hpa", + "flavorFeatures": [ + { + "flavorLabel": "flavor_label_vm_01", + "flavorProperties":[ + { + "hpa-feature" : "cpuTopology", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"numCpuSockets", "hpa-attribute-value": "2","operator": ">=", "unit": ""}, + {"hpa-attribute-key":"numCpuSockets", "hpa-attribute-value": "4","operator": "<=", "unit": ""}, + {"hpa-attribute-key":"numCpuCores", "hpa-attribute-value": "2", "operator":">=", "unit": ""}, + {"hpa-attribute-key":"numCpuCores", "hpa-attribute-value": "4", "operator":"<=", "unit": ""}, + {"hpa-attribute-key":"numCpuThreads", "hpa-attribute-value": "4", "operator":">=", "unit": ""}, + {"hpa-attribute-key":"numCpuThreads", "hpa-attribute-value": "8", "operator":"<=", "unit": ""} + ] + }, + { + "hpa-feature" : "basicCapabilities", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numVirtualCpu", "hpa-attribute-value": "6", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "virtualMemSize", "hpa-attribute-value":"6", "operator": "=", "unit": "GB"} + ] + }, + { + "hpa-feature" : "ovsDpdk", + "mandatory" : "False", + "score" : "3", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"dataProcessingAccelerationLibrary", "hpa-attribute-value":"ovsDpdk_version", "operator": "=", "unit":""} + ] + }, + { + "hpa-feature" : "cpuInstructionSetExtensions", + "mandatory" : "True", + "architecture": "INTEL-64", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"instructionSetExtensions", "hpa-attribute-value":["", ""], "operator": "ALL", "unit":""} + ] + } + ] + }, + { + "flavorLabel": "flavor_label_vm_02", + "flavorProperties":[ + { + "hpa-feature" : "cpuPinningy", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key":"logicalCpuThreadPinningPolicy", "hpa-attribute-value":"", "operator": "=", "unit":""}, + {"hpa-attribute-key":"logicalCpuPinningPolicy", "hpa-attribute-value": "","operator": "=", "unit":""} + ] + }, + { + "hpa-feature" : "basicCapabilities", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numVirtualCpu", "hpa-attribute-value": "6", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "virtualMemSize", "hpa-attribute-value":"6", "operator": "=", "unit": "GB"} + ] + }, + { + "hpa-feature" : "localStorage", + "mandatory" : "False", + "score" : "5", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "diskSize", "hpa-attribute-value": "2", "operator": "=", "unit": "GB"}, + {"hpa-attribute-key": "ephemeralDiskSize", "hpa-attribute-value": "2", "operator": "=", "unit": "GB"}, + {"hpa-attribute-key": "swapMemSize", "hpa-attribute-value":"16", "operator": "=", "unit": "MB"} + ] + }, + { + "hpa-feature" : "pcie", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "pciCount", "hpa-attribute-value": "2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "pciVendorId", "hpa-attribute-value":"8086", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "pciDeviceId", "hpa-attribute-value": "2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "functionType", "hpa-attribute-value": "","operator": "=", "unit": ""} + ] + } + ] + }, + { + "flavorLabel": "flavor_label_vm_03", + "flavorProperties":[ + { + "hpa-feature" : "numa", + "mandatory" : "False", + "score" : "5", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numaNodes", "hpa-attribute-value": "2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "numaCpu-0", "hpa-attribute-value":"2", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "numaMem-0", "hpa-attribute-value": "2048", "operator": "=", "unit": "MB"}, + {"hpa-attribute-key": "numaCpu-1", "hpa-attribute-value":"4", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "numaMem-1", "value": "4096", "operator": "=", "unit": "MB"} + ] + }, + { + "hpa-feature" : "basicCapabilities", + "mandatory" : "True", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "numVirtualCpu", "hpa-attribute-value": "6", "operator": "=", "unit": ""}, + {"hpa-attribute-key": "virtualMemSize", "hpa-attribute-value":"6", "operator": "=", "unit": "GB"} + ] + }, + { + "hpa-feature" : "hugePages", + "mandatory" : "False", + "score" : "7", + "architecture": "generic", + "hpa-feature-attributes": [ + {"hpa-attribute-key": "memoryPageSize", "hpa-attribute-value": "", "operator": "=", "unit": ""} + ] + } + ] + } + ] + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/subscriber_policy.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/subscriber_policy.json new file mode 100644 index 0000000..f1b818c --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/subscriber_policy.json @@ -0,0 +1,22 @@ +{ + "service": "SubscriberPolicy", + "policyName": "oofBeijing.SubscriberPolicy_v1", + "description": "Subscriber Policy", + "templateVersion": "0.0.1", + "version": "oofBeijing", + "priority": "1", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "subscriber", + "policyScope": ["vCPE", "subscriber_x", "subscriber_y", "subscriberPolicy"], + "properties": { + "subscriberName": ["subscriber_x", "subscriber_y"], + "subscriberRole": ["PVT Homing"], + "provStatus": ["CAPPED"] + }, + "policyType": "subscriberPolicy", + "serviceName": "vCPE" + } +} \ No newline at end of file diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vG.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vG.json new file mode 100644 index 0000000..c77cdc7 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vG.json @@ -0,0 +1,32 @@ +{ + "service": "VnfPolicy", + "policyName": "oofBeijing.vnfPolicy_vG", + "description": "vnfPolicy", + "templateVersion": "1702.03", + "version": "oofBeijing", + "priority": "6", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vnf_vG", + "policyScope": ["vCPE", "INTERNATIONAL", "ip", "vG", "vnf_policy"], + "policyType": "vnfPolicy", + "resources": ["vG"], + "applicableResources": "any", + "vnfProperties": [ + { + "inventoryProvider": "aai", + "serviceType": "", + "inventoryType": "cloud", + "customerId": "" + }, + { + "inventoryProvider": "multicloud", + "serviceType": "HNGATEWAY", + "inventoryType": "service", + "customerId": "21014aa2-526b-11e6-beb8-9e71128cae77" + } + ] + } +} diff --git a/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vGMuxInfra.json b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vGMuxInfra.json new file mode 100644 index 0000000..3971519 --- /dev/null +++ b/test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vGMuxInfra.json @@ -0,0 +1,32 @@ +{ + "service": "VnfPolicy", + "policyName": "oofBeijing.vnfPolicy_vGMuxInfra", + "description": "vnfPolicy", + "templateVersion": "1702.03", + "version": "oofBeijing", + "priority": "6", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vnf_vGMuxInfra", + "policyScope": ["vCPE", "INTERNATIONAL", "ip", "vGMuxInfra", "vnf_policy"], + "policyType": "vnfPolicy", + "resources": ["vGMuxInfra"], + "applicableResources": "any", + "vnfProperties": [ + { + "inventoryProvider": "aai", + "serviceType": "", + "inventoryType": "cloud", + "customerId": "" + }, + { + "inventoryProvider": "multicloud", + "serviceType": "HNGATEWAY", + "inventoryType": "service", + "customerId": "21014aa2-526b-11e6-beb8-9e71128cae77" + } + ] + } +} diff --git a/test/functest/simulators/simulated-config/common_config.yaml b/test/functest/simulators/simulated-config/common_config.yaml new file mode 100644 index 0000000..770fef2 --- /dev/null +++ b/test/functest/simulators/simulated-config/common_config.yaml @@ -0,0 +1,63 @@ +osdf_system: + libpath: /opt/app/osdf/libs + osdf_ports: + internal: 8699 # inside the Docker container, the app listens to this port + external: 8698 # clients use this port on DockerHost + osdf_ip_default: 0.0.0.0 +# # Important Note: At deployment time, we need to ensure the port mapping is done +# ssl_context: ['./../etc/sniromanager.crt', './../etc/sniromanager.key'] + +osdf_temp: # special configuration required for "workarounds" or testing + local_policies: + global_disabled: True + local_placement_policies_enabled: True + placement_policy_files_vcpe: # workaroud for policy platform glitches (or "work-arounds" for other components) + - Affinity_vCPE_1.json + - Capacity_vGMuxInfra.json + - Capacity_vG_1.json + - Distance_vGMuxInfra_1.json + - Distance_vG_1.json + - Placement_Optimization_1.json + - QueryPolicy_vCPE.json + - hpa_policy_vGMuxInfra_1.json + - hpa_policy_vG_1.json + - vnfPolicy_vG.json + - vnfPolicy_vGMuxInfra.json +service_info: + vCPE: + vcpeHostName: requestParameters.vcpeHostName + e2eVpnKey: requestParameters.e2eVpnKey + +references: + service_name: + source: request + value: serviceInfo.serviceName + subscriber_role: + source: SubscriberPolicy + value: content.properties.subscriberRole + +policy_info: + prioritization_attributes: + policy_type: + - content.policyType + resources: + - content.resources + - content.objectiveParameter.parameterAttributes.resources + service_name: + - content.serviceName + + placement: + policy_fetch: by_scope + policy_scope: + default_scope: OSDF_R2 + vcpe_scope: OSDF_R2 + secondary_scopes: + - + - get_param: service_name + - SubscriberPolicy + - + - get_param: service_name + - get_param: subscriber_role + default: # if no explicit service related information is needed + policy_fetch: by_name + policy_scope: none diff --git a/test/functest/simulators/simulated-config/has_config.yaml b/test/functest/simulators/simulated-config/has_config.yaml new file mode 100644 index 0000000..8cbeda2 --- /dev/null +++ b/test/functest/simulators/simulated-config/has_config.yaml @@ -0,0 +1,24 @@ +policy_config_mapping: + attributes: + hypervisor: hypervisor, + cloud_version: cloudVersion, + cloud_type: cloudType, + dataplane: dataPlane, + network_roles: networkRoles, + complex: complex, + state: state, + country: country, + geo_region: geoRegion, + exclusivity_groups: exclusivityGroups, + replication_role: replicationRole, + remapping: + model-invariant-id: modelInvariantId, + model-version-id: modelVersionId + candidates: + # for (k1, v1), if k1 is in demand, set prop[k2] = _get_candidates(demand[k1]) + exclusionCandidateInfo: excluded_candidates, + requiredCandidateInfo: required_candidates + extra_fields: + # we have [k1, k2, k3, k4] type items and x is policy-content-properties + # if x[k1] == k2: set prop[k3] = k4 + - [inventoryType, cloud, region, {get_param: CHOSEN_REGION}] \ No newline at end of file diff --git a/test/functest/simulators/simulated-config/osdf_config.yaml b/test/functest/simulators/simulated-config/osdf_config.yaml new file mode 100755 index 0000000..a192b70 --- /dev/null +++ b/test/functest/simulators/simulated-config/osdf_config.yaml @@ -0,0 +1,34 @@ +osdfUserNameForSO: "" # The OSDF Manager username for MSO. +odfPasswordForSO: "" # The OSDF Manager password for MSO. + +# msoUrl: "" # The SO url for call back. This will be part of the request, so no need +soUsername: "" # SO username for call back. +soPassword: "" # SO password for call back. + +conductorUrl: "http://localhost:5000/simulated/oof/has-api/flow1-success-simple/main.json" +conductorUsername: "CONDUCTOR-USER" +conductorPassword: "CONDUCTOR-PASSWD" +conductorPingWaitTime: 2 # seconds to wait before calling the conductor retry URL +conductorMaxRetries: 5 # if we don't get something in 30 minutes, give up + +# Policy Platform -- requires ClientAuth, Authorization, and Environment +policyPlatformUrl: http://localhost:5001/simulated/policy/pdp-has-vcpe-good/pdp/getConfig # Policy Dev platform URL +policyPlatformEnv: TEST # Environment for policy platform +policyPlatformUsername: POLICY-USER # Policy platform username. +policyPlatformPassword: POLICY-PASSWD # Policy platform password. +policyClientUsername: POLICY-CLIENT-USER # For use with ClientAuth +policyClientPassword: POLICY-CLIENT-PASSWD # For use with ClientAuth + +messageReaderHosts: https://DMAAP-HOST1:3905,https://DMAAP-HOST2:3905,https://DMAAP-HOST3:3905 +messageReaderTopic: org.onap.oof.osdf.multicloud +messageReaderAafUserId: DMAAP-OSDF-MC-USER +messageReaderAafPassword: DMAAP-OSDF-MC-PASSWD + +sdcUrl: https://SDC-HOST:8443/sdc/v1/catalog +sdcUsername: SDC-OSDF-USER +sdcPassword: SDC-OSDF-PASSWD +sdcONAPInstanceID: ONAP-OSDF + +osdfPlacementUrl: "http://127.0.0.1:24699/osdf/api/v2/placement" +osdfPlacementUsername: "test" +osdfPlacementPassword: "testpwd" diff --git a/test/functest/simulators/simulated-config/simulated-config b/test/functest/simulators/simulated-config/simulated-config new file mode 120000 index 0000000..9c5a662 --- /dev/null +++ b/test/functest/simulators/simulated-config/simulated-config @@ -0,0 +1 @@ +/Users/sastry/PycharmProjects/osdf/test/functest/simulators/simulated-config \ No newline at end of file diff --git a/test/policy-local-files/has_policies_r2/meta-valid-policies.txt b/test/policy-local-files/has_policies_r2/meta-valid-policies.txt deleted file mode 100644 index 6a22945..0000000 --- a/test/policy-local-files/has_policies_r2/meta-valid-policies.txt +++ /dev/null @@ -1,14 +0,0 @@ -Affinity_vCPE_1.json -Capacity_1.json -Distance_vGMuxInfra_1.json -Distance_vG_1.json -Min_Guarantee_vGMuxInfra_1.json -Placement_Optimization_1.json -QueryPolicy_vCPE.json -hpa_policy_vGMuxInfra_1.json -hpa_policy_vG_1.json -subscriber_policy.json -vnfPolicy_vG.json -vnfPolicy_vGMuxInfra.json - - diff --git a/test/test_PolicyCalls.py b/test/test_PolicyCalls.py index 30fc072..fef7574 100644 --- a/test/test_PolicyCalls.py +++ b/test/test_PolicyCalls.py @@ -45,41 +45,32 @@ class TestPolicyCalls(unittest.TestCase): def tearDown(self): pass + def get_req_resp(self, req_file, resp_file): + """Get request/response from files""" + req_json = json_from_file(req_file) + resp_json = json_from_file(resp_file) + return req_json, resp_json + def test_policy_api_call(self): - req_json_file = "./test/placement-tests/request.json" - req_json = json.loads(open(req_json_file).read()) - policy_response_file = "./test/placement-tests/policy_response.json" - policy_response = json.loads(open(policy_response_file).read()) + req_json, policy_response = self.get_req_resp("./test/placement-tests/request.json", + "./test/placement-tests/policy_response.json") with patch('osdf.adapters.policy.interface.policy_api_call', return_value=policy_response): policy_list = interface.remote_api(req_json, osdf_config, service_type="placement") self.assertIsNotNone(policy_list) - def test_policy_api_call_failed_1(self): - req_json_file = "./test/placement-tests/request_error1.json" - req_json = json.loads(open(req_json_file).read()) - policy_response_file = "./test/placement-tests/policy_response.json" - policy_response = json.loads(open(policy_response_file).read()) - with patch('osdf.adapters.policy.interface.policy_api_call', return_value=policy_response): - self.assertRaises(BusinessException, - lambda: interface.remote_api(req_json, osdf_config, service_type="placement")) - - def test_policy_api_call_failed_2(self): - req_json_file = "./test/placement-tests/request.json" - req_json = json.loads(open(req_json_file).read()) - policy_response_file = "./test/placement-tests/policy_response_error1.json" - policy_response = json.loads(open(policy_response_file).read()) + def failure_policy_call(self, req_json_file, resp_json_file): + req_json, policy_response = self.get_req_resp(req_json_file, resp_json_file) with patch('osdf.adapters.policy.interface.policy_api_call', return_value=policy_response): self.assertRaises(BusinessException, lambda: interface.remote_api(req_json, osdf_config, service_type="placement")) - def test_policy_api_call_failed_3(self): - req_json_file = "./test/placement-tests/request.json" - req_json = json.loads(open(req_json_file).read()) - policy_response_file = "./test/placement-tests/policy_response_error2.json" - policy_response = json.loads(open(policy_response_file).read()) - with patch('osdf.adapters.policy.interface.policy_api_call', return_value=policy_response): - self.assertRaises(BusinessException, - lambda: interface.remote_api(req_json, osdf_config, service_type="placement")) + def test_policy_api_call_failed_multi(self): + prefix = "./test/placement-tests" + fail_cases = [("request_error1.json", "policy_response.json"), + ("request.json", "policy_response_error1.json"), + ("request.json", "policy_response_error2.json")] + for req, resp in fail_cases: + self.failure_policy_call(prefix + "/" + req, prefix + "/" + resp) def test_get_by_scope(self): req_json_file = "./test/placement-tests/testScoperequest.json" @@ -110,5 +101,10 @@ class TestPolicyCalls(unittest.TestCase): self.assertListEqual(genDemandslist, actionsList, 'generated demands are not equal to the passed input' '[placementDemand][resourceModuleName] list') + def test_local_policy_location(self): + req_json = json_from_file("./test/placement-tests/request.json") + return interface.local_policies_location(req_json, osdf_config, service_type="placement") + + if __name__ == '__main__': unittest.main() diff --git a/tox.ini b/tox.ini index cdb7381..18be307 100644 --- a/tox.ini +++ b/tox.ini @@ -6,9 +6,11 @@ envlist = py3 [testenv] distribute = False commands = + /bin/bash test/functest/scripts/start-simulators.sh coverage run --module pytest --junitxml xunit-results.xml coverage xml --omit=".tox/py3/*","test/*" coverage report -m --omit=".tox/py3/*","test/*" + /bin/bash test/functest/scripts/stop-simulators.sh # TODO: need to update the above "omit" when we package osdf as pip-installable deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test/test-requirements.txt -- cgit 1.2.3-korg