Merge "Add possibility to run specific set of tests"
[functest.git] / testcases / VIM / OpenStack / CI / libraries / run_tempest.py
1 #!/usr/bin/env python
2 #
3 # Description:
4 #    Runs tempest and pushes the results to the DB
5 #
6 # Authors:
7 #    morgan.richomme@orange.com
8 #    jose.lausuch@ericsson.com
9 #
10
11 import argparse
12 import json
13 import logging
14 import os
15 import re
16 import requests
17 import subprocess
18 import sys
19 import yaml
20
21 modes = ['full', 'smoke', 'baremetal', 'compute', 'data_processing',
22          'identity', 'image', 'network', 'object_storage', 'orchestration',
23          'telemetry', 'volume']
24
25 """ tests configuration """
26 parser = argparse.ArgumentParser()
27 parser.add_argument("repo_path", help="Path to the Functest repository")
28 parser.add_argument("-d", "--debug", help="Debug mode",  action="store_true")
29 parser.add_argument("-m", "--mode", help="Tempest test mode [smoke, all]",
30                     default="smoke")
31
32 args = parser.parse_args()
33
34 """ logging configuration """
35 logger = logging.getLogger('run_tempest')
36 logger.setLevel(logging.DEBUG)
37
38 ch = logging.StreamHandler()
39 if args.debug:
40     ch.setLevel(logging.DEBUG)
41 else:
42     ch.setLevel(logging.INFO)
43
44 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
45 ch.setFormatter(formatter)
46 logger.addHandler(ch)
47
48 with open(args.repo_path+"/testcases/config_functest.yaml") as f:
49     functest_yaml = yaml.safe_load(f)
50 f.close()
51
52 REPO_PATH = args.repo_path
53 TEST_DB = functest_yaml.get("results").get("test_db_url")
54 sys.path.append(args.repo_path + "/testcases/")
55 import functest_utils
56
57 MODE = "smoke"
58
59
60 def get_info(file_result):
61     test_run = ""
62     duration = ""
63     test_failed = ""
64
65     p = subprocess.Popen('cat tempest.log',
66                          shell=True, stdout=subprocess.PIPE,
67                          stderr=subprocess.STDOUT)
68     for line in p.stdout.readlines():
69         # print line,
70         if (len(test_run) < 1):
71             test_run = re.findall("[0-9]*\.[0-9]*s", line)
72         if (len(duration) < 1):
73             duration = re.findall("[0-9]*\ tests", line)
74         regexp = r"(failures=[0-9]+)"
75         if (len(test_failed) < 1):
76             test_failed = re.findall(regexp, line)
77
78     retval = p.wait()
79
80     logger.debug("test_run:"+test_run)
81     logger.debug("duration:"+duration)
82
83
84 def push_results_to_db(payload, module, pod_name):
85
86     # TODO move DB creds into config file
87     url = TEST_DB + "/results"
88     installer = functest_utils.get_installer_type(logger)
89     git_version = functest_utils.get_git_branch(REPO_PATH)
90     logger.info("Pushing results to DB: '%s'." % url)
91
92     params = {"project_name": "functest", "case_name": "Tempest",
93               "pod_name": str(pod_name), 'installer': installer,
94               "version": git_version, 'details': payload}
95     headers = {'Content-Type': 'application/json'}
96
97     r = requests.post(url, data=json.dumps(params), headers=headers)
98     logger.debug(r)
99
100
101 def run_tempest(OPTION):
102     #
103     # the "main" function of the script which launches Rally to run Tempest
104     # :param option: tempest option (smoke, ..)
105     # :return: void
106     #
107     logger.info("Starting Tempest test suite: '%s'." % OPTION)
108     cmd_line = "rally verify start "+OPTION
109     logger.debug('Executing command : {}'.format(cmd_line))
110     subprocess.call(cmd_line, shell=True, stderr=subprocess.STDOUT)
111
112     cmd_line = "rally verify list"
113     logger.debug('Executing command : {}'.format(cmd_line))
114     cmd = os.popen(cmd_line)
115     output = (((cmd.read()).splitlines()[3]).replace(" ", "")).split("|")
116     # Format:
117     # | UUID | Deployment UUID | smoke | tests | failures | Created at |
118     # Duration | Status  |
119     num_tests = output[4]
120     num_failures = output[5]
121     time_start = output[6]
122     duration = output[7]
123     # Compute duration (lets assume it does not take more than 60 min)
124     dur_min=int(duration.split(':')[1])
125     dur_sec_float=float(duration.split(':')[2])
126     dur_sec_int=int(round(dur_sec_float,0))
127     dur_sec_int = dur_sec_int + 60 * dur_min
128
129     # Generate json results for DB
130     json_results = {"timestart": time_start, "duration": dur_sec_int,
131                     "tests": int(num_tests), "failures": int(num_failures)}
132     logger.info("Results: "+str(json_results))
133     push_results_to_db(json_results, MODE, "opnfv-jump-2")
134
135
136 def main():
137     global MODE
138     if not (args.mode):
139         MODE = "smoke"
140     elif not (args.mode in modes):
141         logger.error("Tempest mode not valid. Possible values are:\n"
142                      + str(modes))
143         exit(-1)
144     else:
145         MODE = args.mode
146
147     run_tempest(MODE)
148
149
150 if __name__ == '__main__':
151     main()