3 import sys, re, os.path
4 from xml.dom.minidom import parse
6 class TestInfo(object):
8 def __init__(self, xmlnode):
9 self.fixture = xmlnode.getAttribute("classname")
10 self.name = xmlnode.getAttribute("name")
11 self.value_param = xmlnode.getAttribute("value_param")
12 self.type_param = xmlnode.getAttribute("type_param")
13 if xmlnode.getElementsByTagName("failure"):
14 self.status = "failed"
16 self.status = xmlnode.getAttribute("status")
17 if self.name.startswith("DISABLED_"):
18 self.status = "disabled"
19 self.fixture = self.fixture.replace("DISABLED_", "")
20 self.name = self.name.replace("DISABLED_", "")
22 self.parseLongMetric(xmlnode, "bytesIn");
23 self.parseLongMetric(xmlnode, "bytesOut");
24 self.parseIntMetric(xmlnode, "samples");
25 self.parseIntMetric(xmlnode, "outliers");
26 self.parseFloatMetric(xmlnode, "frequency", 1);
27 self.parseLongMetric(xmlnode, "min");
28 self.parseLongMetric(xmlnode, "median");
29 self.parseLongMetric(xmlnode, "gmean");
30 self.parseLongMetric(xmlnode, "mean");
31 self.parseLongMetric(xmlnode, "stddev");
32 self.parseFloatMetric(xmlnode, "gstddev");
33 self.parseFloatMetric(xmlnode, "time");
35 def parseLongMetric(self, xmlnode, name, default = 0):
36 if xmlnode.hasAttribute(name):
37 tmp = xmlnode.getAttribute(name)
39 self.metrix[name] = val
41 self.metrix[name] = default
43 def parseIntMetric(self, xmlnode, name, default = 0):
44 if xmlnode.hasAttribute(name):
45 tmp = xmlnode.getAttribute(name)
47 self.metrix[name] = val
49 self.metrix[name] = default
51 def parseFloatMetric(self, xmlnode, name, default = 0):
52 if xmlnode.hasAttribute(name):
53 tmp = xmlnode.getAttribute(name)
55 self.metrix[name] = val
57 self.metrix[name] = default
59 def parseStringMetric(self, xmlnode, name, default = None):
60 if xmlnode.hasAttribute(name):
61 tmp = xmlnode.getAttribute(name)
62 self.metrix[name] = tmp.strip()
64 self.metrix[name] = default
66 def get(self, name, units="ms"):
67 if name == "classname":
71 if name == "fullname":
73 if name == "value_param":
74 return self.value_param
75 if name == "type_param":
76 return self.type_param
79 val = self.metrix.get(name, None)
83 return self.metrix.get("time")
84 if name in ["gmean", "min", "mean", "median", "stddev"]:
86 frequency = self.metrix.get("frequency", 1.0) or 1.0
96 return val * scale / frequency
100 def dump(self, units="ms"):
101 print "%s ->\t\033[1;31m%s\033[0m = \t%.2f%s" % (str(self), self.status, self.get("gmean", units), units)
104 pos = self.name.find("/")
106 name = self.name[:pos]
109 if self.fixture.endswith(name):
110 fixture = self.fixture[:-len(name)]
112 fixture = self.fixture
113 if fixture.endswith("_"):
114 fixture = fixture[:-1]
115 return '::'.join(filter(None, [name, fixture]))
118 pos = self.name.find("/")
120 name = self.name[:pos]
123 if self.fixture.endswith(name):
124 fixture = self.fixture[:-len(name)]
126 fixture = self.fixture
127 if fixture.endswith("_"):
128 fixture = fixture[:-1]
129 return '::'.join(filter(None, [name, fixture, self.type_param, self.value_param]))
131 def __cmp__(self, other):
132 r = cmp(self.fixture, other.fixture);
137 r = cmp(self.type_param, other.type_param);
146 if other.value_param:
147 r = cmp(self.value_param, other.value_param);
153 if other.value_param:
157 def parseLogFile(filename):
159 log = parse(filename)
160 for case in log.getElementsByTagName("testcase"):
161 tests.append(TestInfo(case))
165 if __name__ == "__main__":
166 if len(sys.argv) < 2:
167 print "Usage:\n", os.path.basename(sys.argv[0]), "<log_name>.xml"
170 for arg in sys.argv[1:]:
171 print "Tests found in", arg
172 tests = parseLogFile(arg)
173 for t in sorted(tests):