summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tko/parsers/version_0.py28
-rwxr-xr-xtko/parsers/version_0_unittest.py32
-rwxr-xr-xtko/parsers/version_1_unittest.py7
3 files changed, 45 insertions, 22 deletions
diff --git a/tko/parsers/version_0.py b/tko/parsers/version_0.py
index c690d211..ed12cb48 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 4807beec..286e5bb2 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 4114c59c..d5693663 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", {})