diff --git a/zaza/openstack/charm_tests/tempest/setup.py b/zaza/openstack/charm_tests/tempest/setup.py index af1ee4c..7ce4478 100644 --- a/zaza/openstack/charm_tests/tempest/setup.py +++ b/zaza/openstack/charm_tests/tempest/setup.py @@ -16,11 +16,12 @@ import jinja2 import urllib.parse -import subprocess +import os import zaza.utilities.deployment_env as deployment_env import zaza.openstack.utilities.juju as juju_utils import zaza.openstack.utilities.openstack as openstack_utils +import zaza.openstack.charm_tests.tempest.utils as tempest_utils import zaza.openstack.charm_tests.glance.setup as glance_setup SETUP_ENV_VARS = { @@ -279,21 +280,15 @@ def setup_tempest(tempest_template, accounts_template): :returns: None :rtype: None """ - try: - subprocess.check_call(['tempest', 'workspace', 'remove', '--rmdir', - '--name', 'tempest-workspace']) - except subprocess.CalledProcessError: - pass - try: - subprocess.check_call(['tempest', 'init', 'tempest-workspace']) - except subprocess.CalledProcessError: - pass + workspace_name, workspace_path = tempest_utils.get_workspace() + tempest_utils.destroy_workspace(workspace_name, workspace_path) + tempest_utils.init_workspace(workspace_path) render_tempest_config( - 'tempest-workspace/etc/tempest.conf', + os.path.join(workspace_path, 'etc/tempest.conf'), get_tempest_context(), tempest_template) render_tempest_config( - 'tempest-workspace/etc/accounts.yaml', + os.path.join(workspace_path, 'etc/accounts.yaml'), get_tempest_context(), accounts_template) diff --git a/zaza/openstack/charm_tests/tempest/tests.py b/zaza/openstack/charm_tests/tempest/tests.py index d726930..979caff 100644 --- a/zaza/openstack/charm_tests/tempest/tests.py +++ b/zaza/openstack/charm_tests/tempest/tests.py @@ -20,6 +20,7 @@ import subprocess import zaza import zaza.charm_lifecycle.utils import zaza.charm_lifecycle.test +import zaza.openstack.charm_tests.tempest.utils as tempest_utils import tempfile @@ -33,21 +34,24 @@ class TempestTest(): Test keys are parsed from ['tests_options']['tempest']['model'], where valid test keys are: smoke (bool), whitelist (list of tests), blacklist - (list of tests), and regex (list of regex's). + (list of tests), regex (list of regex's), and keep-workspace (bool). :returns: Status of tempest run :rtype: bool """ + result = True charm_config = zaza.charm_lifecycle.utils.get_charm_config() + workspace_name, workspace_path = tempest_utils.get_workspace() tempest_options = ['tempest', 'run', '--workspace', - 'tempest-workspace', '--config', - 'tempest-workspace/etc/tempest.conf'] + workspace_name, '--config', + os.path.join(workspace_path, 'etc/tempest.conf')] for model_alias in zaza.model.get_juju_model_aliases().keys(): tempest_test_key = model_alias if model_alias == zaza.charm_lifecycle.utils.DEFAULT_MODEL_ALIAS: tempest_test_key = 'default' config = charm_config['tests_options']['tempest'][tempest_test_key] - if config.get('smoke'): + smoke = config.get('smoke') + if smoke and smoke is True: tempest_options.extend(['--smoke']) if config.get('regex'): tempest_options.extend( @@ -74,5 +78,9 @@ class TempestTest(): try: subprocess.check_call(tempest_options) except subprocess.CalledProcessError: - return False - return True + result = False + break + keep_workspace = config.get('keep-workspace') + if not keep_workspace or keep_workspace is not True: + tempest_utils.destroy_workspace(workspace_name, workspace_path) + return result diff --git a/zaza/openstack/charm_tests/tempest/utils.py b/zaza/openstack/charm_tests/tempest/utils.py new file mode 100644 index 0000000..8f3aea7 --- /dev/null +++ b/zaza/openstack/charm_tests/tempest/utils.py @@ -0,0 +1,67 @@ +# Copyright 2020 Canonical Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Utility code for working with tempest workspaces.""" + +import os +from pathlib import Path +import shutil +import subprocess + +import zaza.model as model + + +def get_workspace(): + """Get tempest workspace name and path. + + :returns: A tuple containing tempest workspace name and workspace path + :rtype: Tuple[str, str] + """ + home = str(Path.home()) + workspace_name = model.get_juju_model() + workspace_path = os.path.join(home, '.tempest', workspace_name) + return (workspace_name, workspace_path) + + +def destroy_workspace(workspace_name, workspace_path): + """Delete tempest workspace. + + :param workspace_name: name of workspace + :type workspace_name: str + :param workspace_path: directory path where workspace is stored + :type workspace_path: str + :returns: None + :rtype: None + """ + try: + subprocess.check_call(['tempest', 'workspace', 'remove', '--rmdir', + '--name', workspace_name]) + except subprocess.CalledProcessError: + pass + if os.path.isdir(workspace_path): + shutil.rmtree(workspace_path) + + +def init_workspace(workspace_path): + """Initialize tempest workspace. + + :param workspace_path: directory path where workspace is stored + :type workspace_path: str + :returns: None + :rtype: None + """ + try: + subprocess.check_call(['tempest', 'init', workspace_path]) + except subprocess.CalledProcessError: + pass