Merge "Enable https insecure for functest"
[functest.git] / functest / opnfv_tests / openstack / refstack_client / refstack_client.py
1 #!/usr/bin/env python
2
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
8
9 from __future__ import division
10
11
12 import argparse
13 import logging
14 import os
15 import pkg_resources
16 import re
17 import sys
18 import subprocess
19 import time
20
21 from functest.core import testcase
22 from functest.opnfv_tests.openstack.tempest import conf_utils
23 from functest.utils.constants import CONST
24 import functest.utils.functest_utils as ft_utils
25 from tempest_conf import TempestConf
26
27 """ logging configuration """
28 logger = logging.getLogger(__name__)
29
30
31 class RefstackClient(testcase.OSGCTestCase):
32
33     def __init__(self, **kwargs):
34         if "case_name" not in kwargs:
35             kwargs["case_name"] = "refstack_defcore"
36         super(RefstackClient, self).__init__(**kwargs)
37         self.CONF_PATH = pkg_resources.resource_filename(
38             'functest',
39             'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
40         self.FUNCTEST_TEST = pkg_resources.resource_filename(
41             'functest', 'opnfv_tests')
42         self.DEFCORE_LIST = 'openstack/refstack_client/defcore.txt'
43         self.confpath = os.path.join(self.FUNCTEST_TEST,
44                                      self.CONF_PATH)
45         self.defcorelist = pkg_resources.resource_filename(
46             'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
47
48     def source_venv(self):
49
50         cmd = ("cd {0};"
51                ". .venv/bin/activate;"
52                "cd -;".format(CONST.__getattribute__('dir_refstack_client')))
53         ft_utils.execute_command(cmd)
54
55     def run_defcore(self, conf, testlist):
56         logger.debug("Generating test case list...")
57
58         cmd = ("cd {0};"
59                "./refstack-client test -c {1} -v --test-list {2};"
60                "cd -;".format(CONST.__getattribute__('dir_refstack_client'),
61                               conf,
62                               testlist))
63         ft_utils.execute_command(cmd)
64
65     def run_defcore_default(self):
66         logger.debug("Generating test case list...")
67
68         cmd = ("cd {0};"
69                "./refstack-client test -c {1} -v --test-list {2};"
70                "cd -;".format(CONST.__getattribute__('dir_refstack_client'),
71                               self.confpath,
72                               self.defcorelist))
73         logger.info("Starting Refstack_defcore test case: '%s'." % cmd)
74
75         header = ("Refstack environment:\n"
76                   "  SUT: %s\n  Scenario: %s\n  Node: %s\n  Date: %s\n" %
77                   (CONST.__getattribute__('INSTALLER_TYPE'),
78                    CONST.__getattribute__('DEPLOY_SCENARIO'),
79                    CONST.__getattribute__('NODE_NAME'),
80                    time.strftime("%a %b %d %H:%M:%S %Z %Y")))
81
82         f_stdout = open(
83             os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
84                          "refstack.log"), 'w+')
85         f_env = open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
86                                   "environment.log"), 'w+')
87         f_env.write(header)
88
89         p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
90                              stderr=subprocess.STDOUT, bufsize=1)
91
92         with p.stdout:
93             for line in iter(p.stdout.readline, b''):
94                 if 'Tests' in line:
95                     break
96                 if re.search("\} tempest\.", line):
97                     logger.info(line.replace('\n', ''))
98                 f_stdout.write(line)
99         p.wait()
100
101         f_stdout.close()
102         f_env.close()
103
104     def parse_refstack_result(self):
105         try:
106             with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
107                                    "refstack.log"), 'r') as logfile:
108                 output = logfile.read()
109
110             for match in re.findall("Ran: (\d+) tests in (\d+\.\d{4}) sec.",
111                                     output):
112                 num_tests = match[0]
113                 logger.info("Ran: %s tests in %s sec." % (num_tests, match[1]))
114             for match in re.findall("(- Passed: )(\d+)", output):
115                 num_success = match[1]
116                 logger.info("".join(match))
117             for match in re.findall("(- Skipped: )(\d+)", output):
118                 num_skipped = match[1]
119                 logger.info("".join(match))
120             for match in re.findall("(- Failed: )(\d+)", output):
121                 num_failures = match[1]
122                 logger.info("".join(match))
123             success_testcases = ""
124             for match in re.findall(r"\{0\}(.*?)[. ]*ok", output):
125                 success_testcases += match + ", "
126             failed_testcases = ""
127             for match in re.findall(r"\{0\}(.*?)[. ]*FAILED", output):
128                 failed_testcases += match + ", "
129             skipped_testcases = ""
130             for match in re.findall(r"\{0\}(.*?)[. ]*SKIPPED:", output):
131                 skipped_testcases += match + ", "
132
133             num_executed = int(num_tests) - int(num_skipped)
134
135             try:
136                 self.result = 100 * int(num_success) / int(num_executed)
137             except ZeroDivisionError:
138                 logger.error("No test has been executed")
139
140             self.details = {"tests": int(num_tests),
141                             "failures": int(num_failures),
142                             "success": success_testcases,
143                             "errors": failed_testcases,
144                             "skipped": skipped_testcases}
145         except Exception:
146             self.result = 0
147
148         logger.info("Testcase %s success_rate is %s%%"
149                     % (self.case_name, self.result))
150
151     def run(self):
152         '''used for functest command line,
153            functest testcase run refstack_defcore'''
154         self.start_time = time.time()
155
156         if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR):
157             os.makedirs(conf_utils.REFSTACK_RESULTS_DIR)
158
159         try:
160             tempestconf = TempestConf()
161             tempestconf.generate_tempestconf()
162             self.source_venv()
163             self.run_defcore_default()
164             self.parse_refstack_result()
165             res = testcase.TestCase.EX_OK
166         except Exception as e:
167             logger.error('Error with run: %s', e)
168             res = testcase.TestCase.EX_RUN_ERROR
169
170         self.stop_time = time.time()
171         return res
172
173     def _prep_test(self):
174         '''Check that the config file exists.'''
175         if not os.path.isfile(self.confpath):
176             logger.error("Conf file not valid: %s" % self.confpath)
177         if not os.path.isfile(self.testlist):
178             logger.error("testlist file not valid: %s" % self.testlist)
179
180     def main(self, **kwargs):
181         '''used for manually running,
182            python refstack_client.py -c <tempest_conf_path>
183            --testlist <testlist_path>
184            can generate a reference refstack_tempest.conf by
185            python tempest_conf.py
186         '''
187         try:
188             self.confpath = kwargs['config']
189             self.testlist = kwargs['testlist']
190         except KeyError as e:
191             logger.error("Cannot run refstack client. Please check "
192                          "%s", e)
193             return self.EX_RUN_ERROR
194         try:
195             self.source_venv()
196             self._prep_test()
197             self.run_defcore(self.confpath, self.testlist)
198             res = testcase.TestCase.EX_OK
199         except Exception as e:
200             logger.error('Error with run: %s', e)
201             res = testcase.TestCase.EX_RUN_ERROR
202
203         return res
204
205
206 class RefstackClientParser(object):
207
208     def __init__(self):
209         self.FUNCTEST_TEST = pkg_resources.resource_filename(
210             'functest', 'opnfv_tests')
211         self.CONF_PATH = pkg_resources.resource_filename(
212             'functest',
213             'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
214         self.DEFCORE_LIST = pkg_resources.resource_filename(
215             'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
216         self.confpath = os.path.join(self.FUNCTEST_TEST,
217                                      self.CONF_PATH)
218         self.defcorelist = os.path.join(self.FUNCTEST_TEST,
219                                         self.DEFCORE_LIST)
220         self.parser = argparse.ArgumentParser()
221         self.parser.add_argument(
222             '-c', '--config',
223             help='the file path of refstack_tempest.conf',
224             default=self.confpath)
225         self.parser.add_argument(
226             '-t', '--testlist',
227             help='Specify the file path or URL of a test list text file. '
228                  'This test list will contain specific test cases that '
229                  'should be tested.',
230             default=self.defcorelist)
231
232     def parse_args(self, argv=[]):
233         return vars(self.parser.parse_args(argv))
234
235
236 if __name__ == '__main__':
237     logging.basicConfig()
238     refstackclient = RefstackClient()
239     parser = RefstackClientParser()
240     args = parser.parse_args(sys.argv[1:])
241     try:
242         result = refstackclient.main(**args)
243         if result != testcase.TestCase.EX_OK:
244             sys.exit(result)
245     except Exception:
246         sys.exit(testcase.TestCase.EX_RUN_ERROR)