From 5238bc5d23b926e49c2805890d108cc2f1dcc618 Mon Sep 17 00:00:00 2001 From: Dileep Ranganathan Date: Thu, 15 Feb 2018 08:12:42 -0800 Subject: Added unit tests for Data module Unit test for conductor/data Change-Id: I62e95824a8191adacd630746dc0101660d480886 Issue-ID: OPTFRA-70 Signed-off-by: Dileep Ranganathan --- conductor/conductor/tests/unit/data/__init__.py | 0 .../conductor/tests/unit/data/candidate_list.json | 43 ++++++ .../conductor/tests/unit/data/constraints.json | 95 +++++++++++++ conductor/conductor/tests/unit/data/demands.json | 30 ++++ .../conductor/tests/unit/data/test_service.py | 154 +++++++++++++++++++++ 5 files changed, 322 insertions(+) create mode 100644 conductor/conductor/tests/unit/data/__init__.py create mode 100644 conductor/conductor/tests/unit/data/candidate_list.json create mode 100644 conductor/conductor/tests/unit/data/constraints.json create mode 100644 conductor/conductor/tests/unit/data/demands.json create mode 100644 conductor/conductor/tests/unit/data/test_service.py (limited to 'conductor') diff --git a/conductor/conductor/tests/unit/data/__init__.py b/conductor/conductor/tests/unit/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/conductor/conductor/tests/unit/data/candidate_list.json b/conductor/conductor/tests/unit/data/candidate_list.json new file mode 100644 index 0000000..e29782c --- /dev/null +++ b/conductor/conductor/tests/unit/data/candidate_list.json @@ -0,0 +1,43 @@ +{ + "candidate_list": [ + { + "candidate_id": "1ac71fb8-ad43-4e16-9459-c3f372b8236d", + "candidate_type": "service", + "inventory_type": "service", + "inventory_provider": "aai", + "host_id": "vnf_123456", + "cost": "100", + "location_id": "DLLSTX55", + "location_type": "azure", + "latitude": "32.897480", + "longitude": "-97.040443", + "city": "Dallas", + "state": "TX", + "country": "USA", + "region": "US", + "complex_name": "dalls_one", + "cloud_owner": "att-aic", + "cloud_region_version": "1.1", + "physical_location_id": "DLLSTX55" + }, + { + "candidate_id": "NYCNY55", + "candidate_type": "cloud", + "inventory_type": "cloud", + "inventory_provider": "aai", + "cost": "100", + "location_id": "NYCNY55", + "location_type": "azure", + "latitude": "40.7128", + "longitude": "-74.0060", + "city": "New York", + "state": "NY", + "country": "USA", + "region": "US", + "complex_name": "ny_one", + "cloud_owner": "att-aic", + "cloud_region_version": "1.1", + "physical_location_id": "NYCNY55" + } + ] +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/constraints.json b/conductor/conductor/tests/unit/data/constraints.json new file mode 100644 index 0000000..f89cdaf --- /dev/null +++ b/conductor/conductor/tests/unit/data/constraints.json @@ -0,0 +1,95 @@ +{ + "constraint_name": "check_for_availability", + "candidate_list": [ + { + "candidate_id": "DLLSTX55", + "candidate_type": "cloud", + "inventory_type": "cloud", + "inventory_provider": "aai", + "cost": "100", + "location_id": "DLLSTX55", + "location_type": "azure", + "latitude": "32.897480", + "longitude": "-97.040443", + "city": "Dallas", + "state": "TX", + "country": "USA", + "region": "US", + "complex_name": "dalls_one", + "cloud_owner": "att-aic", + "cloud_region_version": "1.1", + "physical_location_id": "DLLSTX55" + }, + { + "candidate_id": "NYCNY55", + "candidate_type": "cloud", + "inventory_type": "cloud", + "inventory_provider": "aai", + "cost": "100", + "location_id": "NYCNY55", + "location_type": "azure", + "latitude": "40.7128", + "longitude": "-74.0060", + "city": "New York", + "state": "NY", + "country": "USA", + "region": "US", + "complex_name": "ny_one", + "cloud_owner": "att-aic", + "cloud_region_version": "1.1", + "physical_location_id": "NYCNY55" + }, + { + "candidate_id": "c3", + "candidate_type": "service", + "inventory_type": "service", + "inventory_provider": "aai", + "host_id": "vnf_333", + "cost": "100", + "location_id": "SFOCA55", + "location_type": "azure", + "latitude": "32.897480", + "longitude": "-97.040443", + "city": "San Francisco", + "state": "CA", + "country": "USA", + "region": "US", + "complex_name": "sfo_one", + "cloud_owner": "att-aic", + "cloud_region_version": "1.1", + "physical_location_id": "SFOCA55" + } + ], + "constraint_type": "instance_fit", + "controller": "SDN-C", + "request": { + "key1": "value1", + "key2": "value2", + "key3": "value3" + }, + "properties": { + "evaluate": { + "network_roles": "", + "complex_name": { + "any": [ + "dalls_one" + ] + }, + "country": { + "any": [ + "USA" + ] + }, + "state": { + "any": [ + "TX" + ] + }, + "region": { + "all": [ + "US" + ] + } + } + } +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/demands.json b/conductor/conductor/tests/unit/data/demands.json new file mode 100644 index 0000000..459a013 --- /dev/null +++ b/conductor/conductor/tests/unit/data/demands.json @@ -0,0 +1,30 @@ +{ + "demands": { + "vGMuxInfra": [ + { + "inventory_provider": "aai", + "inventory_type": "service", + "service_type": "vG_Mux", + "attributes": { + "customer-id": "some_company", + "orchestration-status": "Activated" + } + } + ], + "vG": [ + { + "inventory_provider": "aai", + "inventory_type": "service", + "service_type": "vG", + "attributes": { + "customer-id": "some_company", + "provisioning-status": "provisioned" + } + }, + { + "inventory_provider": "aai", + "inventory_type": "cloud" + } + ] + } +} \ No newline at end of file diff --git a/conductor/conductor/tests/unit/data/test_service.py b/conductor/conductor/tests/unit/data/test_service.py new file mode 100644 index 0000000..b2c47be --- /dev/null +++ b/conductor/conductor/tests/unit/data/test_service.py @@ -0,0 +1,154 @@ +# +# ------------------------------------------------------------------------- +# Copyright (c) 2018 Intel Corporation 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 conductor.data.service as service +import mock +import stevedore +import yaml +from conductor.data.plugins.inventory_provider import extensions as ip_ext +from conductor.data.plugins.service_controller import extensions as sc_ext +from conductor.data.service import DataEndpoint +from oslo_config import cfg + + +class TestDataEndpoint(unittest.TestCase): + + def setUp(self): + ip_ext_manager = ( + ip_ext.Manager(cfg.CONF, 'conductor.inventory_provider.plugin')) + sc_ext_manager = ( + sc_ext.Manager(cfg.CONF, 'conductor.service_controller.plugin')) + self.data_ep = DataEndpoint(ip_ext_manager, sc_ext_manager) + + def tearDown(self): + pass + + def test_get_candidate_location(self): + req_json_file = './conductor/tests/unit/data/candidate_list.json' + req_json_candidate = json.loads(open(req_json_file).read()) + req_json = dict() + req_json['candidate'] = req_json_candidate['candidate_list'][0] + location = (32.897480, -97.040443) + self.assertEqual({'response': location, 'error': False}, + self.data_ep.get_candidate_location(None, req_json)) + req_json['candidate']['latitude'] = None + req_json['candidate']['longitude'] = None + self.assertEqual({'response': None, 'error': True}, + self.data_ep.get_candidate_location(None, + req_json)) + req_json['candidate'] = req_json_candidate['candidate_list'][1] + location = (40.7128, -74.0060) + self.assertEqual({'response': location, 'error': False}, + self.data_ep.get_candidate_location(None, req_json)) + + def test_get_candidate_zone(self): + req_json_file = './conductor/tests/unit/data/candidate_list.json' + req_json_candidate = json.loads(open(req_json_file).read()) + req_json = dict() + req_json['candidate'] = req_json_candidate['candidate_list'][0] + req_json['category'] = None + self.assertEqual({'response': None, 'error': True}, + self.data_ep.get_candidate_zone(None, req_json)) + req_json['category'] = 'region' + self.assertEqual({'response': 'DLLSTX55', 'error': False}, + self.data_ep.get_candidate_zone(None, req_json)) + req_json['category'] = 'complex' + self.assertEqual({'response': 'dalls_one', 'error': False}, + self.data_ep.get_candidate_zone(None, req_json)) + req_json['candidate'] = req_json_candidate['candidate_list'][1] + req_json['category'] = 'region' + self.assertEqual({'response': 'NYCNY55', 'error': False}, + self.data_ep.get_candidate_zone(None, req_json)) + + + @mock.patch.object(service.LOG, 'error') + @mock.patch.object(service.LOG, 'debug') + @mock.patch.object(stevedore.ExtensionManager, 'map_method') + def test_get_candidates_from_service(self, ext_mock, debug_mock, + error_mock): + req_json_file = './conductor/tests/unit/data/constraints.json' + req_json = yaml.safe_load(open(req_json_file).read()) + candidate_list = req_json['candidate_list'] + ext_mock.return_value = [candidate_list] + self.maxDiff = None + self.assertEqual(2, len( + self.data_ep.get_candidates_from_service(None, req_json))) + req_json['controller'] = 'APP-C' + self.assertEqual({'response': [], 'error': False}, + self.data_ep.get_candidates_from_service(None, + req_json)) + + def test_get_candidate_discard_set(self): + req_json_file = './conductor/tests/unit/data/constraints.json' + req_json = yaml.safe_load(open(req_json_file).read()) + value_attrib = 'complex_name' + value = req_json['properties']['evaluate'][value_attrib] + candidate_list = req_json['candidate_list'] + self.assertEqual(2, len(self.data_ep.get_candidate_discard_set(value, + candidate_list, + value_attrib))) + value_attrib = 'region' + value = req_json['properties']['evaluate'][value_attrib] + self.assertEqual(0, len(self.data_ep.get_candidate_discard_set(value, + candidate_list, + value_attrib))) + + @mock.patch.object(service.LOG, 'error') + @mock.patch.object(service.LOG, 'debug') + @mock.patch.object(service.LOG, 'info') + @mock.patch.object(stevedore.ExtensionManager, 'map_method') + @mock.patch.object(stevedore.ExtensionManager, 'names') + def test_get_candidates_by_attributes(self, ext_mock2, ext_mock1, + info_mock, debug_mock, error_mock): + req_json_file = './conductor/tests/unit/data/constraints.json' + req_json = yaml.safe_load(open(req_json_file).read()) + candidate_list = req_json['candidate_list'] + ext_mock1.return_value = [candidate_list] + ext_mock2.return_value = [None] + self.maxDiff = None + expected_response = {'response': [candidate_list[0]], 'error': False} + self.assertEqual(expected_response, + self.data_ep.get_candidates_by_attributes(None, + req_json)) + + @mock.patch.object(service.LOG, 'error') + @mock.patch.object(service.LOG, 'debug') + @mock.patch.object(service.LOG, 'info') + @mock.patch.object(stevedore.ExtensionManager, 'map_method') + def test_reslove_demands(self, ext_mock, info_mock, debug_mock, + error_mock): + req_json_file = './conductor/tests/unit/data/demands.json' + req_json = yaml.safe_load(open(req_json_file).read()) + ext_mock.return_value = [] + expected_response = {'response': {'resolved_demands': None}, + 'error': True} + self.assertEqual(expected_response, + self.data_ep.resolve_demands(None, req_json)) + return_value = req_json['demands']['vG'] + ext_mock.return_value = [return_value] + expected_response = {'response': {'resolved_demands': return_value}, + 'error': False} + self.assertEqual(expected_response, + self.data_ep.resolve_demands(None, req_json)) + + +if __name__ == "__main__": + unittest.main() -- cgit 1.2.3-korg