[coverage] Add flags to ignore errors

BZ: 115218

2 errors can be raised when parsing PFW logs:
 - criterion that change their state that is not allowed. The PFW
     allows an exclusive criterion to be in the none state.
 - configuration not applicable according to the criterion states
     that are however applied. It happens in case of log corruption
     (log lines missing).
The user should be able to ignore those 2 errors if low coverage
accuracy is allowed.

Add the flags:
 --ignore-incoherent-criterion-state
 --ignore-ineligible-configuration-application

Change-Id: I1a25b47a05e974d711b735e344f9352904c8771b
Signed-off-by: Kevin Rocard <kevinx.rocard@intel.com>
Reviewed-on: http://android.intel.com:8080/112714
Reviewed-by: Denneulin, Guillaume <guillaume.denneulin@intel.com>
Reviewed-by: Gonzalve, Sebastien <sebastien.gonzalve@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Tested-by: Dixon, CharlesX <charlesx.dixon@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/tools/coverage.py b/tools/coverage.py
index 9ce94e6..ead5e08 100755
--- a/tools/coverage.py
+++ b/tools/coverage.py
@@ -707,10 +707,11 @@
 	MATCH = "match"
 	ACTION = "action"
 
-	def __init__(self, domains, criteria):
+	def __init__(self, domains, criteria, ErrorsToIgnore=()):
 
 		self.domains = domains;
 		self.criteria = criteria;
+		self.ErrorsToIgnore = ErrorsToIgnore
 
 		configApplicationRegext = r""".*Applying configuration "(.*)" from domain "([^"]*)"""
 		matchConfigApplicationLine = re.compile(configApplicationRegext).match
@@ -811,22 +812,41 @@
 
 
 	def _digest(self, lineLogType, lineLog):
+
 		match = lineLogType[self.MATCH](lineLog)
 		if match :
 			lineLogType[self.ACTION](match)
 			return True
 		return False
 
+
 	def parsePFWlog(self, lines):
-		for lineLog in lines:
+		for lineNb, lineLog in enumerate(lines):
 
 			logger.debug("Parsing line :%s" % lineLog.rstrip())
 
 			digested = (self._digest(lineLogType, lineLog)
 					for lineLogType in self.lineLogTypes)
 
-			if not any(digested):
-				logger.debug("Line does not match, dropped")
+			try:
+				success = any(digested)
+
+			# Catch some exception in order to print the current parsing line,
+			# then raise the exception again if not continue of error
+			except CustomError as ex:
+				logger.error('Error raised while parsing line %s: "%s"' %
+							(lineNb, repr(lineLog)))
+
+				# If exception is a subclass of ErrorsToIgnore, log it and continue
+				# otherwise raise it again.
+				if not issubclass(type(ex), self.ErrorsToIgnore):
+					raise ex
+				else:
+					logger.error('Ignoring exception:"%s", '
+								'can not guarantee database integrity' % ex)
+			else:
+				if not success:
+					logger.debug("Line does not match, dropped")
 
 
 class Root(Element):
@@ -937,6 +957,21 @@
 						help="raw coverage output report"
 					)
 
+			myArgParser.add_argument(
+						'--ignore-incoherent-criterion-state',
+						dest="incoherentCriterionFlag",
+						action='store_true',
+						help="ignore criterion transition to incoherent state"
+					)
+
+			myArgParser.add_argument(
+						'--ignore-ineligible-configuration-application',
+						dest="ineligibleConfigurationApplicationFlag",
+						action='store_true',
+						help="ignore application of configuration with a false rule "
+						"(not applicable configuration)"
+					)
+
 			# Process command line arguments
 			options = myArgParser.parse_args()
 
@@ -952,6 +987,16 @@
 			levelCapped = min(options.debugLevel, len(self.levelTranslate) - 1)
 			self.debugLevel = self.levelTranslate[levelCapped]
 
+			# Setting ignore options
+			errorToIgnore = []
+			if options.ineligibleConfigurationApplicationFlag :
+				errorToIgnore.append(Configuration.IneligibleConfigurationAppliedError)
+
+			if options.incoherentCriterionFlag:
+				errorToIgnore.append(Criterion.ChangeRequestToNonAccessibleState)
+
+			self.errorToIgnore = tuple(errorToIgnore)
+
 
 
 def main():
@@ -978,7 +1023,7 @@
 	root = Root("Coverage", dom)
 
 	# Parse PFW events
-	parser = ParsePFWlog(root.domains, root.criteria)
+	parser = ParsePFWlog(root.domains, root.criteria, commandLineArguments.errorToIgnore)
 
 	try:
 		parser.parsePFWlog(commandLineArguments.inputFile.readlines())
@@ -996,7 +1041,7 @@
 		outputFile.write(root.exportToXML().toprettyxml())
 
 
-# Execute main function if the python interpreter is running this module as the main program
 if __name__ == "__main__" :
+	""" Execute main if the python interpreter is running this module as the main program """
 	main()