blob: 4006689f7694d2d62c67912289c7b4393e9f3f45 [file] [log] [blame]
gstepanov94531b82015-02-11 14:20:34 +02001from urlparse import urlparse
gstepanov2164d822015-02-04 19:49:40 +02002from flask import Flask, render_template, url_for, request, g
3from flask_bootstrap import Bootstrap
gstepanov725cc302015-02-09 15:08:06 +02004from config import TEST_PATH
gstepanov200d3b42015-02-06 14:01:49 +02005from report import build_vertical_bar, build_lines_chart
gstepanovbdc406b2015-02-11 17:35:55 +02006from storage_api import create_storage, Measurement
gstepanov81a52ee2015-02-10 16:22:20 +02007from logging import getLogger, INFO
8
9import json
10import os.path
gstepanov94531b82015-02-11 14:20:34 +020011from web_app.keystone import KeystoneAuth
gstepanov2164d822015-02-04 19:49:40 +020012
13app = Flask(__name__)
14Bootstrap(app)
15
16
gstepanov9ddc18f2015-02-11 20:28:59 +020017def load_test(test_name):
18 test_name += '.json'
19
20 with open(TEST_PATH + "/" + test_name, 'rt') as f:
21 raw = f.read()
22
23 if raw != "":
24 test = json.loads(raw)
25 else:
26 test = []
27 import time
28 creation_time = os.path.getmtime(TEST_PATH + "/" + test_name)
29
30 for t in test:
31 t['date'] = time.ctime(creation_time)
32
33 return test
34
35
gstepanov2164d822015-02-04 19:49:40 +020036def collect_tests():
37 result = []
38
gstepanovc3ffac72015-02-05 15:39:45 +020039 for file in os.listdir(TEST_PATH):
gstepanov2164d822015-02-04 19:49:40 +020040 if file.endswith(".json"):
41 result.append(file.split('.')[0])
42
43 return result
44
45
gstepanovbdc406b2015-02-11 17:35:55 +020046def collect_builds():
47 builds = []
48 build_set = set()
49 tests = collect_tests()
50
51 for t in tests:
52 test = load_test(t)
53
54 for build in test:
55 if build["type"] not in build_set:
56 build_set.add(build["type"])
57 builds.append(build)
58
59 return builds
60
61
gstepanov9eb8bf32015-02-11 20:13:14 +020062def builds_list():
gstepanov2164d822015-02-04 19:49:40 +020063 data = []
gstepanovbdc406b2015-02-11 17:35:55 +020064
65 for build in collect_builds():
gstepanov2164d822015-02-04 19:49:40 +020066 d = {}
gstepanovbdc406b2015-02-11 17:35:55 +020067 d["name"] = build['type']
68 d["url"] = url_for("render_test", test_name=build['type'])
gstepanov9eb8bf32015-02-11 20:13:14 +020069 d["date"] = build['date']
gstepanov2164d822015-02-04 19:49:40 +020070 data.append(d)
71
gstepanov9eb8bf32015-02-11 20:13:14 +020072 return data
73
gstepanov2164d822015-02-04 19:49:40 +020074
gstepanovbdc406b2015-02-11 17:35:55 +020075def create_measurement(build):
76 m = Measurement()
77 m.build = build.pop("build_id")
78 m.build_type = build.pop("type")
79 m.md5 = build.pop("iso_md5")
gstepanov9eb8bf32015-02-11 20:13:14 +020080 m.date = build.pop("date")
gstepanovbdc406b2015-02-11 17:35:55 +020081 m.results = {k: v for k, v in build.items()}
82
83 return m
84
85
gstepanove1ee9dc2015-02-11 18:09:46 +020086def total_lab_info(data):
87 d = {}
88 d['nodes_count'] = len(data['nodes'])
89 d['total_memory'] = 0
90 d['total_disk'] = 0
91 d['processor_count'] = 0
92
93 for node in data['nodes']:
94 d['total_memory'] += node['memory']['total']
95 d['processor_count'] += len(node['processors'])
96
97 for disk in node['disks']:
98 d['total_disk'] += disk['size']
99
gstepanov9eb8bf32015-02-11 20:13:14 +0200100 to_gb = lambda x: x / (1024 ** 3)
101 d['total_memory'] = format(to_gb(d['total_memory']), ',d')
102 d['total_disk'] = format(to_gb(d['total_disk']), ',d')
gstepanove1ee9dc2015-02-11 18:09:46 +0200103 return d
104
gstepanov9eb8bf32015-02-11 20:13:14 +0200105
gstepanov9ddc18f2015-02-11 20:28:59 +0200106def collect_lab_data(meta):
107 u = urlparse(meta['__meta__'])
108 cred = {"username": "admin", "password": "admin", "tenant_name": "admin"}
109 keystone = KeystoneAuth(root_url=meta['__meta__'], creds=cred, admin_node_ip=u.hostname)
110 lab_info = keystone.do(method='get', path="")
111 nodes = []
112 result = {}
113
114 for node in lab_info:
115 d = {}
116 d['name'] = node['name']
117 p = []
118 i = []
119 disks = []
120 devices = []
121
122 for processor in node['meta']['cpu']['spec']:
123 p.append(processor)
124
125 for iface in node['meta']['interfaces']:
126 i.append(iface)
127
128 m = node['meta']['memory'].copy()
129
130 for disk in node['meta']['disks']:
131 disks.append(disk)
132
133 d['memory'] = m
134 d['disks'] = disks
135 d['devices'] = devices
136 d['interfaces'] = i
137 d['processors'] = p
138
139 nodes.append(d)
140
141 result['nodes'] = nodes
142 result['name'] = 'Perf-1 Env'
143
144 return result
145
146
147@app.route("/", methods=['GET', 'POST'])
148def index():
149 data = builds_list()
150 return render_template("index.html", tests=data)
151
152
gstepanov2164d822015-02-04 19:49:40 +0200153@app.route("/tests/<test_name>", methods=['GET'])
154def render_test(test_name):
gstepanov9eb8bf32015-02-11 20:13:14 +0200155 tests = []
156 header_keys = ['build_id', 'iso_md5', 'type', 'date']
gstepanov0a8fdd32015-02-05 15:54:11 +0200157 table = [[]]
gstepanovbdc406b2015-02-11 17:35:55 +0200158 builds_to_compare = ['GA', 'master', test_name]
159 builds = collect_builds()
160 results = {}
gstepanove1ee9dc2015-02-11 18:09:46 +0200161 meta = {"__meta__": "http://172.16.52.112:8000/api/nodes"}
162 data = collect_lab_data(meta)
163 lab_meta = total_lab_info(data)
gstepanovbdc406b2015-02-11 17:35:55 +0200164
165 for build in builds:
166 if build['type'] in builds_to_compare:
167 type = build['type']
168 m = create_measurement(build)
169 results[type] = m
170
gstepanov200d3b42015-02-06 14:01:49 +0200171 bars = build_vertical_bar(results)
172 lines = build_lines_chart(results)
173 urls = bars + lines
gstepanov2164d822015-02-04 19:49:40 +0200174 if len(tests) > 0:
175 sorted_keys = sorted(tests[0].keys())
176
gstepanov0a8fdd32015-02-05 15:54:11 +0200177 for key in sorted_keys:
178 if key not in header_keys:
179 header_keys.append(key)
gstepanov2164d822015-02-04 19:49:40 +0200180
gstepanov0a8fdd32015-02-05 15:54:11 +0200181 for test in tests:
182 row = []
gstepanov2164d822015-02-04 19:49:40 +0200183
gstepanov0a8fdd32015-02-05 15:54:11 +0200184 for header in header_keys:
185 if isinstance(test[header], list):
186 row.append(str(test[header][0]) + unichr(0x00B1) + str(test[header][1]))
187 else:
188 row.append(test[header])
gstepanov2164d822015-02-04 19:49:40 +0200189
gstepanov0a8fdd32015-02-05 15:54:11 +0200190 table.append(row)
gstepanov2164d822015-02-04 19:49:40 +0200191
gstepanov9eb8bf32015-02-11 20:13:14 +0200192 return render_template("test.html", urls=urls, table_url=url_for('render_table', test_name=test_name),
193 index_url=url_for('index'), lab_meta=lab_meta)
gstepanovcd77d5a2015-02-06 14:49:34 +0200194
195
196@app.route("/tests/table/<test_name>/")
197def render_table(test_name):
gstepanovbdc406b2015-02-11 17:35:55 +0200198 builds = collect_builds()
199 builds = filter(lambda x: x["type"] in ['GA', 'master', test_name], builds)
gstepanov9eb8bf32015-02-11 20:13:14 +0200200 header_keys = ['build_id', 'iso_md5', 'type' ,'date']
gstepanovcd77d5a2015-02-06 14:49:34 +0200201 table = [[]]
gstepanov94531b82015-02-11 14:20:34 +0200202 meta = {"__meta__": "http://172.16.52.112:8000/api/nodes"}
gstepanove1ee9dc2015-02-11 18:09:46 +0200203 data = collect_lab_data(meta)
gstepanovbdc406b2015-02-11 17:35:55 +0200204
205 if len(builds) > 0:
206 sorted_keys = sorted(builds[0].keys())
gstepanovcd77d5a2015-02-06 14:49:34 +0200207
208 for key in sorted_keys:
209 if key not in header_keys:
210 header_keys.append(key)
211
gstepanovbdc406b2015-02-11 17:35:55 +0200212 for test in builds:
gstepanovcd77d5a2015-02-06 14:49:34 +0200213 row = []
214
215 for header in header_keys:
216 if isinstance(test[header], list):
217 row.append(str(test[header][0]) + unichr(0x00B1) + str(test[header][1]))
218 else:
219 row.append(test[header])
220
221 table.append(row)
222
gstepanovbb854922015-02-09 18:18:17 +0200223 return render_template("table.html", headers=header_keys, table=table,
224 back_url=url_for('render_test', test_name=test_name), lab=data)
gstepanov2164d822015-02-04 19:49:40 +0200225
226
227@app.route("/tests/<test_name>", methods=['POST'])
228def add_test(test_name):
229 tests = json.loads(request.data)
230
231 if not hasattr(g, "storage"):
gstepanovf8f01c12015-02-09 18:34:01 +0200232 path = "file://" + TEST_PATH + '/' + test_name + ".json"
233 print path
234 g.storage = create_storage(path, "", "")
gstepanov2164d822015-02-04 19:49:40 +0200235
236 for test in tests:
237 g.storage.store(test)
238 return "Created", 201
239
240
gstepanov2164d822015-02-04 19:49:40 +0200241if __name__ == "__main__":
gstepanov81a52ee2015-02-10 16:22:20 +0200242 logger = getLogger("logger")
243 app.logger.setLevel(INFO)
244 app.logger.addHandler(logger)
gstepanov6f7167d2015-02-06 12:51:58 +0200245 app.run(host='0.0.0.0', debug=True)