update tko

Signed-off-by: Martin J. Bligh <mbligh@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@663 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/tko/create_db b/tko/create_db
index 256c483..b62a5f9 100644
--- a/tko/create_db
+++ b/tko/create_db
@@ -12,7 +12,7 @@
 CREATE TABLE jobs (
 job_idx INTEGER PRIMARY KEY,		-- index number
 tag VARCHAR(30),			-- job key
-machine VARCHAR(20)			-- machine name
+machine VARCHAR(80)			-- machine name
 );
 
 -- One entry per patch used, anywhere
@@ -31,7 +31,8 @@
 subdir VARCHAR(60),			-- subdirectory name
 kernel_idx INTEGER,			-- kernel test was AGAINST
 status INTEGER,				-- test status
-reason VARCHAR(100)			-- reason for test status
+reason VARCHAR(100),			-- reason for test status
+machine VARCHAR(80)			-- machine name
 );
 
 -- test functional results
@@ -51,8 +52,8 @@
 
 -- status key
 CREATE TABLE status (
-status INTEGER PRIMARY KEY,		-- numerical status
-description VARCHAR(10)			-- status word
+status_idx INTEGER PRIMARY KEY,		-- numerical status
+word VARCHAR(10)			-- status word
 );
 
 COMMIT;
diff --git a/tko/db.py b/tko/db.py
index f2c3af9..e38dc91 100644
--- a/tko/db.py
+++ b/tko/db.py
@@ -1,25 +1,52 @@
-import sqlite, re, os
+import sqlite, re, os, sys
 
 class db:
-	def __init__(self):
+	def __init__(self, debug = False):
+		self.debug = debug
 		if not os.path.exists('tko_db'):
 			os.system('sqlite tko_db < create_db')
 		self.con = sqlite.connect('tko_db')
 		self.cur = self.con.cursor()
 
+		# if not present, insert statuses
+		self.status_idx = {}
+		self.status_word = {}
+		for s in ['NOSTATUS', 'ERROR', 'ABORT', 'FAIL', 'WARN', 'GOOD']:
+			idx = self.get_status(s)
+			if not idx:
+				self.insert('status', {'word' : s})
+				idx = self.get_status(s)
+			self.status_idx[s] = idx
+			self.status_word[idx] = s
+		
+
+	def get_status(self, word):
+		rows = self.select('status_idx', 'status', {'word' : word})
+		if rows:
+			return rows[0][0]
+		else:
+			return None
+
+
+	def dprint(self, value):
+		if self.debug:
+			sys.stderr.write('SQL: ' + str(value) + '\n')
+
 
 	def select(self, fields, table, where):
 		"""\
 			select fields from table where {dictionary}
 		"""
 		cmd = 'select %s from %s' % (fields, table)
+		values = []
 
 		if where:
 			keys = [field + '=%s' for field in where.keys()]
 			values = [where[field] for field in where.keys()]
 
-			cmd = cmd + ' where ' + 'and'.join(keys)
+			cmd = cmd + ' where ' + ' and '.join(keys)
 
+		self.dprint('%s %s' % (cmd,values))
 		self.cur.execute(cmd, values)
 		return self.cur.fetchall()
 
@@ -37,22 +64,24 @@
 		cmd = 'insert into %s (%s) values (%s)' % \
 				(table, ','.join(fields), ','.join(refs))
 
+		self.dprint('%s %s' % (cmd,values))
 		self.cur.execute(cmd, values)
 		self.con.commit()
 
 
 	def insert_job(self, tag, job):
-		self.insert('jobs', {'tag':tag, 'machine':'UNKNOWN'})
+		self.insert('jobs', {'tag':tag, 'machine':job.machine})
 		job.index = self.find_job(tag)
 		for test in job.tests:
 			self.insert_test(job, test)
 
 
 	def insert_test(self, job, test):
-		kver = self.insert_kernel_version(test.kernel)
+		kver = self.insert_kernel(test.kernel)
 		data = {'job_idx':job.index, 'test':test.testname,
-			'subdir':test.dir, 
-			'status':test.status, 'reason':test.reason}
+			'subdir':test.dir, 'kernel_idx':kver,
+			'status':self.status_idx[test.status],
+			'reason':test.reason, 'machine':test.machine }
 		self.insert('tests', data)
 
 
@@ -65,7 +94,7 @@
 			return None
 
 
-	def insert_kernel_version(self, kernel):
+	def insert_kernel(self, kernel):
 		kver = self.lookup_kernel(kernel)
 		if kver:
 			return kver
diff --git a/tko/frontend.py b/tko/frontend.py
index a7bedbb..c04ff93 100755
--- a/tko/frontend.py
+++ b/tko/frontend.py
@@ -1,51 +1,64 @@
 #!/usr/bin/python
 import os, re, db
 
-statuses = ['NOSTATUS', 'ERROR', 'ABORT', 'FAIL', 'WARN', 'GOOD']
-status_num = {}
-for x in range(0, len(statuses)):
-	status_num[statuses[x]] = x
-
-
-class job:
-	def __init__(self):
-		self.idx = None
-		self.tag = None
-		self.machine = None
-		self.tests = []
-
+# Pulling hierarchy:
+#
+# test pulls in (kernel, job, attributes, iterations)
+# kernel pulls in (patches)
+#
+# Note that job does put pull test - test is the primary object.
 
 class kernel:
-	fields = ['kernel_idx', 'kernel_hash', 'base', 'printable']
+	@classmethod
+	def select(klass, db, where = {}):
+		fields = ['kernel_idx', 'kernel_hash', 'base', 'printable']
+		kernels = []
+		for row in db.select(','.join(fields), 'kernels', where):
+			kernels.append(klass(db, *row))
+		return kernels
 
-	def __init__(self, db, where):
+
+	def __init__(self, db, idx, hash, base, printable):
 		self.db = db
-		self.base = None
-		self.patches = []
-
-		db.select(fields, kernels, 
-
-		
-class patch:
-	def __init__(self):
-		self.spec = spec
-		self.reference = reference
+		self.idx = idx
 		self.hash = hash
+		self.base = base
+		self.printable = printable
+		self.patches = []    # THIS SHOULD PULL IN PATCHES!
 
 
 class test:
-	def __init__(self, dir, status, reason, kernel):
-		self.dir = dir
-		self.status = status
+	@classmethod
+	def select(klass, db, where = {}):
+		fields = ['test_idx', 'job_idx', 'test', 'subdir', 
+			  'kernel_idx', 'status', 'reason', 'machine']
+		tests = []
+		for row in db.select(','.join(fields), 'tests', where):
+			tests.append(klass(db, *row))
+		return tests
+
+
+	def __init__(self, db, test_idx, job_idx, testname, subdir, kernel_idx, status_num, reason, machine):
+		self.idx = test_idx
+		self.job = None 
+		# self.job = job.select(db, {'job_idx' : job_idx})
+		# self.machine = self.job.machine
+		self.test = testname
+		self.subdir = subdir
+		self.kernel = None
+		# self.kernel = kernel.select(db, {'kernel_idx' : kernel_idx})
+		self.status_num = status_num
+		self.status_word = db.status_word[status_num]
 		self.reason = reason
-		self.keyval = os.path.join(dir, 'results/keyval')
-		self.iterations = []
-		self.testname = re.sub(r'\..*', '', self.dir)
-		self.kernel = kernel
-
-
-class iteration:
-	def __init__(self, index, lines):
-		self.index = index
-		self.keyval = {}
-
+		
+ 
+ 
+# class patch:
+# 	def __init__(self):
+# 		self.spec = None
+# 
+# 
+# class iteration:
+# 	def __init__(self):
+# 		self.a = None
+# 
diff --git a/tko/machine_kernel b/tko/machine_kernel
index 2b47047..28a060a 100755
--- a/tko/machine_kernel
+++ b/tko/machine_kernel
@@ -1,10 +1,10 @@
 #!/usr/bin/python
-import os, re, parse, sys
+import os, re, parse, sys, db
+from frontend import *
 
-db = db.db()
+db = db.db() # db.db(debug=True)
 
 machines = sys.argv[1:]
-kernels = select (kernel, printable) from kernels
 
 def print_machines_row(machines):
 	print "<tr>"
@@ -15,43 +15,48 @@
 	print ""
 
 
-def print_kernel_machine(kernel_idx, machine):
+def print_kernel_machine(kernel, machine):
 	status = None
-	tests = 'select * from tests where kernel = key'
-	# (test_idx, job_idx, test, subdir, status, reason) = test
-	for test in tests:
-		if not status or test.status < status:
-			status = test.status
-	html = ''
-	for test in tests:
-		html .= '%s %s' % (subdir, status)
+	tests = test.select(db, { 'kernel_idx' : kernel.idx ,
+				  'machine' : machine })
+	for t in tests:
+		if not status or t.status_num < status:
+			status = t.status_num
+	if status:
+		status_word = db.status_word[status]
+	else:
+		status_word = 'NOSTATUS'
+	lines = ['%s %s<br>' % (t.subdir, t.status_word) for t in tests]
+	print_colored_box(status_word, '\n'.join(lines))
 
 
 status_colour = {
-	'GOOD'  : '#66ff66', # green
-	'WARN'  : '#fffc00', # yellow
-	'FAIL'  : '#fff666', # red
-	'ABORT' : '#ff6666', # red
+	'GOOD'		: '#66ff66', # green
+	'WARN'		: '#fffc00', # yellow
+	'FAIL'		: '#fff666', # red
+	'ABORT'		: '#ff6666', # red
+	'ERROR'		: '#ff6666', # red
+	'NOSTATUS'	: '#ffffff', # white
 }
 
 def print_colored_box(status, html):
-	print "<td bgcolor=%s>" % status ? status_colour[status] : '#ffffff'
+	print "<td bgcolor=%s>" % status_colour[status]
 	print html
 	print "</td>"
 
 
 print '<table cellpadding=5 border=1 class="boldtable">'
-print_machines_row()
+print_machines_row(machines)
 
-for (kernel_idx, printable) in kernels:
+for kernel in kernel.select(db):
 	print "<tr>"
-	print "<td>%s</td>" % printable
+	print "<td>%s</td>" % kernel.printable
 	for machine in machines:
-		print_kernel_machine(kernel_idx, machine)
+		print_kernel_machine(kernel, machine)
 	print "</tr>"
 	print ""
 
-print_machines_row()
+print_machines_row(machines)
 print "</table>"
 
 
diff --git a/tko/parse b/tko/parse
index be79bb6..641d58c 100755
--- a/tko/parse
+++ b/tko/parse
@@ -8,13 +8,15 @@
 jobs_list = os.listdir(topdir)
 
 jobs = {}
-db = db.db()
+db = db.db(True)
 
 for j in jobs_list:
 	print 'looking for ' + j
-	if db.find_job(j):
+	if db.find_job(j):              # Job has already been parsed
 		continue
 	job = parse.job(os.path.join(topdir, j), 'regression')
+	if not job:
+		continue
 	print 'parsed ' + j
 	if not job.kernel:
 		continue
diff --git a/tko/parse.py b/tko/parse.py
index 1ca6524..5d541be 100755
--- a/tko/parse.py
+++ b/tko/parse.py
@@ -6,12 +6,6 @@
 build_url   = re.compile('build generic url \S*/linux-(2\.\d\.\d+(\.\d+)?(-rc\d+)?).tar')	
 valid_kernel= re.compile('2\.\d\.\d+(\.\d+)?(-rc\d+)?(-(git|bk))\d+')
 
-statuses = ['NOSTATUS', 'ERROR', 'ABORT', 'FAIL', 'WARN', 'GOOD']
-status_num = {}
-for x in range(0, len(statuses)):
-	status_num[statuses[x]] = x
-
-
 def shorten_patch(long):
 	short = os.path.basename(long)
 	short = re.sub(r'^patch-', '', short)
@@ -27,11 +21,20 @@
 		self.type = type
 		self.control = os.path.join(dir, "control")
 		self.status = os.path.join(dir, "status")
-		self.machine = ''
 		self.variables = {}
 		self.tests = []
 		self.kernel = None
 
+		if not os.path.exists(self.status):
+			return None
+
+		# We should really replace this with sysinfo/hostname!
+		uname = os.path.join(dir, "sysinfo/uname_-a")
+		try:
+			self.machine = open(uname, 'r').readline().split()[1]
+		except:
+			return None
+
 		self.grope_status()
 
 
@@ -42,13 +45,12 @@
 		if os.path.exists(build):
 			self.kernel = kernel(build)
 
-		if not os.path.exists(self.status):
-			return
-
 		for line in open(self.status, 'r').readlines():
 			(status, testname, reason) = line.rstrip().split(' ', 2)
+			print 'GROPE_STATUS: ',
+			print (status, testname, reason)
 
-		self.tests.append(test(testname, status, reason, self.kernel))
+		self.tests.append(test(testname, status, reason, self.kernel, self))
 
 
 class kernel:
@@ -94,7 +96,7 @@
 
 
 class test:
-	def __init__(self, dir, status, reason, kernel):
+	def __init__(self, dir, status, reason, kernel, job):
 		self.dir = dir
 		self.status = status
 		self.reason = reason
@@ -102,6 +104,7 @@
 		self.iterations = []
 		self.testname = re.sub(r'\..*', '', self.dir)
 		self.kernel = kernel
+		self.machine = job.machine
 
 		if not os.path.exists(self.keyval):
 			self.keyval = None