3 # Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 """Refstack client testcase implemenation."""
12 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
32 __author__ = ("Matthew Li <matthew.lijun@huawei.com>,"
33 "Linda Wang <wangwulin@huawei.com>")
35 # logging configuration """
36 LOGGER = logging.getLogger(__name__)
39 class RefstackClient(testcase.TestCase):
40 """RefstackClient testcase implementation class."""
42 def __init__(self, **kwargs):
43 """Initialize RefstackClient testcase object."""
44 if "case_name" not in kwargs:
45 kwargs["case_name"] = "refstack_defcore"
46 super(RefstackClient, self).__init__(**kwargs)
47 self.tempestconf = None
48 self.conf_path = pkg_resources.resource_filename(
50 'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
51 self.functest_test = pkg_resources.resource_filename(
52 'functest', 'opnfv_tests')
53 self.defcore_list = 'openstack/refstack_client/defcore.txt'
54 self.confpath = os.path.join(self.functest_test,
56 self.defcorelist = pkg_resources.resource_filename(
57 'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
60 if ('https' in CONST.__getattribute__('OS_AUTH_URL') and
61 CONST.__getattribute__('OS_INSECURE').lower() == 'true'):
64 def generate_conf(self):
65 if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR):
66 os.makedirs(conf_utils.REFSTACK_RESULTS_DIR)
68 self.tempestconf = TempestConf()
69 self.tempestconf.generate_tempestconf()
71 def run_defcore(self, conf, testlist):
72 """Run defcore sys command."""
73 cmd = ("refstack-client test {0} -c {1} -v --test-list {2}"
74 .format(self.insecure, conf, testlist))
75 LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd)
76 ft_utils.execute_command(cmd)
78 def run_defcore_default(self):
79 """Run default defcore sys command."""
80 options = ["-v"] if not self.insecure else ["-v", self.insecure]
81 cmd = (["refstack-client", "test", "-c", self.confpath] +
82 options + ["--test-list", self.defcorelist])
83 LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd)
85 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
86 "environment.log"), 'w+') as f_env:
88 ("Refstack environment:\n"
89 " SUT: {}\n Scenario: {}\n Node: {}\n Date: {}\n").format(
90 CONST.__getattribute__('INSTALLER_TYPE'),
91 CONST.__getattribute__('DEPLOY_SCENARIO'),
92 CONST.__getattribute__('NODE_NAME'),
93 time.strftime("%a %b %d %H:%M:%S %Z %Y")))
95 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
96 "refstack.log"), 'w+') as f_stdout:
97 subprocess.call(cmd, shell=False, stdout=f_stdout,
98 stderr=subprocess.STDOUT)
100 def parse_refstack_result(self):
101 """Parse Refstack results."""
103 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
104 "refstack.log"), 'r') as logfile:
105 for line in logfile.readlines():
108 if re.search(r"\} tempest\.", line):
109 LOGGER.info(line.replace('\n', ''))
111 with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
112 "refstack.log"), 'r') as logfile:
113 output = logfile.read()
115 for match in re.findall(r"Ran: (\d+) tests in (\d+\.\d{4}) sec.",
118 LOGGER.info("Ran: %s tests in %s sec.", num_tests, match[1])
119 for match in re.findall(r"(- Passed: )(\d+)", output):
120 num_success = match[1]
121 LOGGER.info("".join(match))
122 for match in re.findall(r"(- Skipped: )(\d+)", output):
123 num_skipped = match[1]
124 LOGGER.info("".join(match))
125 for match in re.findall(r"(- Failed: )(\d+)", output):
126 num_failures = match[1]
127 LOGGER.info("".join(match))
128 success_testcases = []
129 for match in re.findall(r"\{0\} (.*?) \.{3} ok", output):
130 success_testcases.append(match)
131 failed_testcases = []
132 for match in re.findall(r"\{0\} (.*?) \.{3} FAILED", output):
133 failed_testcases.append(match)
134 skipped_testcases = []
135 for match in re.findall(r"\{0\} (.*?) \.{3} SKIPPED:", output):
136 skipped_testcases.append(match)
138 num_executed = int(num_tests) - int(num_skipped)
141 self.result = 100 * int(num_success) / int(num_executed)
142 except ZeroDivisionError:
143 LOGGER.error("No test has been executed")
145 self.details = {"tests": int(num_tests),
146 "failures": int(num_failures),
147 "success": success_testcases,
148 "errors": failed_testcases,
149 "skipped": skipped_testcases}
153 LOGGER.info("Testcase %s success_rate is %s%%",
154 self.case_name, self.result)
156 @energy.enable_recording
157 def run(self, **kwargs):
159 Start RefstackClient testcase.
161 used for functest command line,
162 functest testcase run refstack_defcore
164 self.start_time = time.time()
167 # Make sure that Tempest is configured
168 if not self.tempestconf:
170 self.run_defcore_default()
171 self.parse_refstack_result()
172 res = testcase.TestCase.EX_OK
174 LOGGER.exception("Error with run")
175 res = testcase.TestCase.EX_RUN_ERROR
177 self.tempestconf.clean()
179 self.stop_time = time.time()
182 def _prep_test(self):
183 """Check that the config file exists."""
184 if not os.path.isfile(self.confpath):
185 LOGGER.error("Conf file not valid: %s", self.confpath)
186 if not os.path.isfile(self.testlist):
187 LOGGER.error("testlist file not valid: %s", self.testlist)
189 def main(self, **kwargs):
191 Execute RefstackClient testcase manually.
193 used for manually running,
194 python refstack_client.py -c <tempest_conf_path>
195 --testlist <testlist_path>
196 can generate a reference refstack_tempest.conf by
197 python tempest_conf.py
200 self.confpath = kwargs['config']
201 self.testlist = kwargs['testlist']
202 except KeyError as exc:
203 LOGGER.error("Cannot run refstack client. Please check "
205 return self.EX_RUN_ERROR
208 self.run_defcore(self.confpath, self.testlist)
209 res = testcase.TestCase.EX_OK
210 except Exception as exc:
211 LOGGER.error('Error with run: %s', exc)
212 res = testcase.TestCase.EX_RUN_ERROR
217 class RefstackClientParser(object): # pylint: disable=too-few-public-methods
218 """Command line argument parser helper."""
221 """Initialize helper object."""
222 self.functest_test = pkg_resources.resource_filename(
223 'functest', 'opnfv_tests')
224 self.conf_path = pkg_resources.resource_filename(
226 'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
227 self.defcore_list = pkg_resources.resource_filename(
228 'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
229 self.confpath = os.path.join(self.functest_test,
231 self.defcorelist = os.path.join(self.functest_test,
233 self.parser = argparse.ArgumentParser()
234 self.parser.add_argument(
236 help='the file path of refstack_tempest.conf',
237 default=self.confpath)
238 self.parser.add_argument(
240 help='Specify the file path or URL of a test list text file. '
241 'This test list will contain specific test cases that '
243 default=self.defcorelist)
245 def parse_args(self, argv=None):
246 """Parse command line arguments."""
247 return vars(self.parser.parse_args(argv))
251 """Run RefstackClient testcase with CLI."""
252 logging.basicConfig()
253 refstackclient = RefstackClient()
254 parser = RefstackClientParser()
255 args = parser.parse_args(sys.argv[1:])
257 result = refstackclient.main(**args)
258 if result != testcase.TestCase.EX_OK:
261 return testcase.TestCase.EX_RUN_ERROR