| 1 | #!/usr/bin/env python3
 | 
|---|
| 2 | """Inspect test results for timing information.
 | 
|---|
| 3 | 
 | 
|---|
| 4 | Run on a file that contains results from tests/test.py to see results.
 | 
|---|
| 5 | """
 | 
|---|
| 6 | 
 | 
|---|
| 7 | 
 | 
|---|
| 8 | import argparse
 | 
|---|
| 9 | from datetime import timedelta
 | 
|---|
| 10 | import re
 | 
|---|
| 11 | import statistics
 | 
|---|
| 12 | 
 | 
|---|
| 13 | 
 | 
|---|
| 14 | def parse_args(args=None):
 | 
|---|
| 15 |     parser = argparse.ArgumentParser(
 | 
|---|
| 16 |         description='Summarize performance results from a test run.')
 | 
|---|
| 17 |     parser.add_argument('result_file', type=argparse.FileType('r'))
 | 
|---|
| 18 |     return parser.parse_args(args)
 | 
|---|
| 19 | 
 | 
|---|
| 20 | 
 | 
|---|
| 21 | def str_to_time(time_str):
 | 
|---|
| 22 |     match = re.search('([0-9]+):([0-9]+)[.]([0-9]+)', time_str)
 | 
|---|
| 23 |     if not match:
 | 
|---|
| 24 |         raise Exception('Badly formatted')
 | 
|---|
| 25 |     minutes, seconds, milli = (int(x) for x in match.groups())
 | 
|---|
| 26 |     return timedelta(minutes=minutes, seconds=seconds, milliseconds=milli)
 | 
|---|
| 27 | 
 | 
|---|
| 28 | 
 | 
|---|
| 29 | def line_to_entry(line):
 | 
|---|
| 30 |     match = re.search('([^\t ]+) +PASSED +C( n/a|.*) - R( n/a|.*)', line)
 | 
|---|
| 31 |     if not match:
 | 
|---|
| 32 |         return None
 | 
|---|
| 33 |     test_id, compile_str, run_str = match.groups()
 | 
|---|
| 34 |     compile_time = None if ' n/a' == compile_str else str_to_time(compile_str)
 | 
|---|
| 35 |     run_time = None if ' n/a' == run_str else str_to_time(run_str)
 | 
|---|
| 36 |     return test_id, compile_time, run_time
 | 
|---|
| 37 | 
 | 
|---|
| 38 | 
 | 
|---|
| 39 | def iter_file_entries(open_file):
 | 
|---|
| 40 |     with open_file as file:
 | 
|---|
| 41 |         for line in file.readlines():
 | 
|---|
| 42 |             entry = line_to_entry(line)
 | 
|---|
| 43 |             if entry is not None:
 | 
|---|
| 44 |                 yield entry
 | 
|---|
| 45 | 
 | 
|---|
| 46 | 
 | 
|---|
| 47 | def entry_to_compile_seconds(entry):
 | 
|---|
| 48 |     _id, compile_time, _run_time = entry
 | 
|---|
| 49 |     return compile_time.total_seconds()
 | 
|---|
| 50 | 
 | 
|---|
| 51 | 
 | 
|---|
| 52 | if '__main__' == __name__:
 | 
|---|
| 53 |     args = parse_args()
 | 
|---|
| 54 |     mean = statistics.geometric_mean(
 | 
|---|
| 55 |         map(entry_to_compile_seconds, iter_file_entries(args.result_file)))
 | 
|---|
| 56 |     print('Source File:', args.result_file.name)
 | 
|---|
| 57 |     print('Geometric Mean:', mean)
 | 
|---|