blob: c666250f527d5af9b22a8890e6a796d022bc91d9 [file] [log] [blame]
koder aka kdanilov4643fd62015-02-10 16:20:13 -08001import re
2import sys
3import json
4
koder aka kdanilovce5444f2015-03-14 09:19:02 +02005from disk_perf_test_tool.utils import kb_to_ssize, ssize_to_kb
koder aka kdanilov6e2ae792015-03-04 18:02:24 -08006
koder aka kdanilov4643fd62015-02-10 16:20:13 -08007splitter_rr = "(?ms)=====+\n"
8
koder aka kdanilov6e2ae792015-03-04 18:02:24 -08009test_time_rr = r"""
10(?ims)(?P<start_time>[:0-9]{8}) - DEBUG - io-perf-tool - Passing barrier, starting test
11(?P<finish_time>[:0-9]{8}) - DEBUG - io-perf-tool - Done\. Closing connection
12"""
13
14test_time_rr = test_time_rr.strip().replace('\n', '\\s+')
15test_time_rr = test_time_rr.strip().replace(' ', '\\s+')
16test_time_re = re.compile(test_time_rr)
17
18
19def to_sec(val):
20 assert val.count(":") == 2
21 h, m, s = val.split(":")
22 return int(h) * 3600 + int(m) * 60 + int(s)
23
24
25def to_min_sec(val):
26 return "{0:2d}:{1:02d}".format(val / 60, val % 60)
27
28
29def get_test_time(block):
30 time_m = test_time_re.search(block)
31 if time_m is None:
32 raise ValueError("Can't found time")
33
34 start_time = to_sec(time_m.group('start_time'))
35 finish_time = to_sec(time_m.group('finish_time'))
36 test_time = finish_time - start_time
37
38 if test_time < 0:
39 # ..... really need print UTC to logs
40 test_time += 24 * 60 * 60
41 return test_time
42
43
44run_test_params_rr = r"(?ims)Run\s+test\s+with" + \
45 r"\s+'.*?--iosize\s+(?P<size>[^ ]*)"
46run_test_params_re = re.compile(run_test_params_rr)
47
48
49def get_orig_size(block):
50 orig_size = run_test_params_re.search(block)
51 if orig_size is None:
52 print block
53 raise ValueError("Can't find origin size")
54 return orig_size.group(1)
55
koder aka kdanilov4643fd62015-02-10 16:20:13 -080056
57def get_data_from_output(fname):
58 results = {}
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080059 results_meta = {}
koder aka kdanilov4643fd62015-02-10 16:20:13 -080060 fc = open(fname).read()
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080061 prev_block = None
koder aka kdanilov4643fd62015-02-10 16:20:13 -080062
63 for block in re.split(splitter_rr, fc):
64 block = block.strip()
koder aka kdanilove21d7472015-02-14 19:02:04 -080065
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080066 if block.startswith("[{u'__meta__':"):
koder aka kdanilove21d7472015-02-14 19:02:04 -080067
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080068 for val in eval(block):
69 meta = val['__meta__']
koder aka kdanilov7dec9df2015-02-15 21:35:19 -080070
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080071 if meta['sync']:
72 meta['sync'] = 's'
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +030073 elif meta['direct']:
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080074 meta['sync'] = 'd'
75 else:
76 meta['sync'] = 'a'
77
78 meta['fsize'] = kb_to_ssize(meta['size'] * meta['concurence'])
79 key = ("{action} {sync} {blocksize}k " +
80 "{concurence} {fsize}").format(**meta)
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +030081 results.setdefault(key, []).append(val['bw'])
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080082
83 cmeta = results_meta.setdefault(key, {})
84 cmeta.setdefault('times', []).append(get_test_time(prev_block))
85 cmeta['orig_size'] = get_orig_size(prev_block)
86
87 prev_block = block
koder aka kdanilov4643fd62015-02-10 16:20:13 -080088
89 processed_res = {}
90
91 for k, v in results.items():
92 v.sort()
93 med = float(sum(v)) / len(v)
94 ran = sum(abs(x - med) for x in v) / len(v)
95 processed_res[k] = (int(med), int(ran))
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080096 t = results_meta[k]['times']
97 results_meta[k]['times'] = int(float(sum(t)) / len(t))
koder aka kdanilov4643fd62015-02-10 16:20:13 -080098
koder aka kdanilov6e2ae792015-03-04 18:02:24 -080099 return processed_res, results_meta
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800100
101
102def ksort(x):
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800103 op, sync, sz, conc, fsize = x.split(" ")
koder aka kdanilov3f356262015-02-13 08:06:14 -0800104 return (op, sync, int(sz[:-1]), int(conc))
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800105
106
107def create_json_results(meta, file_data):
108 row = {"build_id": "",
109 "type": "",
110 "iso_md5": ""}
111 row.update(file_data)
112 return json.dumps(row)
113
114
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800115LINES_PER_HEADER = 20
116
117
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800118def show_data(*pathes):
koder aka kdanilovce5444f2015-03-14 09:19:02 +0200119 begin = "| {:>10} {:>6} {:>5} {:>3} {:>5} {:>7} {:>7}"
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800120 first_file_templ = " | {:>6} ~ {:>5} {:>2}% {:>5} {:>6}"
121 other_file_templ = first_file_templ + " ---- {:>6}%"
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800122
123 line_templ = begin + first_file_templ + \
124 other_file_templ * (len(pathes) - 1) + " |"
125
126 header_ln = line_templ.replace("<", "^").replace(">", "^")
127
koder aka kdanilovce5444f2015-03-14 09:19:02 +0200128 params = ["Oper", "Sync", "BSZ", "CC", "DSIZE", "OSIZE", "XSIZE",
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800129 "BW1", "DEV1", "%", "IOPS1", "TIME"]
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800130 for pos in range(1, len(pathes)):
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800131 params += "BW{0}+DEV{0}+%+IOPS{0}+DIFF %+TTIME".format(pos).split("+")
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800132
133 header_ln = header_ln.format(*params)
134
135 sep = '-' * len(header_ln)
136
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800137 results = []
138 metas = []
139
140 for path in pathes:
141 result, meta = get_data_from_output(path)
142 results.append(result)
143 metas.append(meta)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800144
145 print sep
146 print header_ln
147 print sep
148
149 prev_tp = None
150
151 common_keys = set(results[0].keys())
152 for result in results[1:]:
153 common_keys &= set(result.keys())
154
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800155 lcount = 0
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800156 for k in sorted(common_keys, key=ksort):
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800157 tp = k.rsplit(" ", 3)[0]
158 op, s, sz, conc, fsize = k.split(" ")
koder aka kdanilov7dec9df2015-02-15 21:35:19 -0800159
koder aka kdanilovce5444f2015-03-14 09:19:02 +0200160 xsize = int(ssize_to_kb(fsize) / ssize_to_kb(sz)) / int(conc)
161
koder aka kdanilov7dec9df2015-02-15 21:35:19 -0800162 s = {'a': 'async', "s": "sync", "d": "direct"}[s]
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800163
164 if tp != prev_tp and prev_tp is not None:
165 print sep
166
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800167 if lcount > LINES_PER_HEADER:
168 print header_ln
169 print sep
170 lcount = 0
171
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800172 prev_tp = tp
173
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800174 m0, d0 = results[0][k]
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800175 iops0 = m0 / int(sz[:-1])
176 perc0 = int(d0 * 100.0 / m0 + 0.5)
177
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800178 data = [op, s, sz, conc, fsize,
koder aka kdanilovce5444f2015-03-14 09:19:02 +0200179 metas[0][k]['orig_size'], xsize,
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800180 m0, d0, perc0, iops0,
181 to_min_sec(metas[0][k]['times'])]
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800182
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800183 for meta, result in zip(metas[1:], results[1:]):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800184 m, d = result[k]
185 iops = m / int(sz[:-1])
186 perc = int(d * 100.0 / m + 0.5)
187 avg_diff = int(((m - m0) * 100.) / m + 0.5)
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800188
189 dtime = to_min_sec(meta[k]['times'])
190 data.extend([m, d, perc, iops, avg_diff, dtime])
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800191
192 print line_templ.format(*data)
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800193 lcount += 1
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800194
195 print sep
196
197
198def main(argv):
199 path1 = argv[0]
200 if path1 == '--json':
201 print create_json_results(*get_data_from_output(argv[1]))
202 else:
203 show_data(*argv)
204 return 0
205
206if __name__ == "__main__":
207 exit(main(sys.argv[1:]))
208# print " ", results[k]