diff --git a/greentest/generate_report.py b/greentest/generate_report.py index ed1faaa..b7bae73 100755 --- a/greentest/generate_report.py +++ b/greentest/generate_report.py @@ -2,6 +2,9 @@ import sys import os import sqlite3 +import glob + +REPO_URL = 'http://devel.ag-projects.com/~denis/cgi-bin/hgweb.cgi' def make_table(database): c = sqlite3.connect(database) @@ -9,16 +12,22 @@ def make_table(database): 'timeouts, exitcode, stdout from parsed_command_record join ' 'command_record on parsed_command_record.id=command_record.id ')).fetchall() table = {} # testname -> hub -> test_result (runs, errors, fails, timeouts) - hub_stats = {} # hub -> cumulative test_result tests = set() for id, testname, hub, runs, errors, fails, timeouts, exitcode, stdout in res: tests.add(testname) test_result = TestResult(runs, errors, fails, timeouts, exitcode, id, stdout) table.setdefault(testname, {})[hub] = test_result - hub_stats.setdefault(hub, TestResult(0,0,0,0)).__iadd__(test_result) + return table, sorted(tests) + +def calc_hub_stats(table): + hub_stats = {} # hub -> cumulative test_result + for testname in table: + for hub in table[testname]: + test_result = table[testname][hub] + hub_stats.setdefault(hub, TestResult(0,0,0,0)).__iadd__(test_result) hubs = hub_stats.items() - hubs.sort(key=lambda t: t[1].passed, reverse=True) - return table, [x[0] for x in hubs], sorted(tests), hub_stats + hubs.sort(key=lambda t: (t[1].passed, -t[1].timeouts, -t[1].failed), reverse=True) + return hub_stats, [x[0] for x in hubs] class TestResult: @@ -35,6 +44,14 @@ class TestResult: def passed(self): return self.runs - self.errors - self.fails + @property + def failed(self): + return self.errors + self.fails + + @property + def total(self): + return self.runs + self.timeouts + def __iadd__(self, other): self.runs += other.runs self.errors += other.errors @@ -53,6 +70,23 @@ class TestResult: else: return '"#72ff75"' + def warnings(self): + r = [] + if not self.failed and not self.timeouts: + if self.exitcode in [7, 9, 10]: + r += ['TIMEOUT'] + if self.exitcode: + r += ['exitcode=%s' % self.exitcode] + if self.output is not None: + output = self.output.lower() + warning = output.count('warning') + if warning: + r += ['%s warnings' % warning] + tracebacks = output.count('traceback') + if tracebacks: + r += ['%s tracebacks' % tracebacks] + return r + def text(self): errors = [] if self.fails: @@ -61,28 +95,31 @@ class TestResult: errors += ['%s raised' % self.errors] if self.timeouts: errors += ['%s timeout' % self.timeouts] - if not errors: - if self.exitcode in [7, 9, 10]: - errors += ['TIMEOUT'] - if self.exitcode: - errors += ['exitcode=%s' % self.exitcode] - if self.output is not None: - output = self.output.lower() - warning = output.count('warning') - if warning: - errors += ['%s warnings' % warning] - tracebacks = output.count('traceback') - if tracebacks: - errors += ['%s tracebacks' % tracebacks] + errors += self.warnings() + if self.id is None: + errors += ['
%s total' % self.total] return '\n'.join(["%s passed" % self.passed] + errors).replace(' ', ' ') - + + # shorter passed/failed/raised/timeout + def text_short(self): + r = '%s/%s/%s' % (self.passed, self.failed, self.timeouts) + if self.warnings(): + r += '\n' + '\n'.join(self.warnings()).replace(' ', ' ') + return r + def format(self): text = self.text().replace('\n', '
\n') - if self.id is not None: - text = '%s' % (self.id, text) - return '%s' % (self.color(), text) + if self.id is None: + valign = 'bottom' + else: + text = '%s' % (self.id, text) + valign = 'center' + return '%s' % (valign, self.color(), text) -def format_table(table, hubs, tests, hub_stats): +def format_testname(changeset, test): + return '%s' % (REPO_URL, changeset, test, test) + +def format_table(table, hubs, tests, hub_stats, changeset): r = '\n\n\n' % hub @@ -100,7 +137,7 @@ def format_table(table, hubs, tests, hub_stats): r += '' % (len(hubs)+1) for test in tests: - r += '' % test + r += '' % format_testname(changeset, test) for hub in hubs: test_result = table[test].get(hub) if test_result is None: @@ -112,8 +149,13 @@ def format_table(table, hubs, tests, hub_stats): r += '
\n' for hub in hubs: r += '%s
%s
%s
' return r -def format_html(table): - r = '' +def format_header(rev, changeset): + url = '%s/log/%s' % (REPO_URL, changeset) + return 'Eventlet changeset %s: %s

' % (url, rev, changeset) + +def format_html(table, rev, changeset): + r = '' + r += format_header(rev, changeset) r += table r += '' return r @@ -126,12 +168,13 @@ def generate_raw_results(path, database): sys.stderr.write('.') sys.stderr.write('\n') -def main(): - [db] = sys.argv[1:] - r = make_table(db) - report = format_html(format_table(*r)) - changeset = db.split('.')[1] - path = '../htmlreports/%s' % changeset +def main(db): + full_changeset = db.split('.')[1] + rev, changeset = full_changeset.split('_', 1) + table, tests = make_table(db) + hub_stats, hubs = calc_hub_stats(table) + report = format_html(format_table(table, hubs, tests, hub_stats, changeset), rev, changeset) + path = '../htmlreports/%s' % full_changeset try: os.makedirs(path) except OSError, ex: @@ -141,4 +184,10 @@ def main(): generate_raw_results(path, db) if __name__=='__main__': - main() + if not sys.argv[1:]: + latest_db = sorted(glob.glob('results.*.db'))[-1] + print latest_db + sys.argv.append(latest_db) + for db in sys.argv[1:]: + main(db) +