summaryrefslogtreecommitdiffstats
path: root/vnftest/onap
diff options
context:
space:
mode:
authorChris Donley <christopher.donley@huawei.com>2018-03-14 14:18:27 +0000
committerGerrit Code Review <gerrit@onap.org>2018-03-14 14:18:27 +0000
commit4951250edc384d1736669ec9f656ecca6aab5426 (patch)
treed690c086bd29339cb88bf18bbb3da3de13010ac6 /vnftest/onap
parentab3381d2e8a6207fa792d12ba516e5c6efa2dc27 (diff)
parent30497ac60f062adba7dae751110dd9fc87ef04db (diff)
Merge "Onboard package test case"
Diffstat (limited to 'vnftest/onap')
-rw-r--r--vnftest/onap/common/__init__.py (renamed from vnftest/onap/contexts/__init__.py)0
-rw-r--r--vnftest/onap/common/vnf_type_crawler.py (renamed from vnftest/onap/contexts/dummy.py)30
-rw-r--r--vnftest/onap/contexts/base.py65
-rw-r--r--vnftest/onap/contexts/csar.py44
-rw-r--r--vnftest/onap/core/__init__.py45
-rw-r--r--vnftest/onap/core/plugin.py175
-rw-r--r--vnftest/onap/core/report.py128
-rw-r--r--vnftest/onap/core/runner.py44
-rw-r--r--vnftest/onap/core/step.py44
-rw-r--r--vnftest/onap/core/task.py616
-rw-r--r--vnftest/onap/core/testcase.py113
-rw-r--r--vnftest/onap/onap_api_call.py (renamed from vnftest/onap/steps/onap_api_call.py)64
-rw-r--r--vnftest/onap/onboard/__init__.py (renamed from vnftest/onap/runners/__init__.py)0
-rw-r--r--vnftest/onap/onboard/accept_resource_test.yaml (renamed from vnftest/onap/steps/dummy/dummy.py)38
-rw-r--r--vnftest/onap/onboard/accept_service_test.yaml24
-rw-r--r--vnftest/onap/onboard/add_resource_instance.yaml33
-rw-r--r--vnftest/onap/onboard/add_service.yaml82
-rw-r--r--vnftest/onap/onboard/approve_distribution.yaml23
-rw-r--r--vnftest/onap/onboard/checkin_vlm.yaml (renamed from vnftest/onap/steps/onboard/checkin_vlm.yaml)0
-rw-r--r--vnftest/onap/onboard/checkin_vsp.yaml23
-rw-r--r--vnftest/onap/onboard/create_package_vsp.yaml23
-rw-r--r--vnftest/onap/onboard/create_vlm.yaml (renamed from vnftest/onap/steps/onboard/create_vlm.yaml)0
-rw-r--r--vnftest/onap/onboard/create_vsp.yaml34
-rw-r--r--vnftest/onap/onboard/distribute.yaml23
-rw-r--r--vnftest/onap/onboard/import_vsp.yaml91
-rw-r--r--vnftest/onap/onboard/monitor_distribution.yaml23
-rw-r--r--vnftest/onap/onboard/process_package.yaml22
-rw-r--r--vnftest/onap/onboard/start_resource_test.yaml23
-rw-r--r--vnftest/onap/onboard/start_service_test.yaml23
-rw-r--r--vnftest/onap/onboard/submit_resource_for_testing.yaml23
-rw-r--r--vnftest/onap/onboard/submit_service_for_testing.yaml23
-rw-r--r--vnftest/onap/onboard/submit_vlm.yaml (renamed from vnftest/onap/steps/onboard/submit_vlm.yaml)0
-rw-r--r--vnftest/onap/onboard/submit_vsp.yaml23
-rw-r--r--vnftest/onap/onboard/upload_package.yaml23
-rw-r--r--vnftest/onap/package_upload.py (renamed from vnftest/onap/core/testsuite.py)42
-rwxr-xr-xvnftest/onap/runners/base.py250
-rw-r--r--vnftest/onap/runners/duration.py145
-rwxr-xr-xvnftest/onap/runners/dynamictp.py179
-rw-r--r--vnftest/onap/runners/iteration.py169
-rw-r--r--vnftest/onap/runners/search.py180
-rw-r--r--vnftest/onap/runners/sequence.py149
-rw-r--r--vnftest/onap/steps/__init__.py0
-rw-r--r--vnftest/onap/steps/base.py89
-rw-r--r--vnftest/onap/steps/dummy/__init__.py0
-rw-r--r--vnftest/onap/steps/onboard/__init__.py0
45 files changed, 619 insertions, 2529 deletions
diff --git a/vnftest/onap/contexts/__init__.py b/vnftest/onap/common/__init__.py
index e69de29..e69de29 100644
--- a/vnftest/onap/contexts/__init__.py
+++ b/vnftest/onap/common/__init__.py
diff --git a/vnftest/onap/contexts/dummy.py b/vnftest/onap/common/vnf_type_crawler.py
index b61d55e..9e03dc0 100644
--- a/vnftest/onap/contexts/dummy.py
+++ b/vnftest/onap/common/vnf_type_crawler.py
@@ -13,29 +13,19 @@
##############################################################################
from __future__ import absolute_import
+from vnftest.crawlers.default import DefaultCrawler
import logging
-from vnftest.onap.contexts.base import Context
-
-
LOG = logging.getLogger(__name__)
-class DummyContext(Context):
- """Class that handle dummy info"""
-
- __context_type__ = "Dummy"
-
- def __init__(self):
- super(DummyContext, self).__init__()
-
- def init(self, attrs):
- pass
-
- def deploy(self):
- """don't need to deploy"""
- pass
+class VnfTypeCrawler(DefaultCrawler):
+ __crawler_type__ = 'VnfTypeCrawler'
- def undeploy(self):
- """don't need to undeploy"""
- super(DummyContext, self).undeploy()
+ def crawl(self, dictionary, path):
+ index = 0
+ vnf_type = dictionary['groups'][0]['name']
+ if ".." not in vnf_type:
+ index = 1
+ dictionary = dictionary['groups'][index]
+ return super(VnfTypeCrawler, self).crawl(dictionary, path)
diff --git a/vnftest/onap/contexts/base.py b/vnftest/onap/contexts/base.py
deleted file mode 100644
index a6ddb56..0000000
--- a/vnftest/onap/contexts/base.py
+++ /dev/null
@@ -1,65 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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 abc
-import six
-import vnftest.common.utils as utils
-
-
-@six.add_metaclass(abc.ABCMeta)
-class Context(object):
- """Class that represents a context in the logical model"""
- list = []
- params = {}
-
- @staticmethod
- def split_name(name, sep='.'):
- try:
- name_iter = iter(name.split(sep))
- except AttributeError:
- # name is not a string
- return None, None
- return next(name_iter), next(name_iter, None)
-
- def __init__(self):
- Context.list.append(self)
-
- @abc.abstractmethod
- def init(self, attrs):
- """Initiate context."""
-
- @staticmethod
- def get_cls(context_type):
- """Return class of specified type."""
- for context in utils.itersubclasses(Context):
- if context_type == context.__context_type__:
- return context
- raise RuntimeError("No such context_type %s" % context_type)
-
- @staticmethod
- def get(context_type):
- """Returns instance of a context for context type.
- """
- return Context.get_cls(context_type)()
-
- def _delete_context(self):
- Context.list.remove(self)
-
- @abc.abstractmethod
- def deploy(self):
- """Deploy context."""
-
- @abc.abstractmethod
- def undeploy(self):
- """Undeploy context."""
- self._delete_context()
diff --git a/vnftest/onap/contexts/csar.py b/vnftest/onap/contexts/csar.py
deleted file mode 100644
index 8d89467..0000000
--- a/vnftest/onap/contexts/csar.py
+++ /dev/null
@@ -1,44 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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 logging
-from vnftest.onap.contexts.base import Context
-
-LOG = logging.getLogger(__name__)
-
-
-class CSARContext(Context):
- """Class that handle sdc info"""
-
- __context_type__ = "CSAR"
-
- def __init__(self):
- self.csar_name = None
- self.csar_id = None
- self.csar_package_location = None
- super(CSARContext, self).__init__()
-
- def init(self, attrs):
- """initializes itself from the supplied arguments"""
- self.csar_name = attrs.get("csar_name")
- self.csar_id = attrs.get("csar_id")
- self.csar_package_location = attrs.get("csar_package_location")
-
- def deploy(self):
- """no need to deploy"""
- pass
-
- def undeploy(self):
- """no need to undeploy"""
- super(CSARContext, self).undeploy()
diff --git a/vnftest/onap/core/__init__.py b/vnftest/onap/core/__init__.py
deleted file mode 100644
index c204f9d..0000000
--- a/vnftest/onap/core/__init__.py
+++ /dev/null
@@ -1,45 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/init.py
-"""
-Vnftest core.
-"""
-
-from __future__ import print_function
-
-
-class Param(object):
- """This class converts a parameter dictionary to an object."""
-
- def __init__(self, kwargs):
- # list
- self.inputfile = kwargs.get('inputfile')
- self.task_args = kwargs.get('task-args')
- self.task_args_file = kwargs.get('task-args-file')
- self.keep_deploy = kwargs.get('keep-deploy')
- self.parse_only = kwargs.get('parse-only')
- self.output_file = kwargs.get('output-file', '/tmp/vnftest.out')
- self.suite = kwargs.get('suite')
- self.task_id = kwargs.get('task_id')
- self.yaml_name = kwargs.get('yaml_name')
-
- # list
- self.input_file = kwargs.get('input_file')
-
- # list
- self.casename = kwargs.get('casename')
-
- # list
- self.type = kwargs.get('type')
diff --git a/vnftest/onap/core/plugin.py b/vnftest/onap/core/plugin.py
deleted file mode 100644
index 90b3a7e..0000000
--- a/vnftest/onap/core/plugin.py
+++ /dev/null
@@ -1,175 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/plugin.py
-""" Handler for vnftest command 'plugin' """
-
-from __future__ import print_function
-from __future__ import absolute_import
-import os
-import sys
-import time
-import logging
-import pkg_resources
-import vnftest.ssh as ssh
-
-from vnftest.common.task_template import TaskTemplate
-from vnftest.common.yaml_loader import yaml_load
-
-LOG = logging.getLogger(__name__)
-
-
-class Plugin(object):
- """Plugin commands.
-
- Set of commands to manage plugins.
- """
-
- def install(self, args):
- """Install a plugin."""
-
- total_start_time = time.time()
- parser = PluginParser(args.input_file[0])
-
- plugins, deployment = parser.parse_plugin()
- plugin_name = plugins.get("name")
- LOG.info("Installing plugin: %s", plugin_name)
-
- LOG.debug("Executing _install_setup()")
- self._install_setup(plugin_name, deployment)
-
- LOG.debug("Executing _run()")
- self._run(plugin_name)
-
- total_end_time = time.time()
- LOG.info("Total finished in %d secs",
- total_end_time - total_start_time)
-
- LOG.info("Plugin %s Done, exiting", plugin_name)
-
- def remove(self, args):
- """Remove a plugin."""
-
- total_start_time = time.time()
- parser = PluginParser(args.input_file[0])
-
- plugins, deployment = parser.parse_plugin()
- plugin_name = plugins.get("name")
- print("Removing plugin: %s" % plugin_name)
-
- LOG.info("Executing _remove_setup()")
- self._remove_setup(plugin_name, deployment)
-
- LOG.info("Executing _run()")
- self._run(plugin_name)
-
- total_end_time = time.time()
- LOG.info("total finished in %d secs",
- total_end_time - total_start_time)
-
- print("Done, exiting")
-
- def _install_setup(self, plugin_name, deployment):
- """Deployment environment setup"""
- target_script = plugin_name + ".bash"
- self.script = pkg_resources.resource_filename(
- 'vnftest.resources', 'scripts/install/' + target_script)
-
- deployment_ip = deployment.get("ip", None)
-
- if deployment_ip == "local":
- self.client = ssh.SSH.from_node(deployment, overrides={
- # host can't be None, fail if no JUMP_HOST_IP
- 'ip': os.environ["JUMP_HOST_IP"],
- })
- else:
- self.client = ssh.SSH.from_node(deployment)
- self.client.wait(timeout=600)
-
- # copy script to host
- remotepath = '~/%s.sh' % plugin_name
-
- LOG.info("copying script to host: %s", remotepath)
- self.client._put_file_shell(self.script, remotepath)
-
- def _remove_setup(self, plugin_name, deployment):
- """Deployment environment setup"""
- target_script = plugin_name + ".bash"
- self.script = pkg_resources.resource_filename(
- 'vnftest.resources', 'scripts/remove/' + target_script)
-
- deployment_ip = deployment.get("ip", None)
-
- if deployment_ip == "local":
- self.client = ssh.SSH.from_node(deployment, overrides={
- # host can't be None, fail if no JUMP_HOST_IP
- 'ip': os.environ["JUMP_HOST_IP"],
- })
- else:
- self.client = ssh.SSH.from_node(deployment)
- self.client.wait(timeout=600)
-
- # copy script to host
- remotepath = '~/%s.sh' % plugin_name
-
- LOG.info("copying script to host: %s", remotepath)
- self.client._put_file_shell(self.script, remotepath)
-
- def _run(self, plugin_name):
- """Run installation script """
- cmd = "sudo bash %s" % plugin_name + ".sh"
-
- LOG.info("Executing command: %s", cmd)
- self.client.execute(cmd)
-
-
-class PluginParser(object):
- """Parser for plugin configration files in yaml format"""
-
- def __init__(self, path):
- self.path = path
-
- def parse_plugin(self):
- """parses the plugin file and return a plugins instance
- and a deployment instance
- """
-
- print("Parsing plugin config:", self.path)
-
- try:
- kw = {}
- with open(self.path) as f:
- try:
- input_plugin = f.read()
- rendered_plugin = TaskTemplate.render(input_plugin, **kw)
- except Exception as e:
- print("Failed to render template:\n%(plugin)s\n%(err)s\n"
- % {"plugin": input_plugin, "err": e})
- raise e
- print("Input plugin is:\n%s\n" % rendered_plugin)
-
- cfg = yaml_load(rendered_plugin)
- except IOError as ioerror:
- sys.exit(ioerror)
-
- self._check_schema(cfg["schema"], "plugin")
-
- return cfg["plugins"], cfg["deployment"]
-
- def _check_schema(self, cfg_schema, schema_type):
- """Check if configration file is using the correct schema type"""
-
- if cfg_schema != "vnftest:" + schema_type + ":0.1":
- sys.exit("error: file %s has unknown schema %s" % (self.path,
- cfg_schema))
diff --git a/vnftest/onap/core/report.py b/vnftest/onap/core/report.py
deleted file mode 100644
index bb791dc..0000000
--- a/vnftest/onap/core/report.py
+++ /dev/null
@@ -1,128 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/report.py
-""" Handler for vnftest command 'report' """
-
-from __future__ import absolute_import
-from __future__ import print_function
-
-import ast
-import re
-import uuid
-
-from django.conf import settings
-from django.template import Context
-from django.template import Template
-from oslo_utils import encodeutils
-from oslo_utils import uuidutils
-
-from vnftest.common import constants as consts
-from vnftest.common.html_template import template
-from vnftest.common.utils import cliargs
-
-settings.configure()
-
-
-class Report(object):
- """Report commands.
-
- Set of commands to manage benchmark tasks.
- """
-
- def __init__(self):
- self.Timestamp = []
- self.yaml_name = ""
- self.task_id = ""
-
- def _validate(self, yaml_name, task_id):
- if re.match("^[a-z0-9_-]+$", yaml_name):
- self.yaml_name = yaml_name
- else:
- raise ValueError("invalid yaml_name", yaml_name)
-
- if uuidutils.is_uuid_like(task_id):
- task_id = '{' + task_id + '}'
- task_uuid = (uuid.UUID(task_id))
- self.task_id = task_uuid
- else:
- raise ValueError("invalid task_id", task_id)
-
- # def _get_fieldkeys(self):
- # fieldkeys_cmd = "show field keys from \"%s\""
- # fieldkeys_query = fieldkeys_cmd % (self.yaml_name)
- # query_exec = influx.query(fieldkeys_query)
- # if query_exec:
- # return query_exec
- # else:
- # raise KeyError("Task ID or Test case not found..")
-
- #def _get_tasks(self):
- # task_cmd = "select * from \"%s\" where task_id= '%s'"
- # task_query = task_cmd % (self.yaml_name, self.task_id)
- # query_exec = influx.query(task_query)
- # if query_exec:
- # return query_exec
- # else:
- # raise KeyError("Task ID or Test case not found..")
-
- @cliargs("task_id", type=str, help=" task id", nargs=1)
- @cliargs("yaml_name", type=str, help=" Yaml file Name", nargs=1)
- def generate(self, args):
- """Start report generation."""
- self._validate(args.yaml_name[0], args.task_id[0])
-
- self.db_fieldkeys = self._get_fieldkeys()
-
- self.db_task = self._get_tasks()
-
- field_keys = []
- temp_series = []
- table_vals = {}
-
- field_keys = [encodeutils.to_utf8(field['fieldKey'])
- for field in self.db_fieldkeys]
-
- for key in field_keys:
- self.Timestamp = []
- series = {}
- values = []
- for task in self.db_task:
- task_time = encodeutils.to_utf8(task['time'])
- if not isinstance(task_time, str):
- task_time = str(task_time, 'utf8')
- key = str(key, 'utf8')
- task_time = task_time[11:]
- head, sep, tail = task_time.partition('.')
- task_time = head + "." + tail[:6]
- self.Timestamp.append(task_time)
- if isinstance(task[key], float) is True:
- values.append(task[key])
- else:
- values.append(ast.literal_eval(task[key]))
- table_vals['Timestamp'] = self.Timestamp
- table_vals[key] = values
- series['name'] = key
- series['data'] = values
- temp_series.append(series)
-
- Template_html = Template(template)
- Context_html = Context({"series": temp_series,
- "Timestamp": self.Timestamp,
- "task_id": self.task_id,
- "table": table_vals})
- with open(consts.DEFAULT_HTML_FILE, "w") as file_open:
- file_open.write(Template_html.render(Context_html))
-
- print("Report generated. View /tmp/vnftest.htm")
diff --git a/vnftest/onap/core/runner.py b/vnftest/onap/core/runner.py
deleted file mode 100644
index 32ec6e9..0000000
--- a/vnftest/onap/core/runner.py
+++ /dev/null
@@ -1,44 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/runner.py
-""" Handler for vnftest command 'runner' """
-
-from __future__ import absolute_import
-
-import prettytable
-
-from vnftest.onap.runners.base import Runner
-
-
-class Runners(object): # pragma: no cover
- """Runner commands.
-
- Set of commands to discover and display runner types.
- """
-
- def list_all(self, *args):
- """List existing runner types"""
- types = Runner.get_types()
- runner_table = prettytable.PrettyTable(['Type', 'Description'])
- runner_table.align = 'l'
- for rtype in types:
- runner_table.add_row([rtype.__execution_type__,
- rtype.__doc__.split("\n")[0]])
- print(runner_table)
-
- def show(self, args):
- """Show details of a specific runner type"""
- rtype = Runner.get_cls(args.type[0])
- print(rtype.__doc__)
diff --git a/vnftest/onap/core/step.py b/vnftest/onap/core/step.py
deleted file mode 100644
index 4411780..0000000
--- a/vnftest/onap/core/step.py
+++ /dev/null
@@ -1,44 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/step.py
-
-""" Handler for vnftest command 'step' """
-
-from __future__ import absolute_import
-import prettytable
-
-from vnftest.onap.steps.base import Step
-
-
-class Steps(object): # pragma: no cover
- """Step commands.
-
- Set of commands to discover and display step types.
- """
-
- def list_all(self, *args):
- """List existing step types"""
- types = Step.get_types()
- step_table = prettytable.PrettyTable(['Type', 'Description'])
- step_table.align = 'l'
- for step_class in types:
- step_table.add_row([step_class.get_step_type(),
- step_class.get_description()])
- print(step_table)
-
- def show(self, args):
- """Show details of a specific step type"""
- stype = Step.get_cls(args.type[0])
- print(stype.__doc__)
diff --git a/vnftest/onap/core/task.py b/vnftest/onap/core/task.py
deleted file mode 100644
index 32d61f5..0000000
--- a/vnftest/onap/core/task.py
+++ /dev/null
@@ -1,616 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/task.py
-
-""" Handler for vnftest command 'task' """
-
-from __future__ import absolute_import
-from __future__ import print_function
-import sys
-import os
-from collections import OrderedDict
-
-import copy
-import yaml
-import atexit
-import ipaddress
-import time
-import logging
-import uuid
-import collections
-
-from six.moves import filter
-from jinja2 import Environment
-
-from vnftest.onap.contexts.base import Context
-from vnftest.onap.contexts.csar import CSARContext
-from vnftest.onap.runners import base as base_runner
-from vnftest.onap.runners.duration import DurationRunner
-from vnftest.onap.runners.iteration import IterationRunner
-from vnftest.common.constants import CONF_FILE
-from vnftest.common.yaml_loader import yaml_load
-from vnftest.dispatcher.base import Base as DispatcherBase
-from vnftest.common.task_template import TaskTemplate
-from vnftest.common import utils
-from vnftest.common import constants
-from vnftest.common.html_template import report_template
-
-output_file_default = "/tmp/vnftest.out"
-test_cases_dir_default = "tests/onap/test_cases/"
-LOG = logging.getLogger(__name__)
-
-
-class Task(object): # pragma: no cover
- """Task commands.
-
- Set of commands to manage benchmark tasks.
- """
-
- def __init__(self):
- self.context = None
- self.outputs = {}
-
- def _set_dispatchers(self, output_config):
- dispatchers = output_config.get('DEFAULT', {}).get('dispatcher',
- 'file')
- out_types = [s.strip() for s in dispatchers.split(',')]
- output_config['DEFAULT']['dispatcher'] = out_types
-
- def start(self, args, **kwargs):
- """Start a vnf step."""
-
- atexit.register(self.atexit_handler)
-
- task_id = getattr(args, 'task_id')
- self.task_id = task_id if task_id else str(uuid.uuid4())
-
- self._set_log()
-
- try:
- output_config = utils.parse_ini_file(CONF_FILE)
- except Exception:
- # all error will be ignore, the default value is {}
- output_config = {}
-
- self._init_output_config(output_config)
- self._set_output_config(output_config, args.output_file)
- LOG.debug('Output configuration is: %s', output_config)
-
- self._set_dispatchers(output_config)
-
- # update dispatcher list
- if 'file' in output_config['DEFAULT']['dispatcher']:
- result = {'status': 0, 'result': {}}
- utils.write_json_to_file(args.output_file, result)
-
- total_start_time = time.time()
- parser = TaskParser(args.inputfile[0])
-
- if args.suite:
- # 1.parse suite, return suite_params info
- task_files, task_args, task_args_fnames = \
- parser.parse_suite()
- else:
- task_files = [parser.path]
- task_args = [args.task_args]
- task_args_fnames = [args.task_args_file]
-
- LOG.debug("task_files:%s, task_args:%s, task_args_fnames:%s",
- task_files, task_args, task_args_fnames)
-
- if args.parse_only:
- sys.exit(0)
-
- testcases = {}
- # parse task_files
- for i in range(0, len(task_files)):
- one_task_start_time = time.time()
- parser.path = task_files[i]
- steps, run_in_parallel, meet_precondition, ret_context = \
- parser.parse_task(self.task_id, task_args[i],
- task_args_fnames[i])
-
- self.context = ret_context
-
- if not meet_precondition:
- LOG.info("meet_precondition is %s, please check envrionment",
- meet_precondition)
- continue
-
- case_name = os.path.splitext(os.path.basename(task_files[i]))[0]
- try:
- data = self._run(steps, run_in_parallel, args.output_file)
- except KeyboardInterrupt:
- raise
- except Exception:
- LOG.error('Testcase: "%s" FAILED!!!', case_name, exc_info=True)
- testcases[case_name] = {'criteria': 'FAIL', 'tc_data': []}
- else:
- criteria = self.evaluate_task_criteria(data)
- testcases[case_name] = {'criteria': criteria, 'tc_data': data}
-
- if args.keep_deploy:
- # keep deployment, forget about stack
- # (hide it for exit handler)
- self.context = None
- else:
- self.context.undeploy()
- self.context = None
- one_task_end_time = time.time()
- LOG.info("Task %s finished in %d secs", task_files[i],
- one_task_end_time - one_task_start_time)
-
- result = self._get_format_result(testcases)
-
- self._do_output(output_config, result)
- self._generate_reporting(result)
-
- total_end_time = time.time()
- LOG.info("Total finished in %d secs",
- total_end_time - total_start_time)
-
- step = steps[0]
- LOG.info("To generate report, execute command "
- "'vnftest report generate %(task_id)s %(tc)s'", step)
- LOG.info("Task ALL DONE, exiting")
- return result
-
- def _generate_reporting(self, result):
- env = Environment()
- with open(constants.REPORTING_FILE, 'w') as f:
- f.write(env.from_string(report_template).render(result))
-
- LOG.info("Report can be found in '%s'", constants.REPORTING_FILE)
-
- def _set_log(self):
- log_format = '%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s %(message)s'
- log_formatter = logging.Formatter(log_format)
-
- utils.makedirs(constants.TASK_LOG_DIR)
- log_path = os.path.join(constants.TASK_LOG_DIR, '{}.log'.format(self.task_id))
- log_handler = logging.FileHandler(log_path)
- log_handler.setFormatter(log_formatter)
- log_handler.setLevel(logging.DEBUG)
-
- logging.root.addHandler(log_handler)
-
- def _init_output_config(self, output_config):
- output_config.setdefault('DEFAULT', {})
- output_config.setdefault('dispatcher_http', {})
- output_config.setdefault('dispatcher_file', {})
- output_config.setdefault('dispatcher_influxdb', {})
- output_config.setdefault('nsb', {})
-
- def _set_output_config(self, output_config, file_path):
- try:
- out_type = os.environ['DISPATCHER']
- except KeyError:
- output_config['DEFAULT'].setdefault('dispatcher', 'file')
- else:
- output_config['DEFAULT']['dispatcher'] = out_type
-
- output_config['dispatcher_file']['file_path'] = file_path
-
- try:
- target = os.environ['TARGET']
- except KeyError:
- pass
- else:
- k = 'dispatcher_{}'.format(output_config['DEFAULT']['dispatcher'])
- output_config[k]['target'] = target
-
- def _get_format_result(self, testcases):
- criteria = self._get_task_criteria(testcases)
-
- info = {
- 'deploy_step': os.environ.get('DEPLOY_STEP', 'unknown'),
- 'installer': os.environ.get('INSTALLER_TYPE', 'unknown'),
- 'pod_name': os.environ.get('NODE_NAME', 'unknown'),
- 'version': os.environ.get('VNFTEST_BRANCH', 'unknown')
- }
-
- result = {
- 'status': 1,
- 'result': {
- 'criteria': criteria,
- 'task_id': self.task_id,
- 'info': info,
- 'testcases': testcases
- }
- }
-
- return result
-
- def _get_task_criteria(self, testcases):
- criteria = any(t.get('criteria') != 'PASS' for t in testcases.values())
- if criteria:
- return 'FAIL'
- else:
- return 'PASS'
-
- def evaluate_task_criteria(self, steps_result_list):
- for step_result in steps_result_list:
- errors_list = step_result['errors']
- if errors_list is not None and len(errors_list) > 0:
- return 'FAIL'
- return 'PASS'
-
- def _do_output(self, output_config, result):
- dispatchers = DispatcherBase.get(output_config)
-
- for dispatcher in dispatchers:
- dispatcher.flush_result_data(result)
-
- def _run(self, steps, run_in_parallel, output_file):
- """Deploys context and calls runners"""
- self.context.deploy()
- background_runners = []
-
- result = []
- # Start all background steps
- for step in filter(_is_background_step, steps):
- step["runner"] = dict(type="Duration", duration=1000000000)
- runner = self.run_one_step(step, output_file)
- background_runners.append(runner)
-
- runners = []
- if run_in_parallel:
- for step in steps:
- if not _is_background_step(step):
- runner = self.run_one_step(step, output_file)
- runners.append(runner)
-
- # Wait for runners to finish
- for runner in runners:
- status = runner_join(runner, background_runners, self.outputs, result)
- if status != 0:
- raise RuntimeError(
- "{0} runner status {1}".format(runner.__execution_type__, status))
- LOG.info("Runner ended, output in %s", output_file)
- else:
- # run serially
- for step in steps:
- if not _is_background_step(step):
- runner = self.run_one_step(step, output_file)
- status = runner_join(runner, background_runners, self.outputs, result)
- if status != 0:
- LOG.error('Step NO.%s: "%s" ERROR!',
- steps.index(step) + 1,
- step.get('type'))
- raise RuntimeError(
- "{0} runner status {1}".format(runner.__execution_type__, status))
- LOG.info("Runner ended, output in %s", output_file)
-
- # Abort background runners
- for runner in background_runners:
- runner.abort()
-
- # Wait for background runners to finish
- for runner in background_runners:
- status = runner.join(self.outputs, result)
- if status is None:
- # Nuke if it did not stop nicely
- base_runner.Runner.terminate(runner)
- runner.join(self.outputs, result)
- base_runner.Runner.release(runner)
-
- print("Background task ended")
- return result
-
- def atexit_handler(self):
- """handler for process termination"""
- base_runner.Runner.terminate_all()
-
- if self.context:
- LOG.info("Undeploying context")
- self.context.undeploy()
-
- def _parse_options(self, op):
- if isinstance(op, dict):
- return {k: self._parse_options(v) for k, v in op.items()}
- elif isinstance(op, list):
- return [self._parse_options(v) for v in op]
- elif isinstance(op, str):
- return self.outputs.get(op[1:]) if op.startswith('$') else op
- else:
- return op
-
- def run_one_step(self, step_cfg, output_file):
- """run one step using context"""
- # default runner is Iteration
- if 'runner' not in step_cfg:
- step_cfg['runner'] = dict(type="Iteration", iterations=1)
- runner_cfg = step_cfg['runner']
- runner_cfg['output_filename'] = output_file
- options = step_cfg.get('options', {})
- step_cfg['options'] = self._parse_options(options)
- runner = base_runner.Runner.get(runner_cfg)
-
- LOG.info("Starting runner of type '%s'", runner_cfg["type"])
- # Previous steps output is the input of the next step.
- input_params = copy.deepcopy(self.outputs)
- runner.run(step_cfg, self.context, input_params)
- return runner
-
-
-class TaskParser(object): # pragma: no cover
- """Parser for task config files in yaml format"""
-
- def __init__(self, path):
- self.path = path
-
- def _meet_constraint(self, task, cur_pod, cur_installer):
- if "constraint" in task:
- constraint = task.get('constraint', None)
- if constraint is not None:
- tc_fit_pod = constraint.get('pod', None)
- tc_fit_installer = constraint.get('installer', None)
- LOG.info("cur_pod:%s, cur_installer:%s,tc_constraints:%s",
- cur_pod, cur_installer, constraint)
- if (cur_pod is None) or (tc_fit_pod and cur_pod not in tc_fit_pod):
- return False
- if (cur_installer is None) or (tc_fit_installer and cur_installer
- not in tc_fit_installer):
- return False
- return True
-
- def _get_task_para(self, task, cur_pod):
- task_args = task.get('task_args', None)
- if task_args is not None:
- task_args = task_args.get(cur_pod, task_args.get('default'))
- task_args_fnames = task.get('task_args_fnames', None)
- if task_args_fnames is not None:
- task_args_fnames = task_args_fnames.get(cur_pod, None)
- return task_args, task_args_fnames
-
- def parse_suite(self):
- """parse the suite file and return a list of task config file paths
- and lists of optional parameters if present"""
- LOG.info("\nParsing suite file:%s", self.path)
-
- try:
- with open(self.path) as stream:
- cfg = yaml_load(stream)
- except IOError as ioerror:
- sys.exit(ioerror)
-
- self._check_schema(cfg["schema"], "suite")
- LOG.info("\nStarting step:%s", cfg["name"])
-
- test_cases_dir = cfg.get("test_cases_dir", test_cases_dir_default)
- test_cases_dir = os.path.join(constants.VNFTEST_ROOT_PATH,
- test_cases_dir)
- if test_cases_dir[-1] != os.sep:
- test_cases_dir += os.sep
-
- cur_pod = os.environ.get('NODE_NAME', None)
- cur_installer = os.environ.get('INSTALLER_TYPE', None)
-
- valid_task_files = []
- valid_task_args = []
- valid_task_args_fnames = []
-
- for task in cfg["test_cases"]:
- # 1.check file_name
- if "file_name" in task:
- task_fname = task.get('file_name', None)
- if task_fname is None:
- continue
- else:
- continue
- # 2.check constraint
- if self._meet_constraint(task, cur_pod, cur_installer):
- valid_task_files.append(test_cases_dir + task_fname)
- else:
- continue
- # 3.fetch task parameters
- task_args, task_args_fnames = self._get_task_para(task, cur_pod)
- valid_task_args.append(task_args)
- valid_task_args_fnames.append(task_args_fnames)
-
- return valid_task_files, valid_task_args, valid_task_args_fnames
-
- def parse_task(self, task_id, task_args=None, task_args_file=None):
- """parses the task file and return an context and step instances"""
- LOG.info("Parsing task config: %s", self.path)
-
- try:
- kw = {}
- if task_args_file:
- with open(task_args_file) as f:
- kw.update(parse_task_args("task_args_file", f.read()))
- kw.update(parse_task_args("task_args", task_args))
- except TypeError:
- raise TypeError()
-
- try:
- with open(self.path) as f:
- try:
- input_task = f.read()
- rendered_task = TaskTemplate.render(input_task, **kw)
- except Exception as e:
- LOG.exception('Failed to render template:\n%s\n', input_task)
- raise e
- LOG.debug("Input task is:\n%s\n", rendered_task)
-
- cfg = yaml_load(rendered_task)
- except IOError as ioerror:
- sys.exit(ioerror)
-
- self._check_schema(cfg["schema"], "task")
- meet_precondition = self._check_precondition(cfg)
-
- if "context" in cfg:
- context_cfg = cfg["context"]
- else:
- context_cfg = {"type": "Dummy"}
-
- name_suffix = '-{}'.format(task_id[:8])
- try:
- context_cfg['name'] = '{}{}'.format(context_cfg['name'],
- name_suffix)
- except KeyError:
- pass
- # default to CSAR context
- context_type = context_cfg.get("type", "CSAR")
- context = Context.get(context_type)
- context.init(context_cfg)
-
- run_in_parallel = cfg.get("run_in_parallel", False)
-
- # add tc and task id for influxdb extended tags
- for step in cfg["steps"]:
- task_name = os.path.splitext(os.path.basename(self.path))[0]
- step["tc"] = task_name
- step["task_id"] = task_id
- # embed task path into step so we can load other files
- # relative to task path
- step["task_path"] = os.path.dirname(self.path)
-
- # TODO we need something better here, a class that represent the file
- return cfg["steps"], run_in_parallel, meet_precondition, context
-
- def _check_schema(self, cfg_schema, schema_type):
- """Check if config file is using the correct schema type"""
-
- if cfg_schema != "vnftest:" + schema_type + ":0.1":
- sys.exit("error: file %s has unknown schema %s" % (self.path,
- cfg_schema))
-
- def _check_precondition(self, cfg):
- """Check if the environment meet the precondition"""
-
- if "precondition" in cfg:
- precondition = cfg["precondition"]
- installer_type = precondition.get("installer_type", None)
- deploy_steps = precondition.get("deploy_steps", None)
- tc_fit_pods = precondition.get("pod_name", None)
- installer_type_env = os.environ.get('INSTALL_TYPE', None)
- deploy_step_env = os.environ.get('DEPLOY_STEP', None)
- pod_name_env = os.environ.get('NODE_NAME', None)
-
- LOG.info("installer_type: %s, installer_type_env: %s",
- installer_type, installer_type_env)
- LOG.info("deploy_steps: %s, deploy_step_env: %s",
- deploy_steps, deploy_step_env)
- LOG.info("tc_fit_pods: %s, pod_name_env: %s",
- tc_fit_pods, pod_name_env)
- if installer_type and installer_type_env:
- if installer_type_env not in installer_type:
- return False
- if deploy_steps and deploy_step_env:
- deploy_steps_list = deploy_steps.split(',')
- for deploy_step in deploy_steps_list:
- if deploy_step_env.startswith(deploy_step):
- return True
- return False
- if tc_fit_pods and pod_name_env:
- if pod_name_env not in tc_fit_pods:
- return False
- return True
-
-
-def is_ip_addr(addr):
- """check if string addr is an IP address"""
- try:
- addr = addr.get('public_ip_attr', addr.get('private_ip_attr'))
- except AttributeError:
- pass
-
- try:
- ipaddress.ip_address(addr.encode('utf-8'))
- except ValueError:
- return False
- else:
- return True
-
-
-def _is_background_step(step):
- if "run_in_background" in step:
- return step["run_in_background"]
- else:
- return False
-
-
-def parse_nodes_with_context(step_cfg):
- """parse the 'nodes' fields in step """
- # ensure consistency in node instantiation order
- return OrderedDict((nodename, Context.get_server(step_cfg["nodes"][nodename]))
- for nodename in sorted(step_cfg["nodes"]))
-
-
-def get_networks_from_nodes(nodes):
- """parse the 'nodes' fields in step """
- networks = {}
- for node in nodes.values():
- if not node:
- continue
- interfaces = node.get('interfaces', {})
- for interface in interfaces.values():
- # vld_id is network_name
- network_name = interface.get('network_name')
- if not network_name:
- continue
- network = Context.get_network(network_name)
- if network:
- networks[network['name']] = network
- return networks
-
-
-def runner_join(runner, background_runners, outputs, result):
- """join (wait for) a runner, exit process at runner failure
- :param background_runners:
- :type background_runners:
- :param outputs:
- :type outputs: dict
- :param result:
- :type result: list
- """
- while runner.poll() is None:
- outputs.update(runner.get_output())
- result.extend(runner.get_result())
- # drain all the background runner queues
- for background in background_runners:
- outputs.update(background.get_output())
- result.extend(background.get_result())
- status = runner.join(outputs, result)
- base_runner.Runner.release(runner)
- return status
-
-
-def print_invalid_header(source_name, args):
- print("Invalid %(source)s passed:\n\n %(args)s\n"
- % {"source": source_name, "args": args})
-
-
-def parse_task_args(src_name, args):
- if isinstance(args, collections.Mapping):
- return args
-
- try:
- kw = args and yaml_load(args)
- kw = {} if kw is None else kw
- except yaml.parser.ParserError as e:
- print_invalid_header(src_name, args)
- print("%(source)s has to be YAML. Details:\n\n%(err)s\n"
- % {"source": src_name, "err": e})
- raise TypeError()
-
- if not isinstance(kw, dict):
- print_invalid_header(src_name, args)
- print("%(src)s had to be dict, actually %(src_type)s\n"
- % {"src": src_name, "src_type": type(kw)})
- raise TypeError()
- return kw \ No newline at end of file
diff --git a/vnftest/onap/core/testcase.py b/vnftest/onap/core/testcase.py
deleted file mode 100644
index ef3e535..0000000
--- a/vnftest/onap/core/testcase.py
+++ /dev/null
@@ -1,113 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/testcase.py
-
-""" Handler for vnftest command 'testcase' """
-from __future__ import absolute_import
-from __future__ import print_function
-
-import os
-import logging
-
-from vnftest.common.task_template import TaskTemplate
-from vnftest.common import constants as consts
-from vnftest.common.yaml_loader import yaml_load
-
-LOG = logging.getLogger(__name__)
-
-
-class Testcase(object):
- """Testcase commands.
-
- Set of commands to discover and display test cases.
- """
-
- def list_all(self, args):
- """List existing test cases"""
-
- testcase_files = self._get_testcase_file_list()
- testcase_list = [self._get_record(f) for f in testcase_files]
-
- return testcase_list
-
- def _get_testcase_file_list(self):
- try:
- testcase_files = sorted(os.listdir(consts.TESTCASE_DIR))
- except OSError:
- LOG.exception('Failed to list dir:\n%s\n', consts.TESTCASE_DIR)
- raise
-
- return testcase_files
-
- def _get_record(self, testcase_file):
-
- file_path = os.path.join(consts.TESTCASE_DIR, testcase_file)
- with open(file_path) as f:
- try:
- testcase_info = f.read()
- except IOError:
- LOG.exception('Failed to load test case:\n%s\n', testcase_file)
- raise
-
- description, installer, deploy_steps = self._parse_testcase(
- testcase_info)
-
- record = {
- 'Name': testcase_file.split(".")[0],
- 'Description': description,
- 'installer': installer,
- 'deploy_steps': deploy_steps
- }
-
- return record
-
- def _parse_testcase(self, testcase_info):
-
- rendered_testcase = TaskTemplate.render(testcase_info)
- testcase_cfg = yaml_load(rendered_testcase)
-
- test_precondition = testcase_cfg.get('precondition', {})
- installer_type = test_precondition.get('installer_type', 'all')
- deploy_steps = test_precondition.get('deploy_steps', 'all')
-
- description = self._get_description(testcase_cfg)
-
- return description, installer_type, deploy_steps
-
- def _get_description(self, testcase_cfg):
- try:
- description_list = testcase_cfg['description'].split(';')
- except KeyError:
- return ''
- else:
- try:
- return description_list[1].replace(os.linesep, '').strip()
- except IndexError:
- return description_list[0].replace(os.linesep, '').strip()
-
- def show(self, args):
- """Show details of a specific test case"""
- testcase_name = args.casename[0]
- testcase_path = os.path.join(consts.TESTCASE_DIR,
- testcase_name + ".yaml")
- with open(testcase_path) as f:
- try:
- testcase_info = f.read()
- except IOError:
- LOG.exception('Failed to load test case:\n%s\n', testcase_path)
- raise
-
- print(testcase_info)
- return True
diff --git a/vnftest/onap/steps/onap_api_call.py b/vnftest/onap/onap_api_call.py
index e03e00a..7cc68c3 100644
--- a/vnftest/onap/steps/onap_api_call.py
+++ b/vnftest/onap/onap_api_call.py
@@ -13,17 +13,19 @@
##############################################################################
from __future__ import absolute_import
+import copy
import logging
import time
+
import os
import yaml
-import copy
-from vnftest.common.exceptions import MandatoryKeyException, InputParameterMissing
-from vnftest.onap.steps import base
-from vnftest.common import rest_client
from vnftest.common import constants as consts
-from vnftest.onap.contexts.csar import CSARContext
+from vnftest.common import rest_client
+from vnftest.common.exceptions import MandatoryKeyException, InputParameterMissing
+from vnftest.crawlers.base import Crawler
+from vnftest.onap.common.vnf_type_crawler import VnfTypeCrawler
+from vnftest.steps import base
LOG = logging.getLogger(__name__)
@@ -47,6 +49,7 @@ class OnapApiCall(base.Step):
self.rest_def_file = options.get("file")
self.input_cfg = options.get("input", {})
self.output_cfg = options.get("output", {})
+ self.sla_cfg = self.step_cfg.get('sla', {'retries': 0})
self.setup_done = True
def eval_input(self, params):
@@ -54,19 +57,28 @@ class OnapApiCall(base.Step):
param_name = input_parameter['parameter_name']
value = None
if 'value' in input_parameter:
- value = input_parameter['value']
- elif 'source' in input_parameter:
- source = input_parameter['source']
- if source == 'prev_step':
- if param_name in self.input_params:
- value = self.input_params[param_name]
- else:
- raise InputParameterMissing(param_name=param_name, source='input parameters')
- if value is None:
+ value_def = input_parameter['value']
+ value = self.format_string(value_def, self.input_params)
+ if value is None or value == "":
raise InputParameterMissing(param_name=param_name, source="task configuration")
params[param_name] = value
- def run(self, result):
+ def run(self, result, attempt=0):
+ output = self.run_impl(result)
+ try:
+ self.handle_sla(output)
+ except AssertionError as e:
+ LOG.info(str(e))
+ if attempt < self.sla_cfg['retries']:
+ time.sleep(self.sla_cfg['interval'])
+ LOG.info("retry operation")
+ attempt = attempt + 1
+ return self.run(result, attempt)
+ else:
+ raise e
+ return output
+
+ def run_impl(self, result):
if not self.setup_done:
self.setup()
output = {}
@@ -76,15 +88,17 @@ class OnapApiCall(base.Step):
result_body = execution_result['body']
for output_parameter in self.output_cfg:
param_name = output_parameter['parameter_name']
- param_path = output_parameter['path']
- path_list = param_path.split("|")
- param_value = result_body
- for path_element in path_list:
- param_value = param_value[path_element]
+ param_value = output_parameter['value']
+ if param_value.find("[") > -1:
+ crawler_type = output_parameter.get('type', 'default')
+ crawler_class = Crawler.get_cls(crawler_type)
+ crawler = crawler_class()
+ param_value = crawler.crawl(result_body, param_value)
if param_value is None:
raise MandatoryKeyException(key_name='param_path', class_name=str(result_body))
result[param_name] = param_value
output[param_name] = param_value
+ self.handle_sla(output)
return output
def execute_operation(self, params, attempt=0):
@@ -154,7 +168,8 @@ class OnapApiCall(base.Step):
ret = self.format_string(d, params)
return ret
- def format_string(self, st, params):
+ @staticmethod
+ def format_string(st, params):
try:
return st.format(**params)
except Exception as e:
@@ -165,4 +180,9 @@ class OnapApiCall(base.Step):
LOG.info("param" + params[s])
return st.format(**params)
-
+ def handle_sla(self, output):
+ if 'assert' in self.sla_cfg and 'equals' in self.sla_cfg:
+ value_def = self.sla_cfg['value']
+ value = self.format_string(value_def, output)
+ expected_value = self.sla_cfg['equals']
+ assert value == expected_value
diff --git a/vnftest/onap/runners/__init__.py b/vnftest/onap/onboard/__init__.py
index e69de29..e69de29 100644
--- a/vnftest/onap/runners/__init__.py
+++ b/vnftest/onap/onboard/__init__.py
diff --git a/vnftest/onap/steps/dummy/dummy.py b/vnftest/onap/onboard/accept_resource_test.yaml
index 27e9a32..60a079e 100644
--- a/vnftest/onap/steps/dummy/dummy.py
+++ b/vnftest/onap/onboard/accept_resource_test.yaml
@@ -11,32 +11,14 @@
# See the License for the specific language governing permissions and limitations under
# the License
##############################################################################
-from __future__ import absolute_import
-import logging
-from vnftest.onap.steps import base
-
-LOG = logging.getLogger(__name__)
-
-
-class Dummy(base.Step):
- """Execute Dummy echo
- """
- __step_type__ = "Dummy"
-
- def __init__(self, step_cfg, context_cfg):
- self.step_cfg = step_cfg
- self.context_cfg = context_cfg
- self.setup_done = False
-
- def setup(self):
- """step setup"""
- self.setup_done = True
-
- def run(self, result):
- """execute the benchmark"""
- if not self.setup_done:
- self.setup()
-
- result["hello"] = "vnftest"
- LOG.info("Dummy echo hello vnftest!")
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/resources/{resource_id}/lifecycleState/certify"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_tester_user}",
+ "Accept": "application/json"
+ }
+body: {"userRemarks":"certified"}
diff --git a/vnftest/onap/onboard/accept_service_test.yaml b/vnftest/onap/onboard/accept_service_test.yaml
new file mode 100644
index 0000000..8b5e6db
--- /dev/null
+++ b/vnftest/onap/onboard/accept_service_test.yaml
@@ -0,0 +1,24 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{service_id}/lifecycleState/certify"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_tester_user}",
+ "Accept": "application/json"
+ }
+body: {"userRemarks":"certified"}
diff --git a/vnftest/onap/onboard/add_resource_instance.yaml b/vnftest/onap/onboard/add_resource_instance.yaml
new file mode 100644
index 0000000..b92cc9b
--- /dev/null
+++ b/vnftest/onap/onboard/add_resource_instance.yaml
@@ -0,0 +1,33 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{service_id}/resourceInstance"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {
+ "uniqueId": "{resource_instance_unique_id}",
+ "posX": "500",
+ "posY": "100",
+ "name": "{resource_instance_name}",
+ "componentVersion": "1.0",
+ "originType": "VF",
+ "icon": "defaulticon",
+ "componentUid": "{resource_version_id}"
+ } \ No newline at end of file
diff --git a/vnftest/onap/onboard/add_service.yaml b/vnftest/onap/onboard/add_service.yaml
new file mode 100644
index 0000000..9602a6b
--- /dev/null
+++ b/vnftest/onap/onboard/add_service.yaml
@@ -0,0 +1,82 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {
+ "artifacts": {
+
+ },
+ "toscaArtifacts": {
+
+ },
+ "contactId": "{sdc_designer_user}",
+ "categories": [
+ {
+ "name": "Network L4+",
+ "normalizedName": "network l4+",
+ "uniqueId": "serviceNewCategory.network l4+",
+ "icons": [
+ "network_l_4"
+ ],
+ "subcategories": null,
+ "ownerId": null
+ }
+ ],
+ "description": "service test",
+ "icon": "defaulticon",
+ "componentInstancesProperties": {
+
+ },
+ "componentInstancesAttributes": {
+
+ },
+ "name": "{service_name}",
+ "tags": [
+ "{service_name}"
+ ],
+ "capabilities": {
+
+ },
+ "requirements": {
+
+ },
+ "deploymentArtifacts": {
+
+ },
+ "componentType": "SERVICE",
+ "projectCode": "100100",
+ "componentInstances": [
+
+ ],
+ "properties": [
+
+ ],
+ "attributes": [
+
+ ],
+ "groups": [
+
+ ],
+ "ecompGeneratedNaming": "true",
+ "serviceApiArtifacts": {
+
+ }
+ }
diff --git a/vnftest/onap/onboard/approve_distribution.yaml b/vnftest/onap/onboard/approve_distribution.yaml
new file mode 100644
index 0000000..b1efc48
--- /dev/null
+++ b/vnftest/onap/onboard/approve_distribution.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{service_version_id}/distribution-state/approve"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_governance_user}",
+ "Accept": "application/json"
+ }
+body: {"userRemarks":"approved"}
diff --git a/vnftest/onap/steps/onboard/checkin_vlm.yaml b/vnftest/onap/onboard/checkin_vlm.yaml
index 93fdd07..93fdd07 100644
--- a/vnftest/onap/steps/onboard/checkin_vlm.yaml
+++ b/vnftest/onap/onboard/checkin_vlm.yaml
diff --git a/vnftest/onap/onboard/checkin_vsp.yaml b/vnftest/onap/onboard/checkin_vsp.yaml
new file mode 100644
index 0000000..399aa47
--- /dev/null
+++ b/vnftest/onap/onboard/checkin_vsp.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "PUT"
+url: "http://{sdc_ip}:{sdc_port}/onboarding-api/v1.0/vendor-software-products/{vsp_id}/versions/0.1/actions"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA==",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {"action":"Checkin"}
diff --git a/vnftest/onap/onboard/create_package_vsp.yaml b/vnftest/onap/onboard/create_package_vsp.yaml
new file mode 100644
index 0000000..a961b86
--- /dev/null
+++ b/vnftest/onap/onboard/create_package_vsp.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "PUT"
+url: "http://{sdc_ip}:{sdc_port}/onboarding-api/v1.0/vendor-software-products/{vsp_id}/versions/0.1/actions"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA==",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {"action":"Create_Package"}
diff --git a/vnftest/onap/steps/onboard/create_vlm.yaml b/vnftest/onap/onboard/create_vlm.yaml
index dce110a..dce110a 100644
--- a/vnftest/onap/steps/onboard/create_vlm.yaml
+++ b/vnftest/onap/onboard/create_vlm.yaml
diff --git a/vnftest/onap/onboard/create_vsp.yaml b/vnftest/onap/onboard/create_vsp.yaml
new file mode 100644
index 0000000..d9721a2
--- /dev/null
+++ b/vnftest/onap/onboard/create_vsp.yaml
@@ -0,0 +1,34 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_port}/onboarding-api/v1.0/vendor-software-products"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA==",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {
+ "vendorId": "{vendor_id}",
+ "name": "{vsp_name}",
+ "category": "resourceNewCategory.application l4+",
+ "subCategory": "resourceNewCategory.application l4+.firewall",
+ "description": "vlm via dovetail",
+ "onboardingMethod": "NetworkPackage",
+ "vendorName": "dovetailVendor",
+ "icon": "icon",
+ "licensingData": {
+ }
+ } \ No newline at end of file
diff --git a/vnftest/onap/onboard/distribute.yaml b/vnftest/onap/onboard/distribute.yaml
new file mode 100644
index 0000000..7deb9a1
--- /dev/null
+++ b/vnftest/onap/onboard/distribute.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{service_version_id}/distribution/PROD/activate"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_operations_user}",
+ "Accept": "application/json"
+ }
+body: {}
diff --git a/vnftest/onap/onboard/import_vsp.yaml b/vnftest/onap/onboard/import_vsp.yaml
new file mode 100644
index 0000000..d3a3100
--- /dev/null
+++ b/vnftest/onap/onboard/import_vsp.yaml
@@ -0,0 +1,91 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/resources"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {
+ "artifacts": {
+
+ },
+ "toscaArtifacts": {
+
+ },
+ "contactId": "{sdc_designer_user}",
+ "categories": [
+ {
+ "name": "Application L4+",
+ "normalizedName": "application l4+",
+ "uniqueId": "resourceNewCategory.application l4+",
+ "icons": null,
+ "subcategories": [
+ {
+ "name": "Firewall",
+ "normalizedName": "firewall",
+ "uniqueId": "resourceNewCategory.application l4+.firewall",
+ "icons": [
+ "firewall"
+ ],
+ "groupings": null,
+ "ownerId": null
+ }
+ ],
+ "ownerId": null
+ }
+ ],
+ "description": "dovetail initiated",
+ "icon": "defaulticon",
+ "componentInstancesProperties": {
+
+ },
+ "componentInstancesAttributes": {
+
+ },
+ "name": "{vsp_name}",
+ "tags": [
+ "{vsp_name}"
+ ],
+ "capabilities": {
+
+ },
+ "requirements": {
+
+ },
+ "deploymentArtifacts": {
+
+ },
+ "componentType": "RESOURCE",
+ "vendorName": "dovetailVendor",
+ "vendorRelease": "1.0",
+ "componentInstances": [
+
+ ],
+ "properties": [
+
+ ],
+ "attributes": [
+
+ ],
+ "groups": [
+
+ ],
+ "resourceType": "VF",
+ "csarUUID": "{vsp_id}",
+ "csarVersion": "1.0"
+ }
diff --git a/vnftest/onap/onboard/monitor_distribution.yaml b/vnftest/onap/onboard/monitor_distribution.yaml
new file mode 100644
index 0000000..07216d0
--- /dev/null
+++ b/vnftest/onap/onboard/monitor_distribution.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "GET"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{distributed_service_id}/distribution"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_operations_user}",
+ "Accept": "application/json"
+ }
+body: {}
diff --git a/vnftest/onap/onboard/process_package.yaml b/vnftest/onap/onboard/process_package.yaml
new file mode 100644
index 0000000..ee8f791
--- /dev/null
+++ b/vnftest/onap/onboard/process_package.yaml
@@ -0,0 +1,22 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "PUT"
+url: "http://{sdc_ip}:{sdc_port}/onboarding-api/v1.0/vendor-software-products/{vsp_id}/versions/0.1/orchestration-template-candidate/process"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA==",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ } \ No newline at end of file
diff --git a/vnftest/onap/onboard/start_resource_test.yaml b/vnftest/onap/onboard/start_resource_test.yaml
new file mode 100644
index 0000000..d6ba7b3
--- /dev/null
+++ b/vnftest/onap/onboard/start_resource_test.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/resources/{resource_id}/lifecycleState/startCertification"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_tester_user}",
+ "Accept": "application/json"
+ }
+body: {}
diff --git a/vnftest/onap/onboard/start_service_test.yaml b/vnftest/onap/onboard/start_service_test.yaml
new file mode 100644
index 0000000..6a89b94
--- /dev/null
+++ b/vnftest/onap/onboard/start_service_test.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{service_id}/lifecycleState/startCertification"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_tester_user}",
+ "Accept": "application/json"
+ }
+body: {}
diff --git a/vnftest/onap/onboard/submit_resource_for_testing.yaml b/vnftest/onap/onboard/submit_resource_for_testing.yaml
new file mode 100644
index 0000000..4bdc2be
--- /dev/null
+++ b/vnftest/onap/onboard/submit_resource_for_testing.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/resources/{resource_id}/lifecycleState/certificationRequest"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {"userRemarks":"resource submited for testing"}
diff --git a/vnftest/onap/onboard/submit_service_for_testing.yaml b/vnftest/onap/onboard/submit_service_for_testing.yaml
new file mode 100644
index 0000000..e75e6af
--- /dev/null
+++ b/vnftest/onap/onboard/submit_service_for_testing.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_catalog_port}/sdc1/feProxy/rest/v1/catalog/services/{service_id}/lifecycleState/certificationRequest"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic YmVlcDpib29w",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {"userRemarks":"resource submited for testing"}
diff --git a/vnftest/onap/steps/onboard/submit_vlm.yaml b/vnftest/onap/onboard/submit_vlm.yaml
index eb1683a..eb1683a 100644
--- a/vnftest/onap/steps/onboard/submit_vlm.yaml
+++ b/vnftest/onap/onboard/submit_vlm.yaml
diff --git a/vnftest/onap/onboard/submit_vsp.yaml b/vnftest/onap/onboard/submit_vsp.yaml
new file mode 100644
index 0000000..c255cd7
--- /dev/null
+++ b/vnftest/onap/onboard/submit_vsp.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "PUT"
+url: "http://{sdc_ip}:{sdc_port}/onboarding-api/v1.0/vendor-software-products/{vsp_id}/versions/0.1/actions"
+headers: {
+ "Content-Type": "application/json",
+ "Authorization": "Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA==",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+body: {"action":"Submit"}
diff --git a/vnftest/onap/onboard/upload_package.yaml b/vnftest/onap/onboard/upload_package.yaml
new file mode 100644
index 0000000..958782f
--- /dev/null
+++ b/vnftest/onap/onboard/upload_package.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright 2018 EuropeanSoftwareMarketingLtd.
+# ===================================================================
+# Licensed under the ApacheLicense, Version2.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
+#
+# 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
+##############################################################################
+---
+method: "POST"
+url: "http://{sdc_ip}:{sdc_port}/onboarding-api/v1.0/vendor-software-products/{vsp_id}/versions/0.1/orchestration-template-candidate"
+headers: {
+ "Content-Type": "multipart/form-data",
+ "Authorization": "Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA==",
+ "USER_ID": "{sdc_designer_user}",
+ "Accept": "application/json"
+ }
+file: "{package_file_path}" \ No newline at end of file
diff --git a/vnftest/onap/core/testsuite.py b/vnftest/onap/package_upload.py
index 986982a..084de78 100644
--- a/vnftest/onap/core/testsuite.py
+++ b/vnftest/onap/package_upload.py
@@ -11,39 +11,33 @@
# See the License for the specific language governing permissions and limitations under
# the License
##############################################################################
-# vnftest comment: this is a modified copy of
-# yardstick/benchmark/core/testsuite.py
-
-""" Handler for vnftest command 'testcase' """
from __future__ import absolute_import
-from __future__ import print_function
-import os
+import copy
import logging
+import time
+
+import os
+import yaml
from vnftest.common import constants as consts
+from vnftest.common import rest_client
+from vnftest.common.exceptions import MandatoryKeyException, InputParameterMissing
+from vnftest.contexts.base import Context
+from vnftest.crawlers.base import Crawler
+from vnftest.onap.common.vnf_type_crawler import VnfTypeCrawler
+from vnftest.onap.onap_api_call import OnapApiCall
LOG = logging.getLogger(__name__)
-class Testsuite(object):
- """Testcase commands.
-
- Set of commands to discover and display test cases.
- """
-
- def list_all(self, args):
- """List existing test cases"""
-
- testsuite_list = self._get_testsuite_file_list()
+class PackageUpload(OnapApiCall):
- return testsuite_list
+ __step_type__ = "PackageUpload"
- def _get_testsuite_file_list(self):
- try:
- testsuite_files = sorted(os.listdir(consts.TESTSUITE_DIR))
- except OSError:
- LOG.exception('Failed to list dir:\n%s\n', consts.TESTSUITE_DIR)
- raise
+ def __init__(self, step_cfg, context_cfg, input_params):
+ super(PackageUpload, self).__init__(step_cfg, context_cfg, input_params)
- return testsuite_files
+ def setup(self):
+ super(PackageUpload, self).setup()
+ self.input_cfg.append({'parameter_name': "package_file_path", 'value': Context.vnf_descriptor["csar_package_location"]})
diff --git a/vnftest/onap/runners/base.py b/vnftest/onap/runners/base.py
deleted file mode 100755
index 15d8a8d..0000000
--- a/vnftest/onap/runners/base.py
+++ /dev/null
@@ -1,250 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/benchmark/runners/base.py
-
-from __future__ import absolute_import
-import logging
-import multiprocessing
-import subprocess
-import time
-import traceback
-import importlib
-from Queue import Empty
-
-import vnftest.common.utils as utils
-from vnftest.onap.steps import base as base_step
-from vnftest.onap.steps.onap_api_call import OnapApiCall
-
-log = logging.getLogger(__name__)
-
-
-def _execute_shell_command(command):
- """execute shell script with error handling"""
- exitcode = 0
- try:
- output = subprocess.check_output(command, shell=True)
- except Exception:
- exitcode = -1
- output = traceback.format_exc()
- log.error("exec command '%s' error:\n ", command)
- log.error(traceback.format_exc())
-
- return exitcode, output
-
-
-def _single_action(seconds, command, queue):
- """entrypoint for the single action process"""
- log.debug("single action, fires after %d seconds (from now)", seconds)
- time.sleep(seconds)
- log.debug("single action: executing command: '%s'", command)
- ret_code, data = _execute_shell_command(command)
- if ret_code < 0:
- log.error("single action error! command:%s", command)
- queue.put({'single-action-data': data})
- return
- log.debug("single action data: \n%s", data)
- queue.put({'single-action-data': data})
-
-
-def _periodic_action(interval, command, queue):
- """entrypoint for the periodic action process"""
- log.debug("periodic action, fires every: %d seconds", interval)
- time_spent = 0
- while True:
- time.sleep(interval)
- time_spent += interval
- log.debug("periodic action, executing command: '%s'", command)
- ret_code, data = _execute_shell_command(command)
- if ret_code < 0:
- log.error("periodic action error! command:%s", command)
- queue.put({'periodic-action-data': data})
- break
- log.debug("periodic action data: \n%s", data)
- queue.put({'periodic-action-data': data})
-
-
-class Runner(object):
- runners = []
-
- @staticmethod
- def get_cls(runner_type):
- """return class of specified type"""
- for runner in utils.itersubclasses(Runner):
- if runner_type == runner.__execution_type__:
- return runner
- raise RuntimeError("No such runner_type %s" % runner_type)
-
- @staticmethod
- def get_types():
- """return a list of known runner type (class) names"""
- types = []
- for runner in utils.itersubclasses(Runner):
- types.append(runner)
- return types
-
- @staticmethod
- def get(runner_cfg):
- """Returns instance of a step runner for execution type.
- """
- return Runner.get_cls(runner_cfg["type"])(runner_cfg)
-
- @staticmethod
- def release(runner):
- """Release the runner"""
- if runner in Runner.runners:
- Runner.runners.remove(runner)
-
- @staticmethod
- def terminate(runner):
- """Terminate the runner"""
- if runner.process and runner.process.is_alive():
- runner.process.terminate()
-
- @staticmethod
- def terminate_all():
- """Terminate all runners (subprocesses)"""
- log.debug("Terminating all runners", exc_info=True)
-
- # release dumper process as some errors before any runner is created
- if not Runner.runners:
- return
-
- for runner in Runner.runners:
- log.debug("Terminating runner: %s", runner)
- if runner.process:
- runner.process.terminate()
- runner.process.join()
- if runner.periodic_action_process:
- log.debug("Terminating periodic action process")
- runner.periodic_action_process.terminate()
- runner.periodic_action_process = None
- Runner.release(runner)
-
- def __init__(self, config):
- self.config = config
- self.periodic_action_process = None
- self.output_queue = multiprocessing.Queue()
- self.result_queue = multiprocessing.Queue()
- self.process = None
- self.aborted = multiprocessing.Event()
- Runner.runners.append(self)
-
- def run_post_stop_action(self):
- """run a potentially configured post-stop action"""
- if "post-stop-action" in self.config:
- command = self.config["post-stop-action"]["command"]
- log.debug("post stop action: command: '%s'", command)
- ret_code, data = _execute_shell_command(command)
- if ret_code < 0:
- log.error("post action error! command:%s", command)
- self.result_queue.put({'post-stop-action-data': data})
- return
- log.debug("post-stop data: \n%s", data)
- self.result_queue.put({'post-stop-action-data': data})
-
- def _run_step(self, cls, method_name, step_cfg, context_cfg, input_params):
- raise NotImplementedError
-
- def run(self, step_cfg, context_cfg, input_params):
- step_type = step_cfg["type"]
- class_name = base_step.Step.get(step_type)
- path_split = class_name.split(".")
- module_path = ".".join(path_split[:-1])
- module = importlib.import_module(module_path)
- cls = getattr(module, path_split[-1])
-
- self.config['object'] = class_name
- self.aborted.clear()
-
- # run a potentially configured pre-start action
- if "pre-start-action" in self.config:
- command = self.config["pre-start-action"]["command"]
- log.debug("pre start action: command: '%s'", command)
- ret_code, data = _execute_shell_command(command)
- if ret_code < 0:
- log.error("pre-start action error! command:%s", command)
- self.result_queue.put({'pre-start-action-data': data})
- return
- log.debug("pre-start data: \n%s", data)
- self.result_queue.put({'pre-start-action-data': data})
-
- if "single-shot-action" in self.config:
- single_action_process = multiprocessing.Process(
- target=_single_action,
- name="single-shot-action",
- args=(self.config["single-shot-action"]["after"],
- self.config["single-shot-action"]["command"],
- self.result_queue))
- single_action_process.start()
-
- if "periodic-action" in self.config:
- self.periodic_action_process = multiprocessing.Process(
- target=_periodic_action,
- name="periodic-action",
- args=(self.config["periodic-action"]["interval"],
- self.config["periodic-action"]["command"],
- self.result_queue))
- self.periodic_action_process.start()
-
- self._run_step(cls, "run", step_cfg, context_cfg, input_params)
-
- def abort(self):
- """Abort the execution of a step"""
- self.aborted.set()
-
- QUEUE_JOIN_INTERVAL = 5
-
- def poll(self, timeout=QUEUE_JOIN_INTERVAL):
- self.process.join(timeout)
- return self.process.exitcode
-
- def join(self, outputs, result, interval=QUEUE_JOIN_INTERVAL):
- while self.process.exitcode is None:
- # drain the queue while we are running otherwise we won't terminate
- outputs.update(self.get_output())
- result.extend(self.get_result())
- self.process.join(interval)
- # drain after the process has exited
- outputs.update(self.get_output())
- result.extend(self.get_result())
-
- self.process.terminate()
- if self.periodic_action_process:
- self.periodic_action_process.join(1)
- self.periodic_action_process.terminate()
- self.periodic_action_process = None
-
- self.run_post_stop_action()
- return self.process.exitcode
-
- def get_output(self):
- result = {}
- while not self.output_queue.empty():
- log.debug("output_queue size %s", self.output_queue.qsize())
- try:
- result.update(self.output_queue.get(True, 1))
- except Empty:
- pass
- return result
-
- def get_result(self):
- result = []
- while not self.result_queue.empty():
- log.debug("result_queue size %s", self.result_queue.qsize())
- try:
- result.append(self.result_queue.get(True, 1))
- except Empty:
- pass
- return result
diff --git a/vnftest/onap/runners/duration.py b/vnftest/onap/runners/duration.py
deleted file mode 100644
index 7e539e5..0000000
--- a/vnftest/onap/runners/duration.py
+++ /dev/null
@@ -1,145 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/benchmark/runners/duration.py
-
-"""A runner that runs a specific time before it returns
-"""
-
-from __future__ import absolute_import
-import os
-import multiprocessing
-import logging
-import traceback
-import time
-
-from vnftest.onap.runners import base
-
-LOG = logging.getLogger(__name__)
-
-
-QUEUE_PUT_TIMEOUT = 10
-
-
-def _worker_process(queue, cls, method_name, step_cfg,
- context_cfg, aborted, output_queue):
-
- sequence = 1
-
- runner_cfg = step_cfg['runner']
-
- interval = runner_cfg.get("interval", 1)
- duration = runner_cfg.get("duration", 60)
- LOG.info("Worker START, duration is %ds", duration)
- LOG.debug("class is %s", cls)
-
- runner_cfg['runner_id'] = os.getpid()
-
- step = cls(step_cfg, context_cfg)
- step.setup()
- method = getattr(step, method_name)
-
- sla_action = None
- if "sla" in step_cfg:
- sla_action = step_cfg["sla"].get("action", "assert")
-
- start = time.time()
- timeout = start + duration
- while True:
-
- LOG.debug("runner=%(runner)s seq=%(sequence)s START",
- {"runner": runner_cfg["runner_id"], "sequence": sequence})
-
- data = {}
- errors = ""
-
- try:
- result = method(data)
- except AssertionError as assertion:
- # SLA validation failed in scenario, determine what to do now
- if sla_action == "assert":
- raise
- elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s", assertion.args)
- errors = assertion.args
- # catch all exceptions because with multiprocessing we can have un-picklable exception
- # problems https://bugs.python.org/issue9400
- except Exception:
- errors = traceback.format_exc()
- LOG.exception("")
- else:
- if result:
- # add timeout for put so we don't block test
- # if we do timeout we don't care about dropping individual KPIs
- output_queue.put(result, True, QUEUE_PUT_TIMEOUT)
-
- time.sleep(interval)
-
- step_output = {
- 'timestamp': time.time(),
- 'sequence': sequence,
- 'data': data,
- 'errors': errors
- }
-
- queue.put(step_output, True, QUEUE_PUT_TIMEOUT)
-
- LOG.debug("runner=%(runner)s seq=%(sequence)s END",
- {"runner": runner_cfg["runner_id"], "sequence": sequence})
-
- sequence += 1
-
- if (errors and sla_action is None) or time.time() > timeout or aborted.is_set():
- LOG.info("Worker END")
- break
-
- try:
- step.teardown()
- except Exception:
- # catch any exception in teardown and convert to simple exception
- # never pass exceptions back to multiprocessing, because some exceptions can
- # be unpicklable
- # https://bugs.python.org/issue9400
- LOG.exception("")
- raise SystemExit(1)
-
- LOG.debug("queue.qsize() = %s", queue.qsize())
- LOG.debug("output_queue.qsize() = %s", output_queue.qsize())
-
-
-class DurationRunner(base.Runner):
- """Run a scenario for a certain amount of time
-
-If the scenario ends before the time has elapsed, it will be started again.
-
- Parameters
- duration - amount of time the scenario will be run for
- type: int
- unit: seconds
- default: 1 sec
- interval - time to wait between each scenario invocation
- type: int
- unit: seconds
- default: 1 sec
- """
- __execution_type__ = 'Duration'
-
- def _run_step(self, cls, method, step_cfg, context_cfg):
- name = "{}-{}-{}".format(self.__execution_type__, step_cfg.get("type"), os.getpid())
- self.process = multiprocessing.Process(
- name=name,
- target=_worker_process,
- args=(self.result_queue, cls, method, step_cfg,
- context_cfg, self.aborted, self.output_queue))
- self.process.start()
diff --git a/vnftest/onap/runners/dynamictp.py b/vnftest/onap/runners/dynamictp.py
deleted file mode 100755
index 5ea0910..0000000
--- a/vnftest/onap/runners/dynamictp.py
+++ /dev/null
@@ -1,179 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/step/runners/dynamictp.py
-
-"""A runner that searches for the max throughput with binary search
-"""
-
-import logging
-import multiprocessing
-import time
-import traceback
-
-import os
-
-from vnftest.onap.runners import base
-
-LOG = logging.getLogger(__name__)
-
-
-def _worker_process(queue, cls, method_name, step_cfg,
- context_cfg, aborted): # pragma: no cover
-
- runner_cfg = step_cfg['runner']
- iterations = runner_cfg.get("iterations", 1)
- interval = runner_cfg.get("interval", 1)
- run_step = runner_cfg.get("run_step", "setup,run,teardown")
- delta = runner_cfg.get("delta", 1000)
- options_cfg = step_cfg['options']
- initial_rate = options_cfg.get("pps", 1000000)
- LOG.info("worker START, class %s", cls)
-
- runner_cfg['runner_id'] = os.getpid()
-
- step = cls(step_cfg, context_cfg)
- if "setup" in run_step:
- step.setup()
-
- method = getattr(step, method_name)
-
- queue.put({'runner_id': runner_cfg['runner_id'],
- 'step_cfg': step_cfg,
- 'context_cfg': context_cfg})
-
- if "run" in run_step:
- iterator = 0
- search_max = initial_rate
- search_min = 0
- while iterator < iterations:
- search_min = int(search_min / 2)
- step_cfg['options']['pps'] = search_max
- search_max_found = False
- max_throuput_found = False
- sequence = 0
-
- last_min_data = {'packets_per_second': 0}
-
- while True:
- sequence += 1
-
- data = {}
- errors = ""
- too_high = False
-
- LOG.debug("sequence: %s search_min: %s search_max: %s",
- sequence, search_min, search_max)
-
- try:
- method(data)
- except AssertionError as assertion:
- LOG.warning("SLA validation failed: %s" % assertion.args)
- too_high = True
- except Exception as e:
- errors = traceback.format_exc()
- LOG.exception(e)
-
- actual_pps = data['packets_per_second']
-
- if too_high:
- search_max = actual_pps
-
- if not search_max_found:
- search_max_found = True
- else:
- last_min_data = data
- search_min = actual_pps
-
- # Check if the actual rate is well below the asked rate
- if step_cfg['options']['pps'] > actual_pps * 1.5:
- search_max = actual_pps
- LOG.debug("Sender reached max tput: %s", search_max)
- elif not search_max_found:
- search_max = int(actual_pps * 1.5)
-
- if ((search_max - search_min) < delta) or \
- (search_max <= search_min) or (10 <= sequence):
- if last_min_data['packets_per_second'] > 0:
- data = last_min_data
-
- step_output = {
- 'timestamp': time.time(),
- 'sequence': sequence,
- 'data': data,
- 'errors': errors
- }
-
- record = {
- 'runner_id': runner_cfg['runner_id'],
- 'step': step_output
- }
-
- queue.put(record)
- max_throuput_found = True
-
- if errors or aborted.is_set() or max_throuput_found:
- LOG.info("worker END")
- break
-
- if not search_max_found:
- step_cfg['options']['pps'] = search_max
- else:
- step_cfg['options']['pps'] = \
- (search_max - search_min) / 2 + search_min
-
- time.sleep(interval)
-
- iterator += 1
- LOG.debug("iterator: %s iterations: %s", iterator, iterations)
-
- if "teardown" in run_step:
- try:
- step.teardown()
- except Exception:
- # catch any exception in teardown and convert to simple exception
- # never pass exceptions back to multiprocessing, because some exceptions can
- # be unpicklable
- # https://bugs.python.org/issue9400
- LOG.exception("")
- raise SystemExit(1)
-
- LOG.debug("queue.qsize() = %s", queue.qsize())
-
-
-class IterationRunner(base.Runner):
- """Run a step to find the max throughput
-
-If the step ends before the time has elapsed, it will be started again.
-
- Parameters
- interval - time to wait between each step invocation
- type: int
- unit: seconds
- default: 1 sec
- delta - stop condition for the search.
- type: int
- unit: pps
- default: 1000 pps
- """
- __execution_type__ = 'Dynamictp'
-
- def _run_step(self, cls, method, step_cfg, context_cfg):
- name = "{}-{}-{}".format(self.__execution_type__, step_cfg.get("type"), os.getpid())
- self.process = multiprocessing.Process(
- name=name,
- target=_worker_process,
- args=(self.result_queue, cls, method, step_cfg,
- context_cfg, self.aborted))
- self.process.start()
diff --git a/vnftest/onap/runners/iteration.py b/vnftest/onap/runners/iteration.py
deleted file mode 100644
index 9c9ab2c..0000000
--- a/vnftest/onap/runners/iteration.py
+++ /dev/null
@@ -1,169 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/benchmark/runners/iteration.py
-
-"""A runner that runs a configurable number of times before it returns
-"""
-
-from __future__ import absolute_import
-
-import logging
-import multiprocessing
-import time
-import traceback
-
-import os
-from vnftest.common.exceptions import VnftestException
-
-from vnftest.onap.runners import base
-
-LOG = logging.getLogger(__name__)
-
-
-QUEUE_PUT_TIMEOUT = 10
-
-
-def _worker_process(result_queue, cls, method_name, step_cfg,
- context_cfg, input_params, aborted, output_queue):
-
- sequence = 1
-
- runner_cfg = step_cfg['runner']
-
- interval = runner_cfg.get("interval", 1)
- iterations = runner_cfg.get("iterations", 1)
- run_step = runner_cfg.get("run_step", "setup,run,teardown")
-
- delta = runner_cfg.get("delta", 2)
- LOG.info("worker START, iterations %d times, class %s", iterations, cls)
-
- runner_cfg['runner_id'] = os.getpid()
-
- step = cls(step_cfg, context_cfg, input_params)
- if "setup" in run_step:
- step.setup()
-
- method = getattr(step, method_name)
-
- sla_action = None
- if "sla" in step_cfg:
- sla_action = step_cfg["sla"].get("action", "assert")
- if "run" in run_step:
- while True:
-
- LOG.debug("runner=%(runner)s seq=%(sequence)s START",
- {"runner": runner_cfg["runner_id"],
- "sequence": sequence})
-
- results = {}
- errors = []
- fatal_error = False
-
- try:
- output = method(results)
- if output:
- # add timeout for put so we don't block test
- # if we do timeout we don't care about dropping individual KPIs
- output_queue.put(output, True, QUEUE_PUT_TIMEOUT)
- except AssertionError as assertion:
- # SLA validation failed in step, determine what to do now
- if sla_action == "assert":
- raise
- elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s", assertion.args)
- errors.append(assertion.args)
- elif sla_action == "rate-control":
- try:
- step_cfg['options']['rate']
- except KeyError:
- step_cfg.setdefault('options', {})
- step_cfg['options']['rate'] = 100
-
- step_cfg['options']['rate'] -= delta
- sequence = 1
- continue
- except VnftestException:
- errors.append(traceback.format_exc())
- LOG.exception("")
- LOG.info("Abort the task")
- fatal_error = True
-
- except Exception:
- errors.append(traceback.format_exc())
- LOG.exception("")
-
- time.sleep(interval)
-
- step_results = {
- 'timestamp': time.time(),
- 'sequence': sequence,
- 'data': results,
- 'errors': errors
- }
-
- result_queue.put(step_results, True, QUEUE_PUT_TIMEOUT)
-
- LOG.debug("runner=%(runner)s seq=%(sequence)s END",
- {"runner": runner_cfg["runner_id"],
- "sequence": sequence})
-
- sequence += 1
-
- if (errors and sla_action is None) or \
- (sequence > iterations or aborted.is_set()) or fatal_error:
- LOG.info("worker END")
- break
- if "teardown" in run_step:
- try:
- step.teardown()
- except Exception:
- # catch any exception in teardown and convert to simple exception
- # never pass exceptions back to multiprocessing, because some exceptions can
- # be unpicklable
- # https://bugs.python.org/issue9400
- LOG.exception("")
- raise SystemExit(1)
-
- LOG.debug("queue.qsize() = %s", result_queue.qsize())
- LOG.debug("output_queue.qsize() = %s", output_queue.qsize())
- if fatal_error:
- raise SystemExit(1)
-
-
-class IterationRunner(base.Runner):
- """Run a step for a configurable number of times
-
-If the step ends before the time has elapsed, it will be started again.
-
- Parameters
- iterations - amount of times the step will be run for
- type: int
- unit: na
- default: 1
- interval - time to wait between each step invocation
- type: int
- unit: seconds
- default: 1 sec
- """
- __execution_type__ = 'Iteration'
-
- def _run_step(self, cls, method, step_cfg, context_cfg, input_params):
- name = "{}-{}-{}".format(self.__execution_type__, step_cfg.get("type"), os.getpid())
- self.process = multiprocessing.Process(
- name=name,
- target=_worker_process,
- args=(self.result_queue, cls, method, step_cfg,
- context_cfg, input_params, self.aborted, self.output_queue))
- self.process.start()
diff --git a/vnftest/onap/runners/search.py b/vnftest/onap/runners/search.py
deleted file mode 100644
index d5bd417..0000000
--- a/vnftest/onap/runners/search.py
+++ /dev/null
@@ -1,180 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/benchmark/runners/search.py
-
-"""A runner that runs a specific time before it returns
-"""
-
-from __future__ import absolute_import
-
-import logging
-import multiprocessing
-import time
-import traceback
-from contextlib import contextmanager
-from itertools import takewhile
-
-import os
-from collections import Mapping
-from six.moves import zip
-
-from vnftest.onap.runners import base
-
-LOG = logging.getLogger(__name__)
-
-
-class SearchRunnerHelper(object):
-
- def __init__(self, cls, method_name, step_cfg, context_cfg, aborted):
- super(SearchRunnerHelper, self).__init__()
- self.cls = cls
- self.method_name = method_name
- self.step_cfg = step_cfg
- self.context_cfg = context_cfg
- self.aborted = aborted
- self.runner_cfg = step_cfg['runner']
- self.run_step = self.runner_cfg.get("run_step", "setup,run,teardown")
- self.timeout = self.runner_cfg.get("timeout", 60)
- self.interval = self.runner_cfg.get("interval", 1)
- self.step = None
- self.method = None
-
- def __call__(self, *args, **kwargs):
- if self.method is None:
- raise RuntimeError
- return self.method(*args, **kwargs)
-
- @contextmanager
- def get_step_instance(self):
- self.step = self.cls(self.step_cfg, self.context_cfg)
-
- if 'setup' in self.run_step:
- self.step.setup()
-
- self.method = getattr(self.step, self.method_name)
- LOG.info("worker START, timeout %d sec, class %s", self.timeout, self.cls)
- try:
- yield self
- finally:
- if 'teardown' in self.run_step:
- self.step.teardown()
-
- def is_not_done(self):
- if 'run' not in self.run_step:
- raise StopIteration
-
- max_time = time.time() + self.timeout
-
- abort_iter = iter(self.aborted.is_set, True)
- time_iter = takewhile(lambda t_now: t_now <= max_time, iter(time.time, -1))
-
- for seq, _ in enumerate(zip(abort_iter, time_iter), 1):
- yield seq
- time.sleep(self.interval)
-
-
-class SearchRunner(base.Runner):
- """Run a step for a certain amount of time
-
-If the step ends before the time has elapsed, it will be started again.
-
- Parameters
- timeout - amount of time the step will be run for
- type: int
- unit: seconds
- default: 1 sec
- interval - time to wait between each step invocation
- type: int
- unit: seconds
- default: 1 sec
- """
- __execution_type__ = 'Search'
-
- def __init__(self, config):
- super(SearchRunner, self).__init__(config)
- self.runner_cfg = None
- self.runner_id = None
- self.sla_action = None
- self.worker_helper = None
-
- def _worker_run_once(self, sequence):
- LOG.debug("runner=%s seq=%s START", self.runner_id, sequence)
-
- data = {}
- errors = ""
-
- try:
- self.worker_helper(data)
- except AssertionError as assertion:
- # SLA validation failed in step, determine what to do now
- if self.sla_action == "assert":
- raise
- elif self.sla_action == "monitor":
- LOG.warning("SLA validation failed: %s", assertion.args)
- errors = assertion.args
- except Exception as e:
- errors = traceback.format_exc()
- LOG.exception(e)
-
- record = {
- 'runner_id': self.runner_id,
- 'step': {
- 'timestamp': time.time(),
- 'sequence': sequence,
- 'data': data,
- 'errors': errors,
- },
- }
-
- self.result_queue.put(record)
-
- LOG.debug("runner=%s seq=%s END", self.runner_id, sequence)
-
- # Have to search through all the VNF KPIs
- kpi_done = any(kpi.get('done') for kpi in data.values() if isinstance(kpi, Mapping))
-
- return kpi_done or (errors and self.sla_action is None)
-
- def _worker_run(self, cls, method_name, step_cfg, context_cfg):
- self.runner_cfg = step_cfg['runner']
- self.runner_id = self.runner_cfg['runner_id'] = os.getpid()
-
- self.worker_helper = SearchRunnerHelper(cls, method_name, step_cfg,
- context_cfg, self.aborted)
-
- try:
- self.sla_action = step_cfg['sla'].get('action', 'assert')
- except KeyError:
- self.sla_action = None
-
- self.result_queue.put({
- 'runner_id': self.runner_id,
- 'step_cfg': step_cfg,
- 'context_cfg': context_cfg
- })
-
- with self.worker_helper.get_step_instance():
- for sequence in self.worker_helper.is_not_done():
- if self._worker_run_once(sequence):
- LOG.info("worker END")
- break
-
- def _run_step(self, cls, method, step_cfg, context_cfg):
- name = "{}-{}-{}".format(self.__execution_type__, step_cfg.get("type"), os.getpid())
- self.process = multiprocessing.Process(
- name=name,
- target=self._worker_run,
- args=(cls, method, step_cfg, context_cfg))
- self.process.start()
diff --git a/vnftest/onap/runners/sequence.py b/vnftest/onap/runners/sequence.py
deleted file mode 100644
index b341495..0000000
--- a/vnftest/onap/runners/sequence.py
+++ /dev/null
@@ -1,149 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/benchmark/runners/sequence.py
-
-"""A runner that every run changes a specified input value to the step.
-The input value in the sequence is specified in a list in the input file.
-"""
-
-from __future__ import absolute_import
-
-import logging
-import multiprocessing
-import time
-import traceback
-
-import os
-
-from vnftest.onap.runners import base
-
-LOG = logging.getLogger(__name__)
-
-
-def _worker_process(queue, cls, method_name, step_cfg,
- context_cfg, aborted, output_queue):
-
- sequence = 1
-
- runner_cfg = step_cfg['runner']
-
- interval = runner_cfg.get("interval", 1)
- arg_name = runner_cfg.get('step_option_name')
- sequence_values = runner_cfg.get('sequence')
-
- if 'options' not in step_cfg:
- step_cfg['options'] = {}
-
- options = step_cfg['options']
-
- runner_cfg['runner_id'] = os.getpid()
-
- LOG.info("worker START, sequence_values(%s, %s), class %s",
- arg_name, sequence_values, cls)
-
- step = cls(step_cfg, context_cfg)
- step.setup()
- method = getattr(step, method_name)
-
- sla_action = None
- if "sla" in step_cfg:
- sla_action = step_cfg["sla"].get("action", "assert")
-
- for value in sequence_values:
- options[arg_name] = value
-
- LOG.debug("runner=%(runner)s seq=%(sequence)s START",
- {"runner": runner_cfg["runner_id"], "sequence": sequence})
-
- data = {}
- errors = ""
-
- try:
- result = method(data)
- except AssertionError as assertion:
- # SLA validation failed in step, determine what to do now
- if sla_action == "assert":
- raise
- elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s", assertion.args)
- errors = assertion.args
- except Exception as e:
- errors = traceback.format_exc()
- LOG.exception(e)
- else:
- if result:
- output_queue.put(result)
-
- time.sleep(interval)
-
- step_output = {
- 'timestamp': time.time(),
- 'sequence': sequence,
- 'data': data,
- 'errors': errors
- }
-
- queue.put(step_output)
-
- LOG.debug("runner=%(runner)s seq=%(sequence)s END",
- {"runner": runner_cfg["runner_id"], "sequence": sequence})
-
- sequence += 1
-
- if (errors and sla_action is None) or aborted.is_set():
- break
-
- try:
- step.teardown()
- except Exception:
- # catch any exception in teardown and convert to simple exception
- # never pass exceptions back to multiprocessing, because some exceptions can
- # be unpicklable
- # https://bugs.python.org/issue9400
- LOG.exception("")
- raise SystemExit(1)
- LOG.info("worker END")
- LOG.debug("queue.qsize() = %s", queue.qsize())
- LOG.debug("output_queue.qsize() = %s", output_queue.qsize())
-
-
-class SequenceRunner(base.Runner):
- """Run a step by changing an input value defined in a list
-
- Parameters
- interval - time to wait between each step invocation
- type: int
- unit: seconds
- default: 1 sec
- step_option_name - name of the option that is increased each invocation
- type: string
- unit: na
- default: none
- sequence - list of values which are executed in their respective steps
- type: [int]
- unit: na
- default: none
- """
-
- __execution_type__ = 'Sequence'
-
- def _run_step(self, cls, method, step_cfg, context_cfg):
- name = "{}-{}-{}".format(self.__execution_type__, step_cfg.get("type"), os.getpid())
- self.process = multiprocessing.Process(
- name=name,
- target=_worker_process,
- args=(self.result_queue, cls, method, step_cfg,
- context_cfg, self.aborted, self.output_queue))
- self.process.start()
diff --git a/vnftest/onap/steps/__init__.py b/vnftest/onap/steps/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/vnftest/onap/steps/__init__.py
+++ /dev/null
diff --git a/vnftest/onap/steps/base.py b/vnftest/onap/steps/base.py
deleted file mode 100644
index d5c606a..0000000
--- a/vnftest/onap/steps/base.py
+++ /dev/null
@@ -1,89 +0,0 @@
-##############################################################################
-# Copyright 2018 EuropeanSoftwareMarketingLtd.
-# ===================================================================
-# Licensed under the ApacheLicense, Version2.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
-#
-# 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
-##############################################################################
-# vnftest comment: this is a modified copy of
-# rally/rally/benchmark/steps/base.py
-
-""" Step base class
-"""
-
-from __future__ import absolute_import
-import vnftest.common.utils as utils
-
-
-class Step(object):
-
- def setup(self):
- """ default impl for step setup """
- pass
-
- def run(self, args):
- """ catcher for not implemented run methods in subclasses """
- raise RuntimeError("run method not implemented")
-
- def teardown(self):
- """ default impl for step teardown """
- pass
-
- @staticmethod
- def get_types():
- """return a list of known runner type (class) names"""
- steps = []
- for step in utils.itersubclasses(Step):
- steps.append(step)
- return steps
-
- @staticmethod
- def get_cls(step_type):
- """return class of specified type"""
- for step in utils.itersubclasses(Step):
- if step_type == step.__step_type__:
- return step
-
- raise RuntimeError("No such step type %s" % step_type)
-
- @staticmethod
- def get(step_type):
- """Returns instance of a step runner for execution type.
- """
- for step in utils.itersubclasses(Step):
- if step_type == step.__step_type__:
- return step.__module__ + "." + step.__name__
-
- raise RuntimeError("No such step type %s" % step_type)
-
- @classmethod
- def get_step_type(cls):
- """Return a string with the step type, if defined"""
- return str(getattr(cls, '__step_type__', None))
-
- @classmethod
- def get_description(cls):
- """Return a single line string with the class description
-
- This function will retrieve the class docstring and return the first
- line, or 'None' if it's empty.
- """
- return cls.__doc__.splitlines()[0] if cls.__doc__ else str(None)
-
- def _push_to_outputs(self, keys, values):
- return dict(zip(keys, values))
-
- def _change_obj_to_dict(self, obj):
- dic = {}
- for k, v in vars(obj).items():
- try:
- vars(v)
- except TypeError:
- dic[k] = v
- return dic
diff --git a/vnftest/onap/steps/dummy/__init__.py b/vnftest/onap/steps/dummy/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/vnftest/onap/steps/dummy/__init__.py
+++ /dev/null
diff --git a/vnftest/onap/steps/onboard/__init__.py b/vnftest/onap/steps/onboard/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/vnftest/onap/steps/onboard/__init__.py
+++ /dev/null