blob: b424b76f66ad613cb4d1b04554f602cee2cb7af2 [file] [log] [blame]
gstepanov023c1e42015-04-08 15:50:19 +03001import os
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08002import sys
koder aka kdanilov2c473092015-03-29 17:12:13 +03003import Queue
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08004import pprint
koder aka kdanilove21d7472015-02-14 19:02:04 -08005import logging
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08006import argparse
koder aka kdanilov2c473092015-03-29 17:12:13 +03007import threading
8import collections
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08009
koder aka kdanilov66839a92015-04-11 13:22:31 +030010import yaml
koder aka kdanilov2c473092015-03-29 17:12:13 +030011from concurrent.futures import ThreadPoolExecutor
koder aka kdanilov6c491062015-04-09 22:33:13 +030012
koder aka kdanilov2c473092015-03-29 17:12:13 +030013import utils
koder aka kdanilov66839a92015-04-11 13:22:31 +030014import report
koder aka kdanilove06762a2015-03-22 23:32:09 +020015import ssh_utils
koder aka kdanilovda45e882015-04-06 02:24:42 +030016import start_vms
koder aka kdanilov66839a92015-04-11 13:22:31 +030017import pretty_yaml
koder aka kdanilove06762a2015-03-22 23:32:09 +020018from nodes import discover
koder aka kdanilov2c473092015-03-29 17:12:13 +030019from nodes.node import Node
koder aka kdanilov66839a92015-04-11 13:22:31 +030020from config import cfg_dict, load_config
koder aka kdanilov2c473092015-03-29 17:12:13 +030021from sensors.api import start_monitoring
koder aka kdanilov652cd802015-04-13 12:21:07 +030022from tests.itest import IOPerfTest, PgBenchTest
koder aka kdanilov66839a92015-04-11 13:22:31 +030023from formatters import format_results_for_console
koder aka kdanilov2c473092015-03-29 17:12:13 +030024
25
koder aka kdanilove21d7472015-02-14 19:02:04 -080026logger = logging.getLogger("io-perf-tool")
koder aka kdanilove21d7472015-02-14 19:02:04 -080027
28
koder aka kdanilov652cd802015-04-13 12:21:07 +030029def color_me(color):
30 RESET_SEQ = "\033[0m"
31 COLOR_SEQ = "\033[1;%dm"
32
33 color_seq = COLOR_SEQ % (30 + color)
34
35 def closure(msg):
36 return color_seq + msg + RESET_SEQ
37 return closure
38
39
40class ColoredFormatter(logging.Formatter):
41 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
42
43 colors = {
44 'WARNING': color_me(YELLOW),
45 'DEBUG': color_me(BLUE),
46 'CRITICAL': color_me(YELLOW),
47 'ERROR': color_me(RED)
48 }
49
50 def __init__(self, msg, use_color=True):
51 logging.Formatter.__init__(self, msg)
52 self.use_color = use_color
53
54 def format(self, record):
55 levelname = record.levelname
56
koder aka kdanilovcee43342015-04-14 22:52:53 +030057 prn_name = ' ' * (6 - len(levelname)) + levelname
koder aka kdanilov652cd802015-04-13 12:21:07 +030058 if levelname in self.colors:
koder aka kdanilovcee43342015-04-14 22:52:53 +030059 record.levelname = self.colors[levelname](prn_name)
60 else:
61 record.levelname = prn_name
koder aka kdanilov652cd802015-04-13 12:21:07 +030062
63 return logging.Formatter.format(self, record)
64
65
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030066def setup_logger(logger, level=logging.DEBUG, log_fname=None):
koder aka kdanilov652cd802015-04-13 12:21:07 +030067 logger.setLevel(logging.DEBUG)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030068 sh = logging.StreamHandler()
69 sh.setLevel(level)
Yulia Portnova7ddfa732015-02-24 17:32:58 +020070
koder aka kdanilovcee43342015-04-14 22:52:53 +030071 log_format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s'
koder aka kdanilov652cd802015-04-13 12:21:07 +030072 colored_formatter = ColoredFormatter(log_format,
73 "%H:%M:%S")
74
koder aka kdanilov2c473092015-03-29 17:12:13 +030075 formatter = logging.Formatter(log_format,
76 "%H:%M:%S")
koder aka kdanilov652cd802015-04-13 12:21:07 +030077 sh.setFormatter(colored_formatter)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030078 logger.addHandler(sh)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080079
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030080 if log_fname is not None:
81 fh = logging.FileHandler(log_fname)
koder aka kdanilov652cd802015-04-13 12:21:07 +030082 fh.setFormatter(formatter)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030083 fh.setLevel(logging.DEBUG)
84 logger.addHandler(fh)
koder aka kdanilov6c491062015-04-09 22:33:13 +030085
koder aka kdanilovcee43342015-04-14 22:52:53 +030086 logger_api = logging.getLogger("io-perf-tool.fuel_api")
87 logger_api.addHandler(sh)
88 logger_api.setLevel(logging.WARNING)
89
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080090
Yulia Portnova7ddfa732015-02-24 17:32:58 +020091def format_result(res, formatter):
koder aka kdanilove21d7472015-02-14 19:02:04 -080092 data = "\n{0}\n".format("=" * 80)
93 data += pprint.pformat(res) + "\n"
94 data += "{0}\n".format("=" * 80)
koder aka kdanilovfe056622015-02-19 08:46:15 -080095 templ = "{0}\n\n====> {1}\n\n{2}\n\n"
Yulia Portnova7ddfa732015-02-24 17:32:58 +020096 return templ.format(data, formatter(res), "=" * 80)
koder aka kdanilove21d7472015-02-14 19:02:04 -080097
98
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030099class Context(object):
100 def __init__(self):
101 self.build_meta = {}
102 self.nodes = []
103 self.clear_calls_stack = []
104 self.openstack_nodes_ids = []
105
106
koder aka kdanilov5d589b42015-03-26 12:25:51 +0200107def connect_one(node):
108 try:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300109 ssh_pref = "ssh://"
110 if node.conn_url.startswith(ssh_pref):
111 url = node.conn_url[len(ssh_pref):]
112 node.connection = ssh_utils.connect(url)
113 else:
114 raise ValueError("Unknown url type {0}".format(node.conn_url))
koder aka kdanilov3a6633e2015-03-26 18:20:00 +0200115 except Exception:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300116 logger.exception("During connect to {0}".format(node))
koder aka kdanilov652cd802015-04-13 12:21:07 +0300117 raise
koder aka kdanilov5d589b42015-03-26 12:25:51 +0200118
119
120def connect_all(nodes):
koder aka kdanilov2c473092015-03-29 17:12:13 +0300121 logger.info("Connecting to nodes")
122 with ThreadPoolExecutor(32) as pool:
123 list(pool.map(connect_one, nodes))
koder aka kdanilovda45e882015-04-06 02:24:42 +0300124 logger.info("All nodes connected successfully")
koder aka kdanilov2c473092015-03-29 17:12:13 +0300125
126
127def save_sensors_data(q):
128 logger.info("Start receiving sensors data")
koder aka kdanilovda45e882015-04-06 02:24:42 +0300129 sensor_data = []
koder aka kdanilov2c473092015-03-29 17:12:13 +0300130 while True:
131 val = q.get()
132 if val is None:
koder aka kdanilovda45e882015-04-06 02:24:42 +0300133 q.put(sensor_data)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300134 break
koder aka kdanilovda45e882015-04-06 02:24:42 +0300135 sensor_data.append(val)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300136 logger.info("Sensors thread exits")
137
138
koder aka kdanilov652cd802015-04-13 12:21:07 +0300139def test_thread(test, node, barrier, res_q):
koder aka kdanilov2c473092015-03-29 17:12:13 +0300140 try:
141 logger.debug("Run preparation for {0}".format(node.conn_url))
142 test.pre_run(node.connection)
143 logger.debug("Run test for {0}".format(node.conn_url))
144 test.run(node.connection, barrier)
koder aka kdanilov652cd802015-04-13 12:21:07 +0300145 except Exception as exc:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300146 logger.exception("In test {0} for node {1}".format(test, node))
koder aka kdanilov652cd802015-04-13 12:21:07 +0300147 res_q.put(exc)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300148
149
koder aka kdanilovcee43342015-04-14 22:52:53 +0300150def run_tests(test_block, nodes):
koder aka kdanilov2c473092015-03-29 17:12:13 +0300151 tool_type_mapper = {
152 "io": IOPerfTest,
153 "pgbench": PgBenchTest,
154 }
155
156 test_nodes = [node for node in nodes
157 if 'testnode' in node.roles]
158
159 res_q = Queue.Queue()
160
koder aka kdanilovcee43342015-04-14 22:52:53 +0300161 for name, params in test_block.items():
162 logger.info("Starting {0} tests".format(name))
koder aka kdanilov2c473092015-03-29 17:12:13 +0300163
koder aka kdanilovcee43342015-04-14 22:52:53 +0300164 threads = []
165 barrier = utils.Barrier(len(test_nodes))
166 for node in test_nodes:
167 msg = "Starting {0} test on {1} node"
168 logger.debug(msg.format(name, node.conn_url))
169 test = tool_type_mapper[name](params, res_q.put)
170 th = threading.Thread(None, test_thread, None,
171 (test, node, barrier, res_q))
172 threads.append(th)
173 th.daemon = True
174 th.start()
koder aka kdanilov2c473092015-03-29 17:12:13 +0300175
koder aka kdanilovcee43342015-04-14 22:52:53 +0300176 def gather_results(res_q, results):
177 while not res_q.empty():
178 val = res_q.get()
koder aka kdanilov66839a92015-04-11 13:22:31 +0300179
koder aka kdanilovcee43342015-04-14 22:52:53 +0300180 if isinstance(val, Exception):
181 msg = "Exception during test execution: {0}"
182 raise ValueError(msg.format(val.message))
koder aka kdanilov652cd802015-04-13 12:21:07 +0300183
koder aka kdanilovcee43342015-04-14 22:52:53 +0300184 results.append(val)
koder aka kdanilov652cd802015-04-13 12:21:07 +0300185
koder aka kdanilovcee43342015-04-14 22:52:53 +0300186 results = []
koder aka kdanilov652cd802015-04-13 12:21:07 +0300187
koder aka kdanilovcee43342015-04-14 22:52:53 +0300188 while True:
189 for th in threads:
190 th.join(1)
191 gather_results(res_q, results)
koder aka kdanilov652cd802015-04-13 12:21:07 +0300192
koder aka kdanilovcee43342015-04-14 22:52:53 +0300193 if all(not th.is_alive() for th in threads):
194 break
koder aka kdanilov652cd802015-04-13 12:21:07 +0300195
koder aka kdanilovcee43342015-04-14 22:52:53 +0300196 gather_results(res_q, results)
197 yield name, test.merge_results(results)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300198
199
koder aka kdanilovda45e882015-04-06 02:24:42 +0300200def log_nodes_statistic(_, ctx):
201 nodes = ctx.nodes
koder aka kdanilov2c473092015-03-29 17:12:13 +0300202 logger.info("Found {0} nodes total".format(len(nodes)))
203 per_role = collections.defaultdict(lambda: 0)
204 for node in nodes:
205 for role in node.roles:
206 per_role[role] += 1
207
208 for role, count in sorted(per_role.items()):
209 logger.debug("Found {0} nodes with role {1}".format(count, role))
210
211
koder aka kdanilovda45e882015-04-06 02:24:42 +0300212def connect_stage(cfg, ctx):
213 ctx.clear_calls_stack.append(disconnect_stage)
214 connect_all(ctx.nodes)
215
216
217def discover_stage(cfg, ctx):
koder aka kdanilov652cd802015-04-13 12:21:07 +0300218 if cfg.get('discover') is not None:
koder aka kdanilovda45e882015-04-06 02:24:42 +0300219 discover_objs = [i.strip() for i in cfg['discover'].strip().split(",")]
koder aka kdanilovcee43342015-04-14 22:52:53 +0300220 ctx.nodes.extend(discover.discover(ctx, discover_objs, cfg['clouds']))
koder aka kdanilovda45e882015-04-06 02:24:42 +0300221
222 for url, roles in cfg.get('explicit_nodes', {}).items():
223 ctx.nodes.append(Node(url, roles.split(",")))
224
225
226def deploy_sensors_stage(cfg_dict, ctx):
koder aka kdanilovda45e882015-04-06 02:24:42 +0300227 if 'sensors' not in cfg_dict:
228 return
229
koder aka kdanilov652cd802015-04-13 12:21:07 +0300230 ctx.clear_calls_stack.append(remove_sensors_stage)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300231 cfg = cfg_dict.get('sensors')
232 sens_cfg = []
233
234 for role, sensors_str in cfg["roles_mapping"].items():
235 sensors = [sens.strip() for sens in sensors_str.split(",")]
236
237 collect_cfg = dict((sensor, {}) for sensor in sensors)
238
239 for node in ctx.nodes:
240 if role in node.roles:
241 sens_cfg.append((node.connection, collect_cfg))
242
koder aka kdanilovda45e882015-04-06 02:24:42 +0300243 ctx.sensor_cm = start_monitoring(cfg["receiver_uri"], None,
244 connected_config=sens_cfg)
245
246 ctx.sensors_control_queue = ctx.sensor_cm.__enter__()
247
248 th = threading.Thread(None, save_sensors_data, None,
249 (ctx.sensors_control_queue,))
250 th.daemon = True
251 th.start()
252 ctx.sensor_listen_thread = th
253
254
255def remove_sensors_stage(cfg, ctx):
256 ctx.sensors_control_queue.put(None)
257 ctx.sensor_listen_thread.join()
258 ctx.sensor_data = ctx.sensors_control_queue.get()
259
260
koder aka kdanilovcee43342015-04-14 22:52:53 +0300261def get_os_credentials(cfg, ctx, creds_type):
262 creds = None
koder aka kdanilovda45e882015-04-06 02:24:42 +0300263
koder aka kdanilovcee43342015-04-14 22:52:53 +0300264 if creds_type == 'clouds':
265 if 'openstack' in cfg['clouds']:
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300266 os_cfg = cfg['clouds']['openstack']
koder aka kdanilovcee43342015-04-14 22:52:53 +0300267
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300268 tenant = os_cfg['OS_TENANT_NAME'].strip()
269 user = os_cfg['OS_USERNAME'].strip()
270 passwd = os_cfg['OS_PASSWORD'].strip()
271 auth_url = os_cfg['OS_AUTH_URL'].strip()
272
koder aka kdanilovcee43342015-04-14 22:52:53 +0300273 elif 'fuel' in cfg['clouds'] and \
274 'openstack_env' in cfg['clouds']['fuel']:
275 creds = ctx.fuel_openstack_creds
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300276
koder aka kdanilovcee43342015-04-14 22:52:53 +0300277 elif creds_type == 'ENV':
278 user, passwd, tenant, auth_url = start_vms.ostack_get_creds()
279 elif os.path.isfile(creds_type):
280 user, passwd, tenant, auth_url = start_vms.ostack_get_creds()
281 else:
282 msg = "Creds {0!r} isn't supported".format(creds_type)
283 raise ValueError(msg)
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300284
koder aka kdanilovcee43342015-04-14 22:52:53 +0300285 if creds is None:
286 creds = {'name': user,
287 'passwd': passwd,
288 'tenant': tenant,
289 'auth_url': auth_url}
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300290
koder aka kdanilovcee43342015-04-14 22:52:53 +0300291 return creds
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +0300292
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300293
koder aka kdanilovcee43342015-04-14 22:52:53 +0300294def run_tests_stage(cfg, ctx):
295 ctx.results = []
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300296
koder aka kdanilovcee43342015-04-14 22:52:53 +0300297 if 'tests' not in cfg:
298 return
gstepanov023c1e42015-04-08 15:50:19 +0300299
koder aka kdanilovcee43342015-04-14 22:52:53 +0300300 for group in cfg['tests']:
301
302 assert len(group.items()) == 1
303 key, config = group.items()[0]
304
305 if 'start_test_nodes' == key:
306 params = config['vm_params']
307 os_nodes_ids = []
308
309 os_creds_type = config['creds']
310 os_creds = get_os_credentials(cfg, ctx, os_creds_type)
311
312 start_vms.nova_connect(**os_creds)
313
314 # logger.info("Preparing openstack")
315 # start_vms.prepare_os(**os_creds)
316
317 new_nodes = []
318 try:
319 for new_node, node_id in start_vms.launch_vms(params):
320 new_node.roles.append('testnode')
321 ctx.nodes.append(new_node)
322 os_nodes_ids.append(node_id)
323 new_nodes.append(new_node)
324
325 store_nodes_in_log(cfg, os_nodes_ids)
326 ctx.openstack_nodes_ids = os_nodes_ids
327
328 connect_all(new_nodes)
329
330 for test_group in config.get('tests', []):
331 ctx.results.extend(run_tests(test_group, ctx.nodes))
332
333 finally:
334 # shut_down_vms_stage(cfg, ctx)
335 pass
336
337 elif 'tests' in key:
338 ctx.results.extend(run_tests(config, ctx.nodes))
koder aka kdanilovda45e882015-04-06 02:24:42 +0300339
gstepanov023c1e42015-04-08 15:50:19 +0300340
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300341def shut_down_vms_stage(cfg, ctx):
koder aka kdanilov66839a92015-04-11 13:22:31 +0300342 vm_ids_fname = cfg_dict['vm_ids_fname']
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300343 if ctx.openstack_nodes_ids is None:
koder aka kdanilov66839a92015-04-11 13:22:31 +0300344 nodes_ids = open(vm_ids_fname).read().split()
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300345 else:
346 nodes_ids = ctx.openstack_nodes_ids
347
koder aka kdanilov652cd802015-04-13 12:21:07 +0300348 if len(nodes_ids) != 0:
349 logger.info("Removing nodes")
350 start_vms.clear_nodes(nodes_ids)
351 logger.info("Nodes has been removed")
gstepanov023c1e42015-04-08 15:50:19 +0300352
koder aka kdanilov66839a92015-04-11 13:22:31 +0300353 if os.path.exists(vm_ids_fname):
354 os.remove(vm_ids_fname)
gstepanov023c1e42015-04-08 15:50:19 +0300355
koder aka kdanilov66839a92015-04-11 13:22:31 +0300356
357def store_nodes_in_log(cfg, nodes_ids):
358 with open(cfg['vm_ids_fname'], 'w') as fd:
359 fd.write("\n".join(nodes_ids))
gstepanov023c1e42015-04-08 15:50:19 +0300360
361
362def clear_enviroment(cfg, ctx):
koder aka kdanilov66839a92015-04-11 13:22:31 +0300363 if os.path.exists(cfg_dict['vm_ids_fname']):
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300364 shut_down_vms_stage(cfg, ctx)
gstepanov023c1e42015-04-08 15:50:19 +0300365
366
koder aka kdanilovda45e882015-04-06 02:24:42 +0300367def disconnect_stage(cfg, ctx):
koder aka kdanilov652cd802015-04-13 12:21:07 +0300368 ssh_utils.close_all_sessions()
369
koder aka kdanilovda45e882015-04-06 02:24:42 +0300370 for node in ctx.nodes:
371 if node.connection is not None:
372 node.connection.close()
373
374
koder aka kdanilov66839a92015-04-11 13:22:31 +0300375def yamable(data):
376 if isinstance(data, (tuple, list)):
377 return map(yamable, data)
378
379 if isinstance(data, unicode):
380 return str(data)
381
382 if isinstance(data, dict):
383 res = {}
384 for k, v in data.items():
385 res[yamable(k)] = yamable(v)
386 return res
387
388 return data
389
390
391def store_raw_results_stage(cfg, ctx):
392
393 raw_results = os.path.join(cfg_dict['var_dir'], 'raw_results.yaml')
394
395 if os.path.exists(raw_results):
396 cont = yaml.load(open(raw_results).read())
397 else:
398 cont = []
399
400 cont.extend(yamable(ctx.results))
401 raw_data = pretty_yaml.dumps(cont)
402
403 with open(raw_results, "w") as fd:
404 fd.write(raw_data)
405
406
407def console_report_stage(cfg, ctx):
408 for tp, data in ctx.results:
409 if 'io' == tp:
410 print format_results_for_console(data)
411
412
koder aka kdanilovda45e882015-04-06 02:24:42 +0300413def report_stage(cfg, ctx):
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300414
Yulia Portnova8ca20572015-04-14 14:09:39 +0300415 html_rep_fname = cfg['html_report_file']
416 report.make_io_report(ctx.results, html_rep_fname)
koder aka kdanilov652cd802015-04-13 12:21:07 +0300417
Yulia Portnova8ca20572015-04-14 14:09:39 +0300418 logger.info("Html report were stored in " + html_rep_fname)
koder aka kdanilov652cd802015-04-13 12:21:07 +0300419
420 text_rep_fname = cfg_dict['text_report_file']
421 with open(text_rep_fname, "w") as fd:
422 for tp, data in ctx.results:
423 if 'io' == tp:
424 fd.write(format_results_for_console(data))
425 fd.write("\n")
426 fd.flush()
427
428 logger.info("Text report were stored in " + text_rep_fname)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300429
430
431def complete_log_nodes_statistic(cfg, ctx):
432 nodes = ctx.nodes
433 for node in nodes:
434 logger.debug(str(node))
435
436
koder aka kdanilov66839a92015-04-11 13:22:31 +0300437def load_data_from(var_dir):
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +0300438 def load_data_from_file(cfg, ctx):
koder aka kdanilov66839a92015-04-11 13:22:31 +0300439 raw_results = os.path.join(var_dir, 'raw_results.yaml')
440 ctx.results = yaml.load(open(raw_results).read())
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +0300441 return load_data_from_file
gstepanovcd256d62015-04-07 17:47:32 +0300442
443
koder aka kdanilovcee43342015-04-14 22:52:53 +0300444def parse_args(argv):
445 parser = argparse.ArgumentParser(
446 description="Run disk io performance test")
447
448 parser.add_argument("-l", dest='extra_logs',
449 action='store_true', default=False,
450 help="print some extra log info")
451
452 parser.add_argument("-b", '--build_description',
453 type=str, default="Build info")
454 parser.add_argument("-i", '--build_id', type=str, default="id")
455 parser.add_argument("-t", '--build_type', type=str, default="GA")
456 parser.add_argument("-u", '--username', type=str, default="admin")
457 parser.add_argument("-p", '--post-process-only', default=None)
458 parser.add_argument("-o", '--output-dest', nargs="*")
459 parser.add_argument("config_file", nargs="?", default="config.yaml")
460
461 return parser.parse_args(argv[1:])
462
463
koder aka kdanilov3f356262015-02-13 08:06:14 -0800464def main(argv):
koder aka kdanilove06762a2015-03-22 23:32:09 +0200465 opts = parse_args(argv)
koder aka kdanilov2c473092015-03-29 17:12:13 +0300466
koder aka kdanilov66839a92015-04-11 13:22:31 +0300467 if opts.post_process_only is not None:
468 stages = [
469 load_data_from(opts.post_process_only),
470 console_report_stage,
koder aka kdanilov652cd802015-04-13 12:21:07 +0300471 report_stage
koder aka kdanilov66839a92015-04-11 13:22:31 +0300472 ]
473 else:
474 stages = [
475 discover_stage,
476 log_nodes_statistic,
koder aka kdanilov66839a92015-04-11 13:22:31 +0300477 connect_stage,
koder aka kdanilov66839a92015-04-11 13:22:31 +0300478 deploy_sensors_stage,
479 run_tests_stage,
480 store_raw_results_stage,
481 console_report_stage,
482 report_stage
483 ]
484
koder aka kdanilovcee43342015-04-14 22:52:53 +0300485 load_config(opts.config_file, opts.post_process_only)
koder aka kdanilovf4b82c22015-04-11 13:35:25 +0300486
487 level = logging.DEBUG if opts.extra_logs else logging.WARNING
488 setup_logger(logger, level, cfg_dict['log_file'])
489
koder aka kdanilov652cd802015-04-13 12:21:07 +0300490 logger.info("All info would be stored into {0}".format(
491 cfg_dict['var_dir']))
gstepanovcd256d62015-04-07 17:47:32 +0300492
koder aka kdanilovda45e882015-04-06 02:24:42 +0300493 ctx = Context()
gstepanovaffcdb12015-04-07 17:18:29 +0300494 ctx.build_meta['build_id'] = opts.build_id
495 ctx.build_meta['build_descrption'] = opts.build_description
496 ctx.build_meta['build_type'] = opts.build_type
497 ctx.build_meta['username'] = opts.username
koder aka kdanilov6c491062015-04-09 22:33:13 +0300498
koder aka kdanilovda45e882015-04-06 02:24:42 +0300499 try:
500 for stage in stages:
501 logger.info("Start {0.__name__} stage".format(stage))
502 stage(cfg_dict, ctx)
503 finally:
504 exc, cls, tb = sys.exc_info()
505 for stage in ctx.clear_calls_stack[::-1]:
506 try:
507 logger.info("Start {0.__name__} stage".format(stage))
508 stage(cfg_dict, ctx)
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300509 except Exception as exc:
510 logger.exception("During {0.__name__} stage".format(stage))
koder aka kdanilov2c473092015-03-29 17:12:13 +0300511
koder aka kdanilovda45e882015-04-06 02:24:42 +0300512 if exc is not None:
513 raise exc, cls, tb
koder aka kdanilov2c473092015-03-29 17:12:13 +0300514
koder aka kdanilovcee43342015-04-14 22:52:53 +0300515 logger.info("All info stored into {0}".format(cfg_dict['var_dir']))
koder aka kdanilove06762a2015-03-22 23:32:09 +0200516 return 0
koder aka kdanilov3f356262015-02-13 08:06:14 -0800517
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800518
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800519if __name__ == '__main__':
koder aka kdanilove06762a2015-03-22 23:32:09 +0200520 exit(main(sys.argv))