blob: 7394c6aaf21e5861f85e911b52575e7579e8bf49 [file] [log] [blame]
stgleb75c70412015-02-17 02:52:00 +02001import datetime
2import math
stgleb75c70412015-02-17 02:52:00 +02003from flask import json
gstepanove6ad1f02015-03-02 19:58:00 +02004from meta_info import collect_lab_data, total_lab_info
stgleb75c70412015-02-17 02:52:00 +02005from sqlalchemy import sql
6from persistance.models import *
7
8
gstepanove6ad1f02015-03-02 19:58:00 +02009# class displays measurement. Moved from storage_api_v_1
10# to avoid circular imports.
stgleb75c70412015-02-17 02:52:00 +020011class Measurement(object):
12 def __init__(self):
13 self.build = ""
14 self.build_type = 0 # GA/Master/Other
15 self.md5 = ""
16 self.name = ""
17 self.date = None
18 self.results = {
19 "": (float, float)
20 }
21
22 def __str__(self):
23 return self.build + " " + self.build_type + " " + \
24 self.md5 + " " + str(self.results)
25
26
27def mean(l):
28 n = len(l)
29
30 return sum(l) / n
31
32
33def stdev(l):
34 m = mean(l)
35 return math.sqrt(sum(map(lambda x: (x - m) ** 2, l)))
36
37
gstepanov15681d62015-02-23 17:17:50 +020038def get_build_info(build_name):
39 session = db.session()
gstepanove6ad1f02015-03-02 19:58:00 +020040 result = session.query(Result, Build).join(Build).\
41 filter(Build.name == build_name).first()
gstepanov15681d62015-02-23 17:17:50 +020042 lab = session.query(Lab).filter(Lab.id == result[0].lab_id).first()
43 return eval(lab.lab_general_info)
44
45
46def get_build_detailed_info(build_name):
47 data = get_build_info(build_name)
48 return total_lab_info(data)
49
50
stgleb75c70412015-02-17 02:52:00 +020051def process_build_data(build):
52 for item in build.items():
53 if type(item[1]) is list:
54 m = mean(item[1])
55 s = stdev(item[1])
56 build[item[0]] = [m, s]
57
58
gstepanove6ad1f02015-03-02 19:58:00 +020059# filling Param table with initial parameters.
stgleb75c70412015-02-17 02:52:00 +020060def add_io_params(session):
gstepanove6ad1f02015-03-02 19:58:00 +020061 param1 = Param(name="operation", type='{"write", "randwrite", '
62 '"read", "randread"}',
63 descr="type of write operation")
64 param2 = Param(name="sync", type='{"a", "s"}',
65 descr="Write mode synchronous/asynchronous")
66 param3 = Param(name="block size",
67 type='{"1k", "2k", "4k", "8k", "16k", '
68 '"32k", "64k", "128k", "256k"}')
stgleb75c70412015-02-17 02:52:00 +020069
70 session.add(param1)
71 session.add(param2)
72 session.add(param3)
73
74 session.commit()
75
76
gstepanove6ad1f02015-03-02 19:58:00 +020077# function which adds particular build to database.
stgleb75c70412015-02-17 02:52:00 +020078def add_build(session, build_id, build_name, build_type, md5):
gstepanove6ad1f02015-03-02 19:58:00 +020079 build = Build(type=build_type, build_id=build_id,
80 name=build_name, md5=md5)
stgleb75c70412015-02-17 02:52:00 +020081 session.add(build)
82 session.commit()
83
84 return build.id
85
86
gstepanove6ad1f02015-03-02 19:58:00 +020087# function insert particular result.
stgleb75c70412015-02-17 02:52:00 +020088def insert_results(session, build_id, lab_id, params_combination_id,
89 time=None, bandwith=0.0, meta=""):
gstepanove6ad1f02015-03-02 19:58:00 +020090 result = Result(build_id=build_id, lab_id=lab_id,
91 params_combination_id=params_combination_id, time=time,
stgleb75c70412015-02-17 02:52:00 +020092 bandwith=bandwith, meta=meta)
93 session.add(result)
94 session.commit()
95
96
gstepanove6ad1f02015-03-02 19:58:00 +020097# function responsible for adding particular params combination to database
stgleb75c70412015-02-17 02:52:00 +020098def add_param_comb(session, *params):
gstepanove6ad1f02015-03-02 19:58:00 +020099 params_names = sorted([s for s in dir(ParamCombination)
100 if s.startswith('param_')])
stgleb75c70412015-02-17 02:52:00 +0200101 d = zip(params_names, params)
102 where = ""
103
104 for item in d:
105 where = sql.and_(where, getattr(ParamCombination, item[0]) == item[1])
106
107 query = session.query(ParamCombination).filter(where)
108 rs = session.execute(query).fetchall()
109
stgleb75c70412015-02-17 02:52:00 +0200110 if len(rs) == 0:
111 param_comb = ParamCombination()
112
113 for p in params_names:
114 i = int(p.split('_')[1])
stgleb75c70412015-02-17 02:52:00 +0200115
gstepanove6ad1f02015-03-02 19:58:00 +0200116 if i - 1 < len(params):
117 param_comb.__setattr__('param_' + str(i), params[i - 1])
118 param = session.query(Param).filter(Param.id == i).one()
119 values = eval(param.type)
stgleb75c70412015-02-17 02:52:00 +0200120
gstepanove6ad1f02015-03-02 19:58:00 +0200121 if params[i - 1] not in values:
122 values.add(params[i - 1])
123 param.type = str(values)
stgleb75c70412015-02-17 02:52:00 +0200124
125 session.add(param_comb)
126 session.commit()
127 return param_comb.id
128 else:
129 return rs[0][0]
130
131
gstepanove6ad1f02015-03-02 19:58:00 +0200132def add_lab(session, lab_url, lab_name, ceph_version,
133 fuel_version, data, info):
gstepanov15681d62015-02-23 17:17:50 +0200134 result = session.query(Lab).filter(Lab.name == lab_name).all()
stgleb75c70412015-02-17 02:52:00 +0200135
gstepanov15681d62015-02-23 17:17:50 +0200136 if len(result) != 0:
137 return result[0].id
138 else:
139 lab = Lab(name=lab_name, url=lab_url, ceph_version=ceph_version,
gstepanove6ad1f02015-03-02 19:58:00 +0200140 fuel_version=fuel_version, lab_general_info=str(data),
141 lab_meta=str(info))
gstepanov15681d62015-02-23 17:17:50 +0200142 session.add(lab)
143 session.commit()
144 return lab.id
stgleb75c70412015-02-17 02:52:00 +0200145
gstepanove6ad1f02015-03-02 19:58:00 +0200146
147# function store list of builds in database
stgleb75c70412015-02-17 02:52:00 +0200148def add_data(data):
149 data = json.loads(data)
150 session = db.session()
151 add_io_params(session)
152
153 for build_data in data:
154 build_id = add_build(session,
155 build_data.pop("build_id"),
156 build_data.pop("name"),
157 build_data.pop("type"),
158 build_data.pop("iso_md5"),
159 )
gstepanove6ad1f02015-03-02 19:58:00 +0200160
gstepanov15681d62015-02-23 17:17:50 +0200161 creds = {"username": build_data.pop("username"),
162 "password": build_data.pop("password"),
gstepanove6ad1f02015-03-02 19:58:00 +0200163 "tenant_name": build_data.pop("tenant_name")}
164
gstepanov15681d62015-02-23 17:17:50 +0200165 lab_url = build_data.pop("lab_url")
166 lab_name = build_data.pop("lab_name")
167 ceph_version = build_data.pop("ceph_version")
168 data = collect_lab_data(lab_url, creds)
169 data['name'] = lab_name
170 info = total_lab_info(data)
171 lab_id = add_lab(session, lab_url=lab_name, lab_name=lab_url,
gstepanove6ad1f02015-03-02 19:58:00 +0200172 ceph_version=ceph_version,
173 fuel_version=data['fuel_version'],
174 data=data, info=info)
gstepanov15681d62015-02-23 17:17:50 +0200175
stgleb75c70412015-02-17 02:52:00 +0200176 date = build_data.pop("date")
177 date = datetime.datetime.strptime(date, "%a %b %d %H:%M:%S %Y")
178
179 for params, [bw, dev] in build_data.items():
180 param_comb_id = add_param_comb(session, *params.split(" "))
gstepanove6ad1f02015-03-02 19:58:00 +0200181 result = Result(param_combination_id=param_comb_id,
182 build_id=build_id, bandwith=bw,
183 date=date, lab_id=lab_id)
stgleb75c70412015-02-17 02:52:00 +0200184 session.add(result)
185 session.commit()
186
187
gstepanove6ad1f02015-03-02 19:58:00 +0200188# function loads data by parameters described in *params tuple.
189def load_data(lab_id=None, build_id=None, *params):
stgleb75c70412015-02-17 02:52:00 +0200190 session = db.session()
gstepanove6ad1f02015-03-02 19:58:00 +0200191 params_names = sorted([s for s in dir(ParamCombination)
192 if s.startswith('param_')])
stgleb75c70412015-02-17 02:52:00 +0200193 d = zip(params_names, params)
194 where = ""
195
196 for item in d:
197 where = sql.and_(where, getattr(ParamCombination, item[0]) == item[1])
198
199 query = session.query(ParamCombination).filter(where)
200 rs = session.execute(query).fetchall()
201
202 ids = [r[0] for r in rs]
203
gstepanove6ad1f02015-03-02 19:58:00 +0200204 rs = session.query(Result).\
205 filter(Result.param_combination_id.in_(ids)).all()
stgleb75c70412015-02-17 02:52:00 +0200206
gstepanove6ad1f02015-03-02 19:58:00 +0200207 if lab_id is not None:
208 rs = [r for r in rs if r.lab_id == lab_id]
209
210 if build_id is not None:
211 rs = [r for r in rs if r.build_id == build_id]
212
213 return rs
stgleb75c70412015-02-17 02:52:00 +0200214
215
gstepanove6ad1f02015-03-02 19:58:00 +0200216# load all builds from database
stgleb75c70412015-02-17 02:52:00 +0200217def load_all():
218 session = db.session()
gstepanove6ad1f02015-03-02 19:58:00 +0200219 results = session.query(Result, Build, ParamCombination).\
220 join(Build).join(ParamCombination).all()
stgleb75c70412015-02-17 02:52:00 +0200221
222 return results
223
224
gstepanove6ad1f02015-03-02 19:58:00 +0200225# function collecting all builds from database and filter it by names
stgleb75c70412015-02-17 02:52:00 +0200226def collect_builds_from_db(*names):
227 results = load_all()
228 d = {}
229
230 for item in results:
231 result_data = item[0]
232 build_data = item[1]
233 param_combination_data = item[2]
234
235 if build_data.name not in d:
gstepanove6ad1f02015-03-02 19:58:00 +0200236 d[build_data.name] = \
237 [build_data, result_data, param_combination_data]
stgleb75c70412015-02-17 02:52:00 +0200238 else:
239 d[build_data.name].append(result_data)
240 d[build_data.name].append(param_combination_data)
241
242 if len(names) == 0:
243 return {k: v for k, v in d.items()}
244
245 return {k: v for k, v in d.items() if k in names}
246
247
gstepanove6ad1f02015-03-02 19:58:00 +0200248# function creates measurement from data was extracted from database.
stgleb75c70412015-02-17 02:52:00 +0200249def create_measurement(data):
250 build_data = data[0]
251
252 m = Measurement()
253 m.build = build_data.build_id
254 m.build_type = build_data.type
255 m.name = build_data.name
256 m.results = {}
257
258 for i in range(1, len(data), 2):
259 result = data[i]
260 param_combination = data[i + 1]
261
262 if not str(param_combination) in m.results:
263 m.results[str(param_combination)] = [result.bandwith]
264 else:
265 m.results[str(param_combination)] += [result.bandwith]
266
267 for k in m.results.keys():
268 m.results[k] = [mean(m.results[k]), stdev(m.results[k])]
269
270 return m
271
272
273#function preparing data for display plots.
274#Format {build_name : Measurement}
275def prepare_build_data(build_name):
276 session = db.session()
277 build = session.query(Build).filter(Build.name == build_name).first()
278 names = []
279
280 if build.type == 'GA':
281 names = [build_name]
282 else:
gstepanove6ad1f02015-03-02 19:58:00 +0200283 res = session.query(Build).\
284 filter(Build.type.in_(['GA', 'master', build.type])).all()
stgleb75c70412015-02-17 02:52:00 +0200285 for r in res:
286 names.append(r.name)
287
stgleb75c70412015-02-17 02:52:00 +0200288 d = collect_builds_from_db()
289 d = {k: v for k, v in d.items() if k in names}
290 results = {}
291
292 for data in d.keys():
293 m = create_measurement(d[data])
294 results[m.build_type] = m
295
296 return results
297
298
299#function getting list of all builds available to index page
300#returns list of dicts which contains data to display on index page.
301def builds_list():
302 res = []
303 builds = set()
304 data = load_all()
305
306 for item in data:
307 build = item[1]
308 result = item[0]
309
310 if not build.name in builds:
311 builds.add(build.name)
312 d = {}
313 d["type"] = build.type
314 d["url"] = build.name
315 d["date"] = result.date
316 d["name"] = build.name
317 res.append(d)
318
319 return res
320
321
gstepanove6ad1f02015-03-02 19:58:00 +0200322# Processing data from database.
323# List of dicts, where each dict contains build meta
324# info and kev-value measurements.
325# key - param combination.
326# value - [mean, deviation]
stgleb75c70412015-02-17 02:52:00 +0200327def get_builds_data(names=None):
328 d = collect_builds_from_db()
329
330 if not names is None:
331 d = {k: v for k, v in d.items() if k in names}
332 else:
333 d = {k: v for k, v in d.items()}
334 output = []
335
336 for key, value in d.items():
337 result = {}
338 build = value[0]
339 result["build_id"] = build.build_id
340 result["iso_md5"] = build.md5
341 result["type"] = build.type
342 result["date"] = "Date must be here"
343
344 for i in range(1, len(value), 2):
345 r = value[i]
346 param_combination = value[i + 1]
347
348 if not str(param_combination) in result:
349 result[str(param_combination)] = [r.bandwith]
350 else:
351 result[str(param_combination)].append(r.bandwith)
352
353 output.append(result)
354
355 for build in output:
356 process_build_data(build)
357
358 return output
359
360
gstepanove6ad1f02015-03-02 19:58:00 +0200361# Function for getting result to display table
stgleb75c70412015-02-17 02:52:00 +0200362def get_data_for_table(build_name=""):
363 session = db.session()
364 build = session.query(Build).filter(Build.name == build_name).one()
365 names = []
366
gstepanove6ad1f02015-03-02 19:58:00 +0200367 # Get names of build that we need.
stgleb75c70412015-02-17 02:52:00 +0200368 if build.type == 'GA':
369 names = [build_name]
370 else:
gstepanove6ad1f02015-03-02 19:58:00 +0200371 res = session.query(Build).filter(
372 Build.type.in_(['GA', 'master', build.type])).all()
stgleb75c70412015-02-17 02:52:00 +0200373 for r in res:
374 names.append(r.name)
gstepanove6ad1f02015-03-02 19:58:00 +0200375 # get data for particular builds.
stgleb75c70412015-02-17 02:52:00 +0200376 return get_builds_data(names)
377
378
379if __name__ == '__main__':
380 # add_build("Some build", "GA", "bla bla")
gstepanov15681d62015-02-23 17:17:50 +0200381 cred = {"username": "admin", "password": "admin", "tenant_name": "admin"}
stgleb75c70412015-02-17 02:52:00 +0200382 json_data = '[{\
gstepanov15681d62015-02-23 17:17:50 +0200383 "username": "admin",\
384 "password": "admin", \
385 "tenant_name": "admin",\
386 "lab_url": "http://172.16.52.112:8000",\
387 "lab_name": "Perf-1-Env",\
388 "ceph_version": "v0.80 Firefly",\
stgleb75c70412015-02-17 02:52:00 +0200389 "randwrite a 256k": [16885, 1869],\
390 "randwrite s 4k": [79, 2],\
391 "read a 64k": [74398, 11618],\
392 "write s 1024k": [7490, 193],\
393 "randwrite a 64k": [14167, 4665],\
394 "build_id": "1",\
395 "randread a 1024k": [68683, 8604],\
396 "randwrite s 256k": [3277, 146],\
397 "write a 1024k": [24069, 660],\
398 "type": "GA",\
399 "write a 64k": [24555, 1006],\
400 "write s 64k": [1285, 57],\
401 "write a 256k": [24928, 503],\
402 "write s 256k": [4029, 192],\
403 "randwrite a 1024k": [23980, 1897],\
404 "randread a 64k": [27257, 17268],\
405 "randwrite s 1024k": [8504, 238],\
406 "randread a 256k": [60868, 2637],\
407 "randread a 4k": [3612, 1355],\
408 "read a 1024k": [71122, 9217],\
409 "date": "Thu Feb 12 19:11:56 2015",\
410 "write s 4k": [87, 3],\
411 "read a 4k": [88367, 6471],\
412 "read a 256k": [80904, 8930],\
413 "name": "GA - 6.0 GA",\
414 "randwrite s 1k": [20, 0],\
415 "randwrite s 64k": [1029, 34],\
416 "write s 1k": [21, 0],\
417 "iso_md5": "bla bla"\
418 },\
419 {\
gstepanov15681d62015-02-23 17:17:50 +0200420 "username": "admin",\
421 "password": "admin", \
422 "tenant_name": "admin",\
423 "lab_url": "http://172.16.52.112:8000",\
424 "ceph_version": "v0.80 Firefly",\
425 "lab_name": "Perf-1-Env",\
stgleb75c70412015-02-17 02:52:00 +0200426 "randwrite a 256k": [20212, 5690],\
427 "randwrite s 4k": [83, 6],\
428 "read a 64k": [89394, 3912],\
429 "write s 1024k": [8054, 280],\
430 "randwrite a 64k": [14595, 3245],\
431 "build_id": "2",\
432 "randread a 1024k": [83277, 9310],\
433 "randwrite s 256k": [3628, 433],\
434 "write a 1024k": [29226, 8624],\
435 "type": "master",\
436 "write a 64k": [25089, 790],\
437 "write s 64k": [1236, 30],\
438 "write a 256k": [30327, 9799],\
439 "write s 256k": [4049, 172],\
440 "randwrite a 1024k": [29000, 9302],\
441 "randread a 64k": [26775, 16319],\
442 "randwrite s 1024k": [8665, 1457],\
443 "randread a 256k": [63608, 16126],\
444 "randread a 4k": [3212, 1620],\
445 "read a 1024k": [89676, 4401],\
446 "date": "Thu Feb 12 19:11:56 2015",\
447 "write s 4k": [88, 3],\
448 "read a 4k": [92263, 5186],\
449 "read a 256k": [94505, 6868],\
450 "name": "6.1 Dev",\
451 "randwrite s 1k": [22, 3],\
452 "randwrite s 64k": [1105, 46],\
453 "write s 1k": [22, 0],\
454 "iso_md5": "bla bla"\
455 },\
456 {\
gstepanov15681d62015-02-23 17:17:50 +0200457 "username": "admin",\
458 "password": "admin", \
459 "tenant_name": "admin",\
460 "lab_url": "http://172.16.52.112:8000",\
461 "ceph_version": "v0.80 Firefly",\
462 "lab_name": "Perf-1-Env",\
stgleb75c70412015-02-17 02:52:00 +0200463 "randwrite a 256k": [16885, 1869],\
464 "randwrite s 4k": [79, 2],\
465 "read a 64k": [74398, 11618],\
466 "write s 1024k": [7490, 193],\
467 "randwrite a 64k": [14167, 4665],\
468 "build_id": "1",\
469 "randread a 1024k": [68683, 8604],\
470 "randwrite s 256k": [3277, 146],\
471 "write a 1024k": [24069, 660],\
472 "type": "sometype",\
473 "write a 64k": [24555, 1006],\
474 "write s 64k": [1285, 57],\
475 "write a 256k": [24928, 503],\
476 "write s 256k": [4029, 192],\
477 "randwrite a 1024k": [23980, 1897],\
478 "randread a 64k": [27257, 17268],\
479 "randwrite s 1024k": [8504, 238],\
480 "randread a 256k": [60868, 2637],\
481 "randread a 4k": [3612, 1355],\
482 "read a 1024k": [71122, 9217],\
483 "date": "Thu Feb 12 19:11:56 2015",\
484 "write s 4k": [87, 3],\
485 "read a 4k": [88367, 6471],\
486 "read a 256k": [80904, 8930],\
487 "name": "somedev",\
488 "randwrite s 1k": [20, 0],\
489 "randwrite s 64k": [1029, 34],\
490 "write s 1k": [21, 0],\
491 "iso_md5": "bla bla"\
492 }]'
493
494 # json_to_db(json_data)
gstepanove6ad1f02015-03-02 19:58:00 +0200495 print load_data(1, 2)
496 # add_data(json_data)