diff options
Diffstat (limited to 'functest')
-rw-r--r-- | functest/ci/testcases.yaml | 6 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/refstack/__init__.py (renamed from functest/opnfv_tests/openstack/refstack_client/__init__.py) | 0 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/refstack/refstack.py | 73 | ||||
-rw-r--r-- | functest/opnfv_tests/openstack/refstack_client/refstack_client.py | 261 | ||||
-rw-r--r-- | functest/tests/unit/openstack/refstack_client/__init__.py | 0 | ||||
-rw-r--r-- | functest/tests/unit/openstack/refstack_client/test_refstack_client.py | 148 |
6 files changed, 76 insertions, 412 deletions
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml index ce1823adc..0b7ae4f49 100644 --- a/functest/ci/testcases.yaml +++ b/functest/ci/testcases.yaml @@ -140,14 +140,14 @@ tiers: blocking: false description: >- This test case runs a sub group of tests of the OpenStack - Defcore testcases by using refstack client. + Defcore testcases. dependencies: installer: '' scenario: '' run: module: - 'functest.opnfv_tests.openstack.refstack_client.refstack_client' - class: 'RefstackClient' + 'functest.opnfv_tests.openstack.refstack.refstack' + class: 'Refstack' - case_name: patrole diff --git a/functest/opnfv_tests/openstack/refstack_client/__init__.py b/functest/opnfv_tests/openstack/refstack/__init__.py index e69de29bb..e69de29bb 100644 --- a/functest/opnfv_tests/openstack/refstack_client/__init__.py +++ b/functest/opnfv_tests/openstack/refstack/__init__.py diff --git a/functest/opnfv_tests/openstack/refstack/refstack.py b/functest/opnfv_tests/openstack/refstack/refstack.py new file mode 100644 index 000000000..b5766a020 --- /dev/null +++ b/functest/opnfv_tests/openstack/refstack/refstack.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 + +"""Refstack testcase implementation.""" + +import logging +import os +import shutil +import time + +from refstack_client import list_parser +from xtesting.core import testcase +from xtesting.energy import energy + +from functest.opnfv_tests.openstack.snaps import snaps_utils +from functest.opnfv_tests.openstack.tempest import conf_utils +from functest.opnfv_tests.openstack.tempest import tempest +from functest.utils import config + + +class Refstack(tempest.TempestCommon): + """Refstack testcase implementation class.""" + + __logger = logging.getLogger(__name__) + + defcorelist = os.path.join( + getattr(config.CONF, 'dir_refstack_data'), 'defcore.txt') + + def __init__(self, **kwargs): + if "case_name" not in kwargs: + kwargs["case_name"] = 'refstack' + super(Refstack, self).__init__(**kwargs) + self.res_dir = os.path.join( + getattr(config.CONF, 'dir_results'), 'refstack') + self.list = os.path.join(self.res_dir, 'tempest-list.txt') + + @energy.enable_recording + def run(self, **kwargs): + """Start Refstack testcase.""" + self.start_time = time.time() + try: + if not os.path.exists(self.res_dir): + os.makedirs(self.res_dir) + resources = self.resources.create() + compute_cnt = snaps_utils.get_active_compute_cnt( + self.resources.os_creds) + conf_file = conf_utils.configure_verifier(self.deployment_dir) + conf_utils.configure_tempest_update_params( + conf_file, self.res_dir, + network_name=resources.get("network_name"), + image_id=resources.get("image_id"), + flavor_id=resources.get("flavor_id"), + compute_cnt=compute_cnt) + parser = list_parser.TestListParser('/src/tempest') + nfile = parser.get_normalized_test_list(Refstack.defcorelist) + shutil.copyfile(nfile, self.list) + self.run_verifier_tests() + self.parse_verifier_result() + self.generate_report() + res = testcase.TestCase.EX_OK + except Exception as err: # pylint: disable=broad-except + self.__logger.error('Error with run: %s', err) + res = testcase.TestCase.EX_RUN_ERROR + finally: + self.resources.cleanup() + self.stop_time = time.time() + return res diff --git a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py deleted file mode 100644 index bcd42c30e..000000000 --- a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 - -"""Refstack client testcase implemenation.""" - -from __future__ import division - -import argparse -import ConfigParser -import logging -import os -import re -import sys -import subprocess -import time - -from xtesting.core import testcase -from xtesting.energy import energy - -from functest.opnfv_tests.openstack.tempest import conf_utils -from functest.opnfv_tests.openstack.tempest import tempest -from functest.utils import config -from functest.utils import functest_utils - - -__author__ = ("Matthew Li <matthew.lijun@huawei.com>," - "Linda Wang <wangwulin@huawei.com>") - -# logging configuration """ -LOGGER = logging.getLogger(__name__) - - -class RefstackClient(testcase.TestCase): - """RefstackClient testcase implementation class.""" - # pylint: disable=too-many-instance-attributes - - defcorelist = os.path.join( - getattr(config.CONF, 'dir_refstack_data'), 'defcore.txt') - - def __init__(self, **kwargs): - """Initialize RefstackClient testcase object.""" - if "case_name" not in kwargs: - kwargs["case_name"] = "refstack_defcore" - super(RefstackClient, self).__init__(**kwargs) - self.res_dir = os.path.join( - getattr(config.CONF, 'dir_results'), 'refstack') - self.conf_path = os.path.join(self.res_dir, 'refstack_tempest.conf') - - @staticmethod - def run_defcore(conf, testlist): - """Run defcore sys command.""" - insecure = '' - if ('https' in os.environ['OS_AUTH_URL'] and - os.getenv('OS_INSECURE', '').lower() == 'true'): - insecure = '-k' - cmd = ("refstack-client test {0} -c {1} -v --test-list {2}" - .format(insecure, conf, testlist)) - LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd) - functest_utils.execute_command(cmd) - - def run_defcore_default(self): - """Run default defcore sys command.""" - insecure = '' - if ('https' in os.environ['OS_AUTH_URL'] and - os.getenv('OS_INSECURE', '').lower() == 'true'): - insecure = '-k' - options = ["-v"] if not insecure else ["-v", insecure] - cmd = (["refstack-client", "test", "-c", self.conf_path] + - options + ["--test-list", self.defcorelist]) - LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd) - with open(os.path.join(self.res_dir, "refstack.log"), 'w+') as fstdout: - subprocess.call(cmd, shell=False, stdout=fstdout, - stderr=subprocess.STDOUT) - - def parse_refstack_result(self): - """Parse Refstack results.""" - try: - with open(os.path.join(self.res_dir, - "refstack.log"), 'r') as logfile: - for line in logfile.readlines(): - if 'Tests' in line: - break - if re.search(r"\} tempest\.", line): - LOGGER.info(line.replace('\n', '')) - - with open(os.path.join(self.res_dir, - "refstack.log"), 'r') as logfile: - output = logfile.read() - - for match in re.findall(r"Ran: (\d+) tests in (\d+\.\d{4}) sec.", - output): - num_tests = match[0] - LOGGER.info("Ran: %s tests in %s sec.", num_tests, match[1]) - for match in re.findall(r"(- Passed: )(\d+)", output): - num_success = match[1] - LOGGER.info("".join(match)) - for match in re.findall(r"(- Skipped: )(\d+)", output): - num_skipped = match[1] - LOGGER.info("".join(match)) - for match in re.findall(r"(- Failed: )(\d+)", output): - num_failures = match[1] - LOGGER.info("".join(match)) - success_testcases = [] - for match in re.findall(r"\{0\} (.*?) \.{3} ok", output): - success_testcases.append(match) - failed_testcases = [] - for match in re.findall(r"\{0\} (.*?) \.{3} FAILED", output): - failed_testcases.append(match) - skipped_testcases = [] - for match in re.findall(r"\{0\} (.*?) \.{3} SKIPPED:", output): - skipped_testcases.append(match) - - num_executed = int(num_tests) - int(num_skipped) - - try: - self.result = 100 * int(num_success) / int(num_executed) - except ZeroDivisionError: - LOGGER.error("No test has been executed") - - self.details = {"tests": int(num_tests), - "failures": int(num_failures), - "success": success_testcases, - "errors": failed_testcases, - "skipped": skipped_testcases} - except Exception: # pylint: disable=broad-except - self.result = 0 - LOGGER.info("Testcase %s success_rate is %s%%", - self.case_name, self.result) - - def configure_tempest_defcore(self): - # pylint: disable=too-many-arguments - """ - Add/update needed parameters into tempest.conf file - """ - resources = tempest.TempestResourcesManager().create( - create_project=True, use_custom_images=True, - use_custom_flavors=True) - verifier_id = conf_utils.get_verifier_id() - deployment_id = conf_utils.get_verifier_deployment_id() - deployment_dir = conf_utils.get_verifier_deployment_dir( - verifier_id, deployment_id) - conf_file = conf_utils.configure_verifier(deployment_dir) - conf_utils.configure_tempest_update_params( - conf_file, self.res_dir, resources.get("network_name"), - resources.get("image_id"), resources.get("flavor_id")) - LOGGER.debug( - "Updating selected tempest.conf parameters for defcore...") - rconfig = ConfigParser.RawConfigParser() - rconfig.read(conf_file) - rconfig.set( - 'DEFAULT', 'log_file', '{}/tempest.log'.format(deployment_dir)) - rconfig.set('oslo_concurrency', 'lock_path', - '{}/lock_files'.format(deployment_dir)) - conf_utils.generate_test_accounts_file( - tenant_id=resources.get("project_id")) - rconfig.set('auth', 'test_accounts_file', - conf_utils.TEST_ACCOUNTS_FILE) - rconfig.set('scenario', 'img_dir', '{}'.format(deployment_dir)) - rconfig.set('scenario', 'img_file', 'tempest-image') - rconfig.set('compute', 'image_ref', resources.get("image_id")) - rconfig.set('compute', 'image_ref_alt', resources.get("image_id_alt")) - rconfig.set('compute', 'flavor_ref', resources.get("flavor_id")) - rconfig.set('compute', 'flavor_ref_alt', - resources.get("flavor_id_alt")) - if not os.path.exists(self.res_dir): - os.makedirs(self.res_dir) - with open(self.conf_path, 'w') as config_fd: - rconfig.write(config_fd) - - @energy.enable_recording - def run(self, **kwargs): - """ - Start RefstackClient testcase. - - used for functest command line, - functest testcase run refstack_defcore - """ - self.start_time = time.time() - try: - # Make sure that Tempest is configured - self.configure_tempest_defcore() - self.run_defcore_default() - self.parse_refstack_result() - res = testcase.TestCase.EX_OK - except Exception: # pylint: disable=broad-except - LOGGER.exception("Error with run") - res = testcase.TestCase.EX_RUN_ERROR - self.stop_time = time.time() - return res - - @staticmethod - def main(**kwargs): - """ - Execute RefstackClient testcase manually. - - used for manually running, - python refstack_client.py -c <tempest_conf_path> - --testlist <testlist_path> - can generate a reference refstack_tempest.conf by - python tempest_conf.py - """ - try: - conf_path = kwargs['config'] - if not os.path.isfile(conf_path): - LOGGER.error("Conf file not valid: %s", conf_path) - return testcase.TestCase.EX_RUN_ERROR - testlist = kwargs['testlist'] - if not os.path.isfile(testlist): - LOGGER.error("testlist file not valid: %s", testlist) - return testcase.TestCase.EX_RUN_ERROR - except KeyError as exc: - LOGGER.error("Cannot run refstack client. Please check " - "%s", exc) - return testcase.TestCase.EX_RUN_ERROR - try: - RefstackClient.run_defcore(conf_path, testlist) - except Exception as exc: # pylint: disable=broad-except - LOGGER.error('Error with run: %s', exc) - return testcase.TestCase.EX_RUN_ERROR - return testcase.TestCase.EX_OK - - -class RefstackClientParser(object): # pylint: disable=too-few-public-methods - """Command line argument parser helper.""" - - def __init__(self): - """Initialize helper object.""" - self.parser = argparse.ArgumentParser() - self.parser.add_argument( - '-c', '--config', - help='the file path of refstack_tempest.conf') - self.parser.add_argument( - '-t', '--testlist', - help='Specify the file path or URL of a test list text file. ' - 'This test list will contain specific test cases that ' - 'should be tested.', - default=RefstackClient.defcorelist) - - def parse_args(self, argv=None): - """Parse command line arguments.""" - return vars(self.parser.parse_args(argv)) - - -def main(): - """Run RefstackClient testcase with CLI.""" - logging.basicConfig() - refstackclient = RefstackClient() - parser = RefstackClientParser() - args = parser.parse_args(sys.argv[1:]) - try: - result = refstackclient.main(**args) - if result != testcase.TestCase.EX_OK: - return result - except Exception: # pylint: disable=broad-except - return testcase.TestCase.EX_RUN_ERROR diff --git a/functest/tests/unit/openstack/refstack_client/__init__.py b/functest/tests/unit/openstack/refstack_client/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/functest/tests/unit/openstack/refstack_client/__init__.py +++ /dev/null diff --git a/functest/tests/unit/openstack/refstack_client/test_refstack_client.py b/functest/tests/unit/openstack/refstack_client/test_refstack_client.py deleted file mode 100644 index c26857e4d..000000000 --- a/functest/tests/unit/openstack/refstack_client/test_refstack_client.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 - -# pylint: disable=missing-docstring - -import logging -import os -import unittest - -import mock -import pkg_resources -from snaps.openstack.os_credentials import OSCreds -from xtesting.core import testcase - -from functest.opnfv_tests.openstack.refstack_client.refstack_client import \ - RefstackClient, RefstackClientParser - -__author__ = ("Matthew Li <matthew.lijun@huawei.com>," - "Linda Wang <wangwulin@huawei.com>") - - -class OSRefstackClientTesting(unittest.TestCase): - """The class testing RefstackClient """ - # pylint: disable=missing-docstring, too-many-public-methods - - _config = pkg_resources.resource_filename( - 'functest', - 'opnfv_tests/openstack/refstack_client/refstack_tempest.conf') - - def setUp(self): - self.default_args = {'config': None, - 'testlist': RefstackClient.defcorelist} - os.environ['OS_AUTH_URL'] = 'https://ip:5000/v3' - os.environ['OS_INSECURE'] = 'true' - self.case_name = 'refstack_defcore' - self.result = 0 - self.os_creds = OSCreds( - username='user', password='pass', - auth_url='http://foo.com:5000/v3', project_name='bar') - self.details = {"tests": 3, - "failures": 1, - "success": ['tempest.api.compute [18.464988s]'], - "errors": ['tempest.api.volume [0.230334s]'], - "skipped": ['tempest.api.network [1.265828s]']} - - def _create_client(self): - with mock.patch('snaps.openstack.tests.openstack_tests.' - 'get_credentials', return_value=self.os_creds): - return RefstackClient() - - @mock.patch('functest.utils.functest_utils.execute_command') - def test_run_defcore_insecure(self, m_cmd): - insecure = '-k' - config = 'tempest.conf' - testlist = 'testlist' - client = self._create_client() - cmd = ("refstack-client test {0} -c {1} -v --test-list {2}".format( - insecure, config, testlist)) - client.run_defcore(config, testlist) - m_cmd.assert_any_call(cmd) - - @mock.patch('functest.utils.functest_utils.execute_command') - def test_run_defcore(self, m_cmd): - os.environ['OS_AUTH_URL'] = 'http://ip:5000/v3' - insecure = '' - config = 'tempest.conf' - testlist = 'testlist' - client = self._create_client() - cmd = ("refstack-client test {0} -c {1} -v --test-list {2}".format( - insecure, config, testlist)) - client.run_defcore(config, testlist) - m_cmd.assert_any_call(cmd) - - @mock.patch('functest.opnfv_tests.openstack.refstack_client.' - 'refstack_client.LOGGER.info') - @mock.patch('__builtin__.open', side_effect=Exception) - def test_parse_refstack_result_fail(self, *args): - self._create_client().parse_refstack_result() - args[1].assert_called_once_with( - "Testcase %s success_rate is %s%%", - self.case_name, self.result) - - def test_parse_refstack_result_ok(self): - log_file = (''' - {0} tempest.api.compute [18.464988s] ... ok - {0} tempest.api.volume [0.230334s] ... FAILED - {0} tempest.api.network [1.265828s] ... SKIPPED: - Ran: 3 tests in 1259.0000 sec. - - Passed: 1 - - Skipped: 1 - - Failed: 1 - ''') - client = self._create_client() - with mock.patch('__builtin__.open', - mock.mock_open(read_data=log_file)): - client.parse_refstack_result() - self.assertEqual(client.details, self.details) - - def _get_main_kwargs(self, key=None): - kwargs = {'config': self._config, - 'testlist': RefstackClient.defcorelist} - if key: - del kwargs[key] - return kwargs - - def _test_main_missing_keyword(self, key): - kwargs = self._get_main_kwargs(key) - client = self._create_client() - self.assertEqual(client.main(**kwargs), - testcase.TestCase.EX_RUN_ERROR) - - def test_main_missing_conf(self): - self._test_main_missing_keyword('config') - - def test_main_missing_testlist(self): - self._test_main_missing_keyword('testlist') - - def _test_argparser(self, arg, value): - self.default_args[arg] = value - parser = RefstackClientParser() - self.assertEqual(parser.parse_args(["--{}={}".format(arg, value)]), - self.default_args) - - def test_argparser_conf(self): - self._test_argparser('config', self._config) - - def test_argparser_testlist(self): - self._test_argparser('testlist', RefstackClient.defcorelist) - - def test_argparser_multiple_args(self): - self.default_args['config'] = self._config - self.default_args['testlist'] = RefstackClient.defcorelist - parser = RefstackClientParser() - self.assertEqual(parser.parse_args( - ["--config={}".format(self._config), - "--testlist={}".format(RefstackClient.defcorelist)]), - self.default_args) - - -if __name__ == "__main__": - logging.disable(logging.CRITICAL) - unittest.main(verbosity=2) |