On Thu, Jun 23, 2011 at 8:02 PM, Dale Curtis <[email protected]> wrote: > Allowing reasons with multiple lines and tabs provides more flexibility > in error messages. The parser is also more robust, as any invalid fields > are moved into the reason and can be fixed offline without impacting the > rest of the system.
LGTM, applied, thanks! http://autotest.kernel.org/changeset/5452 > Signed-off-by: Dale Curtis <[email protected]> > --- > tko/parsers/version_0.py | 28 ++++++++++++++++++---------- > tko/parsers/version_0_unittest.py | 32 +++++++++++++++++++++++++++----- > tko/parsers/version_1_unittest.py | 7 ------- > 3 files changed, 45 insertions(+), 22 deletions(-) > > diff --git a/tko/parsers/version_0.py b/tko/parsers/version_0.py > index c690d21..ed12cb4 100644 > --- a/tko/parsers/version_0.py > +++ b/tko/parsers/version_0.py > @@ -251,7 +251,7 @@ class status_line(object): > def parse_line(cls, line): > if not status_line.is_status_line(line): > return None > - match = re.search(r"^(\t*)(.*)$", line) > + match = re.search(r"^(\t*)(.*)$", line, flags=re.DOTALL) > if not match: > # A more useful error message than: > # AttributeError: 'NoneType' object has no attribute 'groups' > @@ -261,15 +261,23 @@ class status_line(object): > indent = len(indent) > > # split the line into the fixed and optional fields > - parts = line.split("\t") > - status, subdir, testname = parts[0:3] > - reason = parts[-1] > - optional_parts = parts[3:-1] > - > - # all the optional parts should be of the form "key=value" > - assert sum('=' not in part for part in optional_parts) == 0 > - optional_fields = dict(part.split("=", 1) > - for part in optional_parts) > + parts = line.rstrip("\n").split("\t") > + > + part_index = 3 > + status, subdir, testname = parts[0:part_index] > + > + # all optional parts should be of the form "key=value". once we've > found > + # a non-matching part, treat it and the rest of the parts as the > reason. > + optional_fields = {} > + while part_index < len(parts): > + kv = parts[part_index].split('=', 1) > + if len(kv) < 2: > + break > + > + optional_fields[kv[0]] = kv[1] > + part_index += 1 > + > + reason = "\t".join(parts[part_index:]) > > # build up a new status_line and return it > return cls(indent, status, subdir, testname, reason, > diff --git a/tko/parsers/version_0_unittest.py > b/tko/parsers/version_0_unittest.py > index 4807bee..286e5bb 100755 > --- a/tko/parsers/version_0_unittest.py > +++ b/tko/parsers/version_0_unittest.py > @@ -230,6 +230,20 @@ class test_status_line(unittest.TestCase): > "field2": "val2"}) > > > + def test_parse_line_handles_embedded_new_lines(self): > + input_data = ("\tEND FAIL\t----\ttest\tfield1=val1\tStatus\nwith\n" > + "embedded\nnew lines\n") > + > + line = version_0.status_line.parse_line(input_data) > + self.assertEquals(line.indent, 1) > + self.assertEquals(line.type, "END") > + self.assertEquals(line.status, "FAIL") > + self.assertEquals(line.subdir, None) > + self.assertEquals(line.testname, "test") > + self.assertEquals(line.reason, "Status\nwith\nembedded\nnew lines") > + self.assertEquals(line.optional_fields, {"field1": "val1"}) > + > + > def test_parse_line_fails_on_untabbed_lines(self): > input_data = " GOOD\trandom\tfields\tof text" > line = version_0.status_line.parse_line(input_data) > @@ -259,11 +273,19 @@ class test_status_line(unittest.TestCase): > self.assertEquals(line.optional_fields, {}) > > > - def test_parse_line_fails_on_bad_optional_fields(self): > - input_data = "GOOD\tfield1\tfield2\tfield3\tfield4" > - self.assertRaises(AssertionError, > - version_0.status_line.parse_line, > - input_data) > + def test_parse_line_handles_tabs_in_reason(self): > + input_data = ("\tEND > FAIL\t----\ttest\tfield1=val1\tfield2=val2\tReason" > + " with\ta\tcouple\ttabs") > + > + line = version_0.status_line.parse_line(input_data) > + self.assertEquals(line.indent, 1) > + self.assertEquals(line.type, "END") > + self.assertEquals(line.status, "FAIL") > + self.assertEquals(line.subdir, None) > + self.assertEquals(line.testname, "test") > + self.assertEquals(line.reason, "Reason with\ta\tcouple\ttabs") > + self.assertEquals(line.optional_fields, {"field1": "val1", > + "field2": "val2"}) > > > if __name__ == "__main__": > diff --git a/tko/parsers/version_1_unittest.py > b/tko/parsers/version_1_unittest.py > index 4114c59..d569366 100755 > --- a/tko/parsers/version_1_unittest.py > +++ b/tko/parsers/version_1_unittest.py > @@ -136,13 +136,6 @@ class test_status_line(unittest.TestCase): > self.assertEquals(line.optional_fields, {}) > > > - def test_parse_line_fails_on_bad_optional_fields(self): > - input_data = "GOOD\tfield1\tfield2\tfield3\tfield4" > - self.assertRaises(AssertionError, > - version_1.status_line.parse_line, > - input_data) > - > - > def test_good_reboot_passes_success_test(self): > line = version_1.status_line(0, "NOSTATUS", None, "reboot", > "reboot success", {}) > -- > 1.7.3.1 > > _______________________________________________ > Autotest mailing list > [email protected] > http://test.kernel.org/cgi-bin/mailman/listinfo/autotest > -- Lucas _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
