3636# SOFTWARE.
3737
3838import csv
39+ import gzip
3940import os
4041import re
4142import subprocess
5556PATH_UNITTESTS = "graalpython/lib-python/3/test/"
5657
5758_BASE_NAME = "unittests"
58- TXT_RESULTS_NAME = "{}.txt" .format (_BASE_NAME )
59+ TXT_RESULTS_NAME = "{}.txt.gz " .format (_BASE_NAME )
5960CSV_RESULTS_NAME = "{}.csv" .format (_BASE_NAME )
6061HTML_RESULTS_NAME = "{}.html" .format (_BASE_NAME )
6162
6566PTRN_NUM_TESTS = re .compile (r'^Ran (?P<num_tests>\d+) test.*$' )
6667PTRN_NUM_ERRORS = re .compile (
6768 r'^FAILED \((failures=(?P<failures>\d+))?(, )?(errors=(?P<errors>\d+))?(, )?(skipped=(?P<skipped>\d+))?\)$' )
69+ PTRN_JAVA_EXCEPTION = re .compile (r'^(?P<exception>com\.oracle\.[^:]*):(?P<message>.*)' )
70+ PTRN_MODULE_NOT_FOUND = re .compile (r'.*ModuleNotFound: \'(?P<module>.*)\'\..*' , re .DOTALL )
6871
6972
7073# ----------------------------------------------------------------------------------------------------------------------
@@ -82,7 +85,7 @@ def debug(msg, *args, **kwargs):
8285
8386
8487def file_name (name , current_date_time ):
85- idx = name .rindex ('.' )
88+ idx = name .index ('.' )
8689 if idx > 0 :
8790 return '{}-{}{}' .format (name [:idx ], current_date_time , name [idx :])
8891 return '{}-{}' .format (name , current_date_time )
@@ -131,14 +134,17 @@ def _run_unittest(test_path):
131134
132135def run_unittests (unittests ):
133136 assert isinstance (unittests , (list , tuple ))
134- log ("[EXEC] running {} unittests ... " .format (len (unittests )))
137+ num_unittests = len (unittests )
138+ log ("[EXEC] running {} unittests ... " , num_unittests )
135139 results = []
140+
136141 pool = Pool ()
137142 for ut in unittests :
138- results .append (pool .apply_async (_run_unittest , args = (ut ,)))
143+ results .append (pool .apply_async (_run_unittest , args = (ut , )))
139144 pool .close ()
140145 pool .join ()
141- return [r .get ()[1 ] for r in results ]
146+
147+ return [res .get ()[1 ] for res in results ]
142148
143149
144150def get_unittests (base_tests_path , limit = None , sort = True ):
@@ -180,6 +186,7 @@ def process_output(output_lines):
180186
181187 unittests = []
182188 error_messages = defaultdict (set )
189+ java_exceptions = defaultdict (set )
183190 stats = defaultdict (StatEntry )
184191
185192 for line in output_lines :
@@ -194,6 +201,12 @@ def process_output(output_lines):
194201 error_messages [unittests [- 1 ]].add ((match .group ('error' ), match .group ('message' )))
195202 continue
196203
204+ # extract java exceptions
205+ match = re .match (PTRN_JAVA_EXCEPTION , line )
206+ if match :
207+ java_exceptions [unittests [- 1 ]].add ((match .group ('exception' ), match .group ('message' )))
208+ continue
209+
197210 # stats
198211 if line .strip () == 'OK' :
199212 stats [unittests [- 1 ]].all_ok ()
@@ -216,27 +229,34 @@ def process_output(output_lines):
216229 stats [unittests [- 1 ]].num_errors = int (errs ) if errs else 0
217230 stats [unittests [- 1 ]].num_skipped = int (skipped ) if skipped else 0
218231
219- return unittests , error_messages , stats
232+ return unittests , error_messages , java_exceptions , stats
220233
221234
222235# ----------------------------------------------------------------------------------------------------------------------
223236#
224237# python error processing
225238#
226239# ----------------------------------------------------------------------------------------------------------------------
227- def process_errors (unittests , error_messages , error , msg_processor ):
240+ def process_errors (unittests , error_messages , error = None , msg_processor = None ):
241+ def _err_filter (item ):
242+ if not error :
243+ return True
244+ return item [0 ] == error
245+
246+ def _processor (msg ):
247+ if not msg_processor :
248+ return msg
249+ return msg_processor (msg )
250+
228251 missing_modules = defaultdict (lambda : 0 )
229252 for ut in unittests :
230253 errors = error_messages [ut ]
231- for name in map (msg_processor , (msg for err , msg in errors if err == error )):
254+ for name in map (_processor , (msg for err , msg in filter ( _err_filter , errors ) )):
232255 missing_modules [name ] = missing_modules [name ] + 1
233256
234257 return missing_modules
235258
236259
237- PTRN_MODULE_NOT_FOUND = re .compile (r'.*ModuleNotFound: \'(?P<module>.*)\'\..*' , re .DOTALL )
238-
239-
240260def get_missing_module (msg ):
241261 match = re .match (PTRN_MODULE_NOT_FOUND , msg )
242262 return match .group ('module' ) if match else None
@@ -282,13 +302,13 @@ class Stat(object):
282302
283303
284304def save_as_txt (report_path , results ):
285- with open (report_path , 'w ' ) as TXT :
305+ with gzip . open (report_path , 'wb ' ) as TXT :
286306 output = '\n ' .join (results )
287- TXT .write (output )
307+ TXT .write (bytes ( output , 'utf-8' ) )
288308 return output
289309
290310
291- def save_as_csv (report_path , unittests , error_messages , stats , current_date ):
311+ def save_as_csv (report_path , unittests , error_messages , java_exceptions , stats ):
292312 rows = []
293313 with open (report_path , 'w' ) as CSV :
294314 totals = {
@@ -304,6 +324,9 @@ def save_as_csv(report_path, unittests, error_messages, stats, current_date):
304324 for unittest in unittests :
305325 unittest_stats = stats [unittest ]
306326 unittest_errmsg = error_messages [unittest ]
327+ if not unittest_errmsg :
328+ unittest_errmsg = java_exceptions [unittest ]
329+
307330 rows .append ({
308331 Col .UNITTEST : unittest ,
309332 Col .NUM_TESTS : unittest_stats .num_tests ,
@@ -434,7 +457,7 @@ def save_as_csv(report_path, unittests, error_messages, stats, current_date):
434457'''
435458
436459
437- def save_as_html (report_name , rows , totals , missing_modules , current_date ):
460+ def save_as_html (report_name , rows , totals , missing_modules , java_issues , current_date ):
438461 def grid (* components ):
439462 def _fmt (cmp ):
440463 if isinstance (cmp , tuple ):
@@ -536,6 +559,11 @@ def format_val(row, k):
536559 for cnt , name in sorted (((cnt , name ) for name , cnt in missing_modules .items ()), reverse = True )
537560 ])
538561
562+ java_issues_info = ul ('Java issues' , [
563+ '<b>{}</b> <span class="text-muted">caused by {} unittests</span>' .format (name , cnt )
564+ for cnt , name in sorted (((cnt , name ) for name , cnt in java_issues .items ()), reverse = True )
565+ ])
566+
539567 total_stats_info = ul ("<b>Summary</b>" , [
540568 grid ('<b># total</b> unittests: {}' .format (totals [Stat .UT_TOTAL ])),
541569 grid ((progress_bar (totals [Stat .UT_PERCENT_RUNS ], color = "info" ), 3 ),
@@ -549,7 +577,7 @@ def format_val(row, k):
549577
550578 table_stats = table ('stats' , CSV_HEADER , rows )
551579
552- content = ' <br> ' .join ([total_stats_info , table_stats , missing_modules_info ])
580+ content = ' <br> ' .join ([total_stats_info , table_stats , missing_modules_info , java_issues_info ])
553581
554582 report = HTML_TEMPLATE .format (
555583 title = 'GraalPython Unittests Stats' ,
@@ -608,16 +636,20 @@ def _fmt(t):
608636 txt_report_path = file_name (TXT_RESULTS_NAME , current_date )
609637 output = save_as_txt (txt_report_path , results )
610638
611- unittests , error_messages , stats = process_output (output )
639+ unittests , error_messages , java_exceptions , stats = process_output (output )
612640
613641 csv_report_path = file_name (CSV_RESULTS_NAME , current_date )
614- rows , totals = save_as_csv (csv_report_path , unittests , error_messages , stats , current_date )
642+ rows , totals = save_as_csv (csv_report_path , unittests , error_messages , java_exceptions , stats )
615643
616- missing_modules = process_errors (unittests , error_messages , 'ModuleNotFoundError' , get_missing_module )
644+ missing_modules = process_errors (unittests , error_messages , error = 'ModuleNotFoundError' ,
645+ msg_processor = get_missing_module )
617646 log ("[MISSING MODULES] \n {}" , pformat (dict (missing_modules )))
618647
648+ java_issues = process_errors (unittests , java_exceptions )
649+ log ("[JAVA ISSUES] \n {}" , pformat (dict (java_issues )))
650+
619651 html_report_path = file_name (HTML_RESULTS_NAME , current_date )
620- save_as_html (html_report_path , rows , totals , missing_modules , current_date )
652+ save_as_html (html_report_path , rows , totals , missing_modules , java_issues , current_date )
621653
622654 if flags .path :
623655 log ("[SAVE] saving results to {} ... " , flags .path )
0 commit comments