aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtools/coverage/coverage.py1452
1 files changed, 726 insertions, 726 deletions
diff --git a/tools/coverage/coverage.py b/tools/coverage/coverage.py
index df79b5b..d6e8916 100755
--- a/tools/coverage/coverage.py
+++ b/tools/coverage/coverage.py
@@ -41,837 +41,837 @@ logging.basicConfig(stream=sys.stderr, level=logging.WARNING, format=FORMAT)
logger = logging.getLogger("Coverage")
class CustomError(Exception):
- pass
+ pass
class ChildError(CustomError):
- def __init__(self, parent, child):
- self.parent = parent
- self.child = child
+ def __init__(self, parent, child):
+ self.parent = parent
+ self.child = child
class ChildNotFoundError(ChildError):
- def __str__(self):
- return "Unable to find the child %s in %s" % (self.child, self.parent)
+ def __str__(self):
+ return "Unable to find the child %s in %s" % (self.child, self.parent)
class DuplicatedChildError(ChildError):
- def __str__(self):
- return "Add existing child %s in %s." % (self.child, self.parent)
+ def __str__(self):
+ return "Add existing child %s in %s." % (self.child, self.parent)
class Element():
- """Root class for all coverage elements"""
- tag = "element"
+ """Root class for all coverage elements"""
+ tag = "element"
- def __init__(self, name):
+ def __init__(self, name):
- self.parent = None
- self.children = []
+ self.parent = None
+ self.children = []
- self.nbUse = 0
+ self.nbUse = 0
- self.name = name
+ self.name = name
- self.debug("New element")
+ self.debug("New element")
- def __str__(self):
- return "%s (%s)" % (self.name, self.tag)
+ def __str__(self):
+ return "%s (%s)" % (self.name, self.tag)
- def __eq__(self, compared):
- return (self.name == compared.name) and (self.children == compared.children)
+ def __eq__(self, compared):
+ return (self.name == compared.name) and (self.children == compared.children)
- def getName(self, default=""):
- return self.name or default
+ def getName(self, default=""):
+ return self.name or default
- def hasChildren(self):
- return bool(self.children)
+ def hasChildren(self):
+ return bool(self.children)
- def getChildren(self):
- return self.children
+ def getChildren(self):
+ return self.children
- def _getDescendants(self):
- for child in self.children:
- yield child
- for descendant in child._getDescendants() :
- yield descendant
+ def _getDescendants(self):
+ for child in self.children:
+ yield child
+ for descendant in child._getDescendants() :
+ yield descendant
- def getChildFromName(self, childName):
+ def getChildFromName(self, childName):
- for child in self.children :
+ for child in self.children :
- if child.getName() == childName :
- return child
+ if child.getName() == childName :
+ return child
- self.debug("Child %s not found" % childName, logging.ERROR)
+ self.debug("Child %s not found" % childName, logging.ERROR)
- self.debug("Child list :")
+ self.debug("Child list :")
- for child in self.children :
- self.debug(" - %s" % child)
+ for child in self.children :
+ self.debug(" - %s" % child)
- raise ChildNotFoundError(self, childName)
+ raise ChildNotFoundError(self, childName)
- def addChild(self, child):
- self.debug("new child: " + child.name)
- self.children.append(child)
- child._adoptedBy(self)
+ def addChild(self, child):
+ self.debug("new child: " + child.name)
+ self.children.append(child)
+ child._adoptedBy(self)
- def _adoptedBy(self, parent):
- assert(not self.parent)
- self.parent = parent
+ def _adoptedBy(self, parent):
+ assert(not self.parent)
+ self.parent = parent
- def _getElementNames(self, elementList):
- return (substate.name for substate in elementList)
+ def _getElementNames(self, elementList):
+ return (substate.name for substate in elementList)
- def _description(self, withCoverage, withNbUse):
- description = self.name
+ def _description(self, withCoverage, withNbUse):
+ description = self.name
- if withNbUse or withCoverage :
- description += " has been used " + str(self.nbUse) + " time"
+ if withNbUse or withCoverage :
+ description += " has been used " + str(self.nbUse) + " time"
- if withCoverage :
- description += self._coverageFormating(self._getCoverage())
+ if withCoverage :
+ description += self._coverageFormating(self._getCoverage())
- return description
+ return description
- def _getCoverage(self):
- """Return the coverage of the element between 0 and 1
+ def _getCoverage(self):
+ """Return the coverage of the element between 0 and 1
- If the element has no coverage dependency (usually child) return 0 or 1.
- otherwise the element coverage is the dependency coverage average"""
- coverageDependanceElements = list(self._getCoverageDependanceElements())
+ If the element has no coverage dependency (usually child) return 0 or 1.
+ otherwise the element coverage is the dependency coverage average"""
+ coverageDependanceElements = list(self._getCoverageDependanceElements())
- nbcoverageDependence = len(coverageDependanceElements)
+ nbcoverageDependence = len(coverageDependanceElements)
- if nbcoverageDependence == 0:
- if self.nbUse == 0:
- return 0
- else:
- return 1
+ if nbcoverageDependence == 0:
+ if self.nbUse == 0:
+ return 0
+ else:
+ return 1
- coverageDependenceValues = (depElement._getCoverage()
- for depElement in coverageDependanceElements)
+ coverageDependenceValues = (depElement._getCoverage()
+ for depElement in coverageDependanceElements)
- return sum(coverageDependenceValues) / nbcoverageDependence
+ return sum(coverageDependenceValues) / nbcoverageDependence
- def _getCoverageDependanceElements(self):
- return self.children
+ def _getCoverageDependanceElements(self):
+ return self.children
- def _coverageFormating(self, coverage):
- # If no coverage provided
- if not coverage :
- return ""
+ def _coverageFormating(self, coverage):
+ # If no coverage provided
+ if not coverage :
+ return ""
- # Calculate coverage
- return " (%s coverage)" % self._number2percent(coverage)
+ # Calculate coverage
+ return " (%s coverage)" % self._number2percent(coverage)
- @staticmethod
- def _number2percent(number):
- """Format a number to a integer % string
+ @staticmethod
+ def _number2percent(number):
+ """Format a number to a integer % string
- example: _number2percent(0.6666) -> "67%"
- """
- return "{0:.0f}%".format(100 * number)
+ example: _number2percent(0.6666) -> "67%"
+ """
+ return "{0:.0f}%".format(100 * number)
- def _dumpDescription(self, withCoverage, withNbUse):
+ def _dumpDescription(self, withCoverage, withNbUse):
- self.debug("yelding description")
- yield RankedLine(self._description(withCoverage, withNbUse), lineSuffix="")
+ self.debug("yelding description")
+ yield RankedLine(self._description(withCoverage, withNbUse), lineSuffix="")
- for dumped in self._dumpPropagate(withCoverage, withNbUse) :
- yield dumped
+ for dumped in self._dumpPropagate(withCoverage, withNbUse) :
+ yield dumped
- def _dumpPropagate(self, withCoverage, withNbUse):
+ def _dumpPropagate(self, withCoverage, withNbUse):
- for child in self.children :
- for dumpedDescription in child._dumpDescription(withCoverage, withNbUse) :
- yield dumpedDescription.increasedRank()
+ for child in self.children :
+ for dumpedDescription in child._dumpDescription(withCoverage, withNbUse) :
+ yield dumpedDescription.increasedRank()
- def dump(self, withCoverage=False, withNbUse=True):
+ def dump(self, withCoverage=False, withNbUse=True):
- return "\n".join(
- str(dumpedDescription) for dumpedDescription in
- self._dumpDescription(withCoverage, withNbUse))
+ return "\n".join(
+ str(dumpedDescription) for dumpedDescription in
+ self._dumpDescription(withCoverage, withNbUse))
- def exportToXML(self, domElement=None):
- if domElement == None:
- domElement = xml.dom.minidom.Element(self.tag)
+ def exportToXML(self, domElement=None):
+ if domElement == None:
+ domElement = xml.dom.minidom.Element(self.tag)
- self._XMLaddAttributes(domElement)
+ self._XMLaddAttributes(domElement)
- for child in self.children :
- domElement.appendChild(child.exportToXML())
+ for child in self.children :
+ domElement.appendChild(child.exportToXML())
- return domElement
+ return domElement
- def _XMLaddAttributes(self, domElement):
- attributes = self._getXMLAttributes()
+ def _XMLaddAttributes(self, domElement):
+ attributes = self._getXMLAttributes()
- coverage = self._getCoverage()
- if coverage != None :
- attributes["Coverage"] = self._number2percent(coverage)
+ coverage = self._getCoverage()
+ if coverage != None :
+ attributes["Coverage"] = self._number2percent(coverage)
- for key, value in attributes.items():
- domElement.setAttribute(key, value)
+ for key, value in attributes.items():
+ domElement.setAttribute(key, value)
- def _getXMLAttributes(self):
- return {
- "Name": self.name,
- "NbUse": str(self.nbUse)
- }
+ def _getXMLAttributes(self):
+ return {
+ "Name": self.name,
+ "NbUse": str(self.nbUse)
+ }
- def _incNbUse(self):
- self.nbUse += 1
+ def _incNbUse(self):
+ self.nbUse += 1
- def childUsed(self, child):
- self._incNbUse()
- # Propagate to parent
- self._tellParentThatChildUsed()
+ def childUsed(self, child):
+ self._incNbUse()
+ # Propagate to parent
+ self._tellParentThatChildUsed()
- def _tellParentThatChildUsed(self):
- if self.parent :
- self.parent.childUsed(self)
+ def _tellParentThatChildUsed(self):
+ if self.parent :
+ self.parent.childUsed(self)
- def parentUsed(self):
- self._incNbUse()
- # Propagate to children
- for child in self.children :
- child.parentUsed()
+ def parentUsed(self):
+ self._incNbUse()
+ # Propagate to children
+ for child in self.children :
+ child.parentUsed()
- def hasBeenUsed(self):
- return self.nbUse > 0
+ def hasBeenUsed(self):
+ return self.nbUse > 0
- def operationOnChild(self, path, operation):
+ def operationOnChild(self, path, operation):
- if path:
- return self._operationPropagate(path, operation)
- else :
- self.debug("operating on self")
- return operation(self)
+ if path:
+ return self._operationPropagate(path, operation)
+ else :
+ self.debug("operating on self")
+ return operation(self)
- def _operationPropagate(self, path, operation):
+ def _operationPropagate(self, path, operation):
- childName = path.pop(0)
- child = self.getChildFromName(childName)
+ childName = path.pop(0)
+ child = self.getChildFromName(childName)
- return child.operationOnChild(path, operation)
+ return child.operationOnChild(path, operation)
- def debug(self, stringOrFunction, level=logging.DEBUG):
- """Print a debug line on stderr in tree form
+ def debug(self, stringOrFunction, level=logging.DEBUG):
+ """Print a debug line on stderr in tree form
- If the debug line is expensive to generate, provide callable
- object, it will be called if log is enable for this level.
- This callable object should return the logline string.
- """
- if logger.isEnabledFor(level):
+ If the debug line is expensive to generate, provide callable
+ object, it will be called if log is enable for this level.
+ This callable object should return the logline string.
+ """
+ if logger.isEnabledFor(level):
- # TODO: use buildin callable if python >= 3.2
- if hasattr(stringOrFunction, "__call__"):
- string = stringOrFunction()
- else:
- string = stringOrFunction
+ # TODO: use buildin callable if python >= 3.2
+ if hasattr(stringOrFunction, "__call__"):
+ string = stringOrFunction()
+ else:
+ string = stringOrFunction
- rankedLine = DebugRankedLine("%s: %s" % (self, string))
- self._logDebug(rankedLine, level)
+ rankedLine = DebugRankedLine("%s: %s" % (self, string))
+ self._logDebug(rankedLine, level)
- def _logDebug(self, rankedLine, level):
+ def _logDebug(self, rankedLine, level):
- if self.parent:
- self.parent._logDebug(rankedLine.increasedRank(), level)
- else :
- logger.log(level, str(rankedLine))
+ if self.parent:
+ self.parent._logDebug(rankedLine.increasedRank(), level)
+ else :
+ logger.log(level, str(rankedLine))
class FromDomElement(Element):
- def __init__(self, DomElement):
- self._initFromDom(DomElement)
- super().__init__(self.name)
+ def __init__(self, DomElement):
+ self._initFromDom(DomElement)
+ super().__init__(self.name)
- def _initFromDom(self, DomElement):
- self.name = DomElement.getAttribute("Name")
+ def _initFromDom(self, DomElement):
+ self.name = DomElement.getAttribute("Name")
class DomElementLocation():
- def __init__(self, classConstructor, path=None):
- self.classConstructor = classConstructor
- if path :
- self.path = path
- else :
- self.path = []
+ def __init__(self, classConstructor, path=None):
+ self.classConstructor = classConstructor
+ if path :
+ self.path = path
+ else :
+ self.path = []
- self.path.append(classConstructor.tag)
+ self.path.append(classConstructor.tag)
class DomPopulatedElement(Element):
- """Default child populate
+ """Default child populate
- Look for each dom element with tag specified in self.tag
- and instantiate it with the dom element
- """
- childClasses = []
+ Look for each dom element with tag specified in self.tag
+ and instantiate it with the dom element
+ """
+ childClasses = []
- def populate(self, dom):
+ def populate(self, dom):
- for childDomElementLocation in self.childClasses :
+ for childDomElementLocation in self.childClasses :
- self.debug("Looking for child %s in path %s" % (
- childDomElementLocation.path[-1], childDomElementLocation.path))
+ self.debug("Looking for child %s in path %s" % (
+ childDomElementLocation.path[-1], childDomElementLocation.path))
- for childDomElement in self._findChildFromTagPath(dom, childDomElementLocation.path) :
+ for childDomElement in self._findChildFromTagPath(dom, childDomElementLocation.path) :
- childElement = childDomElementLocation.classConstructor(childDomElement)
- self.addChild(childElement)
+ childElement = childDomElementLocation.classConstructor(childDomElement)
+ self.addChild(childElement)
- childElement.populate(childDomElement)
+ childElement.populate(childDomElement)
- def _findChildFromTagPath(self, dom, path):
- if not path :
- yield dom
- else :
- # Copy list
- path = list(path)
+ def _findChildFromTagPath(self, dom, path):
+ if not path :
+ yield dom
+ else :
+ # Copy list
+ path = list(path)
- tag = path.pop(0)
+ tag = path.pop(0)
- # Find element with tag
- self.debug("Going to find elements with tag %s in %s" % (tag, dom))
- self.debug(lambda: "Nb of solutions: %s" % len(dom.getElementsByTagName(tag)))
+ # Find element with tag
+ self.debug("Going to find elements with tag %s in %s" % (tag, dom))
+ self.debug(lambda: "Nb of solutions: %s" % len(dom.getElementsByTagName(tag)))
- for elementByTag in dom.getElementsByTagName(tag) :
+ for elementByTag in dom.getElementsByTagName(tag) :
- self.debug("Found element: %s" % elementByTag)
+ self.debug("Found element: %s" % elementByTag)
- # If the same tag is found
- if elementByTag in dom.childNodes :
+ # If the same tag is found
+ if elementByTag in dom.childNodes :
- # Yield next level
- for element in self._findChildFromTagPath(elementByTag, path) :
- yield element
+ # Yield next level
+ for element in self._findChildFromTagPath(elementByTag, path) :
+ yield element
class Rule(Element):
- def usedIfApplicable(self, criteria):
- childApplicability = (child.usedIfApplicable(criteria)
- for child in self.children)
+ def usedIfApplicable(self, criteria):
+ childApplicability = (child.usedIfApplicable(criteria)
+ for child in self.children)
- isApplicable = self._isApplicable(criteria, childApplicability)
+ isApplicable = self._isApplicable(criteria, childApplicability)
- if isApplicable :
- self._incNbUse()
+ if isApplicable :
+ self._incNbUse()
- self.debug("Rule applicability: %s" % isApplicable)
- assert(isApplicable == True or isApplicable == False)
+ self.debug("Rule applicability: %s" % isApplicable)
+ assert(isApplicable == True or isApplicable == False)
- return isApplicable
+ return isApplicable
- def _isApplicable(self, criteria, childApplicability):
- """Return the rule applicability depending on children applicability.
+ def _isApplicable(self, criteria, childApplicability):
+ """Return the rule applicability depending on children applicability.
- If at least one child is applicable, return true"""
- # Lazy evaluation as in the PFW
- return all(childApplicability)
+ If at least one child is applicable, return true"""
+ # Lazy evaluation as in the PFW
+ return all(childApplicability)
class CriterionRule(FromDomElement, DomPopulatedElement, Rule):
- tag = "SelectionCriterionRule"
- childClasses = []
- isApplicableOperations = {
- "Includes" : lambda criterion, value: criterion.stateIncludes(value),
- "Excludes" : lambda criterion, value: not criterion.stateIncludes(value),
- "Is" : lambda criterion, value: criterion.stateIs(value),
- "IsNot" : lambda criterion, value: not criterion.stateIs(value)
- }
+ tag = "SelectionCriterionRule"
+ childClasses = []
+ isApplicableOperations = {
+ "Includes" : lambda criterion, value: criterion.stateIncludes(value),
+ "Excludes" : lambda criterion, value: not criterion.stateIncludes(value),
+ "Is" : lambda criterion, value: criterion.stateIs(value),
+ "IsNot" : lambda criterion, value: not criterion.stateIs(value)
+ }
- def _initFromDom(self, DomElement):
- self.selectionCriterion = DomElement.getAttribute("SelectionCriterion")
- self.matchesWhen = DomElement.getAttribute("MatchesWhen")
- self.value = DomElement.getAttribute("Value")
- self.name = "%s %s %s" % (self.selectionCriterion, self.matchesWhen, self.value)
+ def _initFromDom(self, DomElement):
+ self.selectionCriterion = DomElement.getAttribute("SelectionCriterion")
+ self.matchesWhen = DomElement.getAttribute("MatchesWhen")
+ self.value = DomElement.getAttribute("Value")
+ self.name = "%s %s %s" % (self.selectionCriterion, self.matchesWhen, self.value)
- applicableOperationWithoutValue = self.isApplicableOperations[self.matchesWhen]
- self.isApplicableOperation = lambda criterion: applicableOperationWithoutValue(criterion, self.value)
+ applicableOperationWithoutValue = self.isApplicableOperations[self.matchesWhen]
+ self.isApplicableOperation = lambda criterion: applicableOperationWithoutValue(criterion, self.value)
- def _isApplicable(self, criteria, childApplicability):
+ def _isApplicable(self, criteria, childApplicability):
- return criteria.operationOnChild([self.selectionCriterion],
- self.isApplicableOperation)
+ return criteria.operationOnChild([self.selectionCriterion],
+ self.isApplicableOperation)
class CompoundRule(FromDomElement, DomPopulatedElement, Rule):
- """CompoundRule can be of type ALL or ANY"""
- tag = "CompoundRule"
- # Declare childClasses but define it at first class instantiation
- childClasses = None
+ """CompoundRule can be of type ALL or ANY"""
+ tag = "CompoundRule"
+ # Declare childClasses but define it at first class instantiation
+ childClasses = None
- def __init__(self, dom):
- # Define childClasses at first class instantiation
- if self.childClasses == None :
- self.childClasses = [DomElementLocation(CriterionRule),
- DomElementLocation(CompoundRule)]
- super().__init__(dom)
+ def __init__(self, dom):
+ # Define childClasses at first class instantiation
+ if self.childClasses == None :
+ self.childClasses = [DomElementLocation(CriterionRule),
+ DomElementLocation(CompoundRule)]
+ super().__init__(dom)
- def _initFromDom(self, DomElement):
+ def _initFromDom(self, DomElement):
- type = DomElement.getAttribute("Type")
- self.ofTypeAll = {"All" : True, "Any" : False}[type]
- self.name = type
+ type = DomElement.getAttribute("Type")
+ self.ofTypeAll = {"All" : True, "Any" : False}[type]
+ self.name = type
- def _isApplicable(self, criteria, childApplicability):
- if self.ofTypeAll :
- applicability = super()._isApplicable(criteria, childApplicability)
- else:
- # Lazy evaluation as in the PFW
- applicability = any(childApplicability)
+ def _isApplicable(self, criteria, childApplicability):
+ if self.ofTypeAll :
+ applicability = super()._isApplicable(criteria, childApplicability)
+ else:
+ # Lazy evaluation as in the PFW
+ applicability = any(childApplicability)
- return applicability
+ return applicability
class RootRule(DomPopulatedElement, Rule):
- tag = "RootRule"
- childClasses = [DomElementLocation(CompoundRule)]
+ tag = "RootRule"
+ childClasses = [DomElementLocation(CompoundRule)]
- def populate(self, dom):
- super().populate(dom)
- self.debug("Children: %s" % self.children)
- # A configuration can only have one or no rule
- assert(len(self.children) <= 1)
+ def populate(self, dom):
+ super().populate(dom)
+ self.debug("Children: %s" % self.children)
+ # A configuration can only have one or no rule
+ assert(len(self.children) <= 1)
- def _getCoverageDependanceElements(self):
- return self._getDescendants()
+ def _getCoverageDependanceElements(self):
+ return self._getDescendants()
class CriteronStates(Element):
- """Root of configuration application criterion state"""
- tag = "CriterionStates"
+ """Root of configuration application criterion state"""
+ tag = "CriterionStates"
- def parentUsed(self, criteria):
- """Add criteria to child if not exist, if exist increase it's nbUse"""
- self._incNbUse()
+ def parentUsed(self, criteria):
+ """Add criteria to child if not exist, if exist increase it's nbUse"""
+ self._incNbUse()
- matches = [child for child in self.children if child == criteria]
+ matches = [child for child in self.children if child == criteria]
- assert(len(matches) <= 1)
+ assert(len(matches) <= 1)
- if matches :
- self.debug("Criteria state has already been encounter")
- currentcriteria = matches[0]
- else :
- self.debug("Criteria state has never been encounter, saving it")
- currentcriteria = criteria
- self.addChild(criteria)
+ if matches :
+ self.debug("Criteria state has already been encounter")
+ currentcriteria = matches[0]
+ else :
+ self.debug("Criteria state has never been encounter, saving it")
+ currentcriteria = criteria
+ self.addChild(criteria)
- currentcriteria.parentUsed()
+ currentcriteria.parentUsed()
class Configuration(FromDomElement, DomPopulatedElement):
- tag = "Configuration"
- childClasses = []
+ tag = "Configuration"
+ childClasses = []
- class IneligibleConfigurationAppliedError(CustomError):
+ class IneligibleConfigurationAppliedError(CustomError):
- def __init__(self, configuration, criteria):
- self.configuration = configuration
- self.criteria = criteria
+ def __init__(self, configuration, criteria):
+ self.configuration = configuration
+ self.criteria = criteria
- def __str__(self):
+ def __str__(self):
- return ("Applying ineligible %s, "
- "rule:\n%s\n"
- "Criteria current state:\n%s" % (
- self.configuration,
- self.configuration.rootRule.dump(withCoverage=False, withNbUse=False),
- self.criteria.dump(withCoverage=False, withNbUse=False)
- ))
+ return ("Applying ineligible %s, "
+ "rule:\n%s\n"
+ "Criteria current state:\n%s" % (
+ self.configuration,
+ self.configuration.rootRule.dump(withCoverage=False, withNbUse=False),
+ self.criteria.dump(withCoverage=False, withNbUse=False)
+ ))
- def __init__(self, DomElement):
- super().__init__(DomElement)
+ def __init__(self, DomElement):
+ super().__init__(DomElement)
- self.rootRule = RootRule("RootRule")
- self.addChild(self.rootRule)
+ self.rootRule = RootRule("RootRule")
+ self.addChild(self.rootRule)
- self.criteronStates = CriteronStates("CriterionStates")
- self.addChild(self.criteronStates)
+ self.criteronStates = CriteronStates("CriterionStates")
+ self.addChild(self.criteronStates)
- def populate(self, dom):
- # Delegate to rootRule
- self.rootRule.populate(dom)
+ def populate(self, dom):
+ # Delegate to rootRule
+ self.rootRule.populate(dom)
- def _getCoverage(self):
- # Delegate to rootRule
- return self.rootRule._getCoverage()
+ def _getCoverage(self):
+ # Delegate to rootRule
+ return self.rootRule._getCoverage()
- def used(self, criteria):
+ def used(self, criteria):
- self._incNbUse()
+ self._incNbUse()
- # Propagate use to parents
- self._tellParentThatChildUsed()
+ # Propagate use to parents
+ self._tellParentThatChildUsed()
- # Propagate to criterion coverage
- self.criteronStates.parentUsed(criteria.export())
+ # Propagate to criterion coverage
+ self.criteronStates.parentUsed(criteria.export())
- # Propagate to rules
- if not self.rootRule.usedIfApplicable(criteria) :
+ # Propagate to rules
+ if not self.rootRule.usedIfApplicable(criteria) :
- self.debug("Applied but rule does not match current "
+ self.debug("Applied but rule does not match current "
"criteria (parent: %s) " % self.parent.name,
- logging.ERROR)
+ logging.ERROR)
- raise self.IneligibleConfigurationAppliedError(self, criteria.export())
+ raise self.IneligibleConfigurationAppliedError(self, criteria.export())
- def _dumpPropagate(self, withCoverage, withNbUse):
- self.debug("Going to ask %s for description" % self.rootRule)
- for dumpedDescription in self.rootRule._dumpDescription(
- withCoverage=withCoverage,
- withNbUse=withNbUse) :
- yield dumpedDescription.increasedRank()
+ def _dumpPropagate(self, withCoverage, withNbUse):
+ self.debug("Going to ask %s for description" % self.rootRule)
+ for dumpedDescription in self.rootRule._dumpDescription(
+ withCoverage=withCoverage,
+ withNbUse=withNbUse) :
+ yield dumpedDescription.increasedRank()
- self.debug("Going to ask %s for description" % self.criteronStates)
- for dumpedDescription in self.criteronStates._dumpDescription(
- withCoverage=False,
- withNbUse=withNbUse) :
- yield dumpedDescription.increasedRank()
+ self.debug("Going to ask %s for description" % self.criteronStates)
+ for dumpedDescription in self.criteronStates._dumpDescription(
+ withCoverage=False,
+ withNbUse=withNbUse) :
+ yield dumpedDescription.increasedRank()
class Domain(FromDomElement, DomPopulatedElement):
- tag = "ConfigurableDomain"
- childClasses = [DomElementLocation(Configuration, ["Configurations"])]
+ tag = "ConfigurableDomain"
+ childClasses = [DomElementLocation(Configuration, ["Configurations"])]
class Domains(DomPopulatedElement):
- tag = "Domains"
- childClasses = [DomElementLocation(Domain, ["ConfigurableDomains"])]
+ tag = "Domains"
+ childClasses = [DomElementLocation(Domain, ["ConfigurableDomains"])]
class RankedLine():
- def __init__(self, string,
- stringPrefix="|-- ",
- rankString="| ",
- linePrefix="",
- lineSuffix="\n"):
- self.string = string
- self.rank = 0
- self.stringPrefix = stringPrefix
- self.rankString = rankString
- self.linePrefix = linePrefix
- self.lineSuffix = lineSuffix
-
- def increasedRank(self):
- self.rank += 1
- return self
-
- def __str__(self):
- return self.linePrefix + \
- self.rank * self.rankString + \
- self.stringPrefix + \
- self.string + \
- self.lineSuffix
+ def __init__(self, string,
+ stringPrefix="|-- ",
+ rankString="| ",
+ linePrefix="",
+ lineSuffix="\n"):
+ self.string = string
+ self.rank = 0
+ self.stringPrefix = stringPrefix
+ self.rankString = rankString
+ self.linePrefix = linePrefix
+ self.lineSuffix = lineSuffix
+
+ def increasedRank(self):
+ self.rank += 1
+ return self
+
+ def __str__(self):
+ return self.linePrefix + \
+ self.rank * self.rankString + \
+ self.stringPrefix + \
+ self.string + \
+ self.lineSuffix
class DebugRankedLine(RankedLine):
- def __init__(self, string, lineSuffix=""):
- super().__init__(string,
- stringPrefix="",
- rankString=" ",
- linePrefix="",
- lineSuffix=lineSuffix)
+ def __init__(self, string, lineSuffix=""):
+ super().__init__(string,
+ stringPrefix="",
+ rankString=" ",
+ linePrefix="",
+ lineSuffix=lineSuffix)
class CriterionState(Element):
- tag = "CriterionState"
- def used(self):
- self._incNbUse()
+ tag = "CriterionState"
+ def used(self):
+ self._incNbUse()
class Criterion(Element):
- tag = "Criterion"
- inclusivenessTranslate = {True: "Inclusive", False: "Exclusive"}
+ tag = "Criterion"
+ inclusivenessTranslate = {True: "Inclusive", False: "Exclusive"}
- class ChangeRequestToNonAccessibleState(CustomError):
- def __init__(self, requestedState, detail):
- self.requestedState = requestedState
- self.detail = detail
+ class ChangeRequestToNonAccessibleState(CustomError):
+ def __init__(self, requestedState, detail):
+ self.requestedState = requestedState
+ self.detail = detail
- def __str__(self):
- return ("Change request to non accessible state %s. Detail: %s" %
- (self.requestedState, self.detail))
+ def __str__(self):
+ return ("Change request to non accessible state %s. Detail: %s" %
+ (self.requestedState, self.detail))
- def __init__(self, name, isInclusif,
- stateNamesList, currentStateNamesList,
- ignoreIntegrity=False):
- super().__init__(name)
- self.isInclusif = isInclusif
+ def __init__(self, name, isInclusif,
+ stateNamesList, currentStateNamesList,
+ ignoreIntegrity=False):
+ super().__init__(name)
+ self.isInclusif = isInclusif
- for state in stateNamesList :
- self.addChild(CriterionState(state))
+ for state in stateNamesList :
+ self.addChild(CriterionState(state))
- self.currentState = []
- self.initStateNamesList = list(currentStateNamesList)
- self.changeState(self.initStateNamesList, ignoreIntegrity)
+ self.currentState = []
+ self.initStateNamesList = list(currentStateNamesList)
+ self.changeState(self.initStateNamesList, ignoreIntegrity)
- def reset(self):
- # Set current state as provided at initialisation
- self.changeState(self.initStateNamesList, ignoreIntegrity=True)
+ def reset(self):
+ # Set current state as provided at initialisation
+ self.changeState(self.initStateNamesList, ignoreIntegrity=True)
- def changeState(self, subStateNames, ignoreIntegrity=False):
- self.debug("Changing state from: %s to: %s" % (
- list(self._getElementNames(self.currentState)),
- subStateNames))
+ def changeState(self, subStateNames, ignoreIntegrity=False):
+ self.debug("Changing state from: %s to: %s" % (
+ list(self._getElementNames(self.currentState)),
+ subStateNames))
- if not ignoreIntegrity and not self.isIntegre(subStateNames):
- raise self.ChangeRequestToNonAccessibleState(subStateNames,
- "An exclusive criterion must have a non empty state")
+ if not ignoreIntegrity and not self.isIntegre(subStateNames):
+ raise self.ChangeRequestToNonAccessibleState(subStateNames,
+ "An exclusive criterion must have a non empty state")
- newCurrentState = []
- for subStateName in subStateNames :
- subState = self.getChildFromName(subStateName)
- subState.used()
- newCurrentState.append(subState)
+ newCurrentState = []
+ for subStateName in subStateNames :
+ subState = self.getChildFromName(subStateName)
+ subState.used()
+ newCurrentState.append(subState)
- self.currentState = newCurrentState
+ self.currentState = newCurrentState
- self._incNbUse()
- self._tellParentThatChildUsed()
+ self._incNbUse()
+ self._tellParentThatChildUsed()
- def isIntegre(self, subStateNames):
- return self.isInclusif or len(subStateNames) == 1
+ def isIntegre(self, subStateNames):
+ return self.isInclusif or len(subStateNames) == 1
- def childUsed(self, child):
- self.currentState = child
- super().childUsed(child)
+ def childUsed(self, child):
+ self.currentState = child
+ super().childUsed(child)
- def export(self):
- subStateNames = self._getElementNames(self.currentState)
- return Criterion(self.name, self.isInclusif, subStateNames, subStateNames,
- ignoreIntegrity=True)
+ def export(self):
+ subStateNames = self._getElementNames(self.currentState)
+ return Criterion(self.name, self.isInclusif, subStateNames, subStateNames,
+ ignoreIntegrity=True)
- def stateIncludes(self, subStateName):
- subStateCurrentNames = list(self._getElementNames(self.currentState))
+ def stateIncludes(self, subStateName):
+ subStateCurrentNames = list(self._getElementNames(self.currentState))
- self.debug("Testing if %s is included in %s" % (subStateName, subStateCurrentNames))
+ self.debug("Testing if %s is included in %s" % (subStateName, subStateCurrentNames))
- isIncluded = subStateName in subStateCurrentNames
- self.debug("IsIncluded: %s" % isIncluded)
+ isIncluded = subStateName in subStateCurrentNames
+ self.debug("IsIncluded: %s" % isIncluded)
- return isIncluded
+ return isIncluded
- def stateIs(self, subStateNames):
- if len(self.currentState) != 1 :
- return False
- else :
- return self.stateIncludes(subStateNames)
+ def stateIs(self, subStateNames):
+ if len(self.currentState) != 1 :
+ return False
+ else :
+ return self.stateIncludes(subStateNames)
- def _getXMLAttributes(self):
- attributes = super()._getXMLAttributes()
- attributes["Type"] = self.inclusivenessTranslate[self.isInclusif]
- return attributes
+ def _getXMLAttributes(self):
+ attributes = super()._getXMLAttributes()
+ attributes["Type"] = self.inclusivenessTranslate[self.isInclusif]
+ return attributes
class Criteria(Element):
- tag = "Criteria"
+ tag = "Criteria"
- class DuplicatedCriterionError(DuplicatedChildError):
- pass
+ class DuplicatedCriterionError(DuplicatedChildError):
+ pass
- def export(self):
- self.debug("Exporting criteria")
- assert(self.children)
+ def export(self):
+ self.debug("Exporting criteria")
+ assert(self.children)
- exported = Criteria(self.name)
- for child in self.children :
- exported.addChild(child.export())
- return exported
+ exported = Criteria(self.name)
+ for child in self.children :
+ exported.addChild(child.export())
+ return exported
- def addChild(self, child):
- if child in self.children:
- raise self.DuplicatedCriterionError(self, child)
- super().addChild(child)
+ def addChild(self, child):
+ if child in self.children:
+ raise self.DuplicatedCriterionError(self, child)
+ super().addChild(child)
class ConfigAppliedWithoutCriteriaError(CustomError):
- def __init__(self, configurationName, domainName):
- self.configurationName = configurationName
- self.domainName = domainName
- def __str__(self):
- return ('Applying configuration "%s" from domain "%s" before declaring criteria' %
- (self.configurationName, self.domainName))
+ def __init__(self, configurationName, domainName):
+ self.configurationName = configurationName
+ self.domainName = domainName
+ def __str__(self):
+ return ('Applying configuration "%s" from domain "%s" before declaring criteria' %
+ (self.configurationName, self.domainName))
class ParsePFWlog():
- MATCH = "match"
- ACTION = "action"
-
- def __init__(self, domains, criteria, ErrorsToIgnore=()):
-
- self.domains = domains;
- self.criteria = criteria;
- self.ErrorsToIgnore = ErrorsToIgnore
+ MATCH = "match"
+ ACTION = "action"
+
+ 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
-
- criterionCreationRegext = ", ".join([
- r""".*Criterion name: (.*)""",
- r"""type kind: (.*)""",
- r"""current state: (.*)""",
- r"""states: {(.*)}"""
- ])
- matchCriterionCreationLine = re.compile(criterionCreationRegext).match
+ configApplicationRegext = r""".*Applying configuration "(.*)" from domain "([^"]*)"""
+ matchConfigApplicationLine = re.compile(configApplicationRegext).match
+
+ criterionCreationRegext = ", ".join([
+ r""".*Criterion name: (.*)""",
+ r"""type kind: (.*)""",
+ r"""current state: (.*)""",
+ r"""states: {(.*)}"""
+ ])
+ matchCriterionCreationLine = re.compile(criterionCreationRegext).match
- changingCriterionRegext = r""".*Selection criterion changed event: Criterion name: (.*), current state: ([^\n\r]*)"""
- matchChangingCriterionLine = re.compile(changingCriterionRegext).match
+ changingCriterionRegext = r""".*Selection criterion changed event: Criterion name: (.*), current state: ([^\n\r]*)"""
+ matchChangingCriterionLine = re.compile(changingCriterionRegext).match
- self.lineLogTypes = [
- {
- self.MATCH: matchConfigApplicationLine,
- self.ACTION: self._configApplication
- }, {
- self.MATCH: matchCriterionCreationLine,
- self.ACTION: self._criterionCreation
- }, {
- self.MATCH: matchChangingCriterionLine,
- self.ACTION: self._changingCriterion
- }
- ]
+ self.lineLogTypes = [
+ {
+ self.MATCH: matchConfigApplicationLine,
+ self.ACTION: self._configApplication
+ }, {
+ self.MATCH: matchCriterionCreationLine,
+ self.ACTION: self._criterionCreation
+ }, {
+ self.MATCH: matchChangingCriterionLine,
+ self.ACTION: self._changingCriterion
+ }
+ ]
- @staticmethod
- def _formatCriterionList(liststring, separator):
- list = liststring.split(separator)
- if len(list) == 1 and list[0] == "<none>":
- list = []
- return list
-
- def _criterionCreation(self, matchCriterionCreation):
- # Unpack
- criterionName, criterionType, currentCriterionStates, criterionStates = matchCriterionCreation.group(1, 2, 3, 4)
+ @staticmethod
+ def _formatCriterionList(liststring, separator):
+ list = liststring.split(separator)
+ if len(list) == 1 and list[0] == "<none>":
+ list = []
+ return list
+
+ def _criterionCreation(self, matchCriterionCreation):
+ # Unpack
+ criterionName, criterionType, currentCriterionStates, criterionStates = matchCriterionCreation.group(1, 2, 3, 4)
- criterionStateList = self._formatCriterionList(criterionStates, ", ")
+ criterionStateList = self._formatCriterionList(criterionStates, ", ")
- criterionIsInclusif = {"exclusive" : False, "inclusive" : True}[criterionType]
+ criterionIsInclusif = {"exclusive" : False, "inclusive" : True}[criterionType]
- currentcriterionStateList = self._formatCriterionList(currentCriterionStates, "|")
+ currentcriterionStateList = self._formatCriterionList(currentCriterionStates, "|")
- logger.info("Creating criterion: " + criterionName +
- " (" + criterionType + ") " +
- " with current state: " + str(currentcriterionStateList) +
- ", possible states:" + str(criterionStateList))
+ logger.info("Creating criterion: " + criterionName +
+ " (" + criterionType + ") " +
+ " with current state: " + str(currentcriterionStateList) +
+ ", possible states:" + str(criterionStateList))
- try:
- self.criteria.addChild(Criterion(
- criterionName,
- criterionIsInclusif,
- criterionStateList,
- currentcriterionStateList
- ))
- except self.criteria.DuplicatedCriterionError as ex:
- logger.debug(ex)
- logger.warning("Reseting criterion %s. Did you reset the PFW ?" % criterionName)
- self.criteria.operationOnChild(
- [criterionName],
- lambda criterion: criterion.reset()
- )
+ try:
+ self.criteria.addChild(Criterion(
+ criterionName,
+ criterionIsInclusif,
+ criterionStateList,
+ currentcriterionStateList
+ ))
+ except self.criteria.DuplicatedCriterionError as ex:
+ logger.debug(ex)
+ logger.warning("Reseting criterion %s. Did you reset the PFW ?" % criterionName)
+ self.criteria.operationOnChild(
+ [criterionName],
+ lambda criterion: criterion.reset()
+ )
- def _changingCriterion(self, matchChangingCriterion):
- # Unpack
- criterionName, newCriterionSubStateNames = matchChangingCriterion.group(1, 2)
+ def _changingCriterion(self, matchChangingCriterion):
+ # Unpack
+ criterionName, newCriterionSubStateNames = matchChangingCriterion.group(1, 2)
- newCriterionState = self._formatCriterionList(newCriterionSubStateNames, "|")
+ newCriterionState = self._formatCriterionList(newCriterionSubStateNames, "|")
- logger.info("Changing criterion %s to %s" % (criterionName , newCriterionState))
+ logger.info("Changing criterion %s to %s" % (criterionName , newCriterionState))
- path = [criterionName]
- changeCriterionOperation = lambda criterion : criterion.changeState(newCriterionState)
- self.criteria.operationOnChild(path, changeCriterionOperation)
+ path = [criterionName]
+ changeCriterionOperation = lambda criterion : criterion.changeState(newCriterionState)
+ self.criteria.operationOnChild(path, changeCriterionOperation)
- def _configApplication(self, matchConfig):
- # Unpack
- configurationName, domainName = matchConfig.group(1, 2)
+ def _configApplication(self, matchConfig):
+ # Unpack
+ configurationName, domainName = matchConfig.group(1, 2)
- # Check that at least one criterion exist
- if not self.criteria.hasChildren() :
- logger.error("Applying configuration before declaring criteria")
- logger.info("Is the log starting at PFW boot ?")
- raise ConfigAppliedWithoutCriteriaError(configurationName, domainName)
+ # Check that at least one criterion exist
+ if not self.criteria.hasChildren() :
+ logger.error("Applying configuration before declaring criteria")
+ logger.info("Is the log starting at PFW boot ?")
+ raise ConfigAppliedWithoutCriteriaError(configurationName, domainName)
- # Change criterion state
- path = [domainName, configurationName]
- usedOperation = lambda element : element.used(self.criteria)
+ # Change criterion state
+ path = [domainName, configurationName]
+ usedOperation = lambda element : element.used(self.criteria)
- logger.info("Applying configuration %s from domain %s" % (
- configurationName, domainName))
-
- self.domains.operationOnChild(path, usedOperation)
+ logger.info("Applying configuration %s from domain %s" % (
+ configurationName, domainName))
+
+ self.domains.operationOnChild(path, usedOperation)
- def _digest(self, lineLogType, lineLog):
+ def _digest(self, lineLogType, lineLog):
- match = lineLogType[self.MATCH](lineLog)
- if match :
- lineLogType[self.ACTION](match)
- return True
- return False
+ match = lineLogType[self.MATCH](lineLog)
+ if match :
+ lineLogType[self.ACTION](match)
+ return True
+ return False
- def parsePFWlog(self, lines):
- for lineNb, lineLog in enumerate(lines):
+ def parsePFWlog(self, lines):
+ for lineNb, lineLog in enumerate(lines):
- logger.debug("Parsing line :%s" % lineLog.rstrip())
+ logger.debug("Parsing line :%s" % lineLog.rstrip())
- digested = (self._digest(lineLogType, lineLog)
- for lineLogType in self.lineLogTypes)
+ digested = (self._digest(lineLogType, lineLog)
+ for lineLogType in self.lineLogTypes)
- try:
- success = any(digested)
+ 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)))
+ # 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")
+ # 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):
- tag = "CoverageReport"
- def __init__(self, name, dom):
- super().__init__(name)
- # Create domain tree
- self.domains = Domains("Domains")
- self.domains.populate(dom)
- self.addChild(self.domains)
- # Create criterion list
- self.criteria = Criteria("CriterionRoot")
- self.addChild(self.criteria)
-
- def exportToXML(self):
- """Export tree to an xml document"""
- impl = xml.dom.minidom.getDOMImplementation()
- newdoc = impl.createDocument(namespaceURI=None, qualifiedName=self.tag, doctype=None)
- super().exportToXML(newdoc.documentElement)
-
- return newdoc
+ tag = "CoverageReport"
+ def __init__(self, name, dom):
+ super().__init__(name)
+ # Create domain tree
+ self.domains = Domains("Domains")
+ self.domains.populate(dom)
+ self.addChild(self.domains)
+ # Create criterion list
+ self.criteria = Criteria("CriterionRoot")
+ self.addChild(self.criteria)
+
+ def exportToXML(self):
+ """Export tree to an xml document"""
+ impl = xml.dom.minidom.getDOMImplementation()
+ newdoc = impl.createDocument(namespaceURI=None, qualifiedName=self.tag, doctype=None)
+ super().exportToXML(newdoc.documentElement)
+
+ return newdoc
# ============================
# Command line argument parser
@@ -879,170 +879,170 @@ class Root(Element):
class ArgumentParser:
- """class that parse command line arguments with argparse library
-
- Result of parsing are the class attributes.
- """
- levelTranslate = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG]
-
- def __init__(self):
-
- try:
- # As argparse is only in the stdlib since python 3.2,
- # testing its availability
- import argparse
-
- except ImportError:
- logger.warning("Unable to import argparse "
- "(parser for command-line options and arguments), "
- "using default argument values:")
-
- logger.warning(" - InputFile: stdin")
- self.inputFile = sys.stdin
-
- logger.warning(" - OutputFile: stdout")
- self.outputFile = sys.stdout
-
- try:
- self.domainsFile = sys.argv[1]
- except IndexError as ex:
- logger.fatal("No domain file provided (first argument)")
- raise ex
- else:
- logger.warning(" - Domain file: " + self.domainsFile)
-
- logger.warning(" - Output format: xml")
- self.XMLreport = True
-
- logger.warning(" - Debug level: error")
- self.debugLevel = logging.ERROR
- else :
-
- myArgParser = argparse.ArgumentParser(description='Generate PFW report')
-
- myArgParser.add_argument(
- 'domainsFile',
- type=argparse.FileType('r'),
- help="the PFW domain XML file"
- )
- myArgParser.add_argument(
- 'pfwlog', nargs='?',
- type=argparse.FileType('r'), default=sys.stdin,
- help="the PFW log file, default stdin"
- )
- myArgParser.add_argument(
- '-o', '--output',
- dest="outputFile",
- type=argparse.FileType('w'), default=sys.stdout,
- help="the coverage report output file, default stdout"
- )
- myArgParser.add_argument(
- '-v', '--verbose',
- dest="debugLevel", default=0,
- action='count',
- help="print debug warnings from warning (default) to debug (-vv)"
- )
-
- outputFormatGroupe = myArgParser.add_mutually_exclusive_group(required=False)
-
- outputFormatGroupe.add_argument(
- '--xml',
- dest="xmlFlag",
- action='store_true',
- help=" XML coverage output report"
- )
- outputFormatGroupe.add_argument(
- '--raw',
- dest="rawFlag",
- action='store_true',
- 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()
-
- # Mapping to attributes
- self.inputFile = options.pfwlog
- self.outputFile = options.outputFile
- self.domainsFile = options.domainsFile
-
- # Output report in xml if flag not set
- self.XMLreport = not options.rawFlag
-
- # Setting logger level
- 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)
+ """class that parse command line arguments with argparse library
+
+ Result of parsing are the class attributes.
+ """
+ levelTranslate = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG]
+
+ def __init__(self):
+
+ try:
+ # As argparse is only in the stdlib since python 3.2,
+ # testing its availability
+ import argparse
+
+ except ImportError:
+ logger.warning("Unable to import argparse "
+ "(parser for command-line options and arguments), "
+ "using default argument values:")
+
+ logger.warning(" - InputFile: stdin")
+ self.inputFile = sys.stdin
+
+ logger.warning(" - OutputFile: stdout")
+ self.outputFile = sys.stdout
+
+ try:
+ self.domainsFile = sys.argv[1]
+ except IndexError as ex:
+ logger.fatal("No domain file provided (first argument)")
+ raise ex
+ else:
+ logger.warning(" - Domain file: " + self.domainsFile)
+
+ logger.warning(" - Output format: xml")
+ self.XMLreport = True
+
+ logger.warning(" - Debug level: error")
+ self.debugLevel = logging.ERROR
+ else :
+
+ myArgParser = argparse.ArgumentParser(description='Generate PFW report')
+
+ myArgParser.add_argument(
+ 'domainsFile',
+ type=argparse.FileType('r'),
+ help="the PFW domain XML file"
+ )
+ myArgParser.add_argument(
+ 'pfwlog', nargs='?',
+ type=argparse.FileType('r'), default=sys.stdin,
+ help="the PFW log file, default stdin"
+ )
+ myArgParser.add_argument(
+ '-o', '--output',
+ dest="outputFile",
+ type=argparse.FileType('w'), default=sys.stdout,
+ help="the coverage report output file, default stdout"
+ )
+ myArgParser.add_argument(
+ '-v', '--verbose',
+ dest="debugLevel", default=0,
+ action='count',
+ help="print debug warnings from warning (default) to debug (-vv)"
+ )
+
+ outputFormatGroupe = myArgParser.add_mutually_exclusive_group(required=False)
+
+ outputFormatGroupe.add_argument(
+ '--xml',
+ dest="xmlFlag",
+ action='store_true',
+ help=" XML coverage output report"
+ )
+ outputFormatGroupe.add_argument(
+ '--raw',
+ dest="rawFlag",
+ action='store_true',
+ 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()
+
+ # Mapping to attributes
+ self.inputFile = options.pfwlog
+ self.outputFile = options.outputFile
+ self.domainsFile = options.domainsFile
+
+ # Output report in xml if flag not set
+ self.XMLreport = not options.rawFlag
+
+ # Setting logger level
+ 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():
- errorDuringLogParsing = -1
- errorDuringArgumentParsing = 1
+ errorDuringLogParsing = -1
+ errorDuringArgumentParsing = 1
- try:
- commandLineArguments = ArgumentParser()
- except LookupError as ex:
- logger.error("Error during argument parsing")
- logger.debug(str(ex))
- sys.exit(errorDuringArgumentParsing)
+ try:
+ commandLineArguments = ArgumentParser()
+ except LookupError as ex:
+ logger.error("Error during argument parsing")
+ logger.debug(str(ex))
+ sys.exit(errorDuringArgumentParsing)
- # Setting logger level
- logger.setLevel(commandLineArguments.debugLevel)
- logger.info("Log level set to: %s" %
- logging.getLevelName(commandLineArguments.debugLevel))
+ # Setting logger level
+ logger.setLevel(commandLineArguments.debugLevel)
+ logger.info("Log level set to: %s" %
+ logging.getLevelName(commandLineArguments.debugLevel))
- # Create tree from XML
- dom = xml.dom.minidom.parse(commandLineArguments.domainsFile)
+ # Create tree from XML
+ dom = xml.dom.minidom.parse(commandLineArguments.domainsFile)
- # Create element tree
- root = Root("DomainCoverage", dom)
+ # Create element tree
+ root = Root("DomainCoverage", dom)
- # Parse PFW events
- parser = ParsePFWlog(root.domains, root.criteria, commandLineArguments.errorToIgnore)
+ # Parse PFW events
+ parser = ParsePFWlog(root.domains, root.criteria, commandLineArguments.errorToIgnore)
- try:
- parser.parsePFWlog(commandLineArguments.inputFile.readlines())
- except CustomError as ex:
- logger.fatal("Error during parsing log file %s: %s" %
- (commandLineArguments.inputFile, ex))
- sys.exit(errorDuringLogParsing)
+ try:
+ parser.parsePFWlog(commandLineArguments.inputFile.readlines())
+ except CustomError as ex:
+ logger.fatal("Error during parsing log file %s: %s" %
+ (commandLineArguments.inputFile, ex))
+ sys.exit(errorDuringLogParsing)
- # Output report
- outputFile = commandLineArguments.outputFile
+ # Output report
+ outputFile = commandLineArguments.outputFile
- if not commandLineArguments.XMLreport :
- outputFile.write("%s\n" % root.dump(withCoverage=True, withNbUse=True))
- else :
- outputFile.write(root.exportToXML().toprettyxml())
+ if not commandLineArguments.XMLreport :
+ outputFile.write("%s\n" % root.dump(withCoverage=True, withNbUse=True))
+ else :
+ outputFile.write(root.exportToXML().toprettyxml())
if __name__ == "__main__" :
- """ Execute main if the python interpreter is running this module as the main program """
- main()
+ """ Execute main if the python interpreter is running this module as the main program """
+ main()