From 43f18d19dc859f4bf59b1f21aa921d8674d5e977 Mon Sep 17 00:00:00 2001 From: DR695H Date: Wed, 22 May 2019 15:36:04 -0400 Subject: [PATCH] adding in new onap lib and servicemapping this remvoes the need for servicemapping.json Change-Id: I4a151293c19a386b79135816e86f7402ba29ad8d Issue-ID: TEST-157 Signed-off-by: DR695H --- robotframework-onap/ONAPLibrary/ServiceMapping.py | 27 ++++ .../ONAPLibrary/ServiceMappingKeywords.py | 67 ++++++++++ robotframework-onap/ONAPLibrary/__init__.py | 15 +++ robotframework-onap/ONAPLibrary/robotlibcore.py | 148 +++++++++++++++++++++ robotframework-onap/setup.py | 5 +- robotframework-onap/tests/ONAPLibrary/__init__.py | 0 6 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 robotframework-onap/ONAPLibrary/ServiceMapping.py create mode 100644 robotframework-onap/ONAPLibrary/ServiceMappingKeywords.py create mode 100644 robotframework-onap/ONAPLibrary/__init__.py create mode 100644 robotframework-onap/ONAPLibrary/robotlibcore.py create mode 100644 robotframework-onap/tests/ONAPLibrary/__init__.py diff --git a/robotframework-onap/ONAPLibrary/ServiceMapping.py b/robotframework-onap/ONAPLibrary/ServiceMapping.py new file mode 100644 index 0000000..16125c2 --- /dev/null +++ b/robotframework-onap/ONAPLibrary/ServiceMapping.py @@ -0,0 +1,27 @@ +# Copyright 2019 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. + +from ONAPLibrary.robotlibcore import HybridCore +from ONAPLibrary.ServiceMappingKeywords import ServiceMappingKeywords + + +class ServiceMapping(HybridCore): + """ServiceMapping is an ONAP testing library for Robot Framework that enables the use of a service_mapping.json + to dynamically add services to a robot test suite with out changing robot code""" + + def __init__(self): + self.keyword_implementors = [ + ServiceMappingKeywords() + ] + HybridCore.__init__(self, self.keyword_implementors) diff --git a/robotframework-onap/ONAPLibrary/ServiceMappingKeywords.py b/robotframework-onap/ONAPLibrary/ServiceMappingKeywords.py new file mode 100644 index 0000000..610ee57 --- /dev/null +++ b/robotframework-onap/ONAPLibrary/ServiceMappingKeywords.py @@ -0,0 +1,67 @@ +# Copyright 2019 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. + +from robot import utils +from robot.api.deco import keyword +import os.path +import json + + +class ServiceMappingKeywords(object): + """ServiceMapping is used for loading data for services into the robot framework in a structured decentralized way + that lets vnfs be added without code change to testuite""" + + def __init__(self): + super(ServiceMappingKeywords, self).__init__() + self._cache = utils.ConnectionCache('No Service Mappings directories loaded') + + @keyword + def set_directory(self, alias, service_mappings_directory): + self._cache.register(service_mappings_directory, alias=alias) + + @keyword + def get_service_folder_mapping(self, alias, service): + """returns an array of strings with the folder where the vnf's heat files are stored """ + return self._service_mapping(alias, service)['GLOBAL_SERVICE_FOLDER_MAPPING'][service] + + @keyword + def get_service_vnf_mapping(self, alias, service): + """returns an array of strings that is the vnfs in this service """ + return self._service_mapping(alias, service)['GLOBAL_SERVICE_VNF_MAPPING'][service] + + @keyword + def get_service_neutron_mapping(self, alias, service): + """returns an array of strings that lists the neutron networks needed in this service """ + return self._service_mapping(alias, service)['GLOBAL_SERVICE_GEN_NEUTRON_NETWORK_MAPPING'][service] + + @keyword + def get_service_deployment_artifact_mapping(self, alias, service): + """returns an array of strings that is the extra deployment artifacts needed with this service """ + return self._service_mapping(alias, service)['GLOBAL_SERVICE_DEPLOYMENT_ARTIFACT_MAPPING'][service] + + @keyword + def get_service_template_mapping(self, alias, service, vnf): + """returns an array of strings that are the heat templates for this vnf """ + return self._service_mapping(alias, service)['GLOBAL_SERVICE_TEMPLATE_MAPPING'][vnf] + + """@PendingDeprecationWarning""" + @keyword + def get_validate_name_mapping(self, alias, service, vnf): + """returns an array of strings that are the names to validate in heatbridge for the vnf """ + return self._service_mapping(alias, service)['GLOBAL_VALIDATE_NAME_MAPPING'][vnf] + + def _service_mapping(self, alias, service): + filepath = os.path.join(self._cache.switch(alias), service, 'service_mapping.json') + with open(filepath, 'r') as f: + return json.load(f) diff --git a/robotframework-onap/ONAPLibrary/__init__.py b/robotframework-onap/ONAPLibrary/__init__.py new file mode 100644 index 0000000..5f28b06 --- /dev/null +++ b/robotframework-onap/ONAPLibrary/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2019 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. + +"""ONAPLibrary is an ONAP testing library for Robot Framework.""" diff --git a/robotframework-onap/ONAPLibrary/robotlibcore.py b/robotframework-onap/ONAPLibrary/robotlibcore.py new file mode 100644 index 0000000..9719e52 --- /dev/null +++ b/robotframework-onap/ONAPLibrary/robotlibcore.py @@ -0,0 +1,148 @@ +# Copyright 2017- Robot Framework Foundation +# +# 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. + +"""Generic test library core for Robot Framework. + +Main usage is easing creating larger test libraries. For more information and +examples see the project pages at +https://github.com/robotframework/PythonLibCore +""" + +import inspect +import sys + +try: + from robot.api.deco import keyword +except ImportError: # Support RF < 2.9 + def keyword(name=None, tags=()): + if callable(name): + return keyword()(name) + def decorator(func): + func.robot_name = name + func.robot_tags = tags + return func + return decorator + + +PY2 = sys.version_info < (3,) + +__version__ = '1.0.1.dev1' + + +class HybridCore(object): + + def __init__(self, library_components): + self.keywords = {} + self.attributes = {} + self.add_library_components(library_components) + self.add_library_components([self]) + + def add_library_components(self, library_components): + for component in library_components: + for name, func in self._get_members(component): + if callable(func) and hasattr(func, 'robot_name'): + kw = getattr(component, name) + kw_name = func.robot_name or name + self.keywords[kw_name] = kw + # Expose keywords as attributes both using original + # method names as well as possible custom names. + self.attributes[name] = self.attributes[kw_name] = kw + + def _get_members(self, component): + if inspect.ismodule(component): + return inspect.getmembers(component) + if inspect.isclass(component): + raise TypeError('Libraries must be modules or instances, got ' + 'class {!r} instead.'.format(component.__name__)) + if type(component) != component.__class__: + raise TypeError('Libraries must be modules or new-style class ' + 'instances, got old-style class {!r} instead.' + .format(component.__class__.__name__)) + return self._get_members_from_instance(component) + + def _get_members_from_instance(self, instance): + # Avoid calling properties by getting members from class, not instance. + cls = type(instance) + for name in dir(instance): + owner = cls if hasattr(cls, name) else instance + yield name, getattr(owner, name) + + def __getattr__(self, name): + if name in self.attributes: + return self.attributes[name] + raise AttributeError('{!r} object has no attribute {!r}' + .format(type(self).__name__, name)) + + def __dir__(self): + if PY2: + my_attrs = dir(type(self)) + list(self.__dict__) + else: + my_attrs = super().__dir__() + return sorted(set(my_attrs) | set(self.attributes)) + + def get_keyword_names(self): + return sorted(self.keywords) + + +class DynamicCore(HybridCore): + _get_keyword_tags_supported = False # get_keyword_tags is new in RF 3.0.2 + + def run_keyword(self, name, args, kwargs): + return self.keywords[name](*args, **kwargs) + + def get_keyword_arguments(self, name): + kw = self.keywords[name] if name != '__init__' else self.__init__ + args, defaults, varargs, kwargs = self._get_arg_spec(kw) + args += ['{}={}'.format(name, value) for name, value in defaults] + if varargs: + args.append('*{}'.format(varargs)) + if kwargs: + args.append('**{}'.format(kwargs)) + return args + + def _get_arg_spec(self, kw): + if PY2: + spec = inspect.getargspec(kw) + keywords = spec.keywords + else: + spec = inspect.getfullargspec(kw) + keywords = spec.varkw + args = spec.args[1:] if inspect.ismethod(kw) else spec.args # drop self + defaults = spec.defaults or () + nargs = len(args) - len(defaults) + mandatory = args[:nargs] + defaults = zip(args[nargs:], defaults) + return mandatory, defaults, spec.varargs, keywords + + def get_keyword_tags(self, name): + self._get_keyword_tags_supported = True + return self.keywords[name].robot_tags + + def get_keyword_documentation(self, name): + if name == '__intro__': + return inspect.getdoc(self) or '' + if name == '__init__': + return inspect.getdoc(self.__init__) or '' + kw = self.keywords[name] + doc = inspect.getdoc(kw) or '' + if kw.robot_tags and not self._get_keyword_tags_supported: + tags = 'Tags: {}'.format(', '.join(kw.robot_tags)) + doc = '{}\n\n{}'.format(doc, tags) if doc else tags + return doc + + +class StaticCore(HybridCore): + + def __init__(self): + HybridCore.__init__(self, []) diff --git a/robotframework-onap/setup.py b/robotframework-onap/setup.py index 6cecbc5..31168e5 100644 --- a/robotframework-onap/setup.py +++ b/robotframework-onap/setup.py @@ -39,11 +39,12 @@ setup( 'requests', 'future' ], # what we need - packages=['eteutils', 'loadtest', 'vcpeutils'], # The name of your scripts package + packages=['eteutils', 'loadtest', 'vcpeutils', 'ONAPLibrary'], # The name of your scripts package package_dir={ 'eteutils': 'eteutils', 'loadtest': 'loadtest', - 'vcpeutils': 'vcpeutils' + 'vcpeutils': 'vcpeutils', + 'ONAPLibrary': 'ONAPLibrary' }, # The location of your scipts package classifiers=[ 'Development Status :: 4 - Beta', diff --git a/robotframework-onap/tests/ONAPLibrary/__init__.py b/robotframework-onap/tests/ONAPLibrary/__init__.py new file mode 100644 index 0000000..e69de29 -- 2.16.6