From b8ce22681bdff529644bbfaa40ed8c18370d685d Mon Sep 17 00:00:00 2001 From: krishnaa96 Date: Fri, 23 Oct 2020 11:53:53 +0530 Subject: Fix match_hpa with multiple inventory providers match_hpa is implemented only for AAI inventory provider, but it was called using map_method In order to avoid calling the inventories which have not implemented it, lets create a method "invoke_method" in the inventory provider which will return None, if the method required is not implemented. Issue-ID: OPTFRA-864 Signed-off-by: krishnaa96 Change-Id: Idc49be08f10b23404024f9655900b15bc19776e4 --- .../data/plugins/inventory_provider/aai.py | 13 +- .../data/plugins/inventory_provider/base.py | 3 + .../data/plugins/inventory_provider/hpa_utils.py | 171 ++++++++++++++++++--- conductor/conductor/data/service.py | 160 ++----------------- .../solver/utils/constraint_engine_interface.py | 18 +-- .../data/plugins/inventory_provider/test_aai.py | 13 +- .../conductor/tests/unit/data/test_service.py | 28 ++-- 7 files changed, 203 insertions(+), 203 deletions(-) (limited to 'conductor') diff --git a/conductor/conductor/data/plugins/inventory_provider/aai.py b/conductor/conductor/data/plugins/inventory_provider/aai.py index dc30a59..a87cbb6 100644 --- a/conductor/conductor/data/plugins/inventory_provider/aai.py +++ b/conductor/conductor/data/plugins/inventory_provider/aai.py @@ -151,6 +151,10 @@ class AAI(base.InventoryProviderBase): """Return human-readable name.""" return "A&AI" + def invoke_method(self, arg): + if arg.pop('method_name') == "get_candidates_with_hpa": + return hpa_utils.get_candidates_with_hpa(arg) + @staticmethod def _get_version_from_string(string): """Extract version number from string""" @@ -1859,15 +1863,6 @@ class AAI(base.InventoryProviderBase): reason="excluded candidate") return has_candidate - def match_hpa(self, candidate, features): - """Match HPA features requirement with the candidate flavors """ - hpa_provider = hpa_utils.HpaMatchProvider(candidate, features) - if hpa_provider.init_verify(): - directives = hpa_provider.match_flavor() - else: - directives = None - return directives - def get_nxi_candidates(self, filtering_attributes): raw_path = 'nodes/service-instances' + aai_utils.add_query_params_and_depth(filtering_attributes, "2") path = self._aai_versioned_path(raw_path) diff --git a/conductor/conductor/data/plugins/inventory_provider/base.py b/conductor/conductor/data/plugins/inventory_provider/base.py index 8afb090..e79a1cd 100644 --- a/conductor/conductor/data/plugins/inventory_provider/base.py +++ b/conductor/conductor/data/plugins/inventory_provider/base.py @@ -40,3 +40,6 @@ class InventoryProviderBase(base.DataPlugin): def resolve_demands(self, demands): """Resolve demands into inventory candidate lists""" pass + + def invoke_method(self, arg): + return None diff --git a/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py b/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py index bd7e44c..1d4a2d7 100644 --- a/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py +++ b/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py @@ -18,29 +18,30 @@ # ------------------------------------------------------------------------- # -'''Utility functions for - Hardware Platform Awareness (HPA) constraint plugin''' +"""Utility functions for + Hardware Platform Awareness (HPA) constraint plugin""" import operator +import yaml + +from oslo_log import log import conductor.common.prometheus_metrics as PC -# python imports -import yaml +from conductor.i18n import _LE from conductor.i18n import _LI -# Third-party library imports -from oslo_log import log +from conductor.i18n import _LW + LOG = log.getLogger(__name__) -def match_all_operator(big_list, small_list): - ''' - Match ALL operator for HPA - Check if smaller list is a subset of bigger list +def match_all_operator(big_list, small_list): + """Match ALL operator for HPA Check if smaller list is a subset of bigger list + :param big_list: bigger list :param small_list: smaller list :return: True or False - ''' + """ if not big_list or not small_list: return False @@ -50,6 +51,134 @@ def match_all_operator(big_list, small_list): return small_set.issubset(big_set) +def get_candidates_with_hpa(arg): + """RPC for getting candidates flavor mapping for matching hpa + + :param ctx: context + :param arg: contains input passed from client side for RPC call + :return: response candidate_list with matching label to flavor mapping + """ + candidate_list = arg["candidate_list"] + id = arg["id"] + type = arg["type"] + directives = arg["directives"] + attr = directives[0].get("attributes") + label_name = attr[0].get("attribute_name") + flavorProperties = arg["flavorProperties"] + discard_set = set() + for i in range(len(candidate_list)): + # perform this check only for cloud candidates + if candidate_list[i]["inventory_type"] != "cloud": + continue + + # Check if flavor mapping for current label_name already + # exists. This is an invalid condition. + if candidate_list[i].get("directives") and attr[0].get( + "attribute_value") != "": + LOG.error(_LE("Flavor mapping for label name {} already" + "exists").format(label_name)) + continue + + # RPC call to inventory provider for matching hpa capabilities + result = match_hpa(candidate=candidate_list[i], features=flavorProperties) + + flavor_name = None + if result: + LOG.debug("Find results {}".format(result)) + flavor_info = result.get("flavor_map") + req_directives = result.get("directives") + LOG.debug("Get directives {}".format(req_directives)) + + else: + flavor_info = None + LOG.info( + _LW("No flavor mapping returned" + " for candidate: {}").format( + candidate_list[i].get("candidate_id"))) + + # Metrics to Prometheus + m_vim_id = candidate_list[i].get("vim-id") + if not flavor_info: + discard_set.add(candidate_list[i].get("candidate_id")) + PC.HPA_CLOUD_REGION_UNSUCCESSFUL.labels('ONAP', 'N/A', + m_vim_id).inc() + else: + if not flavor_info.get("flavor-name"): + discard_set.add(candidate_list[i].get("candidate_id")) + PC.HPA_CLOUD_REGION_UNSUCCESSFUL.labels('ONAP', 'N/A', + m_vim_id).inc() + else: + if not candidate_list[i].get("flavor_map"): + candidate_list[i]["flavor_map"] = {} + # Create flavor mapping for label_name to flavor + flavor_name = flavor_info.get("flavor-name") + flavor_id = flavor_info.get("flavor-id") + candidate_list[i]["flavor_map"][label_name] = flavor_name + candidate_list[i]["flavor_map"]["flavorId"] = flavor_id + # Create directives if not exist already + if not candidate_list[i].get("all_directives"): + candidate_list[i]["all_directives"] = {} + candidate_list[i]["all_directives"]["directives"] = [] + # Create flavor mapping and merge directives + merge_directives(candidate_list, i, id, type, directives, req_directives) + if not candidate_list[i].get("hpa_score"): + candidate_list[i]["hpa_score"] = 0 + candidate_list[i]["hpa_score"] += flavor_info.get("score") + + # Metrics to Prometheus + PC.HPA_CLOUD_REGION_SUCCESSFUL.labels('ONAP', 'N/A', + m_vim_id).inc() + + # return candidates not in discard set + candidate_list[:] = [c for c in candidate_list + if c['candidate_id'] not in discard_set] + LOG.info(_LI( + "Candidates with matching hpa capabilities: {}").format(candidate_list)) + return candidate_list + + +def merge_directives(candidate_list, index, id, type, directives, feature_directives): + """Merge the flavor_directives with other diectives listed under hpa capabilities in the policy + + :param candidate_list: all candidates + :param index: index number + :param id: vfc name + :param type: vfc type + :param directives: directives for each vfc + :param feature_directives: directives for hpa-features + :return: + """ + directive = {"id": id, + "type": type, + "directives": ""} + flavor_id_attributes = {"attribute_name": "flavorId", "attribute_value": ""} + for ele in directives: + if "flavor_directives" in ele.get("type"): + flag = True + if len(ele.get("attributes")) <= 1: + ele.get("attributes").append(flavor_id_attributes) + break + else: + flag = False + if not flag: + LOG.error("No flavor directives found in {}".format(id)) + for item in feature_directives: + if item and item not in directives: + directives.append(item) + directive["directives"] = directives + candidate_list[index]["all_directives"]["directives"].append(directive) + + +def match_hpa(candidate, features): + """Match HPA features requirement with the candidate flavors """ + hpa_provider = HpaMatchProvider(candidate, features) + if hpa_provider.init_verify(): + directives = hpa_provider.match_flavor() + else: + directives = None + return directives + + class HpaMatchProvider(object): def __init__(self, candidate, req_cap_list): @@ -75,7 +204,7 @@ class HpaMatchProvider(object): for capability in CapabilityDataParser.get_item(self.req_cap_list, None): if capability.item['mandatory'].lower() == 'true': - hpa_list = {k: capability.item[k] \ + hpa_list = {k: capability.item[k] for k in hpa_keys if k in capability.item} if hpa_list not in req_filter_list: req_filter_list.append(hpa_list) @@ -90,13 +219,13 @@ class HpaMatchProvider(object): # Metrics to Prometheus m_flavor_name = flavor['flavor-name'] PC.HPA_FLAVOR_MATCH_UNSUCCESSFUL.labels('ONAP', 'N/A', 'N/A', - 'N/A', self.m_vim_id, - m_flavor_name).inc() + 'N/A', self.m_vim_id, + m_flavor_name).inc() continue for capability in CapabilityDataParser.get_item(flavor_cap_list, 'hpa-capability'): - hpa_list = {k: capability.item[k] \ - for k in hpa_keys if k in capability.item} + hpa_list = {k: capability.item[k] + for k in hpa_keys if k in capability.item} flavor_filter_list.append(hpa_list) # if flavor has the matching capability compare attributes if self._is_cap_supported(flavor_filter_list, req_filter_list): @@ -132,7 +261,6 @@ class HpaMatchProvider(object): m_flavor_name).inc() return directives - def _is_cap_supported(self, flavor, cap): try: for elem in cap: @@ -174,7 +302,7 @@ class HpaMatchProvider(object): def _get_flavor_attribute(self, flavor_attr): try: attrib_value = yaml.load(flavor_attr['hpa-attribute-value']) - except: + except Exception: return None f_unit = None @@ -210,7 +338,6 @@ class HpaMatchProvider(object): return op - def _compare_attribute(self, flavor_attr, req_attr): req_value, req_op = self._get_req_attribute(req_attr) @@ -240,7 +367,7 @@ class HpaMatchProvider(object): # Only integers left to compare if req_op in ['<', '>', '<=', '>=', '=']: - return op(int(flavor_value), int(req_value)) + return op(int(flavor_value), int(req_value)) return False @@ -279,11 +406,11 @@ class HpaMatchProvider(object): # filter to get the attribute being compared flavor_feature_attr = \ filter(lambda ele: ele['hpa-attribute-key'] == - req_attr_key, flavor_cfa) + req_attr_key, flavor_cfa) if not flavor_feature_attr: flavor_flag = False elif not self._compare_attribute(list(flavor_feature_attr)[0], - req_feature_attr): + req_feature_attr): flavor_flag = False if not flavor_flag: continue diff --git a/conductor/conductor/data/service.py b/conductor/conductor/data/service.py index 48f3305..743ea8e 100644 --- a/conductor/conductor/data/service.py +++ b/conductor/conductor/data/service.py @@ -27,6 +27,7 @@ from conductor import messaging # from conductor import __file__ as conductor_root from conductor.common.music import messaging as music_messaging from conductor.common.utils import conductor_logging_util as log_util +from conductor.data.plugins.inventory_provider.base import InventoryProviderBase as Base 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.plugins.vim_controller import extensions as vc_ext @@ -83,7 +84,6 @@ class DataServiceLauncher(object): PC._init_metrics(0) self.init_extension_managers(conf) - def init_extension_managers(self, conf): """Initialize extension managers.""" self.ip_ext_manager = (ip_ext.Manager(conf, 'conductor.inventory_provider.plugin')) @@ -126,6 +126,17 @@ class DataEndpoint(object): 'translator_triage': [] } + def invoke_method(self, ctx, arg): + error = False + results = self.ip_ext_manager.map_method('invoke_method', arg) + if results: + results = list(filter(None, results)) + results = [item for sublist in results for item in sublist] + else: + error = True + return {'response': results, + 'error': error} + def get_candidate_location(self, ctx, arg): # candidates should have lat long info already error = False @@ -449,130 +460,6 @@ class DataEndpoint(object): candidate_list, self.ip_ext_manager.names()[0])) return {'response': candidate_list, 'error': False} - def get_candidates_with_hpa(self, ctx, arg): - ''' - RPC for getting candidates flavor mapping for matching hpa - :param ctx: context - :param arg: contains input passed from client side for RPC call - :return: response candidate_list with matching label to flavor mapping - ''' - error = False - candidate_list = arg["candidate_list"] - id = arg["id"] - type = arg["type"] - directives = arg["directives"] - attr = directives[0].get("attributes") - label_name = attr[0].get("attribute_name") - flavorProperties = arg["flavorProperties"] - discard_set = set() - for i in range(len(candidate_list)): - # perform this check only for cloud candidates - if candidate_list[i]["inventory_type"] != "cloud": - continue - - # Check if flavor mapping for current label_name already - # exists. This is an invalid condition. - if candidate_list[i].get("directives") and attr[0].get( - "attribute_value") != "": - LOG.error(_LE("Flavor mapping for label name {} already" - "exists").format(label_name)) - continue - - # RPC call to inventory provider for matching hpa capabilities - results = self.ip_ext_manager.map_method( - 'match_hpa', - candidate=candidate_list[i], - features=flavorProperties - ) - - flavor_name = None - if results and len(results) > 0 and results[0] is not None: - LOG.debug("Find results {} and results length {}".format(results, len(results))) - flavor_info = results[0].get("flavor_map") - req_directives = results[0].get("directives") - LOG.debug("Get directives {}".format(req_directives)) - - else: - flavor_info = None - LOG.info( - _LW("No flavor mapping returned by " - "inventory provider: {} for candidate: {}").format( - self.ip_ext_manager.names()[0], - candidate_list[i].get("candidate_id"))) - - # Metrics to Prometheus - m_vim_id = candidate_list[i].get("vim-id") - if not flavor_info: - discard_set.add(candidate_list[i].get("candidate_id")) - PC.HPA_CLOUD_REGION_UNSUCCESSFUL.labels('ONAP', 'N/A', - m_vim_id).inc() - else: - if not flavor_info.get("flavor-name"): - discard_set.add(candidate_list[i].get("candidate_id")) - PC.HPA_CLOUD_REGION_UNSUCCESSFUL.labels('ONAP', 'N/A', - m_vim_id).inc() - else: - if not candidate_list[i].get("flavor_map"): - candidate_list[i]["flavor_map"] = {} - # Create flavor mapping for label_name to flavor - flavor_name = flavor_info.get("flavor-name") - flavor_id = flavor_info.get("flavor-id") - candidate_list[i]["flavor_map"][label_name] = flavor_name - candidate_list[i]["flavor_map"]["flavorId"] = flavor_id - # Create directives if not exist already - if not candidate_list[i].get("all_directives"): - candidate_list[i]["all_directives"] = {} - candidate_list[i]["all_directives"]["directives"] = [] - # Create flavor mapping and merge directives - self.merge_directives(candidate_list, i, id, type, directives, req_directives) - if not candidate_list[i].get("hpa_score"): - candidate_list[i]["hpa_score"] = 0 - candidate_list[i]["hpa_score"] += flavor_info.get("score") - - # Metrics to Prometheus - PC.HPA_CLOUD_REGION_SUCCESSFUL.labels('ONAP', 'N/A', - m_vim_id).inc() - - # return candidates not in discard set - candidate_list[:] = [c for c in candidate_list - if c['candidate_id'] not in discard_set] - LOG.info(_LI( - "Candidates with matching hpa capabilities: {}, " - "inventory provider: {}").format(candidate_list, - self.ip_ext_manager.names()[0])) - return {'response': candidate_list, 'error': error} - - def merge_directives(self, candidate_list, index, id, type, directives, feature_directives): - ''' - Merge the flavor_directives with other diectives listed under hpa capabilities in the policy - :param candidate_list: all candidates - :param index: index number - :param id: vfc name - :param type: vfc type - :param directives: directives for each vfc - :param feature_directives: directives for hpa-features - :return: - ''' - directive= {"id": id, - "type": type, - "directives": ""} - flavor_id_attributes = {"attribute_name": "flavorId", "attribute_value": ""} - for ele in directives: - if "flavor_directives" in ele.get("type"): - flag = True - if len(ele.get("attributes")) <= 1: - ele.get("attributes").append(flavor_id_attributes) - break - else: - flag = False - if not flag: - LOG.error("No flavor directives found in {}".format(id)) - for item in feature_directives: - if item and item not in directives: - directives.append(item) - directive["directives"] = directives - candidate_list[index]["all_directives"]["directives"].append(directive) - def get_candidates_with_vim_capacity(self, ctx, arg): ''' RPC for getting candidates with vim capacity @@ -641,13 +528,8 @@ class DataEndpoint(object): self.triage_data_trans['plan_id'] = triage_translator_data['plan_id'] self.triage_data_trans['translator_triage'].append(triage_translator_data['dropped_candidates']) elif not self.triage_data_trans['plan_id'] == triage_translator_data['plan_id'] : - self.triage_data_trans = { - 'plan_id': None, - 'plan_name': None, - 'translator_triage': [] - } - self.triage_data_trans['plan_name'] = triage_translator_data['plan_name'] - self.triage_data_trans['plan_id'] = triage_translator_data['plan_id'] + self.triage_data_trans = {'plan_id': triage_translator_data['plan_id'], + 'plan_name': triage_translator_data['plan_name'], 'translator_triage': []} self.triage_data_trans['translator_triage'].append(triage_translator_data['dropped_candidates']) else: self.triage_data_trans['translator_triage'].append(triage_translator_data['dropped_candidates']) @@ -736,17 +618,3 @@ class DataEndpoint(object): "{}".format(method, reserved_candidates)) return {'response': result, 'error': not result} - - # def do_something(self, ctx, arg): - # """RPC endpoint for data messages - # - # When another service sends a notification over the message - # bus, this method receives it. - # """ - # LOG.debug("Got a message!") - # - # res = { - # 'note': 'do_something called!', - # 'arg': str(arg), - # } - # return {'response': res, 'error': False} diff --git a/conductor/conductor/solver/utils/constraint_engine_interface.py b/conductor/conductor/solver/utils/constraint_engine_interface.py index bbb782d..c26fd6b 100644 --- a/conductor/conductor/solver/utils/constraint_engine_interface.py +++ b/conductor/conductor/solver/utils/constraint_engine_interface.py @@ -119,33 +119,33 @@ class ConstraintEngineInterface(object): def get_candidates_with_hpa(self, id, type, directives, candidate_list, flavorProperties): - ''' - Returns the candidate_list with an addition of flavor_mapping for - matching cloud candidates with hpa constraints. + """Get candidates with an addition of flavor_mapping for matching cloud candidates with hpa constraints. + :param label_name: vm_label_name passed from the SO/Policy :param candidate_list: list of candidates to process :param flavorProperties: hpa features for this vm_label_name :return: candidate_list with hpa features and flavor mapping - ''' + """ ctxt = {} args = {"candidate_list": candidate_list, "flavorProperties": flavorProperties, "id": id, "type": type, - "directives": directives} + "directives": directives, + "method_name": "get_candidates_with_hpa"} response = self.client.call(ctxt=ctxt, - method="get_candidates_with_hpa", + method="invoke_method", args=args) LOG.debug("get_candidates_with_hpa response: {}".format(response)) return response def get_candidates_with_vim_capacity(self, candidate_list, vim_request): - ''' - Returns the candidate_list with required vim capacity. + """Returns the candidate_list with required vim capacity. + :param candidate_list: list of candidates to process :param requests: vim requests with required cpu, memory and disk :return: candidate_list with required vim capacity. - ''' + """ ctxt = {} args = {"candidate_list": candidate_list, "request": vim_request} 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 index 157c1d9..484806e 100644 --- a/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py @@ -26,6 +26,7 @@ from oslo_config import cfg import conductor.data.plugins.inventory_provider.aai as aai from conductor.data.plugins.inventory_provider.aai import AAI +from conductor.data.plugins.inventory_provider.hpa_utils import match_hpa from conductor.data.plugins.triage_translator.triage_translator import TraigeTranslator @@ -670,7 +671,7 @@ tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set", "score": 0}} self.assertEqual(flavor_map, - self.aai_ep.match_hpa(candidate_json['candidate_list'][1], + match_hpa(candidate_json['candidate_list'][1], feature_json[0])) flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43", @@ -678,7 +679,7 @@ tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d "score": 10}, "directives": []} self.assertEqual(flavor_map, - self.aai_ep.match_hpa(candidate_json['candidate_list'][1], + match_hpa(candidate_json['candidate_list'][1], feature_json[1])) flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43", "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set", @@ -693,9 +694,9 @@ tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d ] }]} self.assertEqual(flavor_map, - self.aai_ep.match_hpa(candidate_json['candidate_list'][1], + match_hpa(candidate_json['candidate_list'][1], feature_json[2])) - self.assertEqual(None, self.aai_ep.match_hpa(candidate_json['candidate_list'][1], + self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1], feature_json[3])) flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-19d5-cf6t2b098c43", "flavor-name": "flavor-ovsdpdk-cpu-pinning-double-sriov-NIC-Network-set", @@ -720,9 +721,9 @@ tenant/3c6c471ada7747fe8ff7f28e100b61e8/vservers/vserver/00bddefc-126e-4e4f-a18d ] }] } - self.assertEqual(flavor_map, self.aai_ep.match_hpa(candidate_json['candidate_list'][1], + self.assertEqual(flavor_map, match_hpa(candidate_json['candidate_list'][1], feature_json[4])) - self.assertEqual(None, self.aai_ep.match_hpa(candidate_json['candidate_list'][1], + self.assertEqual(None, match_hpa(candidate_json['candidate_list'][1], feature_json[5])) def test_filter_nssi_candidates(self): diff --git a/conductor/conductor/tests/unit/data/test_service.py b/conductor/conductor/tests/unit/data/test_service.py index c69f2df..f976609 100644 --- a/conductor/conductor/tests/unit/data/test_service.py +++ b/conductor/conductor/tests/unit/data/test_service.py @@ -26,6 +26,7 @@ import mock import stevedore import yaml from conductor.common.utils import conductor_logging_util as log_util +from conductor.data.plugins.inventory_provider import hpa_utils 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.plugins.vim_controller import extensions as vc_ext @@ -277,7 +278,7 @@ class TestDataEndpoint(unittest.TestCase): @mock.patch.object(service.LOG, 'error') @mock.patch.object(service.LOG, 'info') @mock.patch.object(stevedore.ExtensionManager, 'names') - @mock.patch.object(stevedore.ExtensionManager, 'map_method') + @mock.patch.object(hpa_utils, 'match_hpa') def test_get_candidates_with_hpa(self, hpa_mock, ext_mock1, info_mock, error_mock): req_json_file = './conductor/tests/unit/data/candidate_list.json' @@ -304,7 +305,7 @@ class TestDataEndpoint(unittest.TestCase): "directives": directives } ] - hpa_mock.return_value = [flavor_info] + hpa_mock.return_value = flavor_info self.maxDiff = None args = generate_args(candidate_list, flavorProperties, id, type, directives) hpa_candidate_list = copy.deepcopy(candidate_list) @@ -315,35 +316,40 @@ class TestDataEndpoint(unittest.TestCase): hpa_candidate_list1 = [] hpa_candidate_list1.append(hpa_candidate_list[0]) expected_response = {'response': hpa_candidate_list1, 'error': False} + args["method_name"] = "get_candidates_with_hpa" self.assertEqual(expected_response, - self.data_ep.get_candidates_with_hpa(None, args)) + self.data_ep.invoke_method(None, args)) hpa_candidate_list2 = list() hpa_candidate_list2.append(copy.deepcopy(candidate_list[0])) args = generate_args(candidate_list, flavorProperties, id, type, directives) - hpa_mock.return_value = [] + hpa_mock.return_value = {} expected_response = {'response': hpa_candidate_list2, 'error': False} + args["method_name"] = "get_candidates_with_hpa" self.assertEqual(expected_response, - self.data_ep.get_candidates_with_hpa(None, args)) + self.data_ep.invoke_method(None, args)) flavor_info = {} - hpa_mock.return_value = [flavor_info] + hpa_mock.return_value = flavor_info expected_response = {'response': hpa_candidate_list2, 'error': False} + args["method_name"] = "get_candidates_with_hpa" self.assertEqual(expected_response, - self.data_ep.get_candidates_with_hpa(None, args)) + self.data_ep.invoke_method(None, args)) flavor_info = {"flavor-id": "vim-flavor-id1", "flavor-name": ""} - hpa_mock.return_value = [flavor_info] + hpa_mock.return_value = flavor_info + args["method_name"] = "get_candidates_with_hpa" expected_response = {'response': hpa_candidate_list2, 'error': False} self.assertEqual(expected_response, - self.data_ep.get_candidates_with_hpa(None, args)) + self.data_ep.invoke_method(None, args)) flavor_info = {"flavor-id": "vim-flavor-id1"} - hpa_mock.return_value = [flavor_info] + hpa_mock.return_value = flavor_info + args["method_name"] = "get_candidates_with_hpa" expected_response = {'response': hpa_candidate_list2, 'error': False} self.assertEqual(expected_response, - self.data_ep.get_candidates_with_hpa(None, args)) + self.data_ep.invoke_method(None, args)) @mock.patch.object(service.LOG, 'warn') @mock.patch.object(service.LOG, 'info') -- cgit 1.2.3-korg