2 # Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
3 # matthew.lijun@huawei.com wangwulin@huawei.com
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 """Refstack client testcase implemenation."""
11 from __future__ import division
24 from functest.core import testcase
25 from functest.energy import energy
26 from functest.opnfv_tests.openstack.refstack_client.tempest_conf \
28 from functest.opnfv_tests.openstack.tempest import conf_utils
29 from functest.utils.constants import CONST
30 import functest.utils.functest_utils as ft_utils
31 import functest.utils.openstack_utils as os_utils
33 # logging configuration """
34 LOGGER = logging.getLogger(__name__)
37 class RefstackClient(testcase.TestCase):
38 """RefstackClient testcase implementation class."""
40 def __init__(self, **kwargs):
41 """Initialize RefstackClient testcase object."""
42 if "case_name" not in kwargs:
43 kwargs["case_name"] = "refstack_defcore"
44 super(RefstackClient, self).__init__(**kwargs)
45 self.conf_path = pkg_resources.resource_filename(
47 'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
48 self.tempestconf = None
49 self.functest_test = pkg_resources.resource_filename(
50 'functest', 'opnfv_tests')
51 self.defcore_list = 'openstack/refstack_client/defcore.txt'
52 self.confpath = os.path.join(self.functest_test,
54 self.defcorelist = pkg_resources.resource_filename(
55 'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
58 if ('https' in CONST.__getattribute__('OS_AUTH_URL') and
59 CONST.__getattribute__('OS_INSECURE').lower() == 'true'):
62 def run_defcore(self, conf, testlist):
63 """Run defcore sys command."""
64 cmd = ("refstack-client test {0} -c {1} -v --test-list {2}"
65 .format(self.insecure, conf, testlist))
66 LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd)
67 ft_utils.execute_command(cmd)
69 def run_defcore_default(self):
70 """Run default defcore sys command."""
71 options = ["-v"] if not self.insecure else ["-v", self.insecure]
72 cmd = (["refstack-client", "test", "-c", self.confpath] +
73 options + ["--test-list", self.defcorelist])
74 LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd)
76 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
77 "environment.log"), 'w+') as f_env:
79 ("Refstack environment:\n"
80 " SUT: {}\n Scenario: {}\n Node: {}\n Date: {}\n").format(
81 CONST.__getattribute__('INSTALLER_TYPE'),
82 CONST.__getattribute__('DEPLOY_SCENARIO'),
83 CONST.__getattribute__('NODE_NAME'),
84 time.strftime("%a %b %d %H:%M:%S %Z %Y")))
86 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
87 "refstack.log"), 'w+') as f_stdout:
88 subprocess.call(cmd, shell=False, stdout=f_stdout,
89 stderr=subprocess.STDOUT)
91 def parse_refstack_result(self):
92 """Parse Refstact results."""
94 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
95 "refstack.log"), 'r') as logfile:
96 output = logfile.read()
98 for match in re.findall(r"Ran: (\d+) tests in (\d+\.\d{4}) sec.",
101 LOGGER.info("Ran: %s tests in %s sec.", num_tests, match[1])
102 for match in re.findall(r"(- Passed: )(\d+)", output):
103 num_success = match[1]
104 LOGGER.info("".join(match))
105 for match in re.findall(r"(- Skipped: )(\d+)", output):
106 num_skipped = match[1]
107 LOGGER.info("".join(match))
108 for match in re.findall(r"(- Failed: )(\d+)", output):
109 num_failures = match[1]
110 LOGGER.info("".join(match))
111 success_testcases = []
112 for match in re.findall(r"\{0\} (.*?)[. ]*ok", output):
113 success_testcases.append(match)
114 failed_testcases = []
115 for match in re.findall(r"\{0\} (.*?)[. ]*FAILED", output):
116 failed_testcases.append(match)
117 skipped_testcases = []
118 for match in re.findall(r"\{0\} (.*?)[. ]*SKIPPED:", output):
119 skipped_testcases.append(match)
121 num_executed = int(num_tests) - int(num_skipped)
124 self.result = 100 * int(num_success) / int(num_executed)
125 except ZeroDivisionError:
126 LOGGER.error("No test has been executed")
128 self.details = {"tests": int(num_tests),
129 "failures": int(num_failures),
130 "success": success_testcases,
131 "errors": failed_testcases,
132 "skipped": skipped_testcases}
136 LOGGER.info("Testcase %s success_rate is %s%%",
137 self.case_name, self.result)
139 @energy.enable_recording
140 def run(self, **kwargs):
142 Start RefstackClient testcase.
144 used for functest command line,
145 functest testcase run refstack_defcore
147 self.start_time = time.time()
149 if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR):
150 os.makedirs(conf_utils.REFSTACK_RESULTS_DIR)
153 self.tempestconf = TempestConf()
154 self.tempestconf.generate_tempestconf()
155 self.run_defcore_default()
156 self.parse_refstack_result()
157 res = testcase.TestCase.EX_OK
159 LOGGER.exception("Error with run")
160 res = testcase.TestCase.EX_RUN_ERROR
162 self.tempestconf.clean()
164 self.stop_time = time.time()
167 def _prep_test(self):
168 """Check that the config file exists."""
169 if not os.path.isfile(self.confpath):
170 LOGGER.error("Conf file not valid: %s", self.confpath)
171 if not os.path.isfile(self.testlist):
172 LOGGER.error("testlist file not valid: %s", self.testlist)
174 def main(self, **kwargs):
176 Execute RefstackClient testcase manually.
178 used for manually running,
179 python refstack_client.py -c <tempest_conf_path>
180 --testlist <testlist_path>
181 can generate a reference refstack_tempest.conf by
182 python tempest_conf.py
185 self.confpath = kwargs['config']
186 self.testlist = kwargs['testlist']
187 except KeyError as exc:
188 LOGGER.error("Cannot run refstack client. Please check "
190 return self.EX_RUN_ERROR
193 self.run_defcore(self.confpath, self.testlist)
194 res = testcase.TestCase.EX_OK
195 except Exception as exc:
196 LOGGER.error('Error with run: %s', exc)
197 res = testcase.TestCase.EX_RUN_ERROR
201 def create_snapshot(self):
203 Run the Tempest cleanup utility to initialize OS state.
204 For details, see https://docs.openstack.org/tempest/latest/cleanup.html
206 :return: TestCase.EX_OK
208 LOGGER.info("Initializing the saved state of the OpenStack deployment")
210 # Make sure that the verifier is configured
211 conf_utils.configure_verifier(self.tempestconf.DEPLOYMENT_DIR)
213 os_utils.init_tempest_cleanup(
214 self.tempestconf.DEPLOYMENT_DIR, 'tempest.conf',
215 os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
216 "tempest-cleanup-init.log")
219 return super(RefstackClient, self).create_snapshot()
223 Run the Tempest cleanup utility to delete and destroy OS resources.
224 For details, see https://docs.openstack.org/tempest/latest/cleanup.html
226 LOGGER.info("Initializing the saved state of the OpenStack deployment")
228 os_utils.init_tempest_cleanup(
229 self.tempestconf.DEPLOYMENT_DIR, 'tempest.conf',
230 os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
231 "tempest-cleanup.log")
234 return super(RefstackClient, self).clean()
237 class RefstackClientParser(object): # pylint: disable=too-few-public-methods
238 """Command line argument parser helper."""
241 """Initialize helper object."""
242 self.functest_test = pkg_resources.resource_filename(
243 'functest', 'opnfv_tests')
244 self.conf_path = pkg_resources.resource_filename(
246 'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
247 self.defcore_list = pkg_resources.resource_filename(
248 'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
249 self.confpath = os.path.join(self.functest_test,
251 self.defcorelist = os.path.join(self.functest_test,
253 self.parser = argparse.ArgumentParser()
254 self.parser.add_argument(
256 help='the file path of refstack_tempest.conf',
257 default=self.confpath)
258 self.parser.add_argument(
260 help='Specify the file path or URL of a test list text file. '
261 'This test list will contain specific test cases that '
263 default=self.defcorelist)
265 def parse_args(self, argv=None):
266 """Parse command line arguments."""
267 return vars(self.parser.parse_args(argv))
271 """Run RefstackClient testcase with CLI."""
272 logging.basicConfig()
273 refstackclient = RefstackClient()
274 parser = RefstackClientParser()
275 args = parser.parse_args(sys.argv[1:])
277 result = refstackclient.main(**args)
278 if result != testcase.TestCase.EX_OK:
281 return testcase.TestCase.EX_RUN_ERROR