summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtko/compose_query.cgi106
-rwxr-xr-xtko/frontend.py179
-rwxr-xr-xtko/group_test.cgi61
-rw-r--r--tko/index.html71
-rwxr-xr-xtko/machine_benchmark.cgi70
-rwxr-xr-xtko/machine_kernel.cgi59
-rwxr-xr-xtko/machine_kernel_test.cgi95
-rwxr-xr-xtko/machine_kernel_test_jobs.cgi130
-rw-r--r--tko/query_lib.py99
-rw-r--r--tko/report.py256
10 files changed, 106 insertions, 1020 deletions
diff --git a/tko/compose_query.cgi b/tko/compose_query.cgi
index e2862306..976dafef 100755
--- a/tko/compose_query.cgi
+++ b/tko/compose_query.cgi
@@ -53,19 +53,6 @@ html_header = """\
"""
-# dictionary used simply for fast lookups
-field_dict = {
- 'kernel': 'kernel_printable',
- 'hostname': 'machine_hostname',
- 'test': 'test',
- 'label': 'job_label',
- 'machine_group': 'machine_group',
- 'reason': 'reason',
- 'tag': 'job_tag',
- 'user': 'job_username',
- 'status': 'status_word',
-}
-
next_field = {
'machine_group': 'hostname',
'hostname': 'tag',
@@ -86,7 +73,7 @@ def parse_field(form, form_field, field_default):
if not form_field in form:
return field_default
field_input = form[form_field].value.lower()
- if field_input and field_input in field_dict:
+ if field_input and field_input in frontend.test_view_field_dict:
return field_input
return field_default
@@ -98,42 +85,26 @@ def parse_condition(form, form_field, field_default):
form = cgi.FieldStorage()
-row_field = parse_field(form, 'rows', 'kernel')
-column_field = parse_field(form, 'columns', 'machine_group')
+row = parse_field(form, 'rows', 'kernel')
+column = parse_field(form, 'columns', 'machine_group')
condition_field = parse_condition(form, 'condition', '')
cgitb.enable()
db = db.db()
-def get_value(test, field):
- if field == 'kernel':
- return test.kernel_printable
- if field == 'hostname':
- return test.machine_hostname
- if field == 'test':
- return test.testname
- if field == 'label':
- return test.job_label
- if field == 'machine_group':
- return test.machine_group
- if field == 'reason':
- return test.reason
- raise "Unknown field"
-
-
-def construct_link(row_val, column_val):
- next_row = row_field
- next_column = column_field
+def construct_link(x, y):
+ next_row = row
+ next_column = column
condition_list = []
if condition_field != '':
condition_list.append(condition_field)
- if row_val:
- next_row = next_field[row_field]
- condition_list.append("%s='%s'" % (row_field, row_val))
- if column_val:
- next_column = next_field[column_field]
- condition_list.append("%s='%s'" % (column_field, column_val))
+ if y:
+ next_row = next_field[row]
+ condition_list.append("%s='%s'" % (row, y))
+ if x:
+ next_column = next_field[column]
+ condition_list.append("%s='%s'" % (column, x))
next_condition = '&'.join(condition_list)
return 'compose_query.cgi?' + urllib.urlencode({'columns': next_column,
'rows': next_row, 'condition': next_condition})
@@ -142,69 +113,54 @@ def construct_link(row_val, column_val):
def create_select_options(selected_val):
ret = ""
- for option in sorted(field_dict.keys()):
+ for option in sorted(frontend.test_view_field_dict.keys()):
if selected_val == option:
selected = " SELECTED"
else:
selected = ""
- ret += '<OPTION VALUE="%s"%s>%s</OPTION>\n' % (option,
- selected,
- option)
+ ret += '<OPTION VALUE="%s"%s>%s</OPTION>\n' % \
+ (option, selected, option)
return ret
-def smart_sort(list, field):
- if field == 'kernel':
- def kernel_encode(kernel):
- return kernel_versions.version_encode(kernel)
- list.sort(key = kernel_encode, reverse = True)
- else:
- list.sort()
-
-
def gen_matrix():
where = None
if condition_field.strip() != '':
where = query_lib.parse_scrub_and_gen_condition(
- condition_field, field_dict)
+ condition_field, frontend.test_view_field_dict)
print "<!-- where clause: %s -->" % (where,)
- ret = frontend.get_matrix_data(db, field_dict[column_field],
- field_dict[row_field], where)
- (data, column_list, row_list, stat_list, job_tags) = ret
+ test_data = frontend.get_matrix_data(db, column, row, where)
- if not row_list:
+ if not test_data.y_values:
msg = "There are no results for this query (yet?)."
return [[display.box(msg)]]
- smart_sort(row_list, row_field)
- smart_sort(column_list, column_field)
-
link = 'compose_query.cgi?columns=%s&rows=%s&condition=%s' % (
- row_field, column_field, condition_field)
+ row, column, condition_field)
header_row = [display.box("<center>(Flip Axis)</center>", link=link)]
- for column in column_list:
- link = construct_link(None, column)
- header_row.append(display.box(column, header=True, link=link))
+ for x in test_data.x_values:
+ link = construct_link(x, None)
+ header_row.append(display.box(x, header=True, link=link))
matrix = [header_row]
- for row in row_list:
- link = construct_link(row, None)
- cur_row = [display.box(row, header=True, link=link)]
- for column in column_list:
+ for y in test_data.y_values:
+ link = construct_link(None, y)
+ cur_row = [display.box(y, header=True, link=link)]
+ for x in test_data.x_values:
try:
- box_data = data[column][row]
+ box_data = test_data.data[x][y].status_count
except:
cur_row.append(display.box(None, None))
continue
- job_tag = job_tags[column][row]
+ job_tag = test_data.data[x][y].job_tag
if job_tag:
link = '/results/%s/' % job_tag
else:
- link = construct_link(row, column)
+ link = construct_link(x, y)
cur_row.append(display.status_precounted_box(db,
box_data,
link))
@@ -219,8 +175,8 @@ def main():
print 'Filtered Autotest Results'
print '</title></head><body>'
display.print_main_header()
- print html_header % (create_select_options(column_field),
- create_select_options(row_field),
+ print html_header % (create_select_options(column),
+ create_select_options(row),
condition_field)
display.print_table(gen_matrix())
print '</body></html>'
diff --git a/tko/frontend.py b/tko/frontend.py
index 5f431f35..85f67ec9 100755
--- a/tko/frontend.py
+++ b/tko/frontend.py
@@ -1,125 +1,97 @@
#!/usr/bin/python
import os, re, db, sys
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
+tko = os.path.dirname(os.path.realpath(os.path.abspath(__file__)))
+client_bin = os.path.abspath(os.path.join(tko, '../client/bin'))
+sys.path.insert(0, client_bin)
+import kernel_versions
+
root_url_file = os.path.join(tko, '.root_url')
if os.path.exists(root_url_file):
html_root = open(root_url_file, 'r').readline().rstrip()
else:
html_root = '/results/'
-def select(db, field, value=None, distinct=False):
- """ returns the relevant index values where the field value matches the
- input value to the function.
- If there is no value passed, then it returns the index values and the
- field values corresponsing to them. """
-
- fields = { 'kernel': ['printable', 'kernel_idx', 'kernel_idx'],
- 'machine_group': ['machine_group', 'machine_idx', 'machine_idx'],
- 'hostname': ['hostname', 'machine_idx', 'machine_idx'],
- 'label': ['label', 'job_idx', 'job_idx'],
- 'tag': ['tag', 'job_idx', 'job_idx'],
- 'job': ['job_idx', 'job_idx', 'job_idx'],
- 'user': ['username', 'job_idx', 'job_idx'],
- 'test': ['test', 'test', 'test'],
- 'status': ['word', 'status_idx', 'status'],
- 'reason': ['reason', 'test_idx', 'test_idx'] }
- table = { 'kernel': 'kernels',
- 'machine_group': 'machines',
- 'hostname': 'machines',
- 'label': 'jobs',
- 'tag': 'jobs',
- 'job': 'jobs',
- 'user': 'jobs',
- 'test': 'tests',
- 'status': 'status',
- 'reason': 'tests' }
-
- lookup_field, idx_field, field_name_in_main_table = fields[field]
- tablename = table[field]
- # select all the index values that match the given field name.
- sql = ""
- if distinct:
- sql += " distinct "
- if not value:
- sql += " %s , %s " % (lookup_field, idx_field)
- where = " %s is not null " % lookup_field
- else:
- sql += "%s " % idx_field
- if field == 'tag':
- where = " %s LIKE %s " % (lookup_field, value)
- else:
- where = " %s = %s " % (lookup_field, value)
- match = db.select(sql, tablename, where)
- # returns the value and its field name
- return match, field_name_in_main_table
+class status_cell:
+ # One cell in the matrix of status data.
+ def __init__(self):
+ # Count is a dictionary: status -> count of tests with status
+ self.status_count = {}
+ self.job_tag = None
+ self.job_tag_count = 0
+
+
+ def add(self, status, count, job_tags):
+ assert not self.status_count.has_key(status)
+ assert count > 0
+
+ self.job_tag = job_tags
+ self.job_tag_count += count
+ if self.job_tag_count > 1:
+ self.job_tag = None
+
+ self.status_count[status] = count
+
+class status_data:
+ def __init__(self, sql_rows, x_field, y_field):
+ data = {}
+ y_values = set()
-def get_axis_data(axis):
- rows = db.select(axis , 'test_view', distinct = True)
- # Need to do a magic sort here if axis == 'kernel_printable'
- return sorted([row[0] for row in rows])
+ # Walk through the query, filing all results by x, y info
+ for (x, y, status, count, job_tags) in sql_rows:
+ if not data.has_key(x):
+ data[x] = {}
+ if not data[x].has_key(y):
+ y_values.add(y)
+ data[x][y] = status_cell()
+ data[x][y].add(status, count, job_tags)
+
+ # 2-d hash of data - [x-value][y-value]
+ self.data = data
+ # List of possible columns (x-values)
+ self.x_values = smart_sort(data.keys(), x_field)
+ # List of rows columns (y-values)
+ self.y_values = smart_sort(list(y_values), y_field)
def get_matrix_data(db, x_axis, y_axis, where = None):
- # Return a 3-d hash of data - [x-value][y-value][status_word]
# Searches on the test_view table - x_axis and y_axis must both be
# column names in that table.
- fields = ('%s, %s, status, COUNT(status_word), ' +
- 'LEFT(GROUP_CONCAT(job_tag), 100)' # limit what's returned
- ) % (x_axis, y_axis)
- group_by = '%s, %s, status' % (x_axis, y_axis)
+ x_field = test_view_field_dict[x_axis]
+ y_field = test_view_field_dict[y_axis]
+ fields = ('%s, %s, status, COUNT(status), ' +
+ 'LEFT(GROUP_CONCAT(job_tag), 100)' # limit what's returned
+ ) % (x_field, y_field)
+ group_by = '%s, %s, status' % (x_field, y_field)
rows = db.select(fields, 'test_view', where=where, group_by=group_by)
- data = {}
- job_tags = {}
- x_set = set()
- y_set = set()
- status_set = set()
- for (x, y, status, count, job_tag) in rows:
- if not data.has_key(x):
- data[x] = {}
- job_tags[x] = {}
- if not data[x].has_key(y):
- data[x][y] = {}
- data[x][y][status] = count
- if job_tags[x].has_key(y) or count != 1:
- job_tags[x][y] = None
- else:
- job_tags[x][y] = job_tag
- x_set.add(x)
- y_set.add(y)
- status_set.add(status)
- return (data, list(x_set), list(y_set), list(status_set), job_tags)
-
-
-class anygroup:
- @classmethod
- def selectunique(klass, db, field):
- """Return unique values for all possible groups within
- the table."""
- rows, field_name_in_main_table = select(db, field, value=None, distinct=True)
- groupnames = sorted([row for row in rows])
-
- # collapse duplicates where records have the same name but
- # multiple index values
- headers = {}
- for field_name, idx_value in groupnames:
- if headers.has_key(field_name):
- headers[field_name].append(idx_value)
- else:
- headers[field_name] = [idx_value]
- headers = headers.items()
- headers.sort()
- return [klass(db, field_name_in_main_table, groupname) for groupname in headers]
-
-
- def __init__(self, db, idx_name, name):
- self.db = db
- self.name = name[0]
- self.idx_name = idx_name
- self.idx_value = name[1]
+ return status_data(rows, x_field, y_field)
+
+
+# Dictionary used simply for fast lookups from short reference names for users
+# to fieldnames in test_view
+test_view_field_dict = {
+ 'kernel' : 'kernel_printable',
+ 'hostname' : 'machine_hostname',
+ 'test' : 'test',
+ 'label' : 'job_label',
+ 'machine_group' : 'machine_group',
+ 'reason' : 'reason',
+ 'tag' : 'job_tag',
+ 'user' : 'job_username',
+ 'status' : 'status_word',
+}
+
+def smart_sort(list, field):
+ if field == 'kernel_printable':
+ def kernel_encode(kernel):
+ return kernel_versions.version_encode(kernel)
+ list.sort(key = kernel_encode, reverse = True)
+ else:
+ list.sort()
+ return list
class group:
@@ -225,7 +197,6 @@ class test:
self.url = None
-
def iterations(self):
"""
Caching function for iterations
diff --git a/tko/group_test.cgi b/tko/group_test.cgi
index 82e311b6..e69de29b 100755
--- a/tko/group_test.cgi
+++ b/tko/group_test.cgi
@@ -1,61 +0,0 @@
-#!/usr/bin/python
-print "Content-type: text/html\n"
-import cgi, cgitb, os, sys, re
-sys.stdout.flush()
-cgitb.enable()
-
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
-sys.path.insert(0, tko)
-import db, display, frontend
-
-db = db.db()
-
-def main():
- display.print_main_header()
-
- form = cgi.FieldStorage()
- kernel_idx = form["kernel"].value
- kernel = frontend.kernel.select(db, {'kernel_idx' : kernel_idx })[0]
- groups = frontend.group.select(db)
-
- print_kernel_groups_vs_tests(kernel, groups)
-
-
-def print_kernel_groups_vs_tests(kernel, groups):
- # first we have to get a list of all run tests across all machines
- all_tests = set()
- present_groups = []
- for group in groups:
- tests = group.tests({ 'kernel_idx' : kernel.idx })
- if tests:
- present_groups.append(group)
- for test in tests:
- all_tests.add(test.testname)
- all_tests = list(all_tests)
- all_tests.sort()
-
- print '<h1>%s</h1>' % kernel.printable
-
- header_row = [ display.box('Test', header=True) ]
- for group in present_groups:
- group_name = display.group_name(group)
- header_row.append( display.box(group_name, header=True) )
-
- matrix = [header_row]
- for testname in all_tests:
- shortname = re.sub(r'kernel.', r'kernel<br>', testname)
- row = [display.box(shortname)]
- for group in present_groups:
- tests = group.tests({ 'kernel_idx' : kernel.idx ,
- 'test' : testname })
- link = 'machine_kernel_test.cgi?'
- link += 'group=%s&kernel=%s&test=%s' % \
- (group.name, kernel.idx, testname)
- box = display.status_count_box(db, tests, link=link)
- row.append(box)
- matrix.append(row)
- matrix.append(header_row)
-
- display.print_table(matrix)
-
-main()
diff --git a/tko/index.html b/tko/index.html
index 8afb8439..e69de29b 100644
--- a/tko/index.html
+++ b/tko/index.html
@@ -1,71 +0,0 @@
-<html>
-<head>
-</head>
-<body>
-<table border="0">
- <form action="compose_query.cgi" method="get">
-<tr>
- <td>Column: </td>
- <td>
- <SELECT NAME="columns">
- <OPTION VALUE="kernel">kernel
- <OPTION VALUE="hostname">hostname
- <OPTION VALUE="test">test
- <OPTION VALUE="label">label
- <OPTION VALUE="machine_group">machine_group
- <OPTION VALUE="reason">reason
- <OPTION VALUE="tag">tag
- <OPTION VALUE="user">user
- <OPTION VALUE="status">status
- </SELECT>
- </td>
-</tr>
-<tr>
- <td>Row: </td>
- <td>
- <SELECT NAME="rows">
- <OPTION VALUE="kernel">kernel
- <OPTION VALUE="hostname">hostname
- <OPTION VALUE="test" SELECTED>test
- <OPTION VALUE="label">label
- <OPTION VALUE="machine_group">machine_group
- <OPTION VALUE="reason">reason
- <OPTION VALUE="tag">tag
- <OPTION VALUE="user">user
- <OPTION VALUE="status">status
- </SELECT>
- </td>
-</tr>
-<tr>
- <td>Condition: </td>
- <td>
- <input type="text" name="condition" size="80" maxlength="80"><br />
- <input type="hidden" name="title" value="Report">
- </td>
-</tr>
-<tr>
- <td colspan="100%" align="center"><input type="submit" value="Submit">
- </td>
-</tr>
-<tr>
- <td colspan="100%">
-<p>
-Conditions of the form &lt;column&gt;=&lt;value&gt; &amp; &lt;column&gt;=&lt;value&gt; &amp; ... &amp; &lt;column&gt;=&lt;value&gt;
-</p>
-<p>
-Textual values must be quoted.
-</p>
-<p>
-<div>Examples:</div>
-<ul>
-<li>user='johnmacdonald' & test='burnin'</li>
-<li>hostname='bdpk1' & user='yinghan'</li>
-<li>tag~'134-jorlow%' to search for job '134-jorlow'</li>
-</ul>
-</p>
- </td>
-</tr>
-</form>
-</table>
-</body>
-</html>
diff --git a/tko/machine_benchmark.cgi b/tko/machine_benchmark.cgi
index d0b1aef0..e69de29b 100755
--- a/tko/machine_benchmark.cgi
+++ b/tko/machine_benchmark.cgi
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-print "Content-type: text/html\n"
-import cgi, cgitb, os, sys, re
-sys.stdout.flush()
-cgitb.enable()
-
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
-sys.path.insert(0, tko)
-import db, display, frontend
-
-db = db.db()
-
-benchmark_key = {
-'kernbench' : 'elapsed',
-'dbench' : 'throughput',
-'tbench' : 'throughput',
-}
-
-def main():
-
- display.print_main_header()
-
- rows = db.select('test', 'tests', {}, distinct = True)
- benchmarks = []
- for row in rows:
- benchmark = row[0]
- testname = re.sub(r'\..*', '', benchmark)
- if not benchmark_key.has_key(testname):
- continue
- benchmarks.append(benchmark)
- benchmarks = display.sort_tests(benchmarks)
-
- machine_idx = {}
- benchmark_data = {}
- for benchmark in benchmarks:
- fields = 'machine_idx,machine_hostname,count(status_word)'
- where = { 'subdir': benchmark, 'status_word' : 'GOOD' }
- data = {}
- for (idx, machine, count) in db.select(fields, 'test_view',
- where, group_by = 'machine_hostname'):
- data[machine] = count
- machine_idx[machine] = idx
- benchmark_data[benchmark] = data
-
- print '<h1>Performance</h1>'
-
- header_row = [ display.box('Benchmark', header=True) ]
- header_row += [ display.box(re.sub(r'\.', '<br>', benchmark), header=True) for benchmark in benchmarks ]
-
- matrix = [header_row]
- for machine in machine_idx:
- row = [display.box(machine)]
- for benchmark in benchmarks:
- count = benchmark_data[benchmark].get(machine, None)
- if not count:
- row.append(display.box(None))
- continue
- key = benchmark_key[re.sub(r'\..*', '', benchmark)]
- url = 'machine_test_attribute_graph.cgi'
- url += '?machine=' + str(machine_idx[machine])
- url += '&benchmark=' + benchmark
- url += '&key=' + key
- html = '<a href="%s">%d</a>' % (url, count)
- row.append(display.box(html))
- matrix.append(row)
- matrix.append(header_row)
-
- display.print_table(matrix)
-
-main()
diff --git a/tko/machine_kernel.cgi b/tko/machine_kernel.cgi
index dbd52bb3..e69de29b 100755
--- a/tko/machine_kernel.cgi
+++ b/tko/machine_kernel.cgi
@@ -1,59 +0,0 @@
-#!/usr/bin/python
-print "Content-type: text/html\n"
-import cgi, cgitb, os, sys, re
-sys.stdout.flush()
-cgitb.enable()
-
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
-sys.path.insert(0, tko)
-import db, frontend, display
-client_bin = os.path.abspath(os.path.join(tko, '../client/bin'))
-sys.path.insert(0, client_bin)
-import kernel_versions
-
-db = db.db()
-
-
-def kernel_group_box(kernel, group, box_data):
- machine_idxs = ['%d' % machine.idx for machine in group.machines()]
- link = 'machine_kernel_test.cgi?machine=%s&kernel=%s' % \
- (','.join(machine_idxs), kernel.idx)
- return display.status_precounted_box(db, box_data, link)
-
-
-def kernel_encode(kernel):
- return kernel_versions.version_encode(kernel.printable)
-
-
-def main():
- display.print_main_header()
-
- ret = frontend.get_matrix_data(db, 'machine_group', 'kernel_printable')
- (data, group_list, kernel_list, status_list, job_tags) = ret
-
- groups = frontend.group.select(db)
- group_names = [display.group_name(g) for g in groups]
- headers = ['Version'] + group_names
- header_row = [ display.box(x, header=True) for x in headers ]
-
- kernels = frontend.kernel.select(db)
- kernels.sort(key = kernel_encode, reverse = True)
-
- matrix = [header_row]
- for kernel in kernels:
- link = 'group_test.cgi?kernel=%s' % kernel.idx
- row = [display.box(kernel.printable, link=link)]
- for group in groups:
- try:
- box_data = data[group.name][kernel.printable]
- except:
- row.append(display.box(None, None))
- continue
- row.append(kernel_group_box(kernel, group, box_data))
- matrix.append(row)
- matrix.append(header_row)
-
- display.print_table(matrix)
-
-
-main()
diff --git a/tko/machine_kernel_test.cgi b/tko/machine_kernel_test.cgi
index 25f6a38e..e69de29b 100755
--- a/tko/machine_kernel_test.cgi
+++ b/tko/machine_kernel_test.cgi
@@ -1,95 +0,0 @@
-#!/usr/bin/python
-print "Content-type: text/html\n"
-import cgi, cgitb, os, sys, re
-sys.stdout.flush()
-cgitb.enable()
-
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
-sys.path.insert(0, tko)
-import db, display, frontend
-
-db = db.db()
-
-def main():
- display.print_main_header()
-
- form = cgi.FieldStorage()
-
- kernel_idx = form['kernel'].value
-
- if form.has_key('machine'):
- mlist = form['machine'].value
- machines = []
- for idx in mlist.split(','):
- where = { 'machine_idx' : idx }
- machines.append(frontend.machine.select(db, where)[0])
- elif form.has_key('group'):
- where = { 'machine_group' : form['group'].value }
- machines = frontend.machine.select(db, where)
- mlist = ','.join(['%s'%machine.idx for machine in machines])
- if form.has_key('test'):
- test = form['test'].value
- else:
- test = None
-
- kernel = frontend.kernel.select(db, {'kernel_idx' : kernel_idx })[0]
- print_kernel_machines_vs_test(machines, kernel, test, mlist)
-
-
-def print_kernel_machines_vs_test(machines, kernel, only_test, mlist):
- # first we have to get a list of all run tests across all machines
- all_tests = []
- results = {} # will be a 2d hash [machine][testname]
- for machine in machines:
- where = { 'kernel_idx':kernel.idx , 'machine_idx':machine.idx }
- if only_test:
- where['subdir'] = only_test
- tests = frontend.test.select(db, where)
- if not tests:
- continue
- dict = {}
- for test in tests:
- testname = test.testname
- all_tests.append(testname)
- dict[testname] = dict.get(testname, []) + [test]
- results[machine.idx] = dict
- test_list = display.sort_tests(list(set(all_tests)))
-
- print '<h1>%s</h1>' % kernel.printable
-
- header_row = [ display.box('Version', header=True) ]
- for test in [re.sub(r'kernel.', r'kernel<br>', x) for x in test_list]:
- url='machine_kernel_test_jobs.cgi?machine=%s&kernel=%s&test=%s'\
- % (mlist, kernel.idx, test)
- header_row.append( display.box(test, link=url, header=True) )
-
- matrix = [header_row]
- for machine in machines:
- if not results.has_key(machine.idx):
- continue
- if machine.owner:
- hostname = machine.owner + ' ' + machine.hostname
- else:
- hostname = machine.hostname
- url = 'machine_kernel_test_jobs.cgi?machine=%s&kernel=%s' % \
- (machine.idx, kernel.idx)
- row = [display.box(hostname, link = url)]
- for testname in test_list:
- if results[machine.idx].has_key(testname):
- tests = results[machine.idx][testname]
- if len(tests) == 1:
- link = tests[0].url
- else:
- link = 'machine_kernel_test_jobs.cgi?machine=%s&kernel=%s&test=%s' % (machine.idx, kernel.idx, testname)
- else:
- tests = []
- link = None
-
- box = display.status_count_box(db, tests, link = link)
- row.append(box)
- matrix.append(row)
- matrix.append(header_row)
-
- display.print_table(matrix)
-
-main()
diff --git a/tko/machine_kernel_test_jobs.cgi b/tko/machine_kernel_test_jobs.cgi
index a8a16252..e69de29b 100755
--- a/tko/machine_kernel_test_jobs.cgi
+++ b/tko/machine_kernel_test_jobs.cgi
@@ -1,130 +0,0 @@
-#!/usr/bin/python
-print "Content-type: text/html\n"
-import cgi, cgitb, os, sys, re
-sys.stdout.flush()
-cgitb.enable()
-
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
-sys.path.insert(0, tko)
-import db, display, frontend
-
-db = db.db()
-
-def main():
- display.print_main_header()
- form = cgi.FieldStorage()
-
- kernel_idx = form['kernel'].value
- kernel = frontend.kernel.select(db, {'kernel_idx' : kernel_idx })[0]
-
- if form.has_key('machine'):
- machines = []
- for idx in form['machine'].value.split(','):
- where = { 'machine_idx' : idx }
- machines.append(frontend.machine.select(db, where)[0])
- elif form.has_key('group'):
- where = { 'machine_group' : form['group'].value }
- machines = frontend.machine.select(db, where)
-
- if form.has_key('test'):
- test = form['test'].value
- else:
- test = None
-
- if len(machines) == 1:
- print_jobs_vs_tests(machines[0], kernel, test)
- else:
- print_jobs_vs_machines(machines, kernel, test)
-
-
-def print_jobs_vs_tests(machine, kernel, only_test):
- # first we have to get a list of all run tests
- results = {} # will be a 2d hash on [testname][jobname]
- all_tests = set([])
- all_jobs = set([])
- where = { 'kernel_idx':kernel.idx , 'machine_idx':machine.idx }
- if only_test:
- where['subdir'] = only_test
- tests = frontend.test.select(db, where)
- for test in tests:
- all_tests.add(test.testname)
- all_jobs.add(test.job.tag)
- if not results.has_key(test.testname):
- results[test.testname] = {}
- results[test.testname][test.job.tag] = test
- test_list = sorted(list(all_tests))
- job_list = sorted(list(all_jobs))
-
- print '<h1>Kernel: %s</h1>\n' % kernel.printable
- print '<h1>Machine: %s</h1>\n' % machine.hostname
-
- header_row = [ display.box('Job', header=True) ]
- for jobname in job_list:
- header_row.append( display.box(jobname, header=True) )
-
- matrix = [header_row]
- for testname in test_list:
- if not results.has_key(testname):
- continue
- row = [display.box(testname)]
- for jobname in job_list:
- test = results[testname].get(jobname, None)
- if test:
- box = display.box(test.status_word,
- color_key = test.status_word,
- link = test.url)
- else:
- box = display.box(None)
- row.append(box)
- matrix.append(row)
- matrix.append(header_row)
-
- display.print_table(matrix)
-
-
-def print_jobs_vs_machines(machines, kernel, only_test):
- if not only_test:
- raise "No test specified!"
- results = {} # will be a 2d hash [machine][jobname]
- all_jobs = set([])
- for machine in machines:
- where = { 'kernel_idx':kernel.idx , 'machine_idx':machine.idx,
- 'subdir':only_test }
- tests = frontend.test.select(db, where)
- if tests:
- results[machine] = {}
- for test in tests:
- results[machine][test.job.tag] = test
- all_jobs.add(test.job.tag)
- results[machine.idx] = tests
- job_list = sorted(list(all_jobs))
-
- print '<h1>Kernel: %s</h1>\n' % kernel.printable
- print '<h1>Test: %s</h1>\n' % only_test
-
- header_row = [ display.box('Machine', header=True) ]
- for jobname in job_list:
- header_row.append( display.box(jobname, header=True) )
-
- matrix = [header_row]
- for machine in machines:
- if not results.has_key(machine):
- continue
- tests = results[machine]
- row = [display.box(machine.hostname)]
- for jobname in job_list:
- test = results[machine].get(jobname, None)
- if test:
- box = display.box(test.status_word,
- color_key = test.status_word,
- link = test.url)
- else:
- box = display.box(None)
- row.append(box)
- matrix.append(row)
- matrix.append(header_row)
-
- display.print_table(matrix)
-
-
-main()
diff --git a/tko/query_lib.py b/tko/query_lib.py
index e20a6671..9f492b9d 100644
--- a/tko/query_lib.py
+++ b/tko/query_lib.py
@@ -88,102 +88,3 @@ def parse_scrub_and_gen_condition(condition, valid_field_dict):
raise "Could not parse '%s' (%s)" % (condition, regex)
-
-###
-### Everything past here is depricated.
-###
-
-def generate_sql_condition(condition_list):
- """ generate the sql for the condition list."""
- sql = ''
- value = []
- for field, operator, values in condition_list:
- if len(values) == 1:
- if sql != '':
- sql += " and "
- sql += " %s%s%%s" % (field, operator)
- value.append(values[0][0])
- elif len(values) > 1:
- expression = [" %s %s %%s" % (field, operator) for val in values]
- for val in values:
- value.append(val[0])
- if sql != '':
- sql += " and "
- sql += "(%s)" % " or ".join(expression)
- return sql, value
-
-
-def prune_list(thelist, condition_sql, condition_value):
- """ keep track of which columns do not have any elements."""
- pruned_list = []
- for g in thelist:
- # check for multiple index values in the db.
- sql = "t where "
- expr = [" %s = %%s" % (g.idx_name) for val in g.idx_value]
- sql += " (%s) " % " or ".join(expr)
- value = []
- value.extend(g.idx_value)
- if condition_sql:
- sql += " and "
- sql += condition_sql
- value.extend(condition_value)
- tests = frontend.test.select_sql(db, sql, value)
- if len(tests) > 0:
- pruned_list.append(g)
- return pruned_list
-
-
-def parse_condition(condition):
- """ parse the condition into independent clauses."""
- condition_list = []
- if not condition:
- return condition_list
- attribute_re = r"(\w+)"
- op_re = r"(=|!=)"
- value_re = r"('[^']*')"
- # condition is clause & clause & ..
- clause_re = r"%s\s*%s\s*%s" % (attribute_re, op_re, value_re)
- condition_re = re.compile(r"^\s*%s(\s*&\s*%s)*\s*$" % (clause_re, clause_re))
- if not condition_re.match(condition):
- print "Condition not in the correct format: %s" % condition
- sys.exit(0)
- triples = []
- for clause in [c.strip() for c in condition.split('&')]:
- attribute, op, value = re.match(clause_re, clause).groups()
- triples.append((attribute, op, value))
- for (field_name, operator, value) in triples:
- match, field = frontend.select(db, field_name, value, distinct=True)
- if len(match) > 0:
- condition_list.append((field, operator, match))
- else:
- print "No matching results found for condition %s." % \
- condition
- sys.exit(0)
- return condition_list
-
-
-def get_value(test, field):
- """ get specific field values from the given test object."""
- if field == 'test':
- return test.testname
- elif field == 'kernel_idx':
- return test.kernel_idx
- elif field == 'machine_idx':
- return test.machine_idx
- elif field == 'status':
- return test.status_num
-
-
-def get_tests(condition_sql, condition_value):
- # get all the tests that satify the given condition.
- if condition_sql:
- sql = "t where "
- sql += condition_sql
- value = [str(val) for val in condition_value]
- #print sql , value
- tests = frontend.test.select_sql(db, sql, value)
- else:
- sql = None
- value = None
- tests = frontend.test.select_sql(db, " t ", None)
- return tests
diff --git a/tko/report.py b/tko/report.py
index bd4921f2..e69de29b 100644
--- a/tko/report.py
+++ b/tko/report.py
@@ -1,256 +0,0 @@
-#!/usr/bin/python
-
-"""
-CLI support to enable user to query the database.
-"""
-
-import sys, os, getopt
-
-tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
-sys.path.insert(0, tko)
-
-import query_lib, db, frontend
-
-db = db.db()
-
-help_msg_header = """
-NAME
-report.py - Print the results matching a given condition in the specified format.
-
-SYNOPSIS
-report.py [options]
-
-OPTIONS
-"""
-
-help_msg_trailer = """
-EXAMPLES
-To see every job that has ever been run:
- report.py
-
-To see all the jobs started by johnmacdonald:
- report.py --condition="user='johnmacdonald'"
-
-To see all the jobs started by johnmandonald and on hostname arh22:
- report.py --condition="user='johnmacdonald' & hostname='arh22'"
-
-To see only the test, hostname and user for the reports:
- report.py --columns="test, hostname, user"
-
-You can use both the columns and condition options to generate the kind of report you want.
-"""
-
-condition_desc = """Condition to filter the results with.
- Supported fields are: test, hostname, user, label, machine_group, status, reason, kernel.
- Supported operators are =, != and string values must be quoted within single quotes.
-"""
-
-columns_desc = """Specific columns to display in the results.
- Supported fields are: test, hostname, user, label, machine_group, status, reason, kernel.
-"""
-
-help_desc = """Print command help.
-"""
-
-
-class CliError(Exception):
- pass
-
-
-class InvalidArgsError(CliError):
- def __init__(self, error):
- CliError.__init__(self, 'Unknown arguments: %r\nTry report.py --help' % error)
-
-
-class InvalidColumnValue(CliError):
- def __init__(self, error):
- CliError.__init__(self, 'Unrecognized column value: %r\nTry report.py --help' % error)
-
-
-class cli:
- def __init__(self):
- self.__options = {}
-
-
- def add_option(self, name=None, short_name=None, type=None,
- description=None, value=None):
- """ Adds the options to the cli.
- """
- if not name and not short_name:
- raise Error("No name provided for the option.")
-
- short = False
-
- if not name and short_name:
- short = True
- name = short_name
-
- self.__options[name] = dict(name=name, type=type,
- description=description,
- value=value, short=short)
-
-
- def list_options(self):
- """ Return the options for this cli.
- """
- return self.__options
-
-
- def parse_options(self, args):
- """ Parse the options and the values the cli is invoked with.
- """
- short_opts = ""
- long_opts = []
- for name,val in self.__options.items():
- if val['short']:
- short_opts += val['name']
- if val['type'] != 'bool':
- short_opts += ':'
- else:
- opt = val['name']
- if val['type'] != 'bool':
- opt += '='
- long_opts.append(opt)
-
- opts, args = getopt.getopt(args[1:], short_opts, long_opts)
- return opts, args
-
-
- def usage(self):
- """ Help for the cli.
- """
- msg = help_msg_header
- for opt,value in self.__options.items():
- if value['short']:
- msg += '-'
- else:
- msg += '--'
- msg += '%s \t: %s\n' % (value['name'], value['description'])
-
- msg += help_msg_trailer
- return msg
-
-
-def pretty_print(header, results):
- """ pretty prints the result with all the proper space indentations.
- """
- # add an extra column for the record number.
- header.insert(0, ' # ')
-
- # add the record number to each result.
- for j in xrange(len(results)):
- results[j].insert(0, "[%d]" % (j+1))
-
- # number of columns in the results table.
- size = len(header)
-
- # list containing the max width of each column.
- column_width = [len(col_name) for col_name in header]
-
- # update the column width based on the values in the table.
- for record in results:
- for i in xrange(size):
- column_width[i] = max(column_width[i], len(record[i]))
-
- # Generates the header.
- lines = []
- lines.append(' '.join([header[i].capitalize().ljust(column_width[i])
- for i in xrange(size)]))
- lines.append(' '.join(['-' * c_size for c_size in column_width]))
-
- # Generates the table with the appropriate space indent.
- for record in results:
- lines.append(' '.join([record[i].ljust(column_width[i])
- for i in xrange(size)]))
-
- return '\n'.join(lines)
-
-
-def main(args):
- cli_obj = cli()
-
- # Add all the known and acceptable options.
- cli_obj.add_option(name='condition', type='string',
- description=condition_desc)
- cli_obj.add_option(name='columns', type='string',
- description=columns_desc)
- cli_obj.add_option(name='help', type='bool',
- description=help_desc)
-
- # Parse the options.
- opts,args = cli_obj.parse_options(args)
-
- # unexpected argument.
- if args:
- raise InvalidArgsError(args)
-
- sql = None
- value = None
-
- # by default display these columns
- requested_columns = ['test', 'hostname', 'status', 'reason']
-
- for option, value in opts:
- if option == '--help':
- print cli_obj.usage()
- return
- elif option == '--condition':
- condition_list = query_lib.parse_condition(value.strip('"'))
- sql, value = query_lib.generate_sql_condition(condition_list)
- elif option == '--columns':
- supported_columns = ['test', 'hostname', 'user', 'label',
- 'machine_group', 'status', 'reason', 'kernel']
- requested_columns = [x.strip() for x in value.split(',')]
- for col in requested_columns:
- if col not in supported_columns:
- raise InvalidColumnValue, 'Unknown field %s specified in the columns option' % col
-
- # get the values corresponding to the index fields.
- col_values = {}
- for col in requested_columns:
- if col != 'test' and col != 'status' and col != 'reason':
- # the rest of the columns need the index values.
- col_group = frontend.anygroup.selectunique(db, col)
- col_value, field_name = frontend.select(db, col)
- col_values[col] = list(col_value)
-
- # get all the tests that satisfy the given conditions.
- tests = query_lib.get_tests(sql, value)
-
- # accumulate the fields that are of interest to the user.
- result = []
-
- for test in tests:
- record = []
-
- test_values = {}
- test_values['hostname'] = test.machine_idx
- test_values['user'] = test.job.job_idx
- test_values['label'] = test.job.job_idx
- test_values['machine_group'] = test.machine_idx
- test_values['kernel'] = test.kernel_idx
-
- for col in requested_columns:
- if col == 'test':
- record.append(test.testname)
- elif col == 'status':
- record.append(test.status_word)
- elif col == 'reason':
- record.append(test.reason.strip())
- else:
- column = col_values[col]
- found = False
- for idx_name, idx_value in column:
- if idx_value == test_values[col]:
- record.append(idx_name)
- found = True
- break
- if not found:
- record.append('')
- result.append(record)
-
- # generate the pretty table.
- print pretty_print(requested_columns, result)
-
-
-main(sys.argv)