| #!/usr/bin/env python |
| |
| from htmltags import * |
| |
| import glob |
| import time |
| import sys |
| import os |
| import platform |
| import datetime |
| import subprocess |
| import re |
| |
| year = os.getenv("YEAR", time.strftime("%Y")) |
| day_of_year = os.getenv("DAY_OF_YEAR", time.strftime("%j")) |
| super_diff_dir = None |
| result_date = datetime.datetime.strptime("{0}/{1}".format(year, day_of_year), '%Y/%j') |
| human_readable_date = result_date.strftime("%Y/%b/%d") |
| jdk_version = os.getenv("JDK_VERSION", 8) |
| report_dir = None |
| |
| def jtdiff_stats(jt_report_dir): |
| passed = 0 |
| failed = 0 |
| error = 0 |
| not_run = 0 |
| try: |
| with open(os.path.join(jt_report_dir, 'text', 'summary.txt')) as stats_file: |
| for line in stats_file: |
| if "Passed. " in line: |
| passed = passed + 1 |
| elif "Failed. " in line: |
| failed = failed + 1 |
| elif "Error. " in line: |
| error = error + 1 |
| elif "Not run." in line: |
| not_run = not_run + 1 |
| elif "Test results: " in line: |
| pass |
| else: |
| print >> sys.stderr, "warning: cannot parse: " + line.rstrip() |
| except IOError as e: |
| print >> sys.stderr, ("({})".format(e)) |
| return None |
| return [passed, failed, error, not_run] |
| |
| |
| def add_latest_results(body): |
| result_date = datetime.datetime.strptime("{}/{}".format(year, day_of_year), '%Y/%j') |
| human_readable_date = result_date.strftime("%a, %d %b %Y") |
| body <= H2("Test Result Summary for {}".format(human_readable_date)) |
| table = TABLE(border=1) |
| table <= TR(TH('JVM Variant') + TH('Build Type') + TH('JTREG report') + TH('Passed') + TH('Failed') + TH('Error') + TH('Not run') + TH('Recent Results')) |
| for build_config in sorted(os.listdir(report_dir)): |
| if "." in build_config: |
| continue |
| for jtreg_category in sorted(os.listdir(os.path.join(report_dir, build_config))): |
| jt_report_path = os.path.join(report_dir, build_config, jtreg_category, platform.machine(), year, |
| day_of_year, 'JTreport') |
| jt_super_diff_path = os.path.join(super_diff_dir, build_config, jtreg_category) |
| stats = jtdiff_stats(jt_report_path) |
| if stats: |
| row = TR() |
| row <= TD(build_config.split('-')[0]) |
| row <= TD(build_config.split('-')[1]) |
| row <= TD(A(jtreg_category, href="{0}/html/index.html".format(jt_report_path))) |
| row <= TD(A(stats[0], href="{}/html/passed.html".format(jt_report_path)), align="right") |
| row <= TD(A(stats[1], href="{}/html/failed.html".format(jt_report_path)), align="right", Class='failedCell') |
| row <= TD(A(stats[2], href="{}/html/error.html".format(jt_report_path)), align="right") |
| row <= TD(A(stats[3], href="{}/html/notRun.html".format(jt_report_path)), align="right") |
| row <= TD(A(jtreg_category, href="{}/index.html".format(jt_super_diff_path))) |
| table <= row |
| body <= table |
| |
| |
| def glob_recursive(dirpath, suffix): |
| return [os.path.join(dirpath, f) |
| for dirpath, dirnames, files in os.walk(dirpath) |
| for f in files if f.endswith(suffix)] |
| |
| |
| def jtr_files(dirpath): |
| return glob_recursive(dirpath, '.jtr') |
| |
| |
| def build_config_dirs(top_dir): |
| return os.listdir(os.path.join(top_dir, 'builds')) |
| |
| |
| def add_metadata_table(top_dir, body): |
| metadata_files = glob.glob(os.path.join(top_dir, 'metadata', year, day_of_year, '*')) |
| if metadata_files is None or len(metadata_files) == 0: return |
| body <= H2("Metadata") |
| table = TABLE(border=1) |
| table <= TR(TH('Name') + TH('Value')) |
| for f in metadata_files: |
| if os.path.isfile(os.path.join(f)): |
| with open(f) as fp: |
| row = TR() |
| row <= TD(os.path.basename(f)) |
| row <= TD(fp.read().rstrip()) |
| table <= row |
| body <= table |
| |
| |
| def find_fatal_errors_for_build(top_dir, build_config): |
| fatal_errors = [] |
| for filename in jtr_files(os.path.join(top_dir, 'builds', build_config, year, day_of_year)): |
| with open(filename) as file: |
| for line in file: |
| if "A fatal error has been detected by the Java Runtime Environment" in line: |
| match = [filename, 'not found'] |
| for line in file: |
| if "hs_err" in line: |
| line = line[2:] # remove leading '# ' |
| match[1] = line.rstrip() |
| break |
| # The fatal error may have been an expected |
| # failure. Read through the remainder of the file |
| # looking for the actual result. |
| test_passed = False |
| for line in file: |
| if "test result: Passed. Execution successful" in line: |
| test_passed = True |
| if not test_passed: |
| fatal_errors.append(match) |
| break |
| return fatal_errors |
| |
| |
| def add_fatal_errors(top_dir, body): |
| leading_dirs = len(top_dir.split(os.path.sep)) - 1 |
| fatal_errors_by_build_config = {} |
| for build_config in build_config_dirs(top_dir): |
| fatal_errors_by_build_config[build_config] = find_fatal_errors_for_build(top_dir, build_config) |
| errors = sum([len(fatal_errors_by_build_config[x]) for x in fatal_errors_by_build_config]) |
| if not errors: return |
| body <= H2("Fatal Errors ({})".format(errors)) |
| for build_config, results in sorted(fatal_errors_by_build_config.items()): |
| errors = len(results) |
| if not errors: continue |
| body <= H3("{} ({})".format(build_config, errors)) |
| table = TABLE(border=1) |
| table <= TR(TH('JTR File') + TH('Hotspot Error Log')) |
| for x in sorted(results): |
| row = TR() |
| dirs = x[0].split(os.path.sep) |
| # +5 = builds/<build-config>/<year>/<date>/JTwork-<category> |
| row <= TD(A(os.path.sep.join(dirs[leading_dirs + 5:]), href=x[0])) |
| row <= TD(A(os.path.split(x[1])[1], href=x[1])) |
| table <= row |
| body <= table |
| |
| |
| def main(top_dir, pub_dest): |
| global report_dir |
| global super_diff_dir |
| report_dir = os.path.join(top_dir, "reports") |
| super_diff_dir = os.path.join(top_dir, "super-diff") |
| head = HEAD(TITLE('OpenJDK {} JTREG Test Results ({})'.format(jdk_version, platform.machine()))) |
| head <= LINK(rel="stylesheet", href="../../../style.css") |
| head <= LINK(rel="stylesheet", href="../../../summary.css") |
| body = BODY() |
| if os.path.isdir(report_dir): |
| add_latest_results(body) |
| add_fatal_errors(top_dir, body) |
| add_metadata_table(top_dir, body) |
| body <= H2(A("[Index]", href="{}/index.html".format(top_dir))) |
| body <= P("Page generated on: {}".format(time.strftime("%a, %d %b %Y %T %z"))) |
| print HTML(head + body) |
| |
| |
| if __name__ == '__main__': |
| main(sys.argv[1], sys.argv[2]) |