coverage.py revision 3aa0db4be952157c2842b91a1606cc0edac9e63d
1326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard#!/usr/bin/env python3 2326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 3fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# INTEL CONFIDENTIAL 4fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# Copyright 2013 Intel 5fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# Corporation All Rights Reserved. 6fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# 7fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# The source code contained or described herein and all documents related to 8fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# the source code ("Material") are owned by Intel Corporation or its suppliers 9fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# or licensors. Title to the Material remains with Intel Corporation or its 10fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# suppliers and licensors. The Material contains trade secrets and proprietary 11fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# and confidential information of Intel or its suppliers and licensors. The 12fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# Material is protected by worldwide copyright and trade secret laws and 13fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# treaty provisions. No part of the Material may be used, copied, reproduced, 14fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# modified, published, uploaded, posted, transmitted, distributed, or 15fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# disclosed in any way without Intels prior express written permission. 16fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# 17fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# No license under any patent, copyright, trade secret or other intellectual 18fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# property right is granted to or conferred upon you by disclosure or delivery 19fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# of the Materials, either expressly, by implication, inducement, estoppel or 20fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# otherwise. Any license under such intellectual property rights must be 21fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard# express and approved by Intel in writing. 22fe753d4ba5d5bf3df7b7f4876280b74fc8647285Kevin Rocard 23326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard""" 24326e39e42a801bff4b61655ebc0e3ff759c208ffKevin RocardGenerate a coverage report by parsing parameter framework log. 25326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 26326e39e42a801bff4b61655ebc0e3ff759c208ffKevin RocardThe coverage report contains the: 27326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard - domain 28326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard - configuration 29326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard - rule 30326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard - criterion 31326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardbasic coverage statistics. 32326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard""" 33326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 34326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardimport xml.dom.minidom 35326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardimport sys 36326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardimport re 37326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardimport logging 38326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 39326e39e42a801bff4b61655ebc0e3ff759c208ffKevin RocardFORMAT = '%(levelname)s: %(message)s' 40326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardlogging.basicConfig(stream=sys.stderr, level=logging.WARNING, format=FORMAT) 41326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardlogger = logging.getLogger("Coverage") 42326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 433aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocardclass CustomError(Exception): 44804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard pass 453aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard 463aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocardclass ChildError(CustomError): 47804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, parent, child): 48804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.parent = parent 49804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.child = child 503aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard 513aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocardclass ChildNotFoundError(ChildError): 52804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __str__(self): 53804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return ("Unable to find the child %s in %s" % 543aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard (self.child, self.parent)) 553aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard 56804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass DuplicatedChildError(ChildError): 57804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __str__(self): 58326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return ("Add existing child %s in %s. Did you restart de PFW ?" % 59326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard (self.child, self.parent)) 60804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 61804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Element(): 62326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard """Root class for all coverage elements""" 63804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "element" 64326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 65804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, name): 66804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 67326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.parent = None 68804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.children = [] 69326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 70804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.nbUse = 0 71326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 72804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.name = name 73326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 74326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("New element") 75804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 76804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 77326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def __str__(self): 78804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return "%s (%s)" % (self.name, self.tag) 79804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 80326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def __eq__(self, compared): 81804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug(lambda : "Comparing:\n%s" % self.dump()) 82804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug(lambda : "With:\n%s" % compared.dump()) 83326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard result = self.name == compared.name and self.children == compared.children 84804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Result is %s" % result) 85804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return result 86326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 87804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 88804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def getName(self, default=""): 89326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return self.name or default 90804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 91804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def hasChildren(self): 92804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return bool(self.children) 93804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 94804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def getChildren(self): 95326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return self.children 96804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 97326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def _getDescendants(self): 98804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children: 99326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard yield child 100804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for descendant in child._getDescendants() : 101804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard yield descendant 102326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 103804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def getChildFromName(self, childName): 104326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 105804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children : 106326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 107804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if child.getName() == childName : 108804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return child 109326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 110804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Child %s not found" % childName, logging.ERROR) 111326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 112326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("Child list :") 113804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 114804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children : 115804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug(" - %s" % child) 116804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 117326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard raise ChildNotFoundError(self, childName) 118804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 119804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 120804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def addChild(self, child): 121326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("new child: " + child.name) 122804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.children.append(child) 123804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard child._adoptedBy(self) 124326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 125804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _adoptedBy(self, parent): 126804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard assert(not self.parent) 127326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.parent = parent 128804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 129804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _getElementNames(self, elementList): 130326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return (substate.name for substate in elementList) 131804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 132804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _description(self, withCoverage, withNbUse): 133326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard description = self.name 134804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 135326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard if withNbUse or withCoverage : 136326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard description += " has been used " + str(self.nbUse) + " time" 137804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 138804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if withCoverage : 139326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard description += self._coverageFormating(self._getCoverage()) 140804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 141804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return description 142804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 143326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 144804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _getCoverage(self): 145326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 146804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard coverageDependance = list(self._getCoverageDependance()) 147804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 148804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard nbcoverageDependence = len(coverageDependance) 149804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 150804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if nbcoverageDependence == 0: 151326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard # Coverage makes no sense without any dependence 152804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return None 153804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 154326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard nbcoverageDependanceUsed = len([element 155804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for element in coverageDependance 156326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard if element.hasBeenUsed()]) 157804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 158804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return nbcoverageDependanceUsed / nbcoverageDependence 159326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 160804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _getCoverageDependance(self): 161804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self.children 162804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 163804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _coverageFormating(self, coverage): 164326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard # If no coverage provided 165804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if not coverage : 166804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return "" 167326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 168804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Calculate coverage 169804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return " (%s coverage)" % self._number2percent(coverage) 170804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 171326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard @staticmethod 172804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _number2percent(number): 173804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """Format a number to a integer % string 174804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 175326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard example: _number2percent(0.6666) -> "67%" 176326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard """ 177804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return "{0:.0f}%".format(100 * number) 178326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 179804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 180804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _dumpDescription(self, withCoverage, withNbUse): 181326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 182804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("yelding description") 183804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard yield RankedLine(self._description(withCoverage, withNbUse), lineSuffix="") 184326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 185804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for dumped in self._dumpPropagate(withCoverage, withNbUse) : 186326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard yield dumped 187804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 188804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _dumpPropagate(self, withCoverage, withNbUse): 189804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 190326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for child in self.children : 191326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for dumpedDescription in child._dumpDescription(withCoverage, withNbUse) : 192804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard yield dumpedDescription.increasedRank() 193326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 194804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 195804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def dump(self, withCoverage=False, withNbUse=True): 196804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 197326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return "\n".join( 198804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard str(dumpedDescription) for dumpedDescription in 199804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._dumpDescription(withCoverage, withNbUse)) 200804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 20102726ec37a9686572f825520a04700061ffe5d06Kevin Rocard def exportToXML(self): 202804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard domElement = xml.dom.minidom.Element(self.tag) 203326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self._XMLaddAttributes(domElement) 204804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 205804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children : 206326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard domElement.appendChild(child.exportToXML()) 207804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 208326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return domElement 209804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 210804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _XMLaddAttributes(self, domElement): 211326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard attributes = self._getXMLAttributes() 212804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 213804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard coverage = self._getCoverage() 214804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if coverage != None : 215326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard attributes["Coverage"] = self._number2percent(coverage) 216804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 217804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for key, value in attributes.items(): 218326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard domElement.setAttribute(key, value) 219804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 220804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _getXMLAttributes(self): 221804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return { 222804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "Name": self.name, 223804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "NbUse": str(self.nbUse) 224326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard } 225804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 226804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _incNbUse(self): 227326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.nbUse += 1 228804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 229804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def childUsed(self, child): 230804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._incNbUse() 231804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Propagate to parent 232326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self._tellParentThatChildUsed() 233804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 234804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _tellParentThatChildUsed(self): 235804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if self.parent : 236326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.parent.childUsed(self) 237326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 238804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 239804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def parentUsed(self): 240804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._incNbUse() 241804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Propagate to children 242804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children : 243326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard child.parentUsed() 244804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 245804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def hasBeenUsed(self): 246326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return self.nbUse > 0 247804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 248326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def operationOnChild(self, path, operation): 249804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Stop if path is not consume yet but there is no child 250804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard assert(self.children or not path) 251804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 252804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if path: 253804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self._operationPropagate(path, operation) 254326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard else : 255804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("operating on self") 256326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return operation(self) 257804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 258804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _operationPropagate(self, path, operation): 259326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 260804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childName = path.pop(0) 261326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard child = self.getChildFromName(childName) 262326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 263326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return child.operationOnChild(path, operation) 264804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 265804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 266326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 267804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def debug(self, stringOrFunction, level=logging.DEBUG): 268804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """Print a debug line on stderr in tree form 269804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 270804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard If the debug line is expensive to generate, provide callable 271804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard object, it will be called if log is enable for this level. 272326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard This callable object should return the logline string. 273804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """ 274804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if logger.isEnabledFor(level): 275804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 276804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # TODO: use buildin callable if python >= 3.2 277804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if hasattr(stringOrFunction, "__call__"): 278326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard string = stringOrFunction() 279804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else: 280804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard string = stringOrFunction 281326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 282804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard rankedLine = DebugRankedLine("%s: %s" % (self, string)) 283326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self._logDebug(rankedLine, level) 284804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 285804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _logDebug(self, rankedLine, level): 286804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 287804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if self.parent: 288326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.parent._logDebug(rankedLine.increasedRank(), level) 289326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard else : 290326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard logger.log(level, str(rankedLine)) 291326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 292326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 293804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 294804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 295804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass FromDomElement(Element): 296326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def __init__(self, DomElement): 297326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self._initFromDom(DomElement) 298804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().__init__(self.name) 299804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 300326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 301326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def _initFromDom(self, DomElement): 302326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.name = DomElement.getAttribute("Name") 303326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 304804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 305804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 306804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass DomElementLocation(): 307804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, classConstructor, path=None): 308804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.classConstructor = classConstructor 309804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if path : 310326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.path = path 311804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else : 312326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.path = [] 313326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 314326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.path.append(classConstructor.tag) 315804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 316326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 317804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass DomPopulatedElement(Element): 318804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """Default child populate 319804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 320804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard Look for each dom element with tag specified in self.tag 321326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard and instantiate it with the dom element 322804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """ 323326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard childClasses = [] 324804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 325326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def populate(self, dom): 326804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 327804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for childDomElementLocation in self.childClasses : 328326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 329804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Looking for child %s in path %s" % ( 330326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard childDomElementLocation.path[-1], childDomElementLocation.path)) 331804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 332804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for childDomElement in self._findChildFromTagPath(dom, childDomElementLocation.path) : 333326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 334804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childElement = childDomElementLocation.classConstructor(childDomElement) 335326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.addChild(childElement) 336804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 337804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childElement.populate(childDomElement) 338804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 339804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _findChildFromTagPath(self, dom, path): 340804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if not path : 341804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard yield dom 342326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard else : 343804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Copy list 344326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard path = list(path) 345804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 346804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = path.pop(0) 347804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 348326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard # Find element with tag 349804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Going to find elements with tag %s in %s" % (tag, dom)) 350326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug(lambda: "Nb of solutions: %s" % len(dom.getElementsByTagName(tag))) 351804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 352326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for elementByTag in dom.getElementsByTagName(tag) : 353804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 354804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Found element: %s" % elementByTag) 355326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 356804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # If the same tag is found 357804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if elementByTag in dom.childNodes : 358804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 359326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard # Yield next level 360326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for element in self._findChildFromTagPath(elementByTag, path) : 361326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard yield element 362326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 363804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 364804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Rule(Element): 365804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 366326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def usedIfApplicable(self, criteria): 367804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childApplicability = (child.usedIfApplicable(criteria) 368326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for child in self.children) 369804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 370804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard isApplicable = self._isApplicable(criteria, childApplicability) 371326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 372804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if isApplicable : 373804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._incNbUse() 374326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 375804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Rule applicability: %s" % isApplicable) 376326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard assert(isApplicable == True or isApplicable == False) 377326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 378804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return isApplicable 379804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 380cf031996ede8428065b6d7648e34720a1874f5faKevin Rocard 381804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _isApplicable(self, criteria, childApplicability): 382804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Forcing evaluation of all child by the list creation 383804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return all(list(childApplicability)) 384326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 385326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 386326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardclass CriterionRule(FromDomElement, DomPopulatedElement, Rule): 387804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "SelectionCriterionRule" 388804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childClasses = [] 389804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard isApplicableOperations = { 390804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "Includes" : lambda criterion, value: criterion.stateIncludes(value), 391804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "Excludes" : lambda criterion, value: not criterion.stateIncludes(value), 392804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "Is" : lambda criterion, value: criterion.stateIs(value), 393804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "IsNot" : lambda criterion, value: not criterion.stateIs(value) 394804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard } 395326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 396804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _initFromDom(self, DomElement): 397804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.selectionCriterion = DomElement.getAttribute("SelectionCriterion") 398804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.matchesWhen = DomElement.getAttribute("MatchesWhen") 399804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.value = DomElement.getAttribute("Value") 400804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.name = "%s %s %s" % (self.selectionCriterion, self.matchesWhen, self.value) 401326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 402804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard applicableOperationWithoutValue = self.isApplicableOperations[self.matchesWhen] 403804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.isApplicableOperation = lambda criterion: applicableOperationWithoutValue(criterion, self.value) 404326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 405804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _isApplicable(self, criteria, childApplicability): 406326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 407804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return criteria.operationOnChild([self.selectionCriterion], 408804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.isApplicableOperation) 409326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 410326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 411326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardclass CompoundRule(FromDomElement, DomPopulatedElement, Rule): 412804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """CompoundRule can be of type ALL or ANY""" 413804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "CompoundRule" 414804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Declare childClasses but define it at first class instantiation 415804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childClasses = None 416326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 417804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, dom): 418804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Define childClasses at first class instantiation 419804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if self.childClasses == None : 420804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.childClasses = [DomElementLocation(CriterionRule), 421804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard DomElementLocation(CompoundRule)] 422804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().__init__(dom) 423326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 424804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _initFromDom(self, DomElement): 425326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 426804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard type = DomElement.getAttribute("Type") 427804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.ofTypeAll = {"All" : True, "Any" : False}[type] 428804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.name = type 429326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 430804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _isApplicable(self, criteria, childApplicability): 431804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if self.ofTypeAll : 432804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard applicability = super()._isApplicable(criteria, childApplicability) 433804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else: 434804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Forcing evaluation of all child by the list creation 435804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard applicability = any(list(childApplicability)) 436326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 437804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return applicability 438326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 439326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardclass RootRule(DomPopulatedElement, Rule): 440804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "RootRule" 441804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childClasses = [DomElementLocation(CompoundRule)] 442326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 443804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def populate(self, dom): 444804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().populate(dom) 445804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Children: %s" % self.children) 446804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # A configuration can only have one or no rule 447804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard assert(len(self.children) <= 1) 448326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 449804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _getCoverageDependance(self): 450804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self._getDescendants() 451326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 452326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 453326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardclass CriteronStates(Element): 454804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """Root of configuration application criterion state""" 455804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "CriterionStates" 456326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 457804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def parentUsed(self, criteria): 458804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """Add criteria to child if not exist, if exist increase it's nbUse""" 459804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._incNbUse() 460326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 461804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard matches = [child for child in self.children if child == criteria] 462326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 463804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard assert(len(matches) <= 1) 464326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 465804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if matches : 466804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Criteria state has already been encounter") 467804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard currentcriteria = matches[0] 468804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else : 469804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Criteria state has never been encounter, saving it") 470804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard currentcriteria = criteria 471804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.addChild(criteria) 472326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 473804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard currentcriteria.parentUsed() 474326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 475326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardclass IneligibleConfigurationAppliedError(CustomError): 476326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 477326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def __init__(self, configuration, criteria): 478804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.configuration = configuration 479804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.criteria = criteria 480326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 481804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __str__(self): 48297dbd35c75ee252a674aff3d66293d55fc0b35a5Kevin Rocard 483804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return ("Applying ineligible %s, " 484804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "rule:\n%s\n" 485804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "Criteria current state:\n%s" % 48697dbd35c75ee252a674aff3d66293d55fc0b35a5Kevin Rocard (self.configuration, self.configuration.rootRule.dump(), self.criteria.dump())) 487804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 48897dbd35c75ee252a674aff3d66293d55fc0b35a5Kevin Rocard 489804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Configuration(FromDomElement, DomPopulatedElement): 490804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "Configuration" 491804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard childClasses = [] 492804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 493804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, DomElement): 494804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().__init__(DomElement) 495804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 49697dbd35c75ee252a674aff3d66293d55fc0b35a5Kevin Rocard self.rootRule = RootRule("RootRule") 497804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.addChild(self.rootRule) 498804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 499326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.criteronStates = CriteronStates("CriterionStates") 500804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.addChild(self.criteronStates) 501804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 502326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def populate(self, dom): 503804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Delegate to rootRule 504804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.rootRule.populate(dom) 505326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 506804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _getCoverage(self): 507804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Delegate to rootRule 508804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self.rootRule._getCoverage() 509326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 510804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def used(self, criteria): 511804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 512804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._incNbUse() 513326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 514804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Propagate use to parents 515326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self._tellParentThatChildUsed() 516804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 517326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard # Propagate to criterion coverage 518804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.criteronStates.parentUsed(criteria.export()) 519804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 520326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard # Propagate to rules 521804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if not self.rootRule.usedIfApplicable(criteria) : 522804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 523326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("Applied but rule does not match current " 524804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "criteria (parent: %s) " % self.parent.name, 525804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logging.FATAL) 526326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 527804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard raise IneligibleConfigurationAppliedError(self, criteria.export()) 5283aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard 529804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _dumpPropagate(self, withCoverage, withNbUse): 530326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("Going to ask %s for description" % self.rootRule) 531804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for dumpedDescription in self.rootRule._dumpDescription( 532326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard withCoverage=withCoverage, 533804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard withNbUse=withNbUse) : 534804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard yield dumpedDescription.increasedRank() 535804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 536804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Going to ask %s for description" % self.criteronStates) 537804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for dumpedDescription in self.criteronStates._dumpDescription( 538804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard withCoverage=False, 539326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard withNbUse=withNbUse) : 540804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard yield dumpedDescription.increasedRank() 541804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 542804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 543804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Domain(FromDomElement, DomPopulatedElement): 544804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "ConfigurableDomain" 545326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard childClasses = [DomElementLocation(Configuration, ["Configurations"])] 546326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 547326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 548804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Domains(DomPopulatedElement): 549804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "Domains" 550326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard childClasses = [DomElementLocation(Domain, ["ConfigurableDomains"])] 551326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 552326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 553804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass RankedLine(): 554804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, string, 555326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard stringPrefix="|-- ", 556326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard rankString="| ", 557326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard linePrefix="", 558804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard lineSuffix="\n"): 559804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.string = string 560804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.rank = 0 561804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.stringPrefix = stringPrefix 562804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.rankString = rankString 563804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.linePrefix = linePrefix 564804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.lineSuffix = lineSuffix 565804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 566804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def increasedRank(self): 567804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.rank += 1 568804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self 569804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 570804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __str__(self): 571804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self.linePrefix + \ 572804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.rank * self.rankString + \ 573804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.stringPrefix + \ 574804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.string + \ 575804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.lineSuffix 576804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 577804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass DebugRankedLine(RankedLine): 578804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 579804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, string, lineSuffix=""): 580326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard super().__init__(string, 581326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard stringPrefix="", 582326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard rankString=" ", 583804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard linePrefix="", 584804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard lineSuffix=lineSuffix) 585804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 586804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 587804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass CriterionState(Element): 588804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "CriterionState" 589326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def used(self): 590326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self._incNbUse() 591326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 592804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 593804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Criterion(Element): 594804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "Criterion" 595326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard inclusivenessTranslate = {True: "Inclusive", False: "Exclusive"} 596326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 597326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def __init__(self, name, isInclusif, stateNamesList, currentStateNamesList): 598804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().__init__(name) 599804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.isInclusif = isInclusif 6003aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard 601804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for state in stateNamesList : 602804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.addChild(CriterionState(state)) 603804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 604804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.currentState = [] 605556538e2bda03b54bdd82c5813a5286e90a39f67Kevin Rocard 606804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Set current state as provided 607804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.currentState = [self.getChildFromName(childName) 608804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for childName in currentStateNamesList] 609556538e2bda03b54bdd82c5813a5286e90a39f67Kevin Rocard 610804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def childUsed(self, child): 611804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.currentState = child 612804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().childUsed(child) 613804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 614804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def changeState(self, subStateNames): 615326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("Changing state from: %s to: %s" % ( 616804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard list(self._getElementNames(self.currentState)), 617804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard subStateNames)) 618326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 619804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard assert(len(subStateNames) > 0 or self.isInclusif) 620804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 621804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard newCurrentState = [] 622326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for subStateName in subStateNames : 623804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard subState = self.getChildFromName(subStateName) 624804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard subState.used() 625804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard newCurrentState.append(subState) 626326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 627804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.currentState = newCurrentState 628804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 629804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._incNbUse() 630804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self._tellParentThatChildUsed() 631326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 632804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def export(self): 633804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard subStateNames = self._getElementNames(self.currentState) 634804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return Criterion(self.name, self.isInclusif, subStateNames, subStateNames) 635326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 636804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def stateIncludes(self, subStateName): 637804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard subStateCurrentNames = list(self._getElementNames(self.currentState)) 638804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 639804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("Testing if %s is included in %s" % (subStateName, subStateCurrentNames)) 640804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 641326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard isIncluded = subStateName in subStateCurrentNames 642804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debug("IsIncluded: %s" % isIncluded) 643326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 644804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return isIncluded 645804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 646326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 647804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def stateIs(self, subStateNames): 648804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if len(self.currentState) != 1 : 649556538e2bda03b54bdd82c5813a5286e90a39f67Kevin Rocard return False 650804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else : 651804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return self.stateIncludes(subStateNames) 652804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 653556538e2bda03b54bdd82c5813a5286e90a39f67Kevin Rocard def _getXMLAttributes(self): 654804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard attributes = super()._getXMLAttributes() 655804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard attributes["Type"] = self.inclusivenessTranslate[self.isInclusif] 656804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return attributes 657804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 658326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 659804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Criteria(Element): 660804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard tag = "Criteria" 661326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 662804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def export(self): 663326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.debug("Exporting criteria") 664804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard assert(self.children) 665804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 666326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard exported = Criteria(self.name) 667804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children : 668326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard exported.addChild(child.export()) 669326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return exported 670804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 671804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def addChild(self, child): 672804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if child in self.children: 673804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard raise DuplicatedChildError(self, child) 674804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().addChild(child) 675326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 676804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass ConfigAppliedWithoutCriteriaError(CustomError): 677804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, configurationName, domainName): 678804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.configurationName = configurationName 679804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.domainName = domainName 6803aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard def __str__(self): 681326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return ('Applying configuration "%s" from domain "%s" before declaring criteria' % 682326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard (self.configurationName, self.domainName)) 683804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 684326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocardclass ParsePFWlog(): 685804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard MATCH = "match" 686804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ACTION = "action" 687d077c557e360615a67d97ee249260a1ef7919f09Kevin Rocard 688804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, domains, criteria): 689804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 690804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.domains = domains; 691326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.criteria = criteria; 692804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 693804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard configApplicationRegext = r""".*Applying configuration "(.*)" from domain "([^"]*)""" 694804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard matchConfigApplicationLine = re.compile(configApplicationRegext).match 695804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 696326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard criterionCreationRegext = ", ".join([ 697804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard r""".*Criterion name: (.*)""", 698804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard r"""type kind: (.*)""", 699804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard r"""current state: (.*)""", 700804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard r"""states: {(.*)}""" 7013aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard ]) 7023aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard matchCriterionCreationLine = re.compile(criterionCreationRegext).match 703804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 704804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard changingCriterionRegext = r""".*Selection criterion changed event: Criterion name: (.*), current state: ([^\n\r]*)""" 705804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard matchChangingCriterionLine = re.compile(changingCriterionRegext).match 706804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 707804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.lineLogTypes = [ 708804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard { 709326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.MATCH: matchConfigApplicationLine, 710326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.ACTION: self._configApplication 711804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard }, { 712804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.MATCH: matchCriterionCreationLine, 713804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.ACTION: self._criterionCreation 714804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard }, { 715804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.MATCH: matchChangingCriterionLine, 716804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.ACTION: self._changingCriterion 717804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard } 718804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ] 719326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 720804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard @staticmethod 721804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _formatCriterionList(liststring, separator): 722804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard list = liststring.split(separator) 723804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if len(list) == 1 and list[0] == "<none>": 724804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard list = [] 725804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return list 726804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 727804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _criterionCreation(self, matchCriterionCreation): 728804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Unpack 729804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard criterionName, criterionType, currentCriterionStates, criterionStates = matchCriterionCreation.group(1, 2, 3, 4) 730326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 731804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard criterionStateList = self._formatCriterionList(criterionStates, ", ") 732804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 733326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard criterionIsInclusif = {"exclusive" : False, "inclusive" : True}[criterionType] 734804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 735804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard currentcriterionStateList = self._formatCriterionList(currentCriterionStates, "|") 736804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 737804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.info("Creating criterion: " + criterionName + 738804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard " (" + criterionType + ") " + 739804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard " with current state: " + str(currentcriterionStateList) + 740804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ", possible states:" + str(criterionStateList)) 741804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 742804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.criteria.addChild(Criterion( 743804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard criterionName, 744804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard criterionIsInclusif, 745804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard criterionStateList, 746326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard currentcriterionStateList 747804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard )) 748804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 749804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _changingCriterion(self, matchChangingCriterion): 750804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Unpack 751804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard criterionName, newCriterionSubStateNames = matchChangingCriterion.group(1, 2) 752804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 753804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard newCriterionState = self._formatCriterionList(newCriterionSubStateNames, "|") 754804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 755804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.info("Changing criterion %s to %s" % (criterionName , newCriterionState)) 756804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 757326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard path = [criterionName] 758804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard changeCriterionOperation = lambda criterion : criterion.changeState(newCriterionState) 759326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.criteria.operationOnChild(path, changeCriterionOperation) 760804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 761326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard def _configApplication(self, matchConfig): 762804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Unpack 763326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard configurationName, domainName = matchConfig.group(1, 2) 764804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 765804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Check that at least one criterion exist 766804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if not self.criteria.hasChildren() : 767804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.error("Applying configuration before declaring criteria") 768326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard logger.info("Is the log starting at PFW boot ?") 769804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard raise ConfigAppliedWithoutCriteriaError(configurationName, domainName) 770804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 771804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Change criterion state 772804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard path = [domainName, configurationName] 773804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard usedOperation = lambda element : element.used(self.criteria) 774804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 775804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.info("Applying configuration %s from domain %s" % ( 776804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard configurationName, domainName)) 777804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 778804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.domains.operationOnChild(path, usedOperation) 779804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 780804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 781804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def _digest(self, lineLogType, lineLog): 782804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard match = lineLogType[self.MATCH](lineLog) 783ea87422e14735633cb8e28de114a18e22eaa82fbKevin Rocard if match : 784ea87422e14735633cb8e28de114a18e22eaa82fbKevin Rocard lineLogType[self.ACTION](match) 785326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard return True 786804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return False 787804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 788804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def parsePFWlog(self, lines): 789326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard for lineLog in lines: 790804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 791326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard logger.debug("Parsing line :%s" % lineLog.rstrip()) 792804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 7933aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard digested = (self._digest(lineLogType, lineLog) 794804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for lineLogType in self.lineLogTypes) 795804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 796804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if not any(digested): 797326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard logger.debug("Line does not match, dropped") 798804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 799804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 800804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass Root(Element): 8013aa0db4be952157c2842b91a1606cc0edac9e63dKevin Rocard tag = "Root" 802804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self, name, dom): 803804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard super().__init__(name) 804804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Create domain tree 805804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.domains = Domains("Domains") 806804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.domains.populate(dom) 807326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.addChild(self.domains) 808804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Create criterion list 809804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.criteria = Criteria("CriterionRoot") 810804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.addChild(self.criteria) 811326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 812804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def exportToXML(self): 813804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """Export tree to an xml document""" 814804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard impl = xml.dom.minidom.getDOMImplementation() 815804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard newdoc = impl.createDocument(None, self.name, None) 816326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard XMLDocElement = newdoc.documentElement 817326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 818804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard for child in self.children: 8199050c81c8f9a63aa95e7230705e00585bd0ecec5Kevin Rocard XMLDocElement.appendChild(child.exportToXML()) 820804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 821804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard return newdoc 822804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 823804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard# ============================ 824804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard# Command line argument parser 825326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard# ============================ 8269050c81c8f9a63aa95e7230705e00585bd0ecec5Kevin Rocard 827804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 828804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardclass ArgumentParser: 829326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard """class that parse command line arguments with argparse library 830804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 831326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard Result of parsing are the class attributes. 832804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard """ 833804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard levelTranslate = [logging.WARNING, logging.INFO, logging.DEBUG] 834326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 835804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard def __init__(self): 836804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 8379050c81c8f9a63aa95e7230705e00585bd0ecec5Kevin Rocard try: 838804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # As argparse is only in the stdlib since python 3.2, 839804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # testing its availability 840804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard import argparse 841804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 842804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard except ImportError: 8439050c81c8f9a63aa95e7230705e00585bd0ecec5Kevin Rocard logger.warning("Unable to import argparse " 844804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "(parser for command-line options and arguments), " 845804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard "using default argument values:") 846804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 847804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.warning(" - InputFile: stdin") 848804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.inputFile = sys.stdin 849804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 850804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.warning(" - OutputFile: stdout") 851804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.outputFile = sys.stdout 852804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 853804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard try: 854326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard self.domainsFile = sys.argv[1] 855326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard except IndexError as ex: 856326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard logger.fatal("No domain file provided (first argument)") 857804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard raise ex 858804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else: 859804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.warning(" - Domain file: " + self.domainsFile) 860804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 861804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.warning(" - Output format: xml") 862804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.XMLreport = True 863804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 864804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.warning(" - Debug level: error") 865804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debugLevel = logging.INFO 866804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else : 867804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 868804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard myArgParser = argparse.ArgumentParser(description='Generate PFW report') 869804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 870804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard myArgParser.add_argument( 871804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 'domainsFile', 872804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard type=argparse.FileType('r'), 873804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard help="the PFW domain XML file" 874804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ) 875326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard myArgParser.add_argument( 876326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard 'pfwlog', nargs='?', 877326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard type=argparse.FileType('r'), default=sys.stdin, 878326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard help="the PFW log file, default stdin" 879326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard ) 880326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard myArgParser.add_argument( 881326e39e42a801bff4b61655ebc0e3ff759c208ffKevin Rocard '-o', '--output', 882804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard dest="outputFile", 883804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard type=argparse.FileType('w'), default=sys.stdout, 884804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard help="the coverage report output file, default stdout" 885804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ) 886804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard myArgParser.add_argument( 887804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard '-v', '--verbose', 888804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard dest="debugLevel", default=0, 889804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard action='count', 890804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard help="print debug warnings from warning (default) to debug (-vv)" 891804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ) 892804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 893804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard outputFormatGroupe = myArgParser.add_mutually_exclusive_group(required=False) 894804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 895804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard outputFormatGroupe.add_argument( 896804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard '--xml', 897804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard dest="xmlFlag", 898804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard action='store_true', 899804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard help=" XML coverage output report" 900804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ) 901804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard outputFormatGroupe.add_argument( 902804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard '--raw', 903804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard dest="rawFlag", 904804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard action='store_true', 905804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard help="raw coverage output report" 906804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard ) 907804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 908804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Process command line arguments 909804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard options = myArgParser.parse_args() 910804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 911804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Mapping to attributes 912804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.inputFile = options.pfwlog 913804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.outputFile = options.outputFile 914804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.domainsFile = options.domainsFile 915804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 916804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Output report in xml if flag not set 917804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.XMLreport = not options.rawFlag 918804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 919804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Setting logger level 920804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard levelCapped = min(options.debugLevel, len(self.levelTranslate) - 1) 921804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard self.debugLevel = self.levelTranslate[levelCapped] 922804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 923804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 924804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 925804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocarddef main(): 926804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 927804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard errorDuringLogParsing = -1 928804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard errorDuringArgumentParsing = 1 929804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 930804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard try: 931804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard commandLineArguments = ArgumentParser() 932804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard except LookupError as ex: 933804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.error("Error during argument parsing") 934804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.debug(str(ex)) 935804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard sys.exit(errorDuringArgumentParsing) 936804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 937804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Setting logger level 938804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.setLevel(commandLineArguments.debugLevel) 939804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.info("Log level set to: %s" % 940804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logging.getLevelName(commandLineArguments.debugLevel)) 941804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 942804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Create tree from XML 943804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard dom = xml.dom.minidom.parse(commandLineArguments.domainsFile) 944804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 945804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Create element tree 946804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard root = Root("Coverage", dom) 947804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 948804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Parse PFW events 949804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard parser = ParsePFWlog(root.domains, root.criteria) 950804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 951804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard try: 952804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard parser.parsePFWlog(commandLineArguments.inputFile.readlines()) 953804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard except CustomError as ex: 954804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard logger.fatal("Error during parsing log file %s: %s" % 955804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard (commandLineArguments.inputFile, ex)) 956804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard sys.exit(errorDuringLogParsing) 957804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 958804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard # Output report 959804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard outputFile = commandLineArguments.outputFile 960804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 961804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard if not commandLineArguments.XMLreport : 962804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard outputFile.write("%s\n" % root.dump(withCoverage=True, withNbUse=True)) 963804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard else : 964804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard outputFile.write(root.exportToXML().toprettyxml()) 965804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 966804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 967804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard# Execute main function if the python interpreter is running this module as the main program 968804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocardif __name__ == "__main__" : 969804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard main() 970804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard 971804e064dcd02b87e04b9a189422cc14205e8125cKevin Rocard