1+ #!/usr/bin/env python
2+
3+ from xml .etree import ElementTree as ET
4+ import os
5+ from datetime import date
6+ import subprocess
7+ import codecs
8+
9+
10+ #ctest xml file layout
11+ #<Site ...=...>
12+ # <testing>
13+ # <StartDateTime>..</>
14+ # <StartTestTime>..</>
15+ # <TestList>..</>
16+ # <Test status=..>..</>
17+ # <EndDateTime>Dec 28 17:49 EST</EndDateTime>
18+ # <EndTestTime>1325112579</EndTestTime>
19+ # <ElapsedMinutes>1.9</ElapsedMinutes>
20+ # </Testing>
21+ #</Site>
22+
23+
24+ #summary (aka 's') is a table at the top of the document
25+ #body (aka 'b') contains the details for all schemas
26+
27+ def main ():
28+ #xml_file = os.path.abspath(__file__)
29+ #xml_file = os.path.dirname(xml_file)
30+ #xml_file = os.path.join(xml_file, "Test.xml")
31+ xml_file = "Test.xml"
32+ #output_path = "/opt/step/wiki-scl"
33+ out_main = "Schema-build-matrix.md"
34+ out = codecs .open (out_main ,encoding = 'utf-8' ,mode = 'w' )
35+
36+ #cleanup_wiki(output_path) #delete old files
37+ out .write ( header () )
38+ summary ,body = read_tests (xml_file )
39+ out .write ( summary )
40+ out .write ( body )
41+
42+ def header ():
43+ h = "## Created " + date .today ().__str__ () + "\n " + "### Current as of commit "
44+ l = subprocess .check_output (["git" , "log" , """--pretty=format:%H Commit Summary: %s<br>Author: %aN<br>Date: %aD""" , "-n1" ])
45+ h += "[" + l [:8 ] + "](http://github.com/mpictor/StepClassLibrary/commit/" + l [:l .find (" " )]
46+ h += ") --\n <font color=grey>" + l [l .find (" " )+ 1 :] + "</font>\n \n ----\n "
47+ h += "### Summary\n <table width=100%><tr><th>Schema</th><th>Generate</th><th>Build</th></tr>"
48+ return h
49+
50+ def read_tests (xml ):
51+ # read all <Test>s in xml, create summary and body html/markdown
52+ try :
53+ tree = ET .parse (xml )
54+ except Exception , inst :
55+ print "Unexpected error opening %s: %s" % (xml , inst )
56+ return
57+
58+ root = tree .getroot ()
59+ testing = root .find ("Testing" )
60+
61+
62+ tests = testing .findall ("Test" )
63+ summary = ""
64+ body = ""
65+ for test in tests :
66+ s ,b = schema_info (test ,tests )
67+ summary += s
68+ body += b
69+ summary += "</table>\n \n "
70+ return summary ,body
71+
72+
73+
74+ def schema_info (test ,tests ):
75+ # this returns html & markdown formatted summary and body strings
76+ # for the generate and build tests for a single schema
77+ s = ""
78+ b = ""
79+ name = test .find ("Name" ).text
80+ if name .startswith ("generate_cpp_" ):
81+ #print this one. if it passes, find and print build.
82+ ap = name [len ("generate_cpp_" ):]
83+ s += "<tr><td><a href=#" + ap + ">" + ap .title () + "</a></td><td>"
84+ s += test_status (test ) + "</td><td>"
85+ b += "----\n <a name=\" wiki-" + ap + "\" ></a>\n "
86+ b += "### Schema " + ap .title ()
87+ b += "<table width=100%>"
88+ b += test_table ("generation" ,test )
89+ if test .get ("Status" ) == "passed" :
90+ for build in tests :
91+ if build .find ("Name" ).text == "build_cpp_sdai_" + ap :
92+ s += test_status (build ) + "</td></tr>\n "
93+ b += test_table ("compilation" ,build )
94+ break
95+ else :
96+ s += "----</td></tr>\n "
97+ b += "</table>\n "
98+ return s ,b
99+
100+ def test_table (ttype , test ):
101+ # populate the table for one test
102+ # returns: html & markdown formatted text to be added to 'body'
103+ b = "<tr><td>Code " + ttype
104+ output = test .find ("Results" ).find ("Measurement" ).find ("Value" ).text
105+ w = output .count ("WARNING" )
106+ w += output .count ("warning" )
107+ lines = output .split ("\n " )
108+ if "The rest of the test output was removed since it exceeds the threshold of" in lines [- 2 ]:
109+ trunc1 = "at least "
110+ trunc2 = "(ctest truncated output)"
111+ else :
112+ trunc1 = ""
113+ trunc2 = ""
114+ if test .get ("Status" ) == "passed" :
115+
116+ #print summary in b
117+ b += " succeeded with " + trunc1 + w .__str__ () + " warnings " + trunc2
118+ if w == 0 : #nothing to print in the table, so skip it
119+ b += "</td></tr>\n "
120+ return b
121+ else :
122+ #print warnings and errors in b
123+ e = output .count ("ERROR" )
124+ e += output .count ("error" )
125+ b += " failed with %s%d warnings and %d errors %s" % (trunc1 , w , e , trunc2 )
126+ b += "<br>\n <table border=1 width=100%>\n "
127+ b += "<tr><th>Line</th><th>Text</th></tr>\n "
128+
129+ # ERRORs
130+ # 242_n2813_mim_lf.exp:2278: --ERROR: Expected a type...
131+ # gcc errors look like ???
132+ l = 0
133+ for line in lines :
134+ if ": --ERROR:" in line :
135+ l += 1
136+ c1 = line .find (":" )
137+ c2 = line .find (":" ,c1 + 1 )
138+ b += "<tr><td>" + line [c1 + 1 :c2 ] + "</td><td>" + line [c2 + 4 :] + "</td></tr>\n "
139+ elif ": error:" in line :
140+ l += 1
141+ c1 = line .find (":" )
142+ c2 = line .find (":" ,c1 + 1 )
143+ c3 = line .find (":" ,c2 + 1 ) #skip the character number
144+ b += "<tr><td>" + line [c1 + 1 :c2 ] + "</td><td>" + line [c3 + 2 :] + "</td></tr>\n "
145+ if l > 20 :
146+ b += "<tr><td>-</td><td><font color=red>-- maximum number of errors printed --</font></td></tr>\n "
147+ break
148+ # WARNINGs
149+ # ap239_arm_lf.exp:2731: WARNING: Implicit downcast...
150+ # WARNING: in SELECT TYPE date_or_date... (multi-line warning)
151+ # compstructs.cc:28:23: warning: unused
152+ l = 0
153+ for line in lines :
154+ if ": WARNING" in line :
155+ l += 1
156+ c1 = line .find (":" )
157+ c2 = line .find (":" ,c1 + 1 )
158+ b += "<tr><td>" + line [c1 + 1 :c2 ] + "</td><td>" + line [c2 + 2 :] + "</td></tr>\n "
159+ elif "WARNING" in line :
160+ b += "<tr><td>????</td><td>" + line + "</td></tr>\n "
161+ elif ": warning:" in line :
162+ l += 1
163+ c1 = line .find (":" )
164+ c2 = line .find (":" ,c1 + 1 )
165+ c3 = line .find (":" ,c2 + 1 ) #skip the character number
166+ b += "<tr><td>" + line [c1 + 1 :c2 ] + "</td><td>" + line [c3 + 2 :] + "</td></tr>\n "
167+ if l > 20 :
168+ b += "<tr><td>-</td><td><font color=red>-- maximum number of warnings printed --</font></td></tr>\n "
169+ break
170+ b += "</table></td></tr>\n "
171+ return b
172+
173+ def test_status (test ):
174+ if test .get ("Status" ) == "passed" :
175+ s = "<font color=green>PASS</font>"
176+ elif test .get ("Status" ) == "failed" :
177+ s = "<font color=red>FAIL</font>"
178+ else :
179+ s = "<font color=cyan>" + test .get ("Status" ) + "</font>"
180+ return s
181+
182+ if __name__ == "__main__" :
183+ # Someone is launching this directly
184+ main ()
185+
0 commit comments