blob: fb03f3e408ecbb020fe2c0c81145bbd1c7e616a6 [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
17def collect_tests():
18 result = []
19
gstepanovc3ffac72015-02-05 15:39:45 +020020 for file in os.listdir(TEST_PATH):
gstepanov2164d822015-02-04 19:49:40 +020021 if file.endswith(".json"):
22 result.append(file.split('.')[0])
23
24 return result
25
26
gstepanovbdc406b2015-02-11 17:35:55 +020027def collect_builds():
28 builds = []
29 build_set = set()
30 tests = collect_tests()
31
32 for t in tests:
33 test = load_test(t)
34
35 for build in test:
36 if build["type"] not in build_set:
37 build_set.add(build["type"])
38 builds.append(build)
39
40 return builds
41
42
gstepanov2164d822015-02-04 19:49:40 +020043def load_test(test_name):
44 test_name += '.json'
45
gstepanov3501ad42015-02-05 15:41:39 +020046 with open(TEST_PATH + "/" + test_name, 'rt') as f:
gstepanov2164d822015-02-04 19:49:40 +020047 raw = f.read()
48
gstepanov0a8fdd32015-02-05 15:54:11 +020049 if raw != "":
50 test = json.loads(raw)
51 else:
52 test = []
gstepanov2164d822015-02-04 19:49:40 +020053
54 return test
55
56
57@app.route("/", methods=['GET', 'POST'])
58def index():
59 data = []
gstepanovbdc406b2015-02-11 17:35:55 +020060
61 for build in collect_builds():
gstepanov2164d822015-02-04 19:49:40 +020062 d = {}
gstepanovbdc406b2015-02-11 17:35:55 +020063 d["name"] = build['type']
64 d["url"] = url_for("render_test", test_name=build['type'])
gstepanov2164d822015-02-04 19:49:40 +020065 data.append(d)
66
67 return render_template("index.html", tests=data)
68
69
gstepanovbdc406b2015-02-11 17:35:55 +020070def create_measurement(build):
71 m = Measurement()
72 m.build = build.pop("build_id")
73 m.build_type = build.pop("type")
74 m.md5 = build.pop("iso_md5")
75 m.results = {k: v for k, v in build.items()}
76
77 return m
78
79
gstepanov2164d822015-02-04 19:49:40 +020080@app.route("/tests/<test_name>", methods=['GET'])
81def render_test(test_name):
gstepanovbdc406b2015-02-11 17:35:55 +020082 tests = [] #load_test(test_name)
gstepanov2164d822015-02-04 19:49:40 +020083 header_keys = ['build_id', 'iso_md5', 'type']
gstepanov0a8fdd32015-02-05 15:54:11 +020084 table = [[]]
gstepanovbdc406b2015-02-11 17:35:55 +020085 builds_to_compare = ['GA', 'master', test_name]
86 builds = collect_builds()
87 results = {}
88
89 for build in builds:
90 if build['type'] in builds_to_compare:
91 type = build['type']
92 m = create_measurement(build)
93 results[type] = m
94
gstepanov200d3b42015-02-06 14:01:49 +020095 bars = build_vertical_bar(results)
96 lines = build_lines_chart(results)
97 urls = bars + lines
gstepanov2164d822015-02-04 19:49:40 +020098 if len(tests) > 0:
99 sorted_keys = sorted(tests[0].keys())
100
gstepanov0a8fdd32015-02-05 15:54:11 +0200101 for key in sorted_keys:
102 if key not in header_keys:
103 header_keys.append(key)
gstepanov2164d822015-02-04 19:49:40 +0200104
gstepanov0a8fdd32015-02-05 15:54:11 +0200105 for test in tests:
106 row = []
gstepanov2164d822015-02-04 19:49:40 +0200107
gstepanov0a8fdd32015-02-05 15:54:11 +0200108 for header in header_keys:
109 if isinstance(test[header], list):
110 row.append(str(test[header][0]) + unichr(0x00B1) + str(test[header][1]))
111 else:
112 row.append(test[header])
gstepanov2164d822015-02-04 19:49:40 +0200113
gstepanov0a8fdd32015-02-05 15:54:11 +0200114 table.append(row)
gstepanov2164d822015-02-04 19:49:40 +0200115
gstepanovcd77d5a2015-02-06 14:49:34 +0200116 return render_template("test.html", urls=urls, table_url=url_for('render_table', test_name=test_name))
117
118
gstepanovbb854922015-02-09 18:18:17 +0200119def collect_lab_data(tests, meta):
gstepanov94531b82015-02-11 14:20:34 +0200120 u = urlparse(meta['__meta__'])
121 cred = {"username": "admin", "password": "admin", "tenant_name": "admin"}
122 keystone = KeystoneAuth(root_url=meta['__meta__'], creds=cred, admin_node_ip=u.hostname)
123 lab_info = keystone.do(method='get', path="")
gstepanovbb854922015-02-09 18:18:17 +0200124 nodes = []
125 result = {}
126
127 for node in lab_info:
128 d = {}
129 d['name'] = node['name']
130 p = []
131 i = []
132 disks = []
133 devices = []
134
135 for processor in node['meta']['cpu']['spec']:
136 p.append(processor)
137
138 for iface in node['meta']['interfaces']:
139 i.append(iface)
140
141 m = node['meta']['memory'].copy()
142
143 for disk in node['meta']['disks']:
144 disks.append(disk)
145
146 d['memory'] = m
147 d['disks'] = disks
148 d['devices'] = devices
149 d['interfaces'] = i
150 d['processors'] = p
151
152 nodes.append(d)
153
154 result['nodes'] = nodes
155 result['name'] = 'Perf-1 Env'
156
157 return result
158
159
gstepanovcd77d5a2015-02-06 14:49:34 +0200160@app.route("/tests/table/<test_name>/")
161def render_table(test_name):
gstepanovbdc406b2015-02-11 17:35:55 +0200162 builds = collect_builds()
163 builds = filter(lambda x: x["type"] in ['GA', 'master', test_name], builds)
gstepanovcd77d5a2015-02-06 14:49:34 +0200164 header_keys = ['build_id', 'iso_md5', 'type']
165 table = [[]]
gstepanov94531b82015-02-11 14:20:34 +0200166 meta = {"__meta__": "http://172.16.52.112:8000/api/nodes"}
gstepanovbdc406b2015-02-11 17:35:55 +0200167 data = collect_lab_data(builds, meta)
168
169 if len(builds) > 0:
170 sorted_keys = sorted(builds[0].keys())
gstepanovcd77d5a2015-02-06 14:49:34 +0200171
172 for key in sorted_keys:
173 if key not in header_keys:
174 header_keys.append(key)
175
gstepanovbdc406b2015-02-11 17:35:55 +0200176 for test in builds:
gstepanovcd77d5a2015-02-06 14:49:34 +0200177 row = []
178
179 for header in header_keys:
180 if isinstance(test[header], list):
181 row.append(str(test[header][0]) + unichr(0x00B1) + str(test[header][1]))
182 else:
183 row.append(test[header])
184
185 table.append(row)
186
gstepanovbb854922015-02-09 18:18:17 +0200187 return render_template("table.html", headers=header_keys, table=table,
188 back_url=url_for('render_test', test_name=test_name), lab=data)
gstepanov2164d822015-02-04 19:49:40 +0200189
190
191@app.route("/tests/<test_name>", methods=['POST'])
192def add_test(test_name):
193 tests = json.loads(request.data)
194
195 if not hasattr(g, "storage"):
gstepanovf8f01c12015-02-09 18:34:01 +0200196 path = "file://" + TEST_PATH + '/' + test_name + ".json"
197 print path
198 g.storage = create_storage(path, "", "")
gstepanov2164d822015-02-04 19:49:40 +0200199
200 for test in tests:
201 g.storage.store(test)
202 return "Created", 201
203
204
gstepanov2164d822015-02-04 19:49:40 +0200205if __name__ == "__main__":
gstepanov81a52ee2015-02-10 16:22:20 +0200206 logger = getLogger("logger")
207 app.logger.setLevel(INFO)
208 app.logger.addHandler(logger)
gstepanov6f7167d2015-02-06 12:51:58 +0200209 app.run(host='0.0.0.0', debug=True)