blob: bd7a32525cdd94d512dbd06a5356ec447c5dfe3e [file] [log] [blame]
koder aka kdanilov4af80852015-02-01 23:36:38 +02001import re
2import os
3import sys
4import stat
5import time
6import json
koder aka kdanilove21d7472015-02-14 19:02:04 -08007import Queue
koder aka kdanilov4af80852015-02-01 23:36:38 +02008import os.path
9import argparse
10import warnings
koder aka kdanilove21d7472015-02-14 19:02:04 -080011import threading
koder aka kdanilov4af80852015-02-01 23:36:38 +020012import subprocess
13
14
15class BenchmarkOption(object):
16 def __init__(self, concurence, iodepth, action, blocksize, size):
17 self.iodepth = iodepth
18 self.action = action
19 self.blocksize = blocksize
20 self.concurence = concurence
21 self.size = size
22 self.direct_io = False
23 self.use_hight_io_priority = True
24 self.sync = False
25
26
koder aka kdanilov98615bf2015-02-02 00:59:07 +020027def which(program):
28 def is_exe(fpath):
29 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
30
31 fpath, fname = os.path.split(program)
32 if fpath:
33 if is_exe(program):
34 return program
35 else:
36 for path in os.environ["PATH"].split(os.pathsep):
37 path = path.strip('"')
38 exe_file = os.path.join(path, program)
39 if is_exe(exe_file):
40 return exe_file
41
42 return None
43
44
45# ------------------------------ IOZONE SUPPORT ------------------------------
46
47
koder aka kdanilov4af80852015-02-01 23:36:38 +020048class IOZoneParser(object):
49 "class to parse iozone results"
50
51 start_tests = re.compile(r"^\s+KB\s+reclen\s+")
52 resuts = re.compile(r"[\s0-9]+")
53 mt_iozone_re = re.compile(r"\s+Children see throughput " +
54 r"for\s+\d+\s+(?P<cmd>.*?)\s+=\s+" +
55 r"(?P<perf>[\d.]+)\s+KB/sec")
56
57 cmap = {'initial writers': 'write',
58 'rewriters': 'rewrite',
59 'initial readers': 'read',
60 're-readers': 'reread',
61 'random readers': 'random read',
koder aka kdanilov7dec9df2015-02-15 21:35:19 -080062 'random writers': 'random write',
63 'readers': 'read'}
koder aka kdanilov4af80852015-02-01 23:36:38 +020064
65 string1 = " " + \
66 " random random " + \
67 "bkwd record stride "
68
69 string2 = "KB reclen write rewrite " + \
70 "read reread read write " + \
71 "read rewrite read fwrite frewrite fread freread"
72
73 @classmethod
74 def apply_parts(cls, parts, string, sep=' \t\n'):
75 add_offset = 0
76 for part in parts:
77 _, start, stop = part
78 start += add_offset
79 add_offset = 0
80
81 # condition splited to make pylint happy
82 while stop + add_offset < len(string):
83
84 # condition splited to make pylint happy
85 if not (string[stop + add_offset] not in sep):
86 break
87
88 add_offset += 1
89
90 yield part, string[start:stop + add_offset]
91
92 @classmethod
93 def make_positions(cls):
94 items = [i for i in cls.string2.split() if i]
95
96 pos = 0
97 cls.positions = []
98
99 for item in items:
100 npos = cls.string2.index(item, 0 if pos == 0 else pos + 1)
101 cls.positions.append([item, pos, npos + len(item)])
102 pos = npos + len(item)
103
104 for itm, val in cls.apply_parts(cls.positions, cls.string1):
105 if val.strip():
106 itm[0] = val.strip() + " " + itm[0]
107
108 @classmethod
109 def parse_iozone_res(cls, res, mthreads=False):
110 parsed_res = None
111
112 sres = res.split('\n')
113
114 if not mthreads:
115 for pos, line in enumerate(sres[1:]):
116 if line.strip() == cls.string2 and \
117 sres[pos].strip() == cls.string1.strip():
118 add_pos = line.index(cls.string2)
119 parsed_res = {}
120
121 npos = [(name, start + add_pos, stop + add_pos)
122 for name, start, stop in cls.positions]
123
124 for itm, res in cls.apply_parts(npos, sres[pos + 2]):
125 if res.strip() != '':
126 parsed_res[itm[0]] = int(res.strip())
127
128 del parsed_res['KB']
129 del parsed_res['reclen']
130 else:
131 parsed_res = {}
132 for line in sres:
133 rr = cls.mt_iozone_re.match(line)
134 if rr is not None:
135 cmd = rr.group('cmd')
136 key = cls.cmap.get(cmd, cmd)
137 perf = int(float(rr.group('perf')))
138 parsed_res[key] = perf
139 return parsed_res
140
141
koder aka kdanilov4af80852015-02-01 23:36:38 +0200142IOZoneParser.make_positions()
143
144
koder aka kdanilov3f356262015-02-13 08:06:14 -0800145def iozone_do_prepare(params, filename, pattern_base):
koder aka kdanilov4af80852015-02-01 23:36:38 +0200146 all_files = []
147 threads = int(params.concurence)
148 if 1 != threads:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800149 filename = filename + "_{0}"
150 all_files.extend(filename .format(i) for i in range(threads))
koder aka kdanilov4af80852015-02-01 23:36:38 +0200151 else:
koder aka kdanilov4af80852015-02-01 23:36:38 +0200152 all_files.append(filename)
153
154 bsz = 1024 if params.size > 1024 else params.size
155 if params.size % bsz != 0:
156 fsz = (params.size // bsz + 1) * bsz
157 else:
158 fsz = params.size
159
160 for fname in all_files:
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200161 with open(fname, "wb") as fd:
162 if fsz > 1024:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800163 pattern = pattern_base * 1024 * 1024
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200164 for _ in range(int(fsz / 1024) + 1):
165 fd.write(pattern)
166 else:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800167 fd.write(pattern_base * 1024 * fsz)
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200168 fd.flush()
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800169 return all_files
170
171
172VERIFY_PATTERN = "\x6d"
173
174
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800175def prepare_iozone(params, filename):
176 return iozone_do_prepare(params, filename, VERIFY_PATTERN)
177
178
179def do_run_iozone(params, timeout, all_files,
180 iozone_path='iozone',
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800181 microsecond_mode=False,
182 prepare_only=False):
183
184 cmd = [iozone_path, "-V", str(ord(VERIFY_PATTERN))]
185
186 if params.sync:
187 cmd.append('-o')
188
189 if params.direct_io:
190 cmd.append('-I')
191
192 if microsecond_mode:
193 cmd.append('-N')
194
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800195 threads = int(params.concurence)
196 if 1 != threads:
197 cmd.extend(('-t', str(threads), '-F'))
198 cmd.extend(all_files)
199 else:
200 cmd.extend(('-f', all_files[0]))
koder aka kdanilov4af80852015-02-01 23:36:38 +0200201
202 cmd.append('-i')
203
204 if params.action == 'write':
205 cmd.append("0")
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200206 elif params.action == 'read':
207 cmd.append("1")
208 elif params.action == 'randwrite' or params.action == 'randread':
koder aka kdanilov4af80852015-02-01 23:36:38 +0200209 cmd.append("2")
210 else:
211 raise ValueError("Unknown action {0!r}".format(params.action))
212
213 cmd.extend(('-s', str(params.size)))
214 cmd.extend(('-r', str(params.blocksize)))
215
koder aka kdanilov78ba8952015-02-03 01:11:23 +0200216 # no retest
217 cmd.append('-+n')
koder aka kdanilov4af80852015-02-01 23:36:38 +0200218 raw_res = subprocess.check_output(cmd)
219
220 try:
221 parsed_res = IOZoneParser.parse_iozone_res(raw_res, threads > 1)
222
223 res = {}
224
225 if params.action == 'write':
226 res['bw_mean'] = parsed_res['write']
227 elif params.action == 'randwrite':
228 res['bw_mean'] = parsed_res['random write']
229 elif params.action == 'read':
230 res['bw_mean'] = parsed_res['read']
231 elif params.action == 'randread':
232 res['bw_mean'] = parsed_res['random read']
233 except:
koder aka kdanilov4af80852015-02-01 23:36:38 +0200234 raise
235
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200236 return res, " ".join(cmd)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200237
238
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800239def run_iozone(benchmark, binary_path, all_files,
koder aka kdanilov3f356262015-02-13 08:06:14 -0800240 timeout=None):
241
koder aka kdanilov4af80852015-02-01 23:36:38 +0200242 if timeout is not None:
243 benchmark.size = benchmark.blocksize * 50
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800244 res_time = do_run_iozone(benchmark, timeout, all_files,
245 iozone_path=binary_path,
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200246 microsecond_mode=True)[0]
koder aka kdanilov4af80852015-02-01 23:36:38 +0200247
248 size = (benchmark.blocksize * timeout * 1000000)
249 size /= res_time["bw_mean"]
250 size = (size // benchmark.blocksize + 1) * benchmark.blocksize
251 benchmark.size = size
252
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800253 return do_run_iozone(benchmark, timeout, all_files,
254 iozone_path=binary_path)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200255
256
koder aka kdanilov4af80852015-02-01 23:36:38 +0200257def install_iozone_package():
258 if which('iozone'):
259 return
260
261 is_redhat = os.path.exists('/etc/centos-release')
262 is_redhat = is_redhat or os.path.exists('/etc/fedora-release')
263 is_redhat = is_redhat or os.path.exists('/etc/redhat-release')
264
265 if is_redhat:
266 subprocess.check_output(["yum", "install", 'iozone3'])
267 return
268
269 try:
270 os_release_cont = open('/etc/os-release').read()
271
272 is_ubuntu = "Ubuntu" in os_release_cont
273
274 if is_ubuntu or "Debian GNU/Linux" in os_release_cont:
275 subprocess.check_output(["apt-get", "install", "iozone3"])
276 return
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200277 except (IOError, OSError):
koder aka kdanilov4af80852015-02-01 23:36:38 +0200278 pass
279
280 raise RuntimeError("Unknown host OS.")
281
282
283def install_iozone_static(iozone_url, dst):
284 if not os.path.isfile(dst):
285 import urllib
286 urllib.urlretrieve(iozone_url, dst)
287
288 st = os.stat(dst)
289 os.chmod(dst, st.st_mode | stat.S_IEXEC)
290
291
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200292def locate_iozone():
293 binary_path = which('iozone')
294
295 if binary_path is None:
296 binary_path = which('iozone3')
297
298 if binary_path is None:
299 sys.stderr.write("Can't found neither iozone not iozone3 binary"
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800300 "Provide --binary-path or --binary-url option")
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800301 return None
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200302
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800303 return binary_path
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200304
305# ------------------------------ FIO SUPPORT ---------------------------------
306
307
308def run_fio_once(benchmark, fio_path, tmpname, timeout=None):
koder aka kdanilov3f356262015-02-13 08:06:14 -0800309 if benchmark.size is None:
310 raise ValueError("You need to specify file size for fio")
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200311
312 cmd_line = [fio_path,
313 "--name=%s" % benchmark.action,
314 "--rw=%s" % benchmark.action,
315 "--blocksize=%sk" % benchmark.blocksize,
316 "--iodepth=%d" % benchmark.iodepth,
317 "--filename=%s" % tmpname,
318 "--size={0}k".format(benchmark.size),
319 "--numjobs={0}".format(benchmark.concurence),
320 "--output-format=json",
321 "--sync=" + ('1' if benchmark.sync else '0')]
322
323 if timeout is not None:
324 cmd_line.append("--timeout=%d" % timeout)
325 cmd_line.append("--runtime=%d" % timeout)
326
327 if benchmark.direct_io:
328 cmd_line.append("--direct=1")
329
330 if benchmark.use_hight_io_priority:
331 cmd_line.append("--prio=0")
332
333 raw_out = subprocess.check_output(cmd_line)
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200334 return json.loads(raw_out)["jobs"][0], " ".join(cmd_line)
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200335
336
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800337def run_fio(benchmark, binary_path, all_files, timeout=None):
338 job_output, cmd_line = run_fio_once(benchmark, binary_path,
339 all_files[0], timeout)
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200340
341 if benchmark.action in ('write', 'randwrite'):
342 raw_result = job_output['write']
343 else:
344 raw_result = job_output['read']
345
346 res = {}
koder aka kdanilov78ba8952015-02-03 01:11:23 +0200347
348 # 'bw_dev bw_mean bw_max bw_min'.split()
349 for field in ["bw_mean"]:
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200350 res[field] = raw_result[field]
351
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200352 return res, cmd_line
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200353
354
355def locate_fio():
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800356 return which('fio')
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200357
358
359# ----------------------------------------------------------------------------
360
361
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800362def locate_binary(binary_tp, binary_path):
363 if binary_path is not None:
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200364 if os.path.isfile(binary_path):
365 if not os.access(binary_path, os.X_OK):
366 st = os.stat(binary_path)
367 os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
368 else:
369 binary_path = None
370
371 if binary_path is not None:
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800372 return binary_path
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200373
374 if 'iozone' == binary_tp:
375 return locate_iozone()
376 else:
377 return locate_fio()
378
379
380def run_benchmark(binary_tp, *argv, **kwargs):
381 if 'iozone' == binary_tp:
382 return run_iozone(*argv, **kwargs)
383 else:
384 return run_fio(*argv, **kwargs)
385
386
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800387def prepare_benchmark(binary_tp, *argv, **kwargs):
388 if 'iozone' == binary_tp:
389 return {'all_files': prepare_iozone(*argv, **kwargs)}
390 else:
391 return {}
392
393
koder aka kdanilov4af80852015-02-01 23:36:38 +0200394def type_size(string):
395 try:
396 return re.match("\d+[KGBM]?", string, re.I).group(0)
397 except:
398 msg = "{0!r} don't looks like size-description string".format(string)
399 raise ValueError(msg)
400
401
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200402def type_size_ext(string):
403 if string.startswith("x"):
404 int(string[1:])
405 return string
406
407 if string.startswith("r"):
408 int(string[1:])
409 return string
410
411 try:
412 return re.match("\d+[KGBM]?", string, re.I).group(0)
413 except:
414 msg = "{0!r} don't looks like size-description string".format(string)
415 raise ValueError(msg)
416
417
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200418def ssize_to_kb(ssize):
419 try:
420 smap = dict(k=1, K=1, M=1024, m=1024, G=1024**2, g=1024**2)
421 for ext, coef in smap.items():
422 if ssize.endswith(ext):
423 return int(ssize[:-1]) * coef
424
425 if int(ssize) % 1024 != 0:
426 raise ValueError()
427
428 return int(ssize) / 1024
429
430 except (ValueError, TypeError, AttributeError):
431 tmpl = "Unknow size format {0!r} (or size not multiples 1024)"
432 raise ValueError(tmpl.format(ssize))
433
434
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200435def get_ram_size():
436 try:
437 with open("/proc/meminfo") as fd:
438 for ln in fd:
439 if "MemTotal:" in ln:
440 sz, kb = ln.split(':')[1].strip().split(" ")
441 assert kb == 'kB'
442 return int(sz)
443 except (ValueError, TypeError, AssertionError):
444 raise
445 # return None
446
447
koder aka kdanilov4af80852015-02-01 23:36:38 +0200448def parse_args(argv):
449 parser = argparse.ArgumentParser(
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200450 description="Run 'iozone' or 'fio' and return result")
451 parser.add_argument(
452 "--type", metavar="BINARY_TYPE",
453 choices=['iozone', 'fio'], required=True)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200454 parser.add_argument(
455 "--iodepth", metavar="IODEPTH", type=int,
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800456 help="I/O requests queue depths", required=True)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200457 parser.add_argument(
458 '-a', "--action", metavar="ACTION", type=str,
459 help="actions to run", required=True,
460 choices=["read", "write", "randread", "randwrite"])
461 parser.add_argument(
462 "--blocksize", metavar="BLOCKSIZE", type=type_size,
463 help="single operation block size", required=True)
464 parser.add_argument(
465 "--timeout", metavar="TIMEOUT", type=int,
466 help="runtime of a single run", default=None)
467 parser.add_argument(
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200468 "--iosize", metavar="SIZE", type=type_size_ext,
koder aka kdanilov4af80852015-02-01 23:36:38 +0200469 help="file size", default=None)
470 parser.add_argument(
471 "-s", "--sync", default=False, action="store_true",
472 help="exec sync after each write")
473 parser.add_argument(
474 "-d", "--direct-io", default=False, action="store_true",
475 help="use O_DIRECT", dest='directio')
476 parser.add_argument(
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800477 "-t", "--sync-time", default=None, type=int, metavar="UTC_TIME",
koder aka kdanilov4af80852015-02-01 23:36:38 +0200478 help="sleep till sime utc time", dest='sync_time')
479 parser.add_argument(
koder aka kdanilov4af80852015-02-01 23:36:38 +0200480 "--test-file", help="file path to run test on",
481 default=None, dest='test_file')
482 parser.add_argument(
koder aka kdanilov4ec0f712015-02-19 19:19:27 -0800483 "--binary-path", help="path to binary, used for testing",
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200484 default=None, dest='binary_path')
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800485 parser.add_argument(
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800486 "--prepare-only", default=False, action="store_true")
koder aka kdanilov3f356262015-02-13 08:06:14 -0800487 parser.add_argument("--concurrency", default=1, type=int)
koder aka kdanilove21d7472015-02-14 19:02:04 -0800488
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800489 parser.add_argument("--preparation-results", default="{}")
490
koder aka kdanilove21d7472015-02-14 19:02:04 -0800491 parser.add_argument("--with-sensors", default="",
492 dest="with_sensors")
493
koder aka kdanilov4af80852015-02-01 23:36:38 +0200494 return parser.parse_args(argv)
495
496
koder aka kdanilove21d7472015-02-14 19:02:04 -0800497def sensor_thread(sensor_list, cmd_q, data_q):
498 while True:
499 try:
500 cmd_q.get(timeout=0.5)
501 data_q.put([])
502 return
503 except Queue.Empty:
504 pass
505
506
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800507def clean_prep(preparation_results):
508 if 'all_files' in preparation_results:
509 for fname in preparation_results['all_files']:
510 if os.path.isfile(fname):
511 os.unlink(fname)
512
513
koder aka kdanilov4af80852015-02-01 23:36:38 +0200514def main(argv):
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800515 if argv[0] == '--clean':
516 clean_prep(json.loads(argv[1]))
517 return 0
518
koder aka kdanilov4af80852015-02-01 23:36:38 +0200519 argv_obj = parse_args(argv)
520 argv_obj.blocksize = ssize_to_kb(argv_obj.blocksize)
521
522 if argv_obj.iosize is not None:
koder aka kdanilov4a72f122015-02-09 12:25:54 +0200523 if argv_obj.iosize.startswith('x'):
524 argv_obj.iosize = argv_obj.blocksize * int(argv_obj.iosize[1:])
525 elif argv_obj.iosize.startswith('r'):
526 rs = get_ram_size()
527 if rs is None:
528 sys.stderr.write("Can't determine ram size\n")
529 exit(1)
530 argv_obj.iosize = rs * int(argv_obj.iosize[1:])
531 else:
532 argv_obj.iosize = ssize_to_kb(argv_obj.iosize)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200533
koder aka kdanilov3f356262015-02-13 08:06:14 -0800534 benchmark = BenchmarkOption(argv_obj.concurrency,
koder aka kdanilov4af80852015-02-01 23:36:38 +0200535 argv_obj.iodepth,
536 argv_obj.action,
537 argv_obj.blocksize,
538 argv_obj.iosize)
539
540 benchmark.direct_io = argv_obj.directio
541
koder aka kdanilov98615bf2015-02-02 00:59:07 +0200542 if argv_obj.sync:
543 benchmark.sync = True
544
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800545 if argv_obj.prepare_only:
546 test_file_name = argv_obj.test_file
547 if test_file_name is None:
548 with warnings.catch_warnings():
549 warnings.simplefilter("ignore")
550 test_file_name = os.tmpnam()
koder aka kdanilov4af80852015-02-01 23:36:38 +0200551
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800552 fnames = prepare_benchmark(argv_obj.type,
553 benchmark,
554 test_file_name)
555 print json.dumps(fnames)
556 else:
557 preparation_results = json.loads(argv_obj.preparation_results)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200558
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800559 if not isinstance(preparation_results, dict):
560 raise ValueError("preparation_results should be a dict" +
561 " with all-string keys")
koder aka kdanilov4af80852015-02-01 23:36:38 +0200562
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800563 for key in preparation_results:
564 if not isinstance(key, basestring):
565 raise ValueError("preparation_results should be a dict" +
566 " with all-string keys")
koder aka kdanilov4af80852015-02-01 23:36:38 +0200567
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800568 if argv_obj.test_file and 'all_files' in preparation_results:
569 raise ValueError("Either --test-file or --preparation-results" +
570 " options should be provided, not both")
koder aka kdanilove21d7472015-02-14 19:02:04 -0800571
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800572 if argv_obj.test_file is not None:
573 preparation_results['all_files'] = argv_obj.test_file
koder aka kdanilov3f356262015-02-13 08:06:14 -0800574
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800575 autoremove = False
576 if 'all_files' not in preparation_results:
577 with warnings.catch_warnings():
578 warnings.simplefilter("ignore")
579 preparation_results['all_files'] = [os.tmpnam()]
580 autoremove = True
581
582 binary_path = locate_binary(argv_obj.type,
583 argv_obj.binary_path)
584
585 if binary_path is None:
586 sys.stderr.write("Can't locate binary {0}\n".format(argv_obj.type))
587 return 1
588
589 try:
590 if argv_obj.sync_time is not None:
591 dt = argv_obj.sync_time - time.time()
592 if dt > 0:
593 time.sleep(dt)
594
595 if argv_obj.with_sensors != "":
596 oq = Queue.Queue()
597 iq = Queue.Queue()
598 argv = (argv_obj.with_sensors, oq, iq)
599 th = threading.Thread(None, sensor_thread, None, argv)
600 th.daemon = True
601 th.start()
602
603 res, cmd = run_benchmark(argv_obj.type,
604 benchmark=benchmark,
605 binary_path=binary_path,
606 timeout=argv_obj.timeout,
607 **preparation_results)
608 if argv_obj.with_sensors != "":
609 oq.put(None)
610 th.join()
611 stats = []
612
613 while not iq.empty():
614 stats.append(iq.get())
615 else:
616 stats = None
617
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800618 res['__meta__'] = benchmark.__dict__.copy()
619 res['__meta__']['cmdline'] = cmd
620
koder aka kdanilove21d7472015-02-14 19:02:04 -0800621 if stats is not None:
622 res['__meta__']['sensor_data'] = stats
623
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800624 sys.stdout.write(json.dumps(res))
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800625
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800626 if not argv_obj.prepare_only:
627 sys.stdout.write("\n")
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800628
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800629 finally:
630 if autoremove:
631 clean_prep(preparation_results)
koder aka kdanilov4af80852015-02-01 23:36:38 +0200632
633
koder aka kdanilov4af80852015-02-01 23:36:38 +0200634if __name__ == '__main__':
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800635 exit(main(sys.argv[1:]))