report.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. # Copyright (c) MetaCommunications, Inc. 2003-2004
  2. #
  3. # Use, modification and distribution are subject to the Boost Software
  4. # License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
  5. # at http://www.boost.org/LICENSE_1_0.txt)
  6. import shutil
  7. import sys
  8. import os
  9. import os.path
  10. import string
  11. import time
  12. import inspect
  13. import getopt
  14. report_types = [ 'us', 'ds', 'ud', 'dd', 'l', 'p', 'x', 'i' ]
  15. if __name__ == '__main__':
  16. run_dir = os.path.abspath( os.path.dirname( sys.argv[ 0 ] ) )
  17. else:
  18. run_dir = os.path.abspath( os.path.dirname( sys.modules[ __name__ ].__file__ ) )
  19. class failure_exception:
  20. def __init__( self, rc ):
  21. self.rc_ = rc
  22. def log_level():
  23. frames = inspect.stack()
  24. level = 0
  25. for i in frames[ 3: ]:
  26. if i[0].f_locals.has_key( '__log__' ):
  27. level = level + i[0].f_locals[ '__log__' ]
  28. return level
  29. def stdlog( message ):
  30. sys.stderr.write( '# ' + ' ' * log_level() + message + '\n' );
  31. sys.stderr.flush()
  32. log = stdlog
  33. # log = lambda x: x
  34. def system( commands ):
  35. f = open( 'tmp.cmd', 'w' )
  36. f.write( string.join( commands, '\n' ) )
  37. f.close()
  38. rc = os.system( 'tmp.cmd' )
  39. return rc
  40. def checked_system( commands ):
  41. rc = system( commands )
  42. if 0 != rc : raise failure_exception( rc )
  43. return rc
  44. def set_char( str, index, char ):
  45. return str[ 0 : index ] + char + str[ index + 1: ]
  46. def process_xml_file( input_file, output_file ):
  47. log( 'Processing test log "%s"' % input_file )
  48. f = open( input_file, 'r' )
  49. xml = f.readlines();
  50. f.close()
  51. ascii_chars = ''.join(map(chr, range(0,128)))
  52. nonascii_chars = ''.join(map(chr, range(128,256)))
  53. translated_ascii_chars = ''.join( map( lambda x: '?', range(128,256)))
  54. for i in string.printable:
  55. if ( ord( i ) < 128 and ord(i) not in ( 12, ) ):
  56. translated_ascii_chars = set_char( translated_ascii_chars, ord(i), i )
  57. translated_nonascii_chars = ''.join( map( lambda x: '?', range(128,256) ) )
  58. mask_nonascii_translation_table = string.maketrans( ascii_chars + nonascii_chars
  59. , translated_ascii_chars + translated_nonascii_chars
  60. )
  61. for i in range( 0, len(xml)):
  62. xml[i] = string.translate( xml[i], mask_nonascii_translation_table )
  63. output_file.writelines( xml )
  64. def process_test_log_files( output_file, dir, names ):
  65. for file in names:
  66. if os.path.basename( file ) == 'test_log.xml':
  67. process_xml_file( os.path.join( dir, file ), output_file )
  68. def collect_test_logs( input_dirs, output_file ):
  69. __log__ = 1
  70. log( 'Collecting test logs ...' )
  71. f = open( output_file, 'w+' )
  72. f.write( '<tests>\n' );
  73. for input_dir in input_dirs:
  74. os.path.walk( input_dir, process_test_log_files, f );
  75. f.write( '</tests>\n' );
  76. f.close()
  77. def xalan( xml_file, xsl_file,output_file, parameters = None ):
  78. transform_command = 'xalan'
  79. transform_command = transform_command + ' -o "%s" ' % output_file
  80. if parameters is not None:
  81. for i in parameters:
  82. transform_command = transform_command + ' -p %s "\'%s\'" ' % ( i, parameters[ i ] )
  83. transform_command = transform_command + ' "%s"' % xml_file
  84. transform_command = transform_command + ' "%s"' % xsl_file
  85. log( transform_command )
  86. os.system( transform_command )
  87. def msxsl( xml_file, xsl_file, output_file, parameters = None ):
  88. transform_command = 'msxsl'
  89. transform_command = transform_command + ' "%s"' % xml_file
  90. transform_command = transform_command + ' "%s"' % xsl_file
  91. transform_command = transform_command + ' -o "%s" ' % output_file
  92. if parameters is not None:
  93. for i in parameters:
  94. transform_command = transform_command + ' %s="%s" ' % ( i, parameters[ i ] )
  95. log( transform_command )
  96. os.system( transform_command )
  97. def libxslt( xml_file, xsl_file, output_file, parameters = None ):
  98. if sys.platform == 'win32':
  99. os.chdir( os.path.dirname( xsl_file ) )
  100. transform_command = 'xsltproc'
  101. transform_command = transform_command + ' -o ' + '%s' % output_file
  102. if parameters is not None:
  103. for i in parameters:
  104. parameters[i] = parameters[i].replace( '\\', '/' )
  105. transform_command = transform_command + ' --param %s "\'%s\'" ' % ( i, parameters[ i ] )
  106. transform_command = transform_command + ' "%s" ' % xsl_file
  107. transform_command = transform_command + ' "%s" ' % xml_file
  108. log( transform_command )
  109. os.system( transform_command )
  110. registered_xsltprocs = { 'msxsl': msxsl
  111. , 'xalan': xalan
  112. , 'libxslt': libxslt
  113. }
  114. def map_path( path ):
  115. return os.path.join( run_dir, path )
  116. def xsl_path( xsl_file_name ):
  117. return map_path( os.path.join( 'xsl', xsl_file_name ) )
  118. def makedirs( path ):
  119. if not os.path.exists( path ):
  120. os.makedirs( path )
  121. def make_result_pages( test_results_file
  122. , expected_results_file
  123. , failures_markup_file
  124. , source
  125. , run_date
  126. , comment_file
  127. , results_dir
  128. , result_prefix
  129. , xslt_proc_name
  130. , reports
  131. ):
  132. log( 'Producing the reports...' )
  133. __log__ = 1
  134. output_dir = os.path.join( results_dir, result_prefix )
  135. if not os.path.exists( output_dir ):
  136. os.makedirs( output_dir )
  137. xslt_proc = registered_xsltprocs[ xslt_proc_name ]
  138. if comment_file != '':
  139. comment_file = os.path.abspath( comment_file )
  140. if expected_results_file != '':
  141. expected_results_file = os.path.abspath( expected_results_file )
  142. else:
  143. expected_results_file = os.path.abspath( map_path( 'empty_expected_results.xml' ) )
  144. extended_test_results = os.path.join( output_dir, 'extended_test_results.xml' )
  145. if 'x' in reports:
  146. log( ' Merging with expected results...' )
  147. xslt_proc( test_results_file
  148. , xsl_path( 'add_expected_results.xsl' )
  149. , extended_test_results
  150. , { 'expected_results_file': expected_results_file, 'failures_markup_file' : failures_markup_file }
  151. )
  152. links = os.path.join( output_dir, 'links.html' )
  153. makedirs( os.path.join( output_dir, 'output' ) )
  154. for mode in ( 'developer', 'user' ):
  155. makedirs( os.path.join( output_dir, mode , 'output' ) )
  156. if 'l' in reports:
  157. log( ' Making test output files...' )
  158. xslt_proc( extended_test_results
  159. , xsl_path( 'links_page.xsl' )
  160. , links
  161. , {
  162. 'source': source
  163. , 'run_date': run_date
  164. , 'comment_file': comment_file
  165. , 'explicit_markup_file' : failures_markup_file
  166. }
  167. )
  168. issues = os.path.join( output_dir, 'developer', 'issues.html' )
  169. if 'i' in reports:
  170. log( ' Making issues list...' )
  171. xslt_proc( extended_test_results
  172. , xsl_path( 'issues_page.xsl' )
  173. , issues
  174. , {
  175. 'source': source
  176. , 'run_date': run_date
  177. , 'comment_file': comment_file
  178. , 'explicit_markup_file' : failures_markup_file
  179. }
  180. )
  181. for mode in ( 'developer', 'user' ):
  182. if mode[0] + 'd' in reports:
  183. log( ' Making detailed %s report...' % mode )
  184. xslt_proc( extended_test_results
  185. , xsl_path( 'result_page.xsl' )
  186. , os.path.join( output_dir, mode, 'index.html' )
  187. , { 'links_file': 'links.html'
  188. , 'mode': mode
  189. , 'source': source
  190. , 'run_date': run_date
  191. , 'comment_file': comment_file
  192. , 'expected_results_file': expected_results_file
  193. , 'explicit_markup_file' : failures_markup_file
  194. }
  195. );
  196. for mode in ( 'developer', 'user' ):
  197. if mode[0] + 's' in reports:
  198. log( ' Making summary %s report...' % mode )
  199. xslt_proc( extended_test_results
  200. , xsl_path( 'summary_page.xsl' )
  201. , os.path.join( output_dir, mode, 'summary.html' )
  202. , { 'mode' : mode
  203. , 'source': source
  204. , 'run_date': run_date
  205. , 'comment_file': comment_file
  206. , 'explicit_markup_file' : failures_markup_file
  207. }
  208. );
  209. if 'e' in reports:
  210. log( ' Generating expected_results ...' )
  211. xslt_proc( extended_test_results
  212. , xsl_path( 'produce_expected_results.xsl' )
  213. , os.path.join( output_dir, 'expected_results.xml' )
  214. )
  215. shutil.copyfile(
  216. xsl_path( 'html/master.css' )
  217. , os.path.join( output_dir, 'master.css' )
  218. )
  219. def build_experimental_reports( locate_root_dir
  220. , source
  221. , expected_results_file
  222. , failures_markup_file
  223. , comment_file
  224. , results_dir
  225. , result_file_prefix
  226. , xslt_proc_name
  227. , dont_collect_logs = 0
  228. , reports = report_types
  229. ):
  230. ( run_date ) = time.strftime('%a, %d %b %Y %H:%M:%S +0000', time.gmtime() )
  231. test_results_file = os.path.join( results_dir, 'test_results.xml' )
  232. bin_boost_dir = os.path.join( locate_root_dir, 'bin', 'boost' )
  233. print 'dont_collect_logs: %s' % dont_collect_logs
  234. if not dont_collect_logs:
  235. collect_test_logs( [ os.path.join( bin_boost_dir, 'libs' ), os.path.join( bin_boost_dir, 'status' ) ]
  236. , test_results_file
  237. )
  238. make_result_pages( test_results_file
  239. , expected_results_file
  240. , failures_markup_file
  241. , source
  242. , run_date
  243. , comment_file
  244. , results_dir
  245. , result_file_prefix
  246. , xslt_proc_name
  247. , reports
  248. )
  249. def accept_args( args ):
  250. ( option_pairs, rest_args ) = getopt.getopt( sys.argv[1:], '', [ 'locate-root='
  251. , 'tag='
  252. , 'expected-results='
  253. , 'failures-markup='
  254. , 'comment='
  255. , 'results-dir='
  256. , 'results-prefix='
  257. , 'xsltproc='
  258. , 'dont-collect-logs'
  259. , 'reports='
  260. , 'help'
  261. ] )
  262. options = { '--comment': ''
  263. , '--expected-results': ''
  264. , '--failures-markup': ''
  265. , '--reports' : string.join( report_types, ',' ) }
  266. map( lambda x: options.__setitem__( x[0], x[1] ), option_pairs )
  267. if ( options.has_key( '--help' ) or len( options.keys() ) == 4 ):
  268. usage()
  269. sys.exit( 1 )
  270. if not options.has_key( '--results-dir' ):
  271. options[ '--results-dir' ] = options[ '--locate-root' ]
  272. return ( options[ '--locate-root' ]
  273. , options[ '--tag' ]
  274. , options[ '--expected-results' ]
  275. , options[ '--failures-markup' ]
  276. , options[ '--comment' ]
  277. , options[ '--results-dir' ]
  278. , options[ '--results-prefix' ]
  279. , options[ '--xsltproc' ]
  280. , options.has_key( '--dont-collect-logs' )
  281. , options[ '--reports' ].split( ',' )
  282. )
  283. def usage():
  284. print 'Usage: %s [options]' % os.path.basename( sys.argv[0] )
  285. print '''
  286. \t--locate-root the same as --locate-root in compiler_status
  287. \t--tag the tag for the results (i.e. 'CVS main trunk')
  288. \t--expected-results the file with the results to be compared with
  289. \t the current run
  290. \t--failures-markup the file with the failures markup
  291. \t--comment an html comment file (will be inserted in the reports)
  292. \t--results-dir the directory containing -links.html, -fail.html
  293. \t files produced by compiler_status (by default the
  294. \t same as specified in --locate-root)
  295. \t--results-prefix the prefix of -links.html, -fail.html
  296. \t files produced by compiler_status
  297. \t--xsltproc the name of xslt processor (msxsl, xalan, libxslt)
  298. \t The XSLT used in report generation uses exsl
  299. \t (http:///www.exsl.org). Make sure that specified
  300. \t processor supports it.
  301. The following options are useful in debugging:
  302. \t--dont-collect-logs dont collect the test logs
  303. \t--reports produce only the specified reports
  304. \t us - user summary
  305. \t ds - developer summary
  306. \t ud - user detailed
  307. \t dd - developer detailed
  308. \t l - links
  309. \t p - patches
  310. \t x - extended results file
  311. \t i - issues
  312. '''
  313. def main():
  314. apply( build_experimental_reports, accept_args( sys.argv[ 1 : ] ) )
  315. if __name__ == '__main__':
  316. main()
粤ICP备19079148号