fix: emake log output corruption fix by using output from the annotation file. fix
authortimothy.murphy@nokia.com
Mon, 15 Mar 2010 15:50:33 +0000
branchfix
changeset 357 b4baa7ca35a7
parent 356 245e5b9fda51
child 359 6173843d1ce4
fix: emake log output corruption fix by using output from the annotation file.
sbsv2/raptor/python/raptor_make.py
sbsv2/raptor/test/smoke_suite/test_resources/annofile2log/testanno2log.py
--- a/sbsv2/raptor/python/raptor_make.py	Mon Mar 15 13:13:18 2010 +0000
+++ b/sbsv2/raptor/python/raptor_make.py	Mon Mar 15 15:50:33 2010 +0000
@@ -36,6 +36,52 @@
 class BadMakeEngineException(Exception):
 	pass
 
+def XMLEscapeLog(stream):
+	inRecipe = False
+
+	for line in stream:
+		if line.startswith("<recipe"):
+			inRecipe = True
+		elif line.startswith("</recipe"):
+			inRecipe = False
+			
+		# unless we are inside a "recipe", any line not starting
+		# with "<" is free text that must be escaped.
+		if inRecipe or line.startswith("<"):
+			yield line
+		else:
+			yield escape(line)
+
+def AnnoFileParseOutput(annofile):
+	af = open(annofile, "r")
+
+	inOutput = False
+	inParseJob = False
+	for line in af:
+		line = line.rstrip("\n\r")
+
+		if not inOutput:
+			if line.startswith("<output>"):
+				inOutput = True	
+				yield unescape(line[8:])+'\n'
+				# This is make output so don't unescape it.
+			elif line.startswith('<output src="prog">'):
+				line = line[19:]
+				inOutput = True	
+				yield unescape(line)+'\n'
+		else:
+			end_output = line.find("</output>")
+		
+			if end_output != -1:
+				line = line[:end_output]
+				inOutput = False
+			
+			yield unescape(line)+'\n'
+
+	af.close()
+
+
+
 # raptor_make module classes
 
 class MakeEngine(object):
@@ -82,6 +128,24 @@
 			self.jobsOption = evaluator.Get("jobs")
 			self.defaultMakeOptions = evaluator.Get("defaultoptions")
 
+			# Logging
+			#  copylogfromannofile means, for emake, that we should ignore 
+			# emake's console output and instead extract output from its annotation
+			# file.  This is a workaround for a problem where some emake
+			# console output is lost.  The annotation file has a copy of this
+			# output in the "parse" job and it turns out to be uncorrupted.
+			self.copyLogFromAnnoFile = (evaluator.Get("copylogfromannofile") == "true")
+			self.annoFileName = None
+
+			if self.copyLogFromAnnoFile:
+				for o in self.raptor.makeOptions:
+					if o.startswith("--mo=--emake-annofile="):
+						self.annoFileName = o[22:]
+
+				if not self.annoFileName:
+					self.raptor.Info("Cannot copy log from annotation file as no annotation filename was specified via the option --mo=--emake-annofile=<filename>")
+					self.copyLogFromAnnoFile = False
+
 			# buffering
 			self.scrambled = (evaluator.Get("scrambled") == "true")
 
@@ -481,7 +545,13 @@
 			stderrfilename = makefile+'.stderr'
 			stdoutfilename = makefile+'.stdout'
 			command += " 2>'%s' " % stderrfilename
-			command += " >'%s' " % stdoutfilename
+
+			# Keep a copy of the stdout too in the case of using the 
+			# annofile - so that we can trap the problem that
+			# makes the copy-log-from-annofile workaround necessary
+			# and perhaps determine when we can remove it.
+			if self.copyLogFromAnnoFile:
+				command += " >'%s' " % stdoutfilename
 
 			# Substitute the makefile name for any occurrence of #MAKEFILE#
 			command = command.replace("#MAKEFILE#", str(makefile))
@@ -519,39 +589,22 @@
 						universal_newlines=True, env=makeenv)
 				stream = p.stdout
 
-				line = " "
-				while line:
-					line = stream.readline()
+				inRecipe = False
 
-				# should be done now
-				returncode = p.wait()
-
-				# Report end-time of the build
-				self.raptor.InfoEndTime(object_type = "makefile",
-						task = "build", key = str(makefile))
+				if not self.copyLogFromAnnoFile:
+					for l in XMLEscapeLog(stream):
+						self.raptor.out.write(l)
 
-				try:
-					e = open(stdoutfilename,"r")
-					inRecipe = False
-					for line in e:
-						if line.startswith("<recipe"):
-							inRecipe = True
-						elif line.startswith("</recipe"):
-							inRecipe = False
-						
-						# unless we are inside a "recipe", any line not starting
-						# with "<" is free text that must be escaped.
-						if inRecipe or line.startswith("<"):
-							self.raptor.out.write(line)
-						else:
-							self.raptor.out.write(escape(line))
-					e.close()
-				except Exception,e:
-					self.raptor.Error("Couldn't complete stdout output for %s - '%s'", command, str(e))
+					returncode = p.wait()
+				else:
+					returncode = p.wait()
 
-				if returncode != 0  and not self.raptor.keepGoing:
-					self.Tidy()
-					return False
+					annofilename = self.annoFileName.replace("#MAKEFILE#",makefile)
+					try:
+						for l in XMLEscapeLog(AnnoFileParseOutput(annofilename)):
+							self.raptor.out.write(l)
+					except Exception,e:
+						self.raptor.Error("Couldn't complete stdout output from annofile %s for %s - '%s'", annofile, command, str(e))
 
 
 				# Take all the stderr output that went into the .stderr file
@@ -564,6 +617,9 @@
 					e.close()
 				except Exception,e:
 					self.raptor.Error("Couldn't complete stderr output for %s - '%s'", command, str(e))
+				# Report end-time of the build
+				self.raptor.InfoEndTime(object_type = "makefile",
+						task = "build", key = str(makefile))
 
 				if returncode != 0  and not self.raptor.keepGoing:
 					self.Tidy()
@@ -680,6 +736,8 @@
 				return False
 		return True
 
+
+
 # raptor_make module functions
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/test/smoke_suite/test_resources/annofile2log/testanno2log.py	Mon Mar 15 15:50:33 2010 +0000
@@ -0,0 +1,68 @@
+import sys
+import os
+sys.path.append(os.path.join(os.environ['SBS_HOME'],"python"))
+from xml.sax.saxutils import escape
+from xml.sax.saxutils import unescape
+
+def XMLEscapeLog(stream):
+	inRecipe = False
+
+	for line in stream:
+		if line.startswith("<recipe"):
+			inRecipe = True
+		elif line.startswith("</recipe"):
+			inRecipe = False
+			
+		# unless we are inside a "recipe", any line not starting
+		# with "<" is free text that must be escaped.
+		if inRecipe or line.startswith("<"):
+			yield line
+		else:
+			yield escape(line)
+
+def AnnoFileParseOutput(annofile):
+	af = open(annofile, "r")
+
+	inOutput = False
+	inParseJob = False
+	for line in af:
+		line = line.rstrip("\n\r")
+
+		if not inOutput:
+			if line.startswith("<output>"):
+				inOutput = True	
+				yield unescape(line[8:])
+				# This is make output so don't unescape it.
+			elif line.startswith('<output src="prog">'):
+				line = line[19:]
+				inOutput = True	
+				yield unescape(line)
+		else:
+			end_output = line.find("</output>")
+		
+			if end_output != -1:
+				line = line[:end_output]
+				inOutput = False
+			
+			yield unescape(line)
+
+	af.close()
+
+
+retcode=0
+
+
+annofile = sys.argv[1]
+#print "File = ", annofile
+
+sys.stdout.write("<build>\n")
+try:
+	for l in XMLEscapeLog(AnnoFileParseOutput(annofile)):
+		sys.stdout.write(l+"\n")
+
+except Exception,e:
+	sys.stderr.write("error: " + str(e) + "\n")
+	retcode = 1
+sys.stdout.write("</build>\n")
+
+sys.exit(retcode)