- import xml.dom.minidom
- # **********************************************************************
- # Get the parent node path to a particular node
- def getNodeParentPath(node, path):
- path = "%s.%s" % (node.nodeName, path)
- if node.parentNode != None and node.parentNode.nodeType != node.DOCUMENT_NODE:
- path = getNodeParentPath(node.parentNode, path)
- return path
- # **********************************************************************
- # Given a node return the full node path to that node
- def getNodeFullPath(node):
- path = node.nodeName
- if node.parentNode != None and node.parentNode.nodeType != node.DOCUMENT_NODE:
- return getNodeParentPath(node.parentNode, path)
- else:
- return path
- # **********************************************************************
- # Given a document return the nodeName off the documents root node or
- # create and return if it doesn't already exist
- def getRootNode(nodeName, resultsElement, resultsDoc):
- nodes = resultsElement.getElementsByTagName(nodeName)
- node = nodes.item(0)
- if node == None:
- node = resultsDoc.createElement(nodeName)
- resultsElement.appendChild(node)
- return node
- # **********************************************************************
- # Create an Duration_error node on the resultsElement parameter
- def reportDurationError(baselineDuration, duration, submissionNode):
- submissionNode.setAttributeNS('Duration_delta', 'Duration_delta', '%f' % (duration - baselineDuration))
- # **********************************************************************
- # Create an Attribute_mismatch node on the resultsElement parameter
- def reportAttributeMismatch(node, attributeName, expecting, found, resultElement, resultsDoc):
- # create an xml node to hold the error
- errorNode = resultsDoc.createElement("Attribute_mismatch")
- # get full path of the node that held the mismatched attribute
- path = getNodeFullPath(node)
- # set appropriate attributes on the error node and append to the resultElement
- errorNode.setAttributeNS("Node", "Node", path)
- errorNode.setAttributeNS("Attribute", "Attribute", attributeName)
- errorNode.setAttributeNS("Found", "Found", found)
- errorNode.setAttributeNS("Expecting", "Expecting", expecting)
- getRootNode("Discrepencies", resultElement, resultsDoc).appendChild(errorNode)
- # **********************************************************************
- # Create a Missing_data node on the resultsElement parameter
- def reportMissingData(node, attributeName, resultsElement, resultsDoc):
- # create an xml node to hold the error
- errorNode = resultsDoc.createElement("Missing_data")
- # get full path of the node that held the mismatched attribute
- path = getNodeFullPath(node)
- # set appropriate attributes on the error node and append to the resultElement
- errorNode.setAttributeNS("Node", "Node", path)
- errorNode.setAttributeNS("Attribute", "Attribute", attributeName)
- getRootNode("Data_errors", resultsElement, resultsDoc).appendChild(errorNode)
- # **********************************************************************
- # Given a dump filename (dump from a pathfinder submission), open the file
- # and return the first model node from the xml
- def getModelNodeFromDump(dumpFilename):
- dumpDoc = xml.dom.minidom.parse(dumpFilename)
- submissionModelNodes = dumpDoc.getElementsByTagName('Results')
- submissionModelNode = None
- if submissionModelNodes.length > 0:
- submissionModelNode = submissionModelNodes[0]
- return submissionModelNode
- # **********************************************************************
- # Get a particular submission node from a results doc
- def getSubmissionNode(submissionName, resultsDoc):
- toReturn = None
- submissions = resultsDoc.getElementsByTagName('Submission_report')
- for submissionElement in submissions:
- thisSubmissionName = submissionElement.getAttribute('Name')
- if thisSubmissionName == submissionName:
- toReturn = submissionElement
- break
- return toReturn
- # **********************************************************************
- # Danger, danger! Recursive...
- def compareNodes(node1, node2, resultElement, resultsDoc, indentString):
- # log out some debuggy stuff
- #print "%sComparing nodes: %s and %s" % (indentString, node1.localName, node2.localName)
- errorCount = 0
- # make sure we've got the node we expect to have
- if node1.localName != node2.localName:
- # chuck an error in the error doc
- ReportNodeMismatch(node1, node2, resultElement, resultsDoc)
- errorCount = errorCount + 1
- return
- else:
- # we have matching nodes... check their attributes
- for attributeName in node1.attributes.keys():
- if node2.hasAttribute(attributeName):
- attribute1 = node1.getAttribute(attributeName)
- attribute2 = node2.getAttribute(attributeName)
- if attribute1 != attribute2:
- # values have changed report the chance
- reportAttributeMismatch(node1, attributeName, attribute1, attribute2, resultElement, resultsDoc)
- errorCount = errorCount + 1
- else:
- # node2 doesn't have this expected attribute - report as missing
- reportMissingData(node2, attributeName, resultElement, resultsDoc)
- errorCount = errorCount + 1
- # iterate through any child nodes, checking them in turn
- if node1.hasChildNodes():
- node1Child = node1.firstChild
- while (node1Child != None):
- if (node1Child.nodeType != node1Child.TEXT_NODE):
- node2Children = node2.getElementsByTagName(node1Child.nodeName)
- if node2Children.item(0) == None:
- reportMissingData(node1Child, "", resultElement, resultsDoc)
- errorCount = errorCount + 1
- else:
- errorCount = errorCount + compareNodes(node1Child, node2Children.item(0), resultElement, resultsDoc, indentString + " ")
- node1Child = node1Child.nextSibling
- return errorCount
- # **********************************************************************
- def compareSubmissionDumps(baselineElement, newSubmissionElement, resultElement, resultsDoc):
- # compare the documents, this function is recursive
- return compareNodes(baselineElement, newSubmissionElement, resultElement, resultsDoc, "")