The Gaudi Framework  v31r0 (aeb156f0)
GaudiTest.XMLResultStream Class Reference
Inheritance diagram for GaudiTest.XMLResultStream:
Collaboration diagram for GaudiTest.XMLResultStream:

Public Member Functions

def __init__ (self, arguments=None, args)
 
def WriteAnnotation (self, key, value)
 
def WriteResult (self, result)
 
def Summarize (self)
 

Static Public Attributes

list arguments
 

Private Attributes

 _xmlFile
 
 _startTime
 
 _endTime
 
 _tree
 
 _site
 
 _Testing
 
 _StartDateTime
 
 _StartTestTime
 
 _TestList
 
 _EndDateTime
 
 _EndTestTime
 
 _ElapsedMinutes
 

Detailed Description

An 'XMLResultStream' writes its output to a Ctest XML file.

The argument 'dir' is used to select the destination file for the XML
report.
The destination directory may already contain the report from a previous run
(for example of a different package), in which case it will be overrided to
with the new data.

Definition at line 2096 of file GaudiTest.py.

Constructor & Destructor Documentation

def GaudiTest.XMLResultStream.__init__ (   self,
  arguments = None,
  args 
)
Prepare the destination directory.

Creates the destination directory and store in it some preliminary
annotations .

Definition at line 2123 of file GaudiTest.py.

2123  def __init__(self, arguments=None, **args):
2124  """Prepare the destination directory.
2125 
2126  Creates the destination directory and store in it some preliminary
2127  annotations .
2128  """
2129  ResultStream.__init__(self, arguments, **args)
2130 
2131  self._xmlFile = os.path.join(self.dir, self.prefix + 'Test.xml')
2132 
2133  # add some global variable
2134  self._startTime = None
2135  self._endTime = None
2136  # Format the XML file if it not exists
2137  if not os.path.isfile(self._xmlFile):
2138  # check that the container directory exists and create it if not
2139  if not os.path.exists(os.path.dirname(self._xmlFile)):
2140  os.makedirs(os.path.dirname(self._xmlFile))
2141 
2142  newdataset = ET.Element("newdataset")
2143  self._tree = ET.ElementTree(newdataset)
2144  self._tree.write(self._xmlFile)
2145  else:
2146  # Read the xml file
2147  self._tree = ET.parse(self._xmlFile)
2148  newdataset = self._tree.getroot()
2149 
2150  # Find the corresponding site, if do not exist, create it
2151 
2152  #site = newdataset.find('Site[@BuildStamp="'+result["qmtest.start_time"]+'"][@OSPlatform="'+os.getenv("CMTOPT")+'"]')
2153  # I don't know why this syntax doesn't work. Maybe it is because of the python version. Indeed,
2154  # This works well in the python terminal. So I have to make a for:
2155  for site in newdataset.getiterator():
2156  # and site.get("BuildStamp") == result["qmtest.start_time"] and:
2157  if site.get("OSPlatform") == os.uname()[4]:
2158  # Here we can add some variable to define the difference beetween 2 site
2159  self._site = site
2160  break
2161  else:
2162  site = None
2163 
2164  if site is None:
2165  import socket
2166  import multiprocessing
2167  attrib = {
2168  "BuildName": os.getenv("CMTCONFIG"),
2169  "Name": os.uname()[1],
2170  "Generator": "QMTest " + qm.version,
2171  "OSName": os.uname()[0],
2172  "Hostname": socket.gethostname(),
2173  "OSRelease": os.uname()[2],
2174  "OSVersion": os.uname()[3],
2175  "OSPlatform": os.uname()[4],
2176  "Is64Bits": "unknown",
2177  "VendorString": "unknown",
2178  "VendorID": "unknown",
2179  "FamilyID": "unknown",
2180  "ModelID": "unknown",
2181  "ProcessorCacheSize": "unknown",
2182  "NumberOfLogicalCPU": str(multiprocessing.cpu_count()),
2183  "NumberOfPhysicalCPU": "0",
2184  "TotalVirtualMemory": "0",
2185  "TotalPhysicalMemory": "0",
2186  "LogicalProcessorsPerPhysical": "0",
2187  "ProcessorClockFrequency": "0",
2188  }
2189  self._site = ET.SubElement(newdataset, "Site", attrib)
2190  self._Testing = ET.SubElement(self._site, "Testing")
2191 
2192  # Start time elements
2193  self._StartDateTime = ET.SubElement(self._Testing, "StartDateTime")
2194 
2195  self._StartTestTime = ET.SubElement(self._Testing, "StartTestTime")
2196 
2197  self._TestList = ET.SubElement(self._Testing, "TestList")
2198 
2199  # End time elements
2200  self._EndDateTime = ET.SubElement(self._Testing, "EndDateTime")
2201 
2202  self._EndTestTime = ET.SubElement(self._Testing, "EndTestTime")
2203 
2204  self._ElapsedMinutes = ET.SubElement(self._Testing,
2205  "ElapsedMinutes")
2206 
2207  else: # We get the elements
2208  self._Testing = self._site.find("Testing")
2209  self._StartDateTime = self._Testing.find("StartDateTime")
2210  self._StartTestTime = self._Testing.find("StartTestTime")
2211  self._TestList = self._Testing.find("TestList")
2212  self._EndDateTime = self._Testing.find("EndDateTime")
2213  self._EndTestTime = self._Testing.find("EndTestTime")
2214  self._ElapsedMinutes = self._Testing.find("ElapsedMinutes")
2215  """
2216  # Add some non-QMTest attributes
2217  if "CMTCONFIG" in os.environ:
2218  self.WriteAnnotation("cmt.cmtconfig", os.environ["CMTCONFIG"])
2219  import socket
2220  self.WriteAnnotation("hostname", socket.gethostname())
2221  """
2222 
def __init__(self, arguments=None, args)
Definition: GaudiTest.py:2123

Member Function Documentation

def GaudiTest.XMLResultStream.Summarize (   self)

Definition at line 2384 of file GaudiTest.py.

2384  def Summarize(self):
2385 
2386  # Set the final end date time
2387  self._EndTestTime.text = str(self._endTime)
2388  self._EndDateTime.text = time.strftime("%b %d %H:%M %Z",
2389  time.localtime(self._endTime))
2390 
2391  # Compute the total duration
2392  if self._endTime and self._startTime:
2393  delta = self._endTime - self._startTime
2394  else:
2395  delta = 0
2396  self._ElapsedMinutes.text = str(delta / 60)
2397 
2398  # Write into the file
2399  # ,True) in python 2.7 to add the xml header
2400  self._tree.write(self._xmlFile, "utf-8")
def GaudiTest.XMLResultStream.WriteAnnotation (   self,
  key,
  value 
)

Definition at line 2223 of file GaudiTest.py.

2223  def WriteAnnotation(self, key, value):
2224  if key == "qmtest.run.start_time":
2225  if self._site.get("qmtest.run.start_time") is not None:
2226  return None
2227  self._site.set(str(key), str(value))
2228 
def WriteAnnotation(self, key, value)
Definition: GaudiTest.py:2223
def GaudiTest.XMLResultStream.WriteResult (   self,
  result 
)
Prepare the test result directory in the destination directory storing
into it the result fields.
A summary of the test result is stored both in a file in the test directory
and in the global summary file.

Definition at line 2229 of file GaudiTest.py.

2229  def WriteResult(self, result):
2230  """Prepare the test result directory in the destination directory storing
2231  into it the result fields.
2232  A summary of the test result is stored both in a file in the test directory
2233  and in the global summary file.
2234  """
2235  summary = {}
2236  summary["id"] = result.GetId()
2237  summary["outcome"] = result.GetOutcome()
2238  summary["cause"] = result.GetCause()
2239  summary["fields"] = result.keys()
2240  summary["fields"].sort()
2241 
2242  # Since we miss proper JSON support, I hack a bit
2243  for f in ["id", "outcome", "cause"]:
2244  summary[f] = str(summary[f])
2245  summary["fields"] = map(str, summary["fields"])
2246 
2247  # format
2248  # package_Test.xml
2249 
2250  if "qmtest.start_time" in summary["fields"]:
2251  haveStartDate = True
2252  else:
2253  haveStartDate = False
2254  if "qmtest.end_time" in summary["fields"]:
2255  haveEndDate = True
2256  else:
2257  haveEndDate = False
2258 
2259  # writing the start date time
2260  if haveStartDate:
2261  self._startTime = calendar.timegm(
2262  time.strptime(result["qmtest.start_time"],
2263  "%Y-%m-%dT%H:%M:%SZ"))
2264  if self._StartTestTime.text is None:
2265  self._StartDateTime.text = time.strftime(
2266  "%b %d %H:%M %Z", time.localtime(self._startTime))
2267  self._StartTestTime.text = str(self._startTime)
2268  self._site.set("BuildStamp", result["qmtest.start_time"])
2269 
2270  # Save the end date time in memory
2271  if haveEndDate:
2272  self._endTime = calendar.timegm(
2273  time.strptime(result["qmtest.end_time"], "%Y-%m-%dT%H:%M:%SZ"))
2274 
2275  # add the current test to the test list
2276  tl = ET.Element("Test")
2277  tl.text = summary["id"]
2278  self._TestList.insert(0, tl)
2279 
2280  # Fill the current test
2281  Test = ET.Element("Test")
2282  if summary["outcome"] == "PASS":
2283  Test.set("Status", "passed")
2284  elif summary["outcome"] == "FAIL":
2285  Test.set("Status", "failed")
2286  elif summary["outcome"] == "SKIPPED" or summary[
2287  "outcome"] == "UNTESTED":
2288  Test.set("Status", "skipped")
2289  elif summary["outcome"] == "ERROR":
2290  Test.set("Status", "failed")
2291  Name = ET.SubElement(
2292  Test,
2293  "Name",
2294  )
2295  Name.text = summary["id"]
2296  Results = ET.SubElement(Test, "Results")
2297 
2298  # add the test after the other test
2299  self._Testing.insert(3, Test)
2300 
2301  if haveStartDate and haveEndDate:
2302  # Compute the test duration
2303  delta = self._endTime - self._startTime
2304  testduration = str(delta)
2305  Testduration = ET.SubElement(Results, "NamedMeasurement")
2306  Testduration.set("name", "Execution Time")
2307  Testduration.set("type", "numeric/float")
2308  value = ET.SubElement(Testduration, "Value")
2309  value.text = testduration
2310 
2311  # remove the fields that we store in a different way
2312  for n in ("qmtest.end_time", "qmtest.start_time", "qmtest.cause",
2313  "ExecTest.stdout"):
2314  if n in summary["fields"]:
2315  summary["fields"].remove(n)
2316 
2317  # Here we can add some NamedMeasurment which we know the type
2318  #
2319  if "ExecTest.exit_code" in summary["fields"]:
2320  summary["fields"].remove("ExecTest.exit_code")
2321  ExitCode = ET.SubElement(Results, "NamedMeasurement")
2322  ExitCode.set("name", "exit_code")
2323  ExitCode.set("type", "numeric/integer")
2324  value = ET.SubElement(ExitCode, "Value")
2325  value.text = convert_xml_illegal_chars(
2326  result["ExecTest.exit_code"])
2327 
2328  TestStartTime = ET.SubElement(Results, "NamedMeasurement")
2329  TestStartTime.set("name", "Start_Time")
2330  TestStartTime.set("type", "String")
2331  value = ET.SubElement(TestStartTime, "Value")
2332  if haveStartDate:
2333  value.text = escape_xml_illegal_chars(
2334  time.strftime("%b %d %H:%M %Z %Y",
2335  time.localtime(self._startTime)))
2336  else:
2337  value.text = ""
2338 
2339  TestEndTime = ET.SubElement(Results, "NamedMeasurement")
2340  TestEndTime.set("name", "End_Time")
2341  TestEndTime.set("type", "String")
2342  value = ET.SubElement(TestEndTime, "Value")
2343  if haveStartDate:
2344  value.text = escape_xml_illegal_chars(
2345  time.strftime("%b %d %H:%M %Z %Y",
2346  time.localtime(self._endTime)))
2347  else:
2348  value.text = ""
2349 
2350  if summary["cause"]:
2351  FailureCause = ET.SubElement(Results, "NamedMeasurement")
2352  FailureCause.set("name", "Cause")
2353  FailureCause.set("type", "String")
2354  value = ET.SubElement(FailureCause, "Value")
2355  value.text = escape_xml_illegal_chars(summary["cause"])
2356 
2357  # Fill the result
2358  fields = {}
2359  for field in summary["fields"]:
2360  fields[field] = ET.SubElement(Results, "NamedMeasurement")
2361  fields[field].set("type", "String")
2362  fields[field].set("name", field)
2363  value = ET.SubElement(fields[field], "Value")
2364  # to escape the <pre></pre>
2365  if "<pre>" in result[field][0:6]:
2366  value.text = convert_xml_illegal_chars(result[field][5:-6])
2367  else:
2368  value.text = convert_xml_illegal_chars(result[field])
2369 
2370  if result.has_key("ExecTest.stdout"): # "ExecTest.stdout" in result :
2371  Measurement = ET.SubElement(Results, "Measurement")
2372  value = ET.SubElement(Measurement, "Value")
2373  if "<pre>" in result["ExecTest.stdout"][0:6]:
2374  value.text = convert_xml_illegal_chars(
2375  result["ExecTest.stdout"][5:-6])
2376  else:
2377  value.text = convert_xml_illegal_chars(
2378  result["ExecTest.stdout"])
2379 
2380  # write the file
2381  # ,True) in python 2.7 to add the xml header
2382  self._tree.write(self._xmlFile, "utf-8")
2383 
def escape_xml_illegal_chars(val, replacement='?')
Definition: GaudiTest.py:368
def WriteResult(self, result)
Definition: GaudiTest.py:2229
struct GAUDI_API map
Parametrisation class for map-like implementation.
def convert_xml_illegal_chars(val)
Definition: GaudiTest.py:364

Member Data Documentation

GaudiTest.XMLResultStream._ElapsedMinutes
private

Definition at line 2204 of file GaudiTest.py.

GaudiTest.XMLResultStream._EndDateTime
private

Definition at line 2200 of file GaudiTest.py.

GaudiTest.XMLResultStream._EndTestTime
private

Definition at line 2202 of file GaudiTest.py.

GaudiTest.XMLResultStream._endTime
private

Definition at line 2135 of file GaudiTest.py.

GaudiTest.XMLResultStream._site
private

Definition at line 2159 of file GaudiTest.py.

GaudiTest.XMLResultStream._StartDateTime
private

Definition at line 2193 of file GaudiTest.py.

GaudiTest.XMLResultStream._StartTestTime
private

Definition at line 2195 of file GaudiTest.py.

GaudiTest.XMLResultStream._startTime
private

Definition at line 2134 of file GaudiTest.py.

GaudiTest.XMLResultStream._Testing
private

Definition at line 2190 of file GaudiTest.py.

GaudiTest.XMLResultStream._TestList
private

Definition at line 2197 of file GaudiTest.py.

GaudiTest.XMLResultStream._tree
private

Definition at line 2143 of file GaudiTest.py.

GaudiTest.XMLResultStream._xmlFile
private

Definition at line 2131 of file GaudiTest.py.

list GaudiTest.XMLResultStream.arguments
static
Initial value:
1 = [
2  qm.fields.TextField(
3  name="dir",
4  title="Destination Directory",
5  description=,
6  verbatim="true",
7  default_value=""),
8  qm.fields.TextField(
9  name="prefix",
10  title="Output File Prefix",
11  description=,
12  verbatim="true",
13  default_value=""),
14  ]

Definition at line 2105 of file GaudiTest.py.


The documentation for this class was generated from the following file: