blob: 19e0ce1a9a250e1c266af478bb1ac82fcbb690b1 [file] [log] [blame]
gstepanov9eb8bf32015-02-11 20:13:14 +02001import stat
gstepanov94531b82015-02-11 14:20:34 +02002from urlparse import urlparse
gstepanov2164d822015-02-04 19:49:40 +02003from flask import Flask, render_template, url_for, request, g
4from flask_bootstrap import Bootstrap
gstepanov725cc302015-02-09 15:08:06 +02005from config import TEST_PATH
gstepanov200d3b42015-02-06 14:01:49 +02006from report import build_vertical_bar, build_lines_chart
gstepanovbdc406b2015-02-11 17:35:55 +02007from storage_api import create_storage, Measurement
gstepanov81a52ee2015-02-10 16:22:20 +02008from logging import getLogger, INFO
9
10import json
11import os.path
gstepanov94531b82015-02-11 14:20:34 +020012from web_app.keystone import KeystoneAuth
gstepanov2164d822015-02-04 19:49:40 +020013
14app = Flask(__name__)
15Bootstrap(app)
16
17
18def collect_tests():
19 result = []
20
gstepanovc3ffac72015-02-05 15:39:45 +020021 for file in os.listdir(TEST_PATH):
gstepanov2164d822015-02-04 19:49:40 +020022 if file.endswith(".json"):
23 result.append(file.split('.')[0])
24
25 return result
26
27
gstepanovbdc406b2015-02-11 17:35:55 +020028def collect_builds():
29 builds = []
30 build_set = set()
31 tests = collect_tests()
32
33 for t in tests:
34 test = load_test(t)
35
36 for build in test:
37 if build["type"] not in build_set:
38 build_set.add(build["type"])
39 builds.append(build)
40
41 return builds
42
43
gstepanov2164d822015-02-04 19:49:40 +020044def load_test(test_name):
45 test_name += '.json'
46
gstepanov3501ad42015-02-05 15:41:39 +020047 with open(TEST_PATH + "/" + test_name, 'rt') as f:
gstepanov2164d822015-02-04 19:49:40 +020048 raw = f.read()
49
gstepanov0a8fdd32015-02-05 15:54:11 +020050 if raw != "":
51 test = json.loads(raw)
52 else:
53 test = []
gstepanov9eb8bf32015-02-11 20:13:14 +020054 import time
55 creation_time = os.path.getmtime(TEST_PATH + "/" + test_name)
56
57 for t in test:
58 t['date'] = time.ctime(creation_time)
gstepanov2164d822015-02-04 19:49:40 +020059
60 return test
61
62
gstepanov9eb8bf32015-02-11 20:13:14 +020063def builds_list():
gstepanov2164d822015-02-04 19:49:40 +020064 data = []
gstepanovbdc406b2015-02-11 17:35:55 +020065
66 for build in collect_builds():
gstepanov2164d822015-02-04 19:49:40 +020067 d = {}
gstepanovbdc406b2015-02-11 17:35:55 +020068 d["name"] = build['type']
69 d["url"] = url_for("render_test", test_name=build['type'])
gstepanov9eb8bf32015-02-11 20:13:14 +020070 d["date"] = build['date']
gstepanov2164d822015-02-04 19:49:40 +020071 data.append(d)
72
gstepanov9eb8bf32015-02-11 20:13:14 +020073 return data
74
75@app.route("/", methods=['GET', 'POST'])
76def index():
77 data = builds_list()
gstepanov2164d822015-02-04 19:49:40 +020078 return render_template("index.html", tests=data)
79
80
gstepanovbdc406b2015-02-11 17:35:55 +020081def create_measurement(build):
82 m = Measurement()
83 m.build = build.pop("build_id")
84 m.build_type = build.pop("type")
85 m.md5 = build.pop("iso_md5")
gstepanov9eb8bf32015-02-11 20:13:14 +020086 m.date = build.pop("date")
gstepanovbdc406b2015-02-11 17:35:55 +020087 m.results = {k: v for k, v in build.items()}
88
89 return m
90
91
gstepanove1ee9dc2015-02-11 18:09:46 +020092def total_lab_info(data):
93 d = {}
94 d['nodes_count'] = len(data['nodes'])
95 d['total_memory'] = 0
96 d['total_disk'] = 0
97 d['processor_count'] = 0
98
99 for node in data['nodes']:
100 d['total_memory'] += node['memory']['total']
101 d['processor_count'] += len(node['processors'])
102
103 for disk in node['disks']:
104 d['total_disk'] += disk['size']
105
gstepanov9eb8bf32015-02-11 20:13:14 +0200106 to_gb = lambda x: x / (1024 ** 3)
107 d['total_memory'] = format(to_gb(d['total_memory']), ',d')
108 d['total_disk'] = format(to_gb(d['total_disk']), ',d')
gstepanove1ee9dc2015-02-11 18:09:46 +0200109 return d
110
gstepanov9eb8bf32015-02-11 20:13:14 +0200111
gstepanov2164d822015-02-04 19:49:40 +0200112@app.route("/tests/<test_name>", methods=['GET'])
113def render_test(test_name):
gstepanov9eb8bf32015-02-11 20:13:14 +0200114 tests = []
115 header_keys = ['build_id', 'iso_md5', 'type', 'date']
gstepanov0a8fdd32015-02-05 15:54:11 +0200116 table = [[]]
gstepanovbdc406b2015-02-11 17:35:55 +0200117 builds_to_compare = ['GA', 'master', test_name]
118 builds = collect_builds()
119 results = {}
gstepanove1ee9dc2015-02-11 18:09:46 +0200120 meta = {"__meta__": "http://172.16.52.112:8000/api/nodes"}
121 data = collect_lab_data(meta)
122 lab_meta = total_lab_info(data)
gstepanovbdc406b2015-02-11 17:35:55 +0200123
124 for build in builds:
125 if build['type'] in builds_to_compare:
126 type = build['type']
127 m = create_measurement(build)
128 results[type] = m
129
gstepanov200d3b42015-02-06 14:01:49 +0200130 bars = build_vertical_bar(results)
131 lines = build_lines_chart(results)
132 urls = bars + lines
gstepanov2164d822015-02-04 19:49:40 +0200133 if len(tests) > 0:
134 sorted_keys = sorted(tests[0].keys())
135
gstepanov0a8fdd32015-02-05 15:54:11 +0200136 for key in sorted_keys:
137 if key not in header_keys:
138 header_keys.append(key)
gstepanov2164d822015-02-04 19:49:40 +0200139
gstepanov0a8fdd32015-02-05 15:54:11 +0200140 for test in tests:
141 row = []
gstepanov2164d822015-02-04 19:49:40 +0200142
gstepanov0a8fdd32015-02-05 15:54:11 +0200143 for header in header_keys:
144 if isinstance(test[header], list):
145 row.append(str(test[header][0]) + unichr(0x00B1) + str(test[header][1]))
146 else:
147 row.append(test[header])
gstepanov2164d822015-02-04 19:49:40 +0200148
gstepanov0a8fdd32015-02-05 15:54:11 +0200149 table.append(row)
gstepanov2164d822015-02-04 19:49:40 +0200150
gstepanov9eb8bf32015-02-11 20:13:14 +0200151 return render_template("test.html", urls=urls, table_url=url_for('render_table', test_name=test_name),
152 index_url=url_for('index'), lab_meta=lab_meta)
gstepanovcd77d5a2015-02-06 14:49:34 +0200153
154
gstepanove1ee9dc2015-02-11 18:09:46 +0200155def collect_lab_data(meta):
gstepanov94531b82015-02-11 14:20:34 +0200156 u = urlparse(meta['__meta__'])
157 cred = {"username": "admin", "password": "admin", "tenant_name": "admin"}
158 keystone = KeystoneAuth(root_url=meta['__meta__'], creds=cred, admin_node_ip=u.hostname)
159 lab_info = keystone.do(method='get', path="")
gstepanovbb854922015-02-09 18:18:17 +0200160 nodes = []
161 result = {}
162
163 for node in lab_info:
164 d = {}
165 d['name'] = node['name']
166 p = []
167 i = []
168 disks = []
169 devices = []
170
171 for processor in node['meta']['cpu']['spec']:
172 p.append(processor)
173
174 for iface in node['meta']['interfaces']:
175 i.append(iface)
176
177 m = node['meta']['memory'].copy()
178
179 for disk in node['meta']['disks']:
180 disks.append(disk)
181
182 d['memory'] = m
183 d['disks'] = disks
184 d['devices'] = devices
185 d['interfaces'] = i
186 d['processors'] = p
187
188 nodes.append(d)
189
190 result['nodes'] = nodes
191 result['name'] = 'Perf-1 Env'
192
193 return result
194
195
gstepanovcd77d5a2015-02-06 14:49:34 +0200196@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)