From 946470e3a794cc98e2d5b20af74ae3e5dac7d315 Mon Sep 17 00:00:00 2001 From: Moshe Date: Sun, 3 Mar 2019 12:06:08 +0200 Subject: Allow multiple contexts per test case Issue-ID: VNFSDK-350 Change-Id: Ib189a748bd41c48ef55959cecf221971d15099b5 Signed-off-by: Moshe refactor context handling Change-Id: Ic2bcdbcc98addeeef2cecd42c025a6a25b630b07 Signed-off-by: Moshe produce coverage report Issue-ID: VNFSDK-350 Change-Id: I88722d36710e09d8a2f9309a1214fd3ab53a8c83 Signed-off-by: Moshe --- vnftest/common/utils.py | 13 +++++++- vnftest/contexts/base.py | 14 +++----- vnftest/core/task.py | 53 ++++++++++++++++--------------- vnftest/tests/unit/onap/test_rest_call.py | 2 +- 4 files changed, 45 insertions(+), 37 deletions(-) (limited to 'vnftest') diff --git a/vnftest/common/utils.py b/vnftest/common/utils.py index 882403f..dfd32d5 100644 --- a/vnftest/common/utils.py +++ b/vnftest/common/utils.py @@ -475,7 +475,6 @@ def load_resource(path, mode="r"): try: return open(path, mode) except Exception: - logger.info("path not loaded as file, trying load as package") split_path = os.path.split(path) package = split_path[0].replace("/", ".") if not pkg_resources.resource_exists(package, split_path[1]): @@ -483,6 +482,18 @@ def load_resource(path, mode="r"): return pkg_resources.resource_stream(package, split_path[1]) +def resource_abs_path(path, mode="r"): + try: + open(path, mode) + return path + except Exception: + split_path = os.path.split(path) + package = split_path[0].replace("/", ".") + if not pkg_resources.resource_exists(package, split_path[1]): + raise ResourceNotFound(resource=path) + return pkg_resources.resource_filename(package, split_path[1]) + + def format(in_obj, params): if isinstance(in_obj, list): ret_list = [] diff --git a/vnftest/contexts/base.py b/vnftest/contexts/base.py index 538a2d6..29e3a19 100644 --- a/vnftest/contexts/base.py +++ b/vnftest/contexts/base.py @@ -26,20 +26,14 @@ class Context(object): """Class that represents a context in the logical model""" list = [] - @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) + self._task_id = None + self._name = None def init(self, attrs): - pass + self._task_id = attrs['task_id'] + self._name = attrs['name'] @staticmethod def get_cls(context_type): diff --git a/vnftest/core/task.py b/vnftest/core/task.py index da18441..a9718bb 100644 --- a/vnftest/core/task.py +++ b/vnftest/core/task.py @@ -35,7 +35,6 @@ from six.moves import filter from vnftest.runners import base as base_runner from vnftest.contexts.base import Context -from vnftest.contexts.csar import CSARContext from vnftest.runners import base as base_runner from vnftest.runners.duration import DurationRunner from vnftest.runners.iteration import IterationRunner @@ -61,7 +60,7 @@ class Task(object): # pragma: no cover """ def __init__(self, args): - self.context = None + self.contexts = None self.outputs = {} self.args = args or {} task_id = getattr(args, 'task_id', None) @@ -129,10 +128,10 @@ class Task(object): # pragma: no cover except TypeError: raise TypeError() parser.path = task_files[i] - steps, run_in_parallel, meet_precondition, ret_context = \ + steps, run_in_parallel, meet_precondition, ret_contexts = \ parser.parse_task(self.task_id, inputs) - self.context = ret_context + self.contexts = ret_contexts if not meet_precondition: LOG.info("meet_precondition is %s, please check envrionment", @@ -150,10 +149,12 @@ class Task(object): # pragma: no cover if self.args.keep_deploy: # keep deployment, forget about stack # (hide it for exit handler) - self.context = None + self.contexts = None else: - self.context.undeploy() - self.context = None + if self.contexts is not None: + for context in self.contexts: + context.undeploy() + self.contexts = 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) @@ -229,8 +230,10 @@ class Task(object): # pragma: no cover def _run(self, steps, case_name, run_in_parallel, output_file, inputs): """Deploys context and calls runners""" - if self.context: - self.context.deploy() + if self.contexts is not None: + for context in self.contexts: + context.deploy() + try: self.task_info.testcase_start(case_name) for step in steps: @@ -284,9 +287,10 @@ class Task(object): # pragma: no cover """handler for process termination""" base_runner.Runner.terminate_all() - if self.context: + if self.contexts: LOG.info("Undeploying context") - self.context.undeploy() + for context in self.contexts: + context.undeploy() def _parse_options(self, op): if isinstance(op, dict): @@ -312,7 +316,7 @@ class Task(object): # pragma: no cover LOG.info("Starting runner of type '%s'", runner_cfg["type"]) # Previous steps output is the input of the next step. inputs.update(self.outputs) - runner.run(step_cfg, self.context, inputs) + runner.run(step_cfg, self.contexts, inputs) return runner def finalize_step(self, step, runner, result): @@ -420,20 +424,19 @@ class TaskParser(object): # pragma: no cover meet_precondition = self._check_precondition(cfg) if "context" in cfg: - context_cfg = cfg["context"] + context_cfgs = [cfg["context"]] + elif "contexts" in cfg: + context_cfgs = cfg["contexts"] else: - context_cfg = {"type": "Dummy"} + context_cfgs = [{"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) + _contexts = [] + for cfg_attrs in context_cfgs: + cfg_attrs['task_id'] = task_id + context_type = cfg_attrs.get("type") + context = Context.get(context_type) + context.init(cfg_attrs) + _contexts.append(context) run_in_parallel = cfg.get("run_in_parallel", False) @@ -447,7 +450,7 @@ class TaskParser(object): # pragma: no cover 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 + return cfg["steps"], run_in_parallel, meet_precondition, _contexts def _check_schema(self, cfg_schema, schema_type): """Check if config file is using the correct schema type""" diff --git a/vnftest/tests/unit/onap/test_rest_call.py b/vnftest/tests/unit/onap/test_rest_call.py index 6735774..8e6b402 100644 --- a/vnftest/tests/unit/onap/test_rest_call.py +++ b/vnftest/tests/unit/onap/test_rest_call.py @@ -51,7 +51,7 @@ class RestCallTestCase(testtools.TestCase): def test_run(self, mock_execute_operation): mock_execute_operation.return_value = {'body': {'value': 'output1'}} t = task.Task({}) - context_cfg = {} + context_cfg = {'task_id': '123', 'name': 'dummy'} context = Context.get("CSAR") context.init(context_cfg) t.context = context -- cgit 1.2.3-korg