The branch, master has been updated via 07eec5a Parse log line-by-line. via bd94958 Simplify log parsing a bit. from 3da72d3 Remove svn/cvs support.
http://gitweb.samba.org/?p=build-farm.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 07eec5adf22d08a0287dde5a0eb1907845adcf43 Author: Jelmer Vernooij <jel...@samba.org> Date: Tue Nov 9 09:13:42 2010 +0100 Parse log line-by-line. commit bd94958b2e4741c84e21503c11406009be72c0c1 Author: Jelmer Vernooij <jel...@samba.org> Date: Tue Nov 9 08:37:48 2010 +0100 Simplify log parsing a bit. ----------------------------------------------------------------------- Summary of changes: buildfarm/data.py | 107 +++++++++++++++++++----------------------- buildfarm/tests/test_data.py | 29 +++++++----- 2 files changed, 66 insertions(+), 70 deletions(-) Changeset truncated at 500 lines: diff --git a/buildfarm/data.py b/buildfarm/data.py index 0b30cdc..15afd31 100644 --- a/buildfarm/data.py +++ b/buildfarm/data.py @@ -33,9 +33,12 @@ import util class BuildStatus(object): - def __init__(self, stages, other_failures): + def __init__(self, stages=None, other_failures=None): self.stages = stages - self.other_failures = other_failures + if other_failures is not None: + self.other_failures = other_failures + else: + self.other_failures = set() def __str__(self): return repr((self.stages, self.other_failures)) @@ -48,66 +51,54 @@ def check_dir_exists(kind, path): def build_status_from_logs(log, err): """get status of build""" - log = log.read() - m = re.search("TEST STATUS:(\s*\d+)", log) - other_failures = set() - if m: - tstatus = int(m.group(1).strip()) - else: - m = re.search("ACTION (PASSED|FAILED): test", log) - if m: - test_failures = len(re.findall("testsuite-(failure|error): ", log)) - test_successes = len(re.findall("testsuite-success: ", log)) - if test_successes > 0: - tstatus = test_failures - else: - tstatus = 255 - if m.group(1) == "FAILED" and tstatus == 0: - tstatus = -1 - other_failures.add("make test error") - else: - tstatus = None - - m = re.search("INSTALL STATUS:(\s*\d+)", log) - if m: - istatus = int(m.group(1).strip()) - else: - istatus = None - - m = re.search("BUILD STATUS:(\s*\d+)", log) - if m: - bstatus = int(m.group(1).strip()) - else: - bstatus = None - - m = re.search("CONFIGURE STATUS:(\s*\d+)", log) - if m: - cstatus = int(m.group(1).strip()) - else: - cstatus = None - - m = re.search("(PANIC|INTERNAL ERROR):.*", log) - if m: - other_failures.add("panic") - - if "No space left on device" in log: - other_failures.add("disk full") - - if "maximum runtime exceeded" in log: - other_failures.add("timeout") + test_failures = 0 + test_successes = 0 + ret = BuildStatus() - stages = (cstatus, bstatus, istatus, tstatus) + stages = [] - m = re.search("CC_CHECKER STATUS:(\s*\d+)", log) - if m: - stages = stages + (int(m.group(1).strip()),) - - # Scan err file for specific + for l in log: + m = re.match("^([A-Z_]+) STATUS:(\s*\d+)$", l) + if m: + stages.append((m.group(1), int(m.group(2).strip()))) + continue + if l.startswith("No space left on device"): + ret.other_failures.add("disk full") + continue + if l.startswith("maximum runtime exceeded"): + ret.other_failures.add("timeout") + continue + m = re.match("^(PANIC|INTERNAL ERROR):.*$", l) + if m: + ret.other_failures.add("panic") + continue + if l.startswith("testsuite-failure: ") or l.startswith("testsuite-error: "): + test_failures += 1 + continue + if l.startswith("testsuite-success: "): + test_successes += 1 + continue + + # Scan err file for specific errors for l in err: if "No space left on device" in l: - other_failures.add("disk full") - - return BuildStatus(stages, other_failures) + ret.other_failures.add("disk full") + + stage_results = dict(stages) + def map_stage(name, result): + if name != "TEST": + return result + # TEST is special + if test_successes + test_failures == 0: + # No granular test output + return result + if result == 0 and test_failures == 0: + ret.other_failures.add("inconsistent test result") + return -1 + return test_failures + + ret.stages = tuple([map_stage(k, v) for k, v in stages]) + return ret def lcov_extract_percentage(text): diff --git a/buildfarm/tests/test_data.py b/buildfarm/tests/test_data.py index 7db834d..6b776ca 100755 --- a/buildfarm/tests/test_data.py +++ b/buildfarm/tests/test_data.py @@ -184,7 +184,7 @@ class BuildStatusFromLogs(testtools.TestCase): def test_nothing(self): s = self.parse_logs("", "") - self.assertEquals((None, None, None, None), s.stages) + self.assertEquals((), s.stages) self.assertEquals(set(), s.other_failures) def test_disk_full(self): @@ -200,43 +200,48 @@ class BuildStatusFromLogs(testtools.TestCase): self.parse_logs("foo\nbar\nmaximum runtime exceeded\nla\n", "").other_failures) - def test_status(self): + def test_failed_test(self): log = """ TEST STATUS:1 """ res = self.parse_logs(log, "") - self.assertEquals(res.stages[3], 1) + self.assertEquals(res.stages, (1,)) + + def test_failed_test_whitespace(self): log = """ TEST STATUS: 1 """ res = self.parse_logs(log, "") - self.assertEquals(res.stages[3], 1) + self.assertEquals(res.stages, (1,)) + + def test_failed_test_noise(self): log = """ CONFIGURE STATUS: 2 TEST STATUS: 1 CC_CHECKER STATUS: 2 """ res = self.parse_logs(log, "") - self.assertEquals(res.stages[4], 2) + self.assertEquals(res.stages, (2,1,2)) + + def test_no_test_output(self): log = """ CONFIGURE STATUS: 2 -ACTION PASSED: test +TEST STATUS: 0 CC_CHECKER STATUS: 2 """ res = self.parse_logs(log, "") - self.assertEquals(res.stages[4], 2) - self.assertEquals(res.stages[3], 255) + self.assertEquals(res.stages, (2, 0, 2)) + + def test_granular_test(self): log = """ CONFIGURE STATUS: 2 -ACTION PASSED: test testsuite-success: toto testsuite-failure: foo testsuite-failure: bar testsuite-failure: biz +TEST STATUS: 1 CC_CHECKER STATUS: 2 """ res = self.parse_logs(log, "") - self.assertEquals(res.stages[0], 2) - self.assertEquals(res.stages[3], 3) - + self.assertEquals(res.stages, (2, 3, 2)) -- build.samba.org