Add the version 1 of the TKO parser, modify server_job to use this
version, and modify parse.py to look up the status version number
in order to instantiate the correct parser version.

Basically, it's an implementation of the parser that follows
the spec as outlined in
http://test.kernel.org/autotest/DraftParserSpecification. I did that
by implementing the "version 1" parser, as opposed to the existing
"version 0" parser, and it also adds some code to autotest itself to
log the fact that the status logs being written out follow the
"version 1" specification, so that when re-parsing existing results
older logs will still be parsed using the old (rather ad-hoc and
difficult to follow) algorithm.

The implementation is fairly similar to the existing version 0
implementation; it still uses all the same files for gathering
results, but there are the core changes:
- instead of grabbing kernel information from build.log, it gets
embedded into the status logs associated with reboots
- if a group is lacking a proper "END" section it implicitly assumes
it was somehow aborted
- reboots are wrapped in a group
- a "JOB" result is logged even if nothing bad happens (rather than
only logging it when something bad happens)
- you can have arbitrarily large amounts of group nesting

Signed-off-by: John Admanski <jadmanski@google.com>




git-svn-id: http://test.kernel.org/svn/autotest/trunk@1511 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/server/hosts/ssh_host.py b/server/hosts/ssh_host.py
index fafd409..6b46d38 100644
--- a/server/hosts/ssh_host.py
+++ b/server/hosts/ssh_host.py
@@ -271,6 +271,13 @@
 		return result == 0
 
 
+	def __run_group(self, function, *args, **dargs):
+		if self.job:
+			self.job.run_group(function, *args, **dargs)
+		else:
+			function(*args, **dargs)
+
+
 	def __record(self, status_code, subdir, operation, status = ''):
 		if self.job:
 			self.job.record(status_code, subdir, operation, status)
@@ -451,17 +458,22 @@
 				default = int(self.bootloader.get_default())
 				label = self.bootloader.get_titles()[default]
 			self.bootloader.add_args(label, kernel_args)
+
+		# define a function for the reboot and run it in a group
 		print "Reboot: initiating reboot"
-		self.__record("GOOD", None, "reboot.start")
-		try:
-			self.run('(sleep 5; reboot) </dev/null >/dev/null 2>&1 &')
-		except error.AutoservRunError:
-			self.__record("ABORT", None, "reboot.start",
-				      "reboot command failed")
-			raise
-		if wait:
-			self.wait_for_restart(timeout) 
-			self.reboot_followup()
+		def reboot():
+			self.__record("GOOD", None, "reboot.start")
+			try:
+				self.run('(sleep 5; reboot) '
+					 '</dev/null >/dev/null 2>&1 &')
+			except error.AutoservRunError:
+				self.__record("ABORT", None, "reboot.start",
+					      "reboot command failed")
+				raise
+			if wait:
+				self.wait_for_restart(timeout) 
+				self.reboot_followup()
+		self.__run_group(reboot)
 
 
 	def reboot_followup(self):
diff --git a/server/server_job.py b/server/server_job.py
index a11e2d3..62244f4 100755
--- a/server/server_job.py
+++ b/server/server_job.py
@@ -121,6 +121,9 @@
 			the control file for this job
 	"""
 
+	STATUS_VERSION = 1
+
+
 	def __init__(self, control, args, resultdir, label, user, machines,
 		     client=False, parse_job=""):
 		"""
@@ -169,8 +172,9 @@
 
 		if os.path.exists(self.status):
 			os.unlink(self.status)
-		job_data = { 'label' : label, 'user' : user,
-					'hostname' : ','.join(machines) }
+		job_data = {'label' : label, 'user' : user,
+                            'hostname' : ','.join(machines),
+                            'status_version' : str(self.STATUS_VERSION)}
 		job_data.update(get_site_job_data(self))
 		write_keyval(self.resultdir, job_data)
 
@@ -192,7 +196,7 @@
 		tko_utils.redirect_parser_debugging(parse_log)
 		# create a job model object and set up the db
 		self.results_db = tko_db.db(autocommit=True)
-		self.parser = status_lib.parser(0)
+		self.parser = status_lib.parser(self.STATUS_VERSION)
 		self.job_model = self.parser.make_job(resultdir)
 		self.parser.start(self.job_model)
 		# check if a job already exists in the db and insert it if