blob: 85f67ec903af630fde4438e01c16afa21e92ade2 [file] [log] [blame]
mbligh9bb92fe2007-09-12 15:54:23 +00001#!/usr/bin/python
mbligh2aaeb672007-10-01 14:54:18 +00002import os, re, db, sys
mbligh9bb92fe2007-09-12 15:54:23 +00003
mbligh2ba3e732008-01-16 01:30:19 +00004tko = os.path.dirname(os.path.realpath(os.path.abspath(__file__)))
5client_bin = os.path.abspath(os.path.join(tko, '../client/bin'))
6sys.path.insert(0, client_bin)
7import kernel_versions
8
mbligh2aaeb672007-10-01 14:54:18 +00009root_url_file = os.path.join(tko, '.root_url')
10if os.path.exists(root_url_file):
11 html_root = open(root_url_file, 'r').readline().rstrip()
12else:
mblighc959f4f2007-10-25 14:47:17 +000013 html_root = '/results/'
mbligh2aaeb672007-10-01 14:54:18 +000014
mbligh2e4e5df2007-11-05 17:22:46 +000015
mbligh2ba3e732008-01-16 01:30:19 +000016class status_cell:
17 # One cell in the matrix of status data.
18 def __init__(self):
19 # Count is a dictionary: status -> count of tests with status
20 self.status_count = {}
21 self.job_tag = None
22 self.job_tag_count = 0
mbligh2e4e5df2007-11-05 17:22:46 +000023
mbligh83f63a02007-12-12 19:13:04 +000024
mbligh2ba3e732008-01-16 01:30:19 +000025 def add(self, status, count, job_tags):
26 assert not self.status_count.has_key(status)
27 assert count > 0
28
29 self.job_tag = job_tags
30 self.job_tag_count += count
31 if self.job_tag_count > 1:
32 self.job_tag = None
33
34 self.status_count[status] = count
35
36
37class status_data:
38 def __init__(self, sql_rows, x_field, y_field):
39 data = {}
40 y_values = set()
41
42 # Walk through the query, filing all results by x, y info
43 for (x, y, status, count, job_tags) in sql_rows:
44 if not data.has_key(x):
45 data[x] = {}
46 if not data[x].has_key(y):
47 y_values.add(y)
48 data[x][y] = status_cell()
49 data[x][y].add(status, count, job_tags)
50
51 # 2-d hash of data - [x-value][y-value]
52 self.data = data
53 # List of possible columns (x-values)
54 self.x_values = smart_sort(data.keys(), x_field)
55 # List of rows columns (y-values)
56 self.y_values = smart_sort(list(y_values), y_field)
mbligh83f63a02007-12-12 19:13:04 +000057
58
59def get_matrix_data(db, x_axis, y_axis, where = None):
mbligh83f63a02007-12-12 19:13:04 +000060 # Searches on the test_view table - x_axis and y_axis must both be
61 # column names in that table.
mbligh2ba3e732008-01-16 01:30:19 +000062 x_field = test_view_field_dict[x_axis]
63 y_field = test_view_field_dict[y_axis]
64 fields = ('%s, %s, status, COUNT(status), ' +
65 'LEFT(GROUP_CONCAT(job_tag), 100)' # limit what's returned
66 ) % (x_field, y_field)
67 group_by = '%s, %s, status' % (x_field, y_field)
mbligh83f63a02007-12-12 19:13:04 +000068 rows = db.select(fields, 'test_view', where=where, group_by=group_by)
69
mbligh2ba3e732008-01-16 01:30:19 +000070 return status_data(rows, x_field, y_field)
mbligh83f63a02007-12-12 19:13:04 +000071
72
mbligh2ba3e732008-01-16 01:30:19 +000073# Dictionary used simply for fast lookups from short reference names for users
74# to fieldnames in test_view
75test_view_field_dict = {
76 'kernel' : 'kernel_printable',
77 'hostname' : 'machine_hostname',
78 'test' : 'test',
79 'label' : 'job_label',
80 'machine_group' : 'machine_group',
81 'reason' : 'reason',
82 'tag' : 'job_tag',
83 'user' : 'job_username',
84 'status' : 'status_word',
85}
mbligh2b672532007-11-05 19:24:51 +000086
mbligh2ba3e732008-01-16 01:30:19 +000087def smart_sort(list, field):
88 if field == 'kernel_printable':
89 def kernel_encode(kernel):
90 return kernel_versions.version_encode(kernel)
91 list.sort(key = kernel_encode, reverse = True)
92 else:
93 list.sort()
94 return list
mbligh2e4e5df2007-11-05 17:22:46 +000095
mbligh2aaeb672007-10-01 14:54:18 +000096
mblighcff2d212007-10-07 00:11:10 +000097class group:
98 @classmethod
99 def select(klass, db):
100 """Return all possible machine groups"""
101 rows = db.select('distinct machine_group', 'machines',
102 'machine_group is not null')
103 groupnames = sorted([row[0] for row in rows])
104 return [klass(db, groupname) for groupname in groupnames]
mbligh83f63a02007-12-12 19:13:04 +0000105
106
mblighcff2d212007-10-07 00:11:10 +0000107 def __init__(self, db, name):
108 self.name = name
109 self.db = db
110
111
112 def machines(self):
113 return machine.select(self.db, { 'machine_group' : self.name })
mbligh2e4e5df2007-11-05 17:22:46 +0000114
mblighcff2d212007-10-07 00:11:10 +0000115
116 def tests(self, where = {}):
117 values = [self.name]
118 sql = 't inner join machines m on m.machine_idx=t.machine_idx where m.machine_group=%s'
119 for key in where.keys():
120 sql += ' and %s=%%s' % key
121 values.append(where[key])
122 return test.select_sql(self.db, sql, values)
123
mbligh2e4e5df2007-11-05 17:22:46 +0000124
mbligh2aaeb672007-10-01 14:54:18 +0000125class machine:
126 @classmethod
127 def select(klass, db, where = {}):
128 fields = ['machine_idx', 'hostname', 'machine_group', 'owner']
129 machines = []
130 for row in db.select(','.join(fields), 'machines', where):
131 machines.append(klass(db, *row))
132 return machines
133
134
135 def __init__(self, db, idx, hostname, group, owner):
136 self.db = db
137 self.idx = idx
138 self.hostname = hostname
139 self.group = group
mblighf736b332007-12-18 20:56:51 +0000140 self.owner = owner
mbligh2e4e5df2007-11-05 17:22:46 +0000141
mbligh250300e2007-09-18 00:50:57 +0000142
mbligh9bb92fe2007-09-12 15:54:23 +0000143class kernel:
mbligh8e1ab172007-09-13 17:29:56 +0000144 @classmethod
145 def select(klass, db, where = {}):
146 fields = ['kernel_idx', 'kernel_hash', 'base', 'printable']
mbligh83f63a02007-12-12 19:13:04 +0000147 rows = db.select(','.join(fields), 'kernels', where)
148 return [klass(db, *row) for row in rows]
mbligh9bb92fe2007-09-12 15:54:23 +0000149
mbligh8e1ab172007-09-13 17:29:56 +0000150
151 def __init__(self, db, idx, hash, base, printable):
mbligh9bb92fe2007-09-12 15:54:23 +0000152 self.db = db
mbligh8e1ab172007-09-13 17:29:56 +0000153 self.idx = idx
mbligh9bb92fe2007-09-12 15:54:23 +0000154 self.hash = hash
mbligh8e1ab172007-09-13 17:29:56 +0000155 self.base = base
156 self.printable = printable
157 self.patches = [] # THIS SHOULD PULL IN PATCHES!
mbligh9bb92fe2007-09-12 15:54:23 +0000158
159
160class test:
mbligh8e1ab172007-09-13 17:29:56 +0000161 @classmethod
mbligh85952b42007-12-07 16:28:33 +0000162 def select(klass, db, where = {}, wherein = {}, distinct = False):
mbligh8e1ab172007-09-13 17:29:56 +0000163 fields = ['test_idx', 'job_idx', 'test', 'subdir',
mbligh2aaeb672007-10-01 14:54:18 +0000164 'kernel_idx', 'status', 'reason', 'machine_idx']
mbligh8e1ab172007-09-13 17:29:56 +0000165 tests = []
mbligh85952b42007-12-07 16:28:33 +0000166 for row in db.select(','.join(fields), 'tests', where, wherein,distinct):
mbligh8e1ab172007-09-13 17:29:56 +0000167 tests.append(klass(db, *row))
168 return tests
169
170
mbligh414c69e2007-10-05 15:13:06 +0000171 @classmethod
172 def select_sql(klass, db, sql, values):
173 fields = ['test_idx', 'job_idx', 'test', 'subdir',
174 'kernel_idx', 'status', 'reason', 'machine_idx']
175 fields = ['t.'+field for field in fields]
176 rows = db.select_sql(','.join(fields), 'tests', sql, values)
177 return [klass(db, *row) for row in rows]
178
179
mbligh2aaeb672007-10-01 14:54:18 +0000180 def __init__(self, db, test_idx, job_idx, testname, subdir, kernel_idx, status_num, reason, machine_idx):
mbligh8e1ab172007-09-13 17:29:56 +0000181 self.idx = test_idx
mbligh250300e2007-09-18 00:50:57 +0000182 self.job = job(db, job_idx)
mblighde7335d2007-09-26 16:53:20 +0000183 self.testname = testname
mbligh8e1ab172007-09-13 17:29:56 +0000184 self.subdir = subdir
mbligh50a25252007-09-27 15:26:17 +0000185 self.kernel_idx = kernel_idx
186 self.__kernel = None
187 self.__iterations = None
mbligh2aaeb672007-10-01 14:54:18 +0000188 self.machine_idx = machine_idx
189 self.__machine = None
mbligh8e1ab172007-09-13 17:29:56 +0000190 self.status_num = status_num
191 self.status_word = db.status_word[status_num]
mbligh9bb92fe2007-09-12 15:54:23 +0000192 self.reason = reason
mbligh50a25252007-09-27 15:26:17 +0000193 self.db = db
mblighde7335d2007-09-26 16:53:20 +0000194 if self.subdir:
195 self.url = html_root + self.job.tag + '/' + self.subdir
196 else:
mbligh676510c2007-09-28 01:28:12 +0000197 self.url = None
mbligh16ae9262007-09-21 00:53:08 +0000198
mbligh50a25252007-09-27 15:26:17 +0000199
mbligh50a25252007-09-27 15:26:17 +0000200 def iterations(self):
201 """
202 Caching function for iterations
203 """
204 if not self.__iterations:
205 self.__iterations = {}
206 # A dictionary - dict{key} = [value1, value2, ....]
207 where = {'test_idx' : self.idx}
208 for i in iteration.select(self.db, where):
209 if self.__iterations.has_key(i.key):
210 self.__iterations[i.key].append(i.value)
211 else:
212 self.__iterations[i.key] = [i.value]
213 return self.__iterations
214
215
216 def kernel(self):
217 """
218 Caching function for kernels
219 """
220 if not self.__kernel:
221 where = {'kernel_idx' : self.kernel_idx}
222 self.__kernel = kernel.select(self.db, where)[0]
223 return self.__kernel
224
mbligh250300e2007-09-18 00:50:57 +0000225
mbligh2aaeb672007-10-01 14:54:18 +0000226 def machine(self):
227 """
228 Caching function for kernels
229 """
230 if not self.__machine:
231 where = {'machine_idx' : self.machine_idx}
232 self.__machine = machine.select(self.db, where)[0]
233 return self.__machine
234
235
mbligh250300e2007-09-18 00:50:57 +0000236class job:
237 def __init__(self, db, job_idx):
238 where = {'job_idx' : job_idx}
mbligh2aaeb672007-10-01 14:54:18 +0000239 rows = db.select('tag, machine_idx', 'jobs', where)
mbligh250300e2007-09-18 00:50:57 +0000240 if not rows:
241 return None
mbligh2aaeb672007-10-01 14:54:18 +0000242 (self.tag, self.machine_idx) = rows[0]
mbligh2b672532007-11-05 19:24:51 +0000243 self.job_idx = job_idx
mbligh250300e2007-09-18 00:50:57 +0000244
mbligh8e1ab172007-09-13 17:29:56 +0000245
mbligh16ae9262007-09-21 00:53:08 +0000246class iteration:
247 @classmethod
248 def select(klass, db, where):
249 fields = ['iteration', 'attribute', 'value']
250 iterations = []
251 rows = db.select(','.join(fields), 'iteration_result', where)
252 for row in rows:
253 iterations.append(klass(*row))
254 return iterations
255
256
257 def __init__(self, iteration, key, value):
258 self.iteration = iteration
259 self.key = key
260 self.value = value
261
mbligh8e1ab172007-09-13 17:29:56 +0000262# class patch:
263# def __init__(self):
264# self.spec = None