| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Public Member Functions | Static Public Attributes | Private Attributes | List of all members
GaudiTest.XMLResultStream Class Reference
Inheritance diagram for GaudiTest.XMLResultStream:
[legend]
Collaboration diagram for GaudiTest.XMLResultStream:
[legend]

## Public Member Functions
def | __init__
def | WriteAnnotation
def | WriteResult
def | Summarize

## Static Public Attributes
list | arguments

## Private Attributes
| _xmlFile
| _startTime
| _endTime
| _tree
| _site
| _Testing
| _StartDateTime
| _StartTestTime
| _TestList
| _EndDateTime
| End time elements.
| _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 1916 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 1943 of file GaudiTest.py.

1943
1944 def __init__(self, arguments = None, **args):
1945 """Prepare the destination directory.
1946
1947 Creates the destination directory and store in it some preliminary
1948 annotations .
1949 """
1950 ResultStream.__init__(self, arguments, **args)
1951
1952 self._xmlFile = os.path.join(self.dir, self.prefix + 'Test.xml')
1953
1954 # add some global variable
1955 self._startTime = None
1956 self._endTime = None
1957 # Format the XML file if it not exists
1958 if not os.path.isfile(self._xmlFile):
1959 # check that the container directory exists and create it if not
1960 if not os.path.exists(os.path.dirname(self._xmlFile)):
1961 os.makedirs(os.path.dirname(self._xmlFile))
1962
1963 newdataset = ET.Element("newdataset")
1964 self._tree = ET.ElementTree(newdataset)
1965 self._tree.write(self._xmlFile)
1966 else :
1967 # Read the xml file
1968 self._tree = ET.parse(self._xmlFile)
1969 newdataset = self._tree.getroot()
1970
1971 # Find the corresponding site, if do not exist, create it
1972
1973 #site = newdataset.find('Site[@BuildStamp="'+result["qmtest.start_time"]+'"][@OSPlatform="'+os.getenv("CMTOPT")+'"]')
1974 # I don't know why this syntax doesn't work. Maybe it is because of the python version. Indeed,
1975 # This works well in the python terminal. So I have to make a for:
1976 for site in newdataset.getiterator() :
1977 if site.get("OSPlatform") == os.uname()[4]: # and site.get("BuildStamp") == result["qmtest.start_time"] and:
1978 # Here we can add some variable to define the difference beetween 2 site
1979 self._site = site
1980 break
1981 else :
1982 site = None
1983
1984
1985 if site is None :
1986 import socket
1987 import multiprocessing
1988 attrib = {
1989 "BuildName" : os.getenv("CMTCONFIG"),
1990 "Name" : os.uname()[1] ,
1991 "Generator" : "QMTest "+qm.version ,
1992 "OSName" : os.uname()[0] ,
1993 "Hostname" : socket.gethostname() ,
1994 "OSRelease" : os.uname()[2] ,
1995 "OSVersion" :os.uname()[3] ,
1996 "OSPlatform" :os.uname()[4] ,
1997 "Is64Bits" : "unknown" ,
1998 "VendorString" : "unknown" ,
1999 "VendorID" :"unknown" ,
2000 "FamilyID" :"unknown" ,
2001 "ModelID" :"unknown" ,
2002 "ProcessorCacheSize" :"unknown" ,
2003 "NumberOfLogicalCPU" : str(multiprocessing.cpu_count()) ,
2004 "NumberOfPhysicalCPU" : "0" ,
2005 "TotalVirtualMemory" : "0" ,
2006 "TotalPhysicalMemory" : "0" ,
2007 "LogicalProcessorsPerPhysical" : "0" ,
2008 "ProcessorClockFrequency" : "0" ,
2009 }
2010 self._site = ET.SubElement(newdataset, "site", attrib)
2011 self._Testing = ET.SubElement(self._site,"Testing")
2012
2013 # Start time elements
2014 self._StartDateTime = ET.SubElement(self._Testing, "StartDateTime")
2015
2016 self._StartTestTime = ET.SubElement(self._Testing, "StartTestTime")
2017
2018
2019 self._TestList = ET.SubElement(self._Testing, "TestList")
2020
2021 ## End time elements
2022 self._EndDateTime = ET.SubElement(self._Testing, "EndDateTime")
2023
2024
2025 self._EndTestTime = ET.SubElement(self._Testing, "EndTestTime")
2026
2027
2028
2029 self._ElapsedMinutes = ET.SubElement(self._Testing, "ElapsedMinutes")
2030
2031
2032 else : # We get the elements
2033 self._Testing = self._site.find("Testing")
2034 self._StartDateTime = self._Testing.find("StartDateTime")
2035 self._StartTestTime = self._Testing.find("StartTestTime")
2036 self._TestList = self._Testing.find("TestList")
2037 self._EndDateTime = self._Testing.find("EndDateTime")
2038 self._EndTestTime = self._Testing.find("EndTestTime")
2039 self._ElapsedMinutes = self._Testing.find("ElapsedMinutes")
2040
2041 """
2042 # Add some non-QMTest attributes
2043 if "CMTCONFIG" in os.environ:
2044 self.WriteAnnotation("cmt.cmtconfig", os.environ["CMTCONFIG"])
2045 import socket
2046 self.WriteAnnotation("hostname", socket.gethostname())
2047 """
2048

## Member Function Documentation

def GaudiTest.XMLResultStream.Summarize | ( |  | self | ) |

Definition at line 2198 of file GaudiTest.py.

2198
2199 def Summarize(self):
2200
2201 # Set the final end date time
2202 self._EndTestTime.text = str(self._endTime)
2203 self._EndDateTime.text = time.strftime("%b %d %H:%M %Z", time.localtime(self._endTime))
2204
2205 # Compute the total duration
2206 if self._endTime and self._startTime:
2207 delta = self._endTime - self._startTime
2208 else:
2209 delta = 0
2210 self._ElapsedMinutes.text = str(delta/60)
2211
2212 # Write into the file
2213 self._tree.write(self._xmlFile, "utf-8") #,True) in python 2.7 to add the xml header
2214

def GaudiTest.XMLResultStream.WriteAnnotation | ( |  | self,
|  |  | key,
|  |  | value
| ) |  |

Definition at line 2049 of file GaudiTest.py.

2049
2050 def WriteAnnotation(self, key, value):
2051 if key == "qmtest.run.start_time":
2052 if self._site.get("qmtest.run.start_time") is not None :
2053 return None
self._site.set(str(key),str(value))

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 2054 of file GaudiTest.py.

2054
2055 def WriteResult(self, result):
2056 """Prepare the test result directory in the destination directory storing
2057 into it the result fields.
2058 A summary of the test result is stored both in a file in the test directory
2059 and in the global summary file.
2060 """
2061 summary = {}
2062 summary["id"] = result.GetId()
2063 summary["outcome"] = result.GetOutcome()
2064 summary["cause"] = result.GetCause()
2065 summary["fields"] = result.keys()
2066 summary["fields"].sort()
2067
2068
2069 # Since we miss proper JSON support, I hack a bit
2070 for f in ["id", "outcome", "cause"]:
2071 summary[f] = str(summary[f])
2072 summary["fields"] = map(str, summary["fields"])
2073
2074
2075 # format
2076 # package_Test.xml
2077
2078 if "qmtest.start_time" in summary["fields"]:
2079 haveStartDate = True
2080 else :
2081 haveStartDate = False
2082 if "qmtest.end_time" in summary["fields"]:
2083 haveEndDate = True
2084 else :
2085 haveEndDate = False
2086
2087 # writing the start date time
2088 if haveStartDate:
2089 self._startTime = calendar.timegm(time.strptime(result["qmtest.start_time"], "%Y-%m-%dT%H:%M:%SZ"))
2090 if self._StartTestTime.text is None:
2091 self._StartDateTime.text = time.strftime("%b %d %H:%M %Z", time.localtime(self._startTime))
2092 self._StartTestTime.text = str(self._startTime)
2093 self._site.set("BuildStamp" , result["qmtest.start_time"] )
2094
2095 #Save the end date time in memory
2096 if haveEndDate:
2097 self._endTime = calendar.timegm(time.strptime(result["qmtest.end_time"], "%Y-%m-%dT%H:%M:%SZ"))
2098
2099
2100 #add the current test to the test list
2101 tl = ET.Element("Test")
2102 tl.text = summary["id"]
2103 self._TestList.insert(0,tl)
2104
2105 #Fill the current test
2106 Test = ET.Element("Test")
2107 if summary["outcome"] == "PASS":
2108 Test.set("Status", "passed")
2109 elif summary["outcome"] == "FAIL":
2110 Test.set("Status", "failed")
2111 elif summary["outcome"] == "SKIPPED" or summary["outcome"] == "UNTESTED":
2112 Test.set("Status", "skipped")
2113 elif summary["outcome"] == "ERROR":
2114 Test.set("Status", "failed")
2115 Name = ET.SubElement(Test, "Name",)
2116 Name.text = summary["id"]
2117 Results = ET.SubElement(Test, "Results")
2118
2119 # add the test after the other test
2120 self._Testing.insert(3,Test)
2121
2122 if haveStartDate and haveEndDate:
2123 # Compute the test duration
2124 delta = self._endTime - self._startTime
2125 testduration = str(delta)
2126 Testduration= ET.SubElement(Results,"NamedMeasurement")
2127 Testduration.set("name","Execution Time")
2128 Testduration.set("type","numeric/float" )
2129 value = ET.SubElement(Testduration, "Value")
2130 value.text = testduration
2131
2132 #remove the fields that we store in a different way
2133 for n in ("qmtest.end_time", "qmtest.start_time", "qmtest.cause", "ExecTest.stdout"):
2134 if n in summary["fields"]:
2135 summary["fields"].remove(n)
2136
2137 # Here we can add some NamedMeasurment which we know the type
2138 #
2139 if "ExecTest.exit_code" in summary["fields"] :
2140 summary["fields"].remove("ExecTest.exit_code")
2141 ExitCode= ET.SubElement(Results,"NamedMeasurement")
2142 ExitCode.set("name","exit_code")
2143 ExitCode.set("type","numeric/integer" )
2144 value = ET.SubElement(ExitCode, "Value")
2145 value.text = convert_xml_illegal_chars(result["ExecTest.exit_code"])
2146
2147 TestStartTime= ET.SubElement(Results,"NamedMeasurement")
2148 TestStartTime.set("name","Start_Time")
2149 TestStartTime.set("type","String" )
2150 value = ET.SubElement(TestStartTime, "Value")
2151 if haveStartDate :
2152 value.text = escape_xml_illegal_chars(time.strftime("%b %d %H:%M %Z %Y", time.localtime(self._startTime)))
2153 else :
2154 value.text = ""
2155
2156 TestEndTime= ET.SubElement(Results,"NamedMeasurement")
2157 TestEndTime.set("name","End_Time")
2158 TestEndTime.set("type","String" )
2159 value = ET.SubElement(TestEndTime, "Value")
2160 if haveStartDate :
2161 value.text = escape_xml_illegal_chars(time.strftime("%b %d %H:%M %Z %Y", time.localtime(self._endTime)))
2162 else :
2163 value.text = ""
2164
2165 if summary["cause"]:
2166 FailureCause= ET.SubElement(Results,"NamedMeasurement")
2167 FailureCause.set("name", "Cause")
2168 FailureCause.set("type", "String" )
2169 value = ET.SubElement(FailureCause, "Value")
2170 value.text = escape_xml_illegal_chars(summary["cause"])
2171
2172 #Fill the result
2173 fields = {}
2174 for field in summary["fields"] :
2175 fields[field] = ET.SubElement(Results, "NamedMeasurement")
2176 fields[field].set("type","String")
2177 fields[field].set("name",field)
2178 value = ET.SubElement(fields[field], "Value")
2179 # to escape the <pre></pre>
2180 if "<pre>" in result[field][0:6] :
2181 value.text = convert_xml_illegal_chars(result[field][5:-6])
2182 else :
2183 value.text = convert_xml_illegal_chars(result[field])
2184
2185
2186 if result.has_key("ExecTest.stdout" ) : #"ExecTest.stdout" in result :
2187 Measurement = ET.SubElement(Results, "Measurement")
2188 value = ET.SubElement(Measurement, "Value")
2189 if "<pre>" in result["ExecTest.stdout"][0:6] :
2190 value.text = convert_xml_illegal_chars(result["ExecTest.stdout"][5:-6])
2191 else :
2192 value.text = convert_xml_illegal_chars(result["ExecTest.stdout"])
2193
2194
2195 # write the file
2196 self._tree.write(self._xmlFile, "utf-8") #,True) in python 2.7 to add the xml header
2197

## Member Data Documentation

GaudiTest.XMLResultStream._ElapsedMinutes
| private

Definition at line 2028 of file GaudiTest.py.

GaudiTest.XMLResultStream._EndDateTime
| private

End time elements.

Definition at line 2021 of file GaudiTest.py.

GaudiTest.XMLResultStream._EndTestTime
| private

Definition at line 2024 of file GaudiTest.py.

GaudiTest.XMLResultStream._endTime
| private

Definition at line 1955 of file GaudiTest.py.

GaudiTest.XMLResultStream._site
| private

Definition at line 1978 of file GaudiTest.py.

GaudiTest.XMLResultStream._StartDateTime
| private

Definition at line 2013 of file GaudiTest.py.

GaudiTest.XMLResultStream._StartTestTime
| private

Definition at line 2015 of file GaudiTest.py.

GaudiTest.XMLResultStream._startTime
| private

Definition at line 1954 of file GaudiTest.py.

GaudiTest.XMLResultStream._Testing
| private

Definition at line 2010 of file GaudiTest.py.

GaudiTest.XMLResultStream._TestList
| private

Definition at line 2018 of file GaudiTest.py.

GaudiTest.XMLResultStream._tree
| private

Definition at line 1963 of file GaudiTest.py.

GaudiTest.XMLResultStream._xmlFile
| private

Definition at line 1951 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 = """The name of the directory.All results will be written to the directory indicated.""",
6 verbatim = "true",
7 default_value = ""),
8 qm.fields.TextField(
9 name = "prefix",
10 title = "Output File Prefix",
11 description = """The output file name will be the specified prefixfollowed by 'Test.xml' (CTest convention).""",
12 verbatim = "true",
13 default_value = ""),
14 ]

Definition at line 1925 of file GaudiTest.py.

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

- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v25r0/GaudiPolicy/qmtest_classes/GaudiTest.py