summaryrefslogtreecommitdiffstats
path: root/dcae-services-policy-sync/tests
diff options
context:
space:
mode:
Diffstat (limited to 'dcae-services-policy-sync/tests')
-rw-r--r--dcae-services-policy-sync/tests/mocks.py191
-rw-r--r--dcae-services-policy-sync/tests/test_client_v0.py191
-rw-r--r--dcae-services-policy-sync/tests/test_client_v1.py216
-rw-r--r--dcae-services-policy-sync/tests/test_cmd.py79
-rw-r--r--dcae-services-policy-sync/tests/test_coroutines.py142
-rw-r--r--dcae-services-policy-sync/tests/test_inventory.py153
6 files changed, 972 insertions, 0 deletions
diff --git a/dcae-services-policy-sync/tests/mocks.py b/dcae-services-policy-sync/tests/mocks.py
new file mode 100644
index 0000000..9a3d6cd
--- /dev/null
+++ b/dcae-services-policy-sync/tests/mocks.py
@@ -0,0 +1,191 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+
+from urllib.parse import urlsplit
+import asyncio, aiohttp
+
+
+class MockConfig:
+ def __init__(self):
+ self.check_period = 60
+ self.quiet_period = 0
+ self.bind = urlsplit("//localhost:8080")
+
+
+class MockFileDumper:
+ def __init__(self):
+ self.closed = False
+
+ async def close(self):
+ self.closed = True
+
+
+class MockInventory:
+ def __init__(self, queue=None):
+ self.was_updated = False
+ self.was_gathered = False
+ self.client = MockClient()
+ self.queue = queue
+ self.quiet = 0
+ self.updates = []
+ self.policy_filters = []
+ self.policy_ids = []
+
+ async def update(self):
+ self.was_updated = True
+ return True
+
+ async def gather(self):
+ self.was_gathered = True
+ print("got here GATHERED")
+ return True
+
+ async def close(self):
+ self.client.closed = True
+
+ async def check_and_update(self):
+ await self.update()
+
+ async def get_policy_content(self, action="UPDATED"):
+ self.updates.append(action)
+
+
+class MockClient:
+ def __init__(self, raise_on_listpolicies=False, raise_on_getconfig=False):
+ self.closed = False
+ self.opened = False
+ self.raise_on_listpolicies = raise_on_listpolicies
+ self.raise_on_getconfig = raise_on_getconfig
+
+ async def close(self):
+ self.closed = True
+
+ async def notificationhandler(self, callback, ids=[], filters=[]):
+ await callback()
+
+ def supports_notifications(self):
+ return True
+
+ async def list_policies(self, filters=[], ids=[]):
+ if self.raise_on_listpolicies:
+ raise aiohttp.ClientError
+
+ return set(
+ [
+ "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml"
+ ]
+ )
+
+ async def get_config(self, filters=[], ids=[]):
+ if self.raise_on_getconfig:
+ raise aiohttp.ClientError
+
+ return [
+ {
+ "policyConfigMessage": "Config Retrieved!",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": {
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "location": " Edge",
+ "uuid": "TestUUID",
+ "policyName": "DCAE.AGING_UVERS_PROD_Tosca_HP_GOC_Model_cl55973_IT64_testAging",
+ "configName": "DCAE_HighlandPark_AgingConfig",
+ "templateVersion": "1607",
+ "priority": "4",
+ "version": 11.0,
+ "policyScope": "resource=Test1,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73_7831_4d02_9545_db4e101f88f8",
+ "riskType": "test",
+ "riskLevel": "2",
+ "guard": "False",
+ "content": {
+ "signature": {
+ "filter_clause": "event.faultFields.alarmCondition LIKE('%chrisluckenbaugh%')"
+ },
+ "name": "testAging",
+ "context": ["PROD"],
+ "priority": 1,
+ "prePublishAging": 40,
+ "preCorrelationAging": 20,
+ },
+ "policyNameWithPrefix": "DCAE.AGING_UVERSE_PSL_Tosca_HP_GOC_Model_cl55973_IT64_testAging",
+ },
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "adlskjfadslkjf",
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ ]
+
+
+class MockLoop:
+ def __init__(self):
+ self.stopped = False
+ self.handlers = []
+ self.tasks = []
+
+ def stop(self):
+ self.stopped = True
+
+ def add_signal_handler(self, signal, handler):
+ self.handlers.append(signal)
+
+ def create_task(self, task):
+ self.tasks.append(task)
+
+ def run_until_complete(self, task):
+ loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(loop)
+ loop.run_until_complete(task)
+
+
+class MockTask:
+ def __init__(self):
+ self.canceled = False
+
+ def cancel(self):
+ self.canceled = True
+
+ def __await__(self):
+ return iter([])
diff --git a/dcae-services-policy-sync/tests/test_client_v0.py b/dcae-services-policy-sync/tests/test_client_v0.py
new file mode 100644
index 0000000..6ca590e
--- /dev/null
+++ b/dcae-services-policy-sync/tests/test_client_v0.py
@@ -0,0 +1,191 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+
+from aiohttp import web, WSMsgType
+import json, pytest, re
+from policysync.clients import (
+ PolicyClientV0 as PolicyClient,
+ WS_HEARTBEAT
+)
+
+
+async def listpolicy(request):
+ return web.json_response(["hello"])
+
+
+async def getconfig(request):
+ j = [
+ {
+ "policyConfigMessage": "Config Retrieved!",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": '{"service":"DCAE_HighlandPark_AgingConfig","location":" Edge","uuid":"TestUUID","policyName":"DCAE.AGING_UVERS_PROD_Tosca_HP_GOC_Model_cl55973_IT64_testAging","configName":"DCAE_HighlandPark_AgingConfig","templateVersion":"1607","priority":"4","version":11.0,"policyScope":"resource=Test1,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73_7831_4d02_9545_db4e101f88f8","riskType":"test","riskLevel":"2","guard":"False","content":{"signature":{"filter_clause":"event.faultFields.alarmCondition LIKE(\'%chrisluckenbaugh%\')"},"name":"testAging","context":["PROD"],"priority":1,"prePublishAging":40,"preCorrelationAging":20},"policyNameWithPrefix":"DCAE.AGING_UVERSE_PSL_Tosca_HP_GOC_Model_cl55973_IT64_testAging"}',
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "adlskjfadslkjf",
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ ]
+
+ return web.json_response(j)
+
+
+async def wshandler(request):
+ resp = web.WebSocketResponse()
+ available = resp.can_prepare(request)
+ await resp.prepare(request)
+ await resp.send_str('{ "loadedPolicies": [{ "policyName": "bar"}] }')
+ await resp.send_bytes(b"bar!!!")
+ await resp.close("closed")
+
+
+@pytest.fixture
+def policyclient(aiohttp_client, loop):
+ app = web.Application()
+ app.router.add_route("POST", "/pdp/api/listPolicy", listpolicy)
+ app.router.add_route("POST", "/pdp/api/getConfig", getconfig)
+ app.router.add_get("/pdp/notifications", wshandler)
+ fake_client = loop.run_until_complete(aiohttp_client(app))
+ server = "{}://{}:{}".format("http", fake_client.host, fake_client.port)
+ return PolicyClient({}, server)
+
+
+async def test_listpolicies(policyclient):
+ j = await policyclient.list_policies(filters=["bar"])
+ assert j == set(["hello"])
+ await policyclient.close()
+ assert policyclient.session.closed
+
+
+async def test_getconfig(policyclient):
+ j = await policyclient.get_config(filters=["bar"])
+
+ assert j == [
+ {
+ "policyConfigMessage": "Config Retrieved!",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": {
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "location": " Edge",
+ "uuid": "TestUUID",
+ "policyName": "DCAE.AGING_UVERS_PROD_Tosca_HP_GOC_Model_cl55973_IT64_testAging",
+ "configName": "DCAE_HighlandPark_AgingConfig",
+ "templateVersion": "1607",
+ "priority": "4",
+ "version": 11.0,
+ "policyScope": "resource=Test1,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73_7831_4d02_9545_db4e101f88f8",
+ "riskType": "test",
+ "riskLevel": "2",
+ "guard": "False",
+ "content": {
+ "signature": {
+ "filter_clause": "event.faultFields.alarmCondition LIKE('%chrisluckenbaugh%')"
+ },
+ "name": "testAging",
+ "context": ["PROD"],
+ "priority": 1,
+ "prePublishAging": 40,
+ "preCorrelationAging": 20,
+ },
+ "policyNameWithPrefix": "DCAE.AGING_UVERSE_PSL_Tosca_HP_GOC_Model_cl55973_IT64_testAging",
+ },
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "adlskjfadslkjf",
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ ]
+ await policyclient.close()
+
+
+async def test_supports_notifications(policyclient):
+ assert policyclient.supports_notifications()
+
+
+async def test_needs_update(policyclient):
+ assert policyclient._needs_update(
+ {"loadedPolicies": [{"policyName": "bar"}]}, [], ["bar"]
+ )
+ assert not policyclient._needs_update(
+ {"loadedPolicies": [{"policyName": "bar"}]}, [], ["foo"]
+ )
+
+
+async def test_ws(policyclient):
+ async def ws_callback():
+ assert True
+
+ await policyclient.notificationhandler(ws_callback, filters=["bar"])
+ await policyclient.close()
+
+ assert policyclient.ws_session.closed
diff --git a/dcae-services-policy-sync/tests/test_client_v1.py b/dcae-services-policy-sync/tests/test_client_v1.py
new file mode 100644
index 0000000..6994a6f
--- /dev/null
+++ b/dcae-services-policy-sync/tests/test_client_v1.py
@@ -0,0 +1,216 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+
+from aiohttp import web, WSMsgType
+import json, pytest, re
+from policysync.clients import PolicyClientV1 as PolicyClient
+
+DECISION_ENDPOINT = 'policy/pdpx/v1/decision'
+async def get_decision(request):
+ req_data = await request.json()
+ assert req_data['ONAPName'] == 'DCAE'
+ assert req_data['ONAPComponent'] == 'policy-sync'
+ assert req_data['action'] == 'configure'
+ assert req_data['resource'] == {
+ 'policy-id': [
+ 'onap.scaleout.tca',
+ 'onap.restart.tca'
+ ]
+ }
+
+
+ j = {
+ "policies": {
+ "onap.scaleout.tca": {
+ "type": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+ "version": "1.0.0",
+ "metadata": {"policy-id": "onap.scaleout.tca"},
+ "properties": {
+ "tca_policy": {
+ "domain": "measurementsForVfScaling",
+ "metricsPerEventName": [
+ {
+ "eventName": "vLoadBalancer",
+ "controlLoopSchemaType": "VNF",
+ "policyScope": "type=configuration",
+ "policyName": "onap.scaleout.tca",
+ "policyVersion": "v0.0.1",
+ "thresholds": [
+ {
+ "closedLoopControlName": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "closedLoopEventStatus": "ONSET",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated",
+ "thresholdValue": 500,
+ "direction": "LESS_OR_EQUAL",
+ "severity": "MAJOR",
+ },
+ {
+ "closedLoopControlName": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "closedLoopEventStatus": "ONSET",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated",
+ "thresholdValue": 5000,
+ "direction": "GREATER_OR_EQUAL",
+ "severity": "CRITICAL",
+ },
+ ],
+ }
+ ],
+ }
+ },
+ },
+ "onap.restart.tca": {
+ "type": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+ "version": "1.0.0",
+ "metadata": {"policy-id": "onap.restart.tca", "policy-version": 1},
+ "properties": {
+ "tca_policy": {
+ "domain": "measurementsForVfScaling",
+ "metricsPerEventName": [
+ {
+ "eventName": "Measurement_vGMUX",
+ "controlLoopSchemaType": "VNF",
+ "policyScope": "DCAE",
+ "policyName": "DCAE.Config_tca-hi-lo",
+ "policyVersion": "v0.0.1",
+ "thresholds": [
+ {
+ "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value",
+ "thresholdValue": 0,
+ "direction": "EQUAL",
+ "severity": "MAJOR",
+ "closedLoopEventStatus": "ABATED",
+ },
+ {
+ "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value",
+ "thresholdValue": 0,
+ "direction": "GREATER",
+ "severity": "CRITICAL",
+ "closedLoopEventStatus": "ONSET",
+ },
+ ],
+ }
+ ],
+ }
+ },
+ },
+ }
+ }
+
+ return web.json_response(j)
+
+
+@pytest.fixture
+def policyclient(aiohttp_client, loop):
+ app = web.Application()
+ app.router.add_route("POST", "/" + DECISION_ENDPOINT, get_decision)
+ fake_client = loop.run_until_complete(aiohttp_client(app))
+ server = "{}://{}:{}".format("http", fake_client.host, fake_client.port)
+ return PolicyClient({}, server)
+
+
+async def test_getconfig(policyclient):
+ j = await policyclient.get_config(ids=['onap.scaleout.tca', 'onap.restart.tca' ])
+ assert j == [{
+ "type": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+ "version": "1.0.0",
+ "metadata": {
+ "policy-id": "onap.scaleout.tca"
+ },
+ "policyName": "onap.scaleout.tca.1-0-0.xml",
+ "policyVersion": "1.0.0",
+ "config": {
+ "tca_policy": {
+ "domain": "measurementsForVfScaling",
+ "metricsPerEventName": [{
+ "eventName": "vLoadBalancer",
+ "controlLoopSchemaType": "VNF",
+ "policyScope": "type=configuration",
+ "policyName": "onap.scaleout.tca",
+ "policyVersion": "v0.0.1",
+ "thresholds": [{
+ "closedLoopControlName": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "closedLoopEventStatus": "ONSET",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated",
+ "thresholdValue": 500,
+ "direction": "LESS_OR_EQUAL",
+ "severity": "MAJOR"
+ },
+ {
+ "closedLoopControlName": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+ "closedLoopEventStatus": "ONSET",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated",
+ "thresholdValue": 5000,
+ "direction": "GREATER_OR_EQUAL",
+ "severity": "CRITICAL"
+ }
+ ]
+ }]
+ }
+ }
+ }, {
+ "type": "onap.policies.monitoring.cdap.tca.hi.lo.app",
+ "version": "1.0.0",
+ "metadata": {
+ "policy-id": "onap.restart.tca",
+ "policy-version": 1
+ },
+ "policyName": "onap.restart.tca.1-0-0.xml",
+ "policyVersion": "1.0.0",
+ "config": {
+ "tca_policy": {
+ "domain": "measurementsForVfScaling",
+ "metricsPerEventName": [{
+ "eventName": "Measurement_vGMUX",
+ "controlLoopSchemaType": "VNF",
+ "policyScope": "DCAE",
+ "policyName": "DCAE.Config_tca-hi-lo",
+ "policyVersion": "v0.0.1",
+ "thresholds": [{
+ "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value",
+ "thresholdValue": 0,
+ "direction": "EQUAL",
+ "severity": "MAJOR",
+ "closedLoopEventStatus": "ABATED"
+ },
+ {
+ "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
+ "version": "1.0.2",
+ "fieldPath": "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value",
+ "thresholdValue": 0,
+ "direction": "GREATER",
+ "severity": "CRITICAL",
+ "closedLoopEventStatus": "ONSET"
+ }
+ ]
+ }]
+ }
+ }
+ }]
+ await policyclient.close()
+
+
+async def test_supports_notifications(policyclient):
+ assert not policyclient.supports_notifications()
diff --git a/dcae-services-policy-sync/tests/test_cmd.py b/dcae-services-policy-sync/tests/test_cmd.py
new file mode 100644
index 0000000..3c061c0
--- /dev/null
+++ b/dcae-services-policy-sync/tests/test_cmd.py
@@ -0,0 +1,79 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+
+import pytest, json, sys, logging, logging.config
+from policysync.cmd import Config, main, parsecmd
+import policysync.coroutines
+
+
+class TestConfig:
+ def test_parse_args(self):
+ args = [
+ "--out",
+ "out",
+ "--pdp-user",
+ "chris",
+ "--pdp-pass",
+ "notapassword",
+ "--pdp-url",
+ "blah",
+ "--duration",
+ "60",
+ "--filters",
+ "[blah]",
+ ]
+
+ c = parsecmd(args)
+
+ assert c.filters == ["blah"]
+ assert c.check_period == 60
+ assert c.out_file == "out"
+
+ def test_parse_args_no_auth(self):
+ c = parsecmd(
+ ["--out", "out", "--pdp-url", "blah", "--duration", "60", "--filters", "[blah]"]
+ )
+
+ assert c.client.pdp_url == "blah"
+ assert c.filters == ["blah"]
+ assert c.check_period == 60
+ assert c.out_file == "out"
+
+ def test_parse_args_no_pdp(self):
+ args = []
+ with pytest.raises(ValueError):
+ parsecmd(args)
+
+ def test_parse_bad_bind(self):
+ args = [
+ "--out",
+ "out",
+ "--pdp-user",
+ "chris",
+ "--pdp-pass",
+ "notapassword",
+ "--pdp-url",
+ "blah",
+ "--duration",
+ "60",
+ "--filters",
+ "[blah]",
+ "--http-bind",
+ "l[ocalhost:100",
+ ]
+
+ with pytest.raises(ValueError):
+ parsecmd(args)
diff --git a/dcae-services-policy-sync/tests/test_coroutines.py b/dcae-services-policy-sync/tests/test_coroutines.py
new file mode 100644
index 0000000..4c90ae8
--- /dev/null
+++ b/dcae-services-policy-sync/tests/test_coroutines.py
@@ -0,0 +1,142 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+
+import pytest, json, sys, asyncio, signal
+from tests.mocks import (
+ MockClient,
+ MockTask,
+ MockLoop,
+ MockInventory,
+ MockConfig,
+ MockFileDumper,
+)
+from policysync.coroutines import (
+ shutdown,
+ periodic_task,
+ notify_task,
+ task_runner,
+ _setup_coroutines,
+ SLEEP_ON_ERROR,
+)
+import policysync.coroutines as coroutines
+
+
+async def test_shutdownhandler():
+ client = MockClient()
+ tasks = [MockTask()]
+ loop = MockLoop()
+ inventory = MockInventory()
+
+ await shutdown( loop, tasks, inventory)
+
+ # Assert that a shutdown results in all tasks in the loop being canceled
+ for x in tasks:
+ assert x.canceled
+
+ # ... And the the PDP client is closed
+ assert inventory.client.closed
+
+ # ... And that the event loop is stopped
+ assert loop.stopped
+
+
+async def test_periodic():
+ inventory = MockInventory()
+ await periodic_task(inventory, 1)
+ assert inventory.was_updated
+
+
+async def test_ws():
+ inventory = MockInventory()
+ await notify_task(inventory, 1)
+ assert inventory.was_updated
+
+
+async def test_task_runner():
+ def should_run():
+ if should_run.counter == 0:
+ should_run.counter += 1
+ return True
+ else:
+ return False
+
+ should_run.counter = 0
+
+ def mocktask(inventory):
+ assert True
+
+ await task_runner(MockInventory(), 1, mocktask, should_run)
+
+
+async def test_task_runner_cancel():
+ def should_run():
+ if should_run.counter == 0:
+ should_run.counter += 1
+ return True
+ elif should_run.counter == 1:
+ # If we get here then fail the test
+ assert False, "Task runner should have broken out of loop before this"
+ return False
+
+ should_run.counter = 0
+
+ # We create a mock task that raises a cancellation error (sent when a asyncio task is canceled)
+ def mocktask(inventory, sleep):
+ raise asyncio.CancelledError
+
+ await task_runner(MockInventory(), 1, mocktask, should_run)
+
+
+def test_setup_coroutines():
+ loop = MockLoop()
+
+ def fake_task_runner(inventory, sleep, task, should_run):
+ return (sleep, task)
+
+ def fake_shutdown(sig, loop, tasks, client):
+ return sig
+
+ def fake_metrics_server(port, addr=None):
+ fake_metrics_server.started = True
+
+ fake_metrics_server.started = False
+
+ inventory = MockInventory()
+ client = MockClient()
+ config = MockConfig()
+
+ _setup_coroutines(
+ loop,
+ inventory,
+ fake_shutdown,
+ fake_task_runner,
+ metrics_server=fake_metrics_server,
+ check_period=config.check_period,
+ bind=config.bind,
+ )
+
+ # By the end of setup coroutines we should have...
+
+ # Gathered initial set of policies
+ assert inventory.was_gathered
+
+ # started the websocket and periodic task running
+ assert (SLEEP_ON_ERROR, notify_task) in loop.tasks
+ assert (config.check_period, periodic_task) in loop.tasks
+
+ # Signal handlers for SIGINT and SIGTERM
+ assert signal.SIGINT in loop.handlers
+ assert signal.SIGTERM in loop.handlers
diff --git a/dcae-services-policy-sync/tests/test_inventory.py b/dcae-services-policy-sync/tests/test_inventory.py
new file mode 100644
index 0000000..5b6f21b
--- /dev/null
+++ b/dcae-services-policy-sync/tests/test_inventory.py
@@ -0,0 +1,153 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+
+import pytest, json, aiohttp, asyncio
+from policysync.inventory import (
+ Inventory,
+ ACTION_GATHERED,
+ ACTION_UPDATED,
+)
+from tests.mocks import MockClient
+
+
+class MockMessage:
+ def __init__(self, type, data):
+ self.type = type
+ self.data = data
+
+
+@pytest.fixture()
+def inventory(request, tmpdir):
+ f1 = tmpdir.mkdir("sub").join("myfile")
+ print(f1)
+ return Inventory(["DCAE.Config_MS_AGING_UVERSE_PROD_.*"], [], f1, MockClient())
+
+
+class TestInventory:
+ @pytest.mark.asyncio
+ async def test_close(self, inventory):
+ await inventory.close()
+ assert inventory.client.closed
+
+ @pytest.mark.asyncio
+ async def test_get_policy_content(self, inventory):
+ await inventory.get_policy_content()
+ with open(inventory.file) as f:
+ data = json.load(f)
+
+ assert data["policies"] == {
+ "items": [
+ {
+ "policyConfigMessage": "Config Retrieved!",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": {
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "location": " Edge",
+ "uuid": "TestUUID",
+ "policyName": "DCAE.AGING_UVERS_PROD_Tosca_HP_GOC_Model_cl55973_IT64_testAging",
+ "configName": "DCAE_HighlandPark_AgingConfig",
+ "templateVersion": "1607",
+ "priority": "4",
+ "version": 11.0,
+ "policyScope": "resource=Test1,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73_7831_4d02_9545_db4e101f88f8",
+ "riskType": "test",
+ "riskLevel": "2",
+ "guard": "False",
+ "content": {
+ "signature": {
+ "filter_clause": "event.faultFields.alarmCondition LIKE('%chrisluckenbaugh%')"
+ },
+ "name": "testAging",
+ "context": ["PROD"],
+ "priority": 1,
+ "prePublishAging": 40,
+ "preCorrelationAging": 20,
+ },
+ "policyNameWithPrefix": "DCAE.AGING_UVERSE_PSL_Tosca_HP_GOC_Model_cl55973_IT64_testAging",
+ },
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "adlskjfadslkjf",
+ "policyName": "DCAE.Config_MS_AGING_UVERSE_PROD_Tosca_HP_AGING_Model_cl55973_IT64_testAging.78.xml",
+ "policyType": "MicroService",
+ "policyVersion": "78",
+ "matchingConditions": {
+ "ECOMPName": "DCAE",
+ "ONAPName": "DCAE",
+ "ConfigName": "DCAE_HighlandPark_AgingConfig",
+ "service": "DCAE_HighlandPark_AgingConfig",
+ "uuid": "TestUUID",
+ "Location": " Edge",
+ },
+ "responseAttributes": {},
+ "property": None,
+ },
+ ]
+ }
+
+ assert data["event"]["action"] == ACTION_UPDATED
+
+ @pytest.mark.asyncio
+ async def test_update(self, inventory):
+ await inventory.update()
+ assert len(inventory.hp_active_inventory) == 1
+
+ assert not await inventory.update()
+
+ @pytest.mark.asyncio
+ async def test_update_listpolicies_exception(self, inventory):
+ inventory.client.raise_on_listpolicies = True
+ assert not await inventory.update()
+
+ @pytest.mark.asyncio
+ async def test_update_getconfig_exception(self, inventory):
+ inventory.client.raise_on_getconfig = True
+ await inventory.get_policy_content()
+
+ @pytest.mark.asyncio
+ async def test_gather(self, inventory):
+ await inventory.gather()
+
+ # We should gather one policy
+ assert len(inventory.hp_active_inventory) == 1
+
+ # type in event should be gather
+ with open(inventory.file) as f:
+ data = json.load(f)
+
+ assert data["event"]["action"] == ACTION_GATHERED
+
+ @pytest.mark.asyncio
+ async def test_ws_text(self, inventory):
+ result = await inventory.check_and_update()
+ assert result == True