kernel: add a boot validation step post boot

When requesting a boot via a kernel generate a kernel identifier
for that kernel and a command line validator (the time).  These
are then checked in a post boot validation stepper "step" which
is inserted before the users next step.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@657 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/tko/create_db b/tko/create_db
index 09e00a4..bbff238 100644
--- a/tko/create_db
+++ b/tko/create_db
@@ -17,9 +17,9 @@
 
 -- One entry per patch used, anywhere
 CREATE TABLE patches (
-kversion INTEGER PRIMARY KEY,		-- index number
-name VARCHAR(20),			-- short name
-url VARCHAR(200),			-- full URL
+kversion INTEGER,			-- index number
+name VARCHAR(80),			-- short name
+url VARCHAR(300),			-- full URL
 hash VARCHAR(35)
 );
 
diff --git a/tko/db.py b/tko/db.py
index 270f077..cd547e8 100644
--- a/tko/db.py
+++ b/tko/db.py
@@ -1,4 +1,4 @@
-import sqlite, re
+import sqlite, re, os
 
 class db:
 	def __init__(self):
@@ -40,26 +40,48 @@
 
 
 	def insert_job(self, tag, job):
-		# is kernel version in tree?
 		self.insert('jobs', {'tag':tag, 'machine':'UNKNOWN'})
 		job.index = self.find_job(tag)
 		for test in job.tests:
 			self.insert_test(job, test)
 
+
 	def insert_test(self, job, test):
-		# WE ARE MISSING KVERSION HERE!!!!
+		kver = self.insert_kernel_version(test.kernel)
 		data = {'job_idx':job.index, 'test':test.testname,
 			'subdir':test.dir, 
 			'status':test.status, 'reason':test.reason}
 		self.insert('tests', data)
 
 
-	def lookup_kernel_version(self, base, patches):
-		return self.select('kversion', 'kversions', {'base':base})[0]
+	def lookup_kversion(self, kernel):
+		rows = self.select('kversion', 'kversions', 
+				{'kversion_hash':kernel.kversion_hash})
+		if rows:
+			return rows[0][0]
+		else:
+			return None
 
 
-	def insert_kernel_version(self, base, patches):
-		self.insert('kversions', {'base': base})
+	def insert_kernel_version(self, kernel):
+		kver = self.lookup_kversion(kernel)
+		if kver:
+			return kver
+		self.insert('kversions', {'base':kernel.base,
+					  'kversion_hash':kernel.kversion_hash})
+		kver = self.lookup_kversion(kernel)
+		for patch in kernel.patches:
+			self.insert_patch(kver, patch)
+		return kver
+
+
+	def insert_patch(self, kver, patch):
+		print patch.reference
+		name = os.path.basename(patch.reference)[:80]
+		self.insert('patches', {'kversion': kver, 
+					'name':name,
+					'url':patch.reference, 
+					'hash':patch.hash})
 
 
 	def find_job(self, tag):
diff --git a/tko/parse.py b/tko/parse.py
index 30e8acb..d3a5894 100755
--- a/tko/parse.py
+++ b/tko/parse.py
@@ -26,52 +26,29 @@
 		self.dir = dir
 		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
 
-		print 'FOOFACE ' + self.control
-		if not os.path.exists(self.control):
-			return
-		# HACK. we don't have proper build tags in the status file yet
-		# so we hardcode build/ and do it at the start of the job
-		print 'POOFACE'
-		self.kernel = kernel(os.path.join(dir, 'build'))
 		self.grope_status()
 
 
-	def derive_build(self, raw_build):
-		# First to expand variables in the build line ...
-		self.build = ''
-		for element in re.split(r'(\$\w+)', raw_build):
-			if element.startswith('$'):
-				element = self.variables[element.lstrip('$')]
-			self.build += element
-
-
-	def derive_patches(self):
-		self.patches_short = []
-		self.patches_long = []
-		for segment in re.split(r'(-p \S+)', self.build):
-			if segment.startswith('-p'):
-				self.patches_long.append(segment.split(' ')[1])
-		self.patches_short = [shorten_patch(p) for p in self.patches_long]
-		
-
 	def grope_status(self):
-		status_file = os.path.join(self.dir, "status")
-		for line in open(status_file, 'r').readlines():
+		# HACK. we don't have proper build tags in the status file yet
+		# so we hardcode build/ and do it at the start of the job
+		build = os.path.join(self.dir, 'build')
+		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)
 
-		self.tests.append(test(testname, status, reason))
-
-
-	def set_status(self, status):
-		if status not in status_num:
-			return
-		self.status = status
-		self.status_num = status_num[status]
+		self.tests.append(test(testname, status, reason, self.kernel))
 
 
 class kernel:
@@ -80,19 +57,23 @@
 		self.patches = []
 
 		log = os.path.join(builddir, 'debug/build_log')
+		if not os.path.exists(log):
+			return
 		patch_hashes = []
 		for line in open(log, 'r'):
+			print line
 			(type, rest) = line.split(': ', 1)
 			words = rest.split()
 			if type == 'BUILD VERSION':
 				self.base = words[0]
 			if type == 'PATCH':
-				self.patches.append(words[0:])
+				print words
+				self.patches.append(patch(*words[0:]))
 				# patch_hashes.append(words[2])
-		self.kversion_hash = self.get_kversion_hash(self.base, patch_hashes)
+		self.kversion_hash = self.get_kver_hash(self.base, patch_hashes)
 
 
-	def get_kversion_hash(self, base, patch_hashes):
+	def get_kver_hash(self, base, patch_hashes):
 		"""\
 		Calculate a hash representing the unique combination of
 		the kernel base version plus 
@@ -101,14 +82,26 @@
 		return md5.new(key_string).hexdigest()
 
 
+class patch:
+	def __init__(self, spec, reference=None, hash=None):
+		# NEITHER OF THE ABOVE SHOULD HAVE DEFAULTS!!!! HACK HACK
+		if not reference:
+			reference = spec
+		print 'PATCH::%s %s %s' % (spec, reference, hash)
+		self.spec = spec
+		self.reference = reference
+		self.hash = hash
+
+
 class test:
-	def __init__(self, dir, status, reason):
+	def __init__(self, dir, status, reason, kernel):
 		self.dir = dir
 		self.status = status
 		self.reason = reason
 		self.keyval = os.path.join(dir, 'results/keyval')
 		self.iterations = []
 		self.testname = re.sub(r'\..*', '', self.dir)
+		self.kernel = kernel
 
 		if not os.path.exists(self.keyval):
 			self.keyval = None