From 0d081aedfdcd2a4995e434f6e716e7ac2efe3004 Mon Sep 17 00:00:00 2001 From: rl001m Date: Wed, 7 Mar 2018 16:53:50 -0500 Subject: Added unit test cases for data component Added Python unit test cases for aai.py file in data component. Modified the code in aai.py to make it test-driven. Issue-ID: OPTFRA-79 Change-Id: I5c912c8a13226c6dada921f255a030e798665938 Signed-off-by: rl001m --- .../data/plugins/inventory_provider/aai.py | 28 ++-- .../conductor/tests/unit/data/plugins/__init__.py | 0 .../data/plugins/inventory_provider/__init__.py | 0 .../inventory_provider/_get_complex_host_name.json | 6 + .../inventory_provider/_request_clli_location.json | 6 + .../inventory_provider/_request_get_complex.json | 9 ++ .../inventory_provider/_request_host_name.json | 6 + .../_request_inventory_group_pair.json | 31 +++++ .../plugins/inventory_provider/demand_list.json | 19 +++ .../inventory_provider/generic_vnf_list.json | 49 +++++++ .../data/plugins/inventory_provider/regions.json | 20 +++ .../data/plugins/inventory_provider/test_aai.py | 149 +++++++++++++++++++++ conductor/docker/conductor.conf | 6 +- 13 files changed, 315 insertions(+), 14 deletions(-) create mode 100644 conductor/conductor/tests/unit/data/plugins/__init__.py create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/__init__.py create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/_get_complex_host_name.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/demand_list.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/regions.json create mode 100644 conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py diff --git a/conductor/conductor/data/plugins/inventory_provider/aai.py b/conductor/conductor/data/plugins/inventory_provider/aai.py index fab1505..cb76034 100644 --- a/conductor/conductor/data/plugins/inventory_provider/aai.py +++ b/conductor/conductor/data/plugins/inventory_provider/aai.py @@ -98,23 +98,15 @@ class AAI(base.InventoryProviderBase): self.timeout = self.conf.aai.aai_rest_timeout self.retries = self.conf.aai.aai_retries - kwargs = { - "server_url": self.base, - "retries": self.retries, - "cert_file": self.cert, - "cert_key_file": self.key, - "ca_bundle_file": self.verify, - "log_debug": self.conf.debug, - "read_timeout": self.timeout, - } - self.rest = rest.REST(**kwargs) - # Cache is initially empty self._aai_cache = {} self._aai_complex_cache = {} def initialize(self): + """Perform any late initialization.""" + # Initialize the Python requests + self._init_python_request() # Refresh the cache once for now self._refresh_cache() @@ -175,6 +167,20 @@ class AAI(base.InventoryProviderBase): self.base, path)) return response + def _init_python_request(self): + + kwargs = { + "server_url": self.base, + "retries": self.retries, + "cert_file": self.cert, + "cert_key_file": self.key, + "ca_bundle_file": self.verify, + "log_debug": self.conf.debug, + "read_timeout": self.timeout, + } + self.rest = rest.REST(**kwargs) + + def _refresh_cache(self): """Refresh the A&AI cache.""" if not self.last_refresh_time or \ diff --git a/conductor/conductor/tests/unit/data/plugins/__init__.py b/conductor/conductor/tests/unit/data/plugins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/__init__.py b/conductor/conductor/tests/unit/data/plugins/inventory_provider/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/_get_complex_host_name.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_get_complex_host_name.json new file mode 100644 index 0000000..21a0b3c --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_get_complex_host_name.json @@ -0,0 +1,6 @@ +{ + "country": "USA", + "region": "SE", + "latitude": "28.543251", + "longitude": "-81.377112" +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json new file mode 100644 index 0000000..e3bd708 --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json @@ -0,0 +1,6 @@ +{ + "country": "USA", + "region": "USA", + "latitude": "40.39596", + "longitude": "-74.135342" +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json new file mode 100644 index 0000000..2d51082 --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json @@ -0,0 +1,9 @@ +{ + "complex": { + "country": "USA", + "region": "SE", + "latitude": "28.543251", + "longitude": "-81.377112", + "city": "Middletown" + } +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json new file mode 100644 index 0000000..3c3bd86 --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json @@ -0,0 +1,6 @@ +{ + "results": [{ + "resource-link": "/aai/v11/resources/id/10743840", + "resource-type": "complex" + }] +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json new file mode 100644 index 0000000..8132b78 --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json @@ -0,0 +1,31 @@ +{ + "instance-group": [ + { + "description": "INVENTORY_PAIR", + "relationship-list": { + "relationship": [ + { + "relationship-data": [ + { + "relationship-key": "service-instance.service-instance-id", + "relationship-value": "instance-1" + } + ], + "related-to": "service-instance" + }, + { + "relationship-data": [ + { + "relationship-key": "service-instance.service-instance-id", + "relationship-value": "instance-2" + } + ], + "related-to": "service-instance" + } + ] + }, + "resource-version": "1", + "id": "1" + } + ] +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/demand_list.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/demand_list.json new file mode 100644 index 0000000..c817fbb --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/demand_list.json @@ -0,0 +1,19 @@ + { + "demand_name": [ + { + "attributes": { + "global-customer-id": "customer-123", + "equipment-role": "TEST", + "service-type": "TEST" + }, + "inventory_provider": "aai", + "inventory_type": "service" + }, + { + "service_resource_id": "service-resource-id-123", + "region": "", + "inventory_type": "cloud", + "inventory_provider": "aai" + } + ] + } \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json new file mode 100644 index 0000000..81a82ed --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json @@ -0,0 +1,49 @@ +{ + "generic-vnf": [ + { + "vnf-id": "vnf-id", + "vnf-name": "vnf-name", + "vnf-type": "vpe", + "prov-status": "prov-status", + "equipment-role": "equipment-role", + "resource-version": "resource-version-id", + "relationship-list": { + "relationship": [ + { + "related-to": "service-instance", + "related-link": "service-instance-link", + "relationship-data": [ + { + "relationship-key": "customer.global-customer-id", + "relationship-value": "customer-id" + }, + { + "relationship-key": "service-subscription.service-type", + "relationship-value": "service-type" + }, + { + "relationship-key": "service-instance.service-instance-id", + "relationship-value": "service-instance-id" + } + ] + }, + { + "related-to": "vserver", + "related-link": "vserver-id", + "relationship-data": [ + { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "cloud-owner" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "cloud-region-id" + } + ] + } + + ] + } + } + ] +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/regions.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/regions.json new file mode 100644 index 0000000..e6412c1 --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/regions.json @@ -0,0 +1,20 @@ +{ + "region-name": { + "cloud_type": "opensource", + "complex": { + "city": "Middletown", + "state": "NJ", + "longitude": "30.12", + "latitude": "50.34", + "country": "USA", + "complex_name": "complex-name", + "region": "USA", + "complex_id": "complex-id" + }, + "cloud_region_version": "1.0", + "physical_location_id": "location-id", + "cloud_owner": "cloud-owner", + "cloud_zone": "cloud-zone", + "complex_name": "complex-name" + } +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py b/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py new file mode 100644 index 0000000..4b9a24c --- /dev/null +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py @@ -0,0 +1,149 @@ +# +# ------------------------------------------------------------------------- +# 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. +# +# ------------------------------------------------------------------------- +# +import json +import unittest +import mock +import conductor.data.plugins.inventory_provider.aai as aai +from conductor.data.plugins.inventory_provider.aai import AAI +from oslo_config import cfg + +class TestAAI(unittest.TestCase): + + def setUp(self): + + CONF = cfg.CONF + CONF.register_opts(aai.AAI_OPTS, group='aai') + self.conf = CONF + self.aai_ep = AAI() + + def tearDown(self): + mock.patch.stopall() + + def test_get_version_from_string(self): + + self.assertEqual("2.5", self.aai_ep._get_version_from_string("AAI2.5")) + self.assertEqual("3.0", self.aai_ep._get_version_from_string("AAI3.0")) + + def test_aai_versioned_path(self): + + self.assertEqual('/{}/cloud-infrastructure/cloud-regions/?depth=0'.format(self.conf.aai.server_url_version), + self.aai_ep._aai_versioned_path("/cloud-infrastructure/cloud-regions/?depth=0")) + self.assertEqual('/{}/query?format=id'.format(self.conf.aai.server_url_version), + self.aai_ep._aai_versioned_path("/query?format=id")) + + + def test_resolve_clli_location(self): + + req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json' + req_json = json.loads(open(req_json_file).read()) + + response = mock.MagicMock() + response.status_code = 200 + response.ok = True + response.json.return_value = req_json + + self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response) + self.mock_get_request.start() + self.assertEqual({'country': u'USA', 'latitude': u'40.39596', 'longitude': u'-74.135342'} , + self.aai_ep.resolve_clli_location("clli_code")) + + def test_get_inventory_group_pair(self): + + req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json' + req_json = json.loads(open(req_json_file).read()) + + response = mock.MagicMock() + response.status_code = 200 + response.ok = True + response.json.return_value = req_json + + self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response) + self.mock_get_request.start() + self.assertEqual([[u'instance-1', u'instance-2']] , + self.aai_ep.get_inventory_group_pairs("service_description")) + + def test_resolve_host_location(self): + + req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json' + req_json = json.loads(open(req_json_file).read()) + + req_response = mock.MagicMock() + req_response.status_code = 200 + req_response.ok = True + req_response.json.return_value = req_json + + complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_get_complex_host_name.json' + complex_json = json.loads(open(complex_json_file).read()) + + self.mock_get_request = mock.patch.object(AAI, '_request', return_value=req_response) + self.mock_get_request.start() + + self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json) + self.mock_get_complex.start() + + self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'} , + self.aai_ep.resolve_host_location("host_name")) + + def test_resolve_demands(self): + + self.assertEqual({}, self.aai_ep.resolve_demands(dict())) + + demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/demand_list.json' + demands_list = json.loads(open(demands_list_file).read()) + + generic_vnf_list_file = './conductor/tests/unit/data/plugins/inventory_provider/generic_vnf_list.json' + generic_vnf_list = json.loads(open(generic_vnf_list_file).read()) + + regions_response_file = './conductor/tests/unit/data/plugins/inventory_provider/regions.json' + regions_response = json.loads(open(regions_response_file).read()) + + req_response = mock.MagicMock() + req_response.status_code = 200 + req_response.ok = True + req_response.json.return_value = generic_vnf_list + + self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call', return_value=req_response) + self.mock_first_level_service_call.start() + + self.mock_get_regions = mock.patch.object(AAI, '_get_regions', return_value=regions_response) + self.mock_get_regions.start() + + self.maxDiff = None + self.assertEqual({u'demand_name': [{'sriov_automation': 'false', 'longitude': u'30.12', 'inventory_type': 'cloud', 'inventory_provider': 'aai', 'cloud_owner': u'cloud-owner', 'cloud_region_version': u'1.0', 'service_resource_id': u'service-resource-id-123', 'city': u'Middletown', 'state': u'NJ', 'country': u'USA', 'existing_placement': 'false', 'location_type': 'att_aic', 'location_id': u'region-name', 'complex_name': u'complex-name', 'latitude': u'50.34', 'candidate_id': u'region-name', 'cost': 2.0, 'physical_location_id': u'complex-id', 'region': u'USA'}]} , + self.aai_ep.resolve_demands(demands_list)) + + + #check_network_roles + + + def test_get_complex(self): + + complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json' + complex_json = json.loads(open(complex_json_file).read()) + + response = mock.MagicMock() + response.status_code = 200 + response.ok = True + response.json.return_value = complex_json + + self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response) + self.mock_get_request.start() + + self.assertEqual({u'city': u'Middletown', u'latitude': u'28.543251', u'longitude': u'-81.377112', u'country': u'USA', u'region': u'SE'} , + self.aai_ep._get_complex("/v10/complex/complex_id", "complex_id")) \ No newline at end of file diff --git a/conductor/docker/conductor.conf b/conductor/docker/conductor.conf index b668af4..c93e9ec 100644 --- a/conductor/docker/conductor.conf +++ b/conductor/docker/conductor.conf @@ -151,17 +151,17 @@ server_url_version = v11 # SSL/TLS certificate file in pem format. This certificate must be registered # with the A&AI endpoint. (string value) #certificate_file = /home/saisree/certs/imacculate.client.research.att.com.cer -certificate_file = /home/saisree/larry_certs/lt_hp1174418.client.research.att.com.cer +certificate_file = /home/larry/Desktop/Development/larry_certs/lt_hp1174418.client.research.att.com.cer # Private Certificate Key file in pem format. (string value) # certificate_key_file = /home/saisree/certs/imacculate.client.research.att.com.key -certificate_key_file = /home/saisree/larry_certs/lt_hp1174418.client.research.att.com.key +certificate_key_file = /home/larry/Desktop/Development/larry_certs/lt_hp1174418.client.research.att.com.key # Certificate Authority Bundle file in pem format. Must contain the appropriate # trust chain for theCertificate file. (string value) # certificate_authority_bundle_file = ~/certs/ca-bundle.pem # certificate_authority_bundle_file = /home/saisree/cert/ca-bundle.pem -certificate_authority_bundle_file = /home/saisree/larry_certs/ca_bundle.pem +#certificate_authority_bundle_file = /home/saisree/larry_certs/ca_bundle.pem [api] -- cgit 1.2.3-korg