1 # Python module for parsing and generating the Subunit protocol
3 # Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 __all__ = ['parse_results']
23 VALID_RESULTS = ['success', 'successful', 'failure', 'fail', 'skip', 'knownfail', 'error', 'xfail', 'skip-testsuite', 'testsuite-failure', 'testsuite-xfail', 'testsuite-success', 'testsuite-error']
25 def parse_results(msg_ops, statistics, fh):
33 if l.startswith("test: "):
34 msg_ops.control_msg(l)
35 name = l.split(":", 1)[1].strip()
36 msg_ops.start_test(name)
37 open_tests.append(name)
38 elif l.startswith("time: "):
40 "^time: (\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)\n", l)
41 msg_ops.report_time(time.mktime((int(grp.group(1)), int(grp.group(2)), int(grp.group(3)), int(grp.group(4)), int(grp.group(5)), int(grp.group(6)), 0, 0, 0)))
42 elif re.match("^(" + "|".join(VALID_RESULTS) + "): (.*?)( \[)?([ \t]*)( multipart)?\n", l):
43 msg_ops.control_msg(l)
44 grp = re.match("^(" + "|".join(VALID_RESULTS) + "): (.*?)( \[)?([ \t]*)( multipart)?\n", l)
45 (result, testname, hasreason) = (grp.group(1), grp.group(2), grp.group(3))
48 # reason may be specified in next lines
54 msg_ops.control_msg(l)
62 statistics['TESTS_ERROR']+=1
63 msg_ops.end_test(testname, "error", 1,
64 "reason (%s) interrupted" % result)
68 if result in ("success", "successful"):
69 open_tests.pop() #FIXME: Check that popped value == $testname
70 statistics['TESTS_EXPECTED_OK']+=1
71 msg_ops.end_test(testname, "success", 0, reason)
72 elif result in ("xfail", "knownfail"):
73 open_tests.pop() #FIXME: Check that popped value == $testname
74 statistics['TESTS_EXPECTED_FAIL']+=1
75 msg_ops.end_test(testname, "xfail", 0, reason)
77 elif result in ("failure", "fail"):
78 open_tests.pop() #FIXME: Check that popped value == $testname
79 statistics['TESTS_UNEXPECTED_FAIL']+=1
80 msg_ops.end_test(testname, "failure", 1, reason)
81 elif result == "skip":
82 statistics['TESTS_SKIP']+=1
83 # Allow tests to be skipped without prior announcement of test
84 last = open_tests.pop()
85 if last is not None and last != testname:
86 open_tests.append(testname)
87 msg_ops.end_test(testname, "skip", 0, reason)
88 elif result == "error":
89 statistics['TESTS_ERROR']+=1
90 open_tests.pop() #FIXME: Check that popped value == $testname
91 msg_ops.end_test(testname, "error", 1, reason)
92 elif result == "skip-testsuite":
93 msg_ops.skip_testsuite(testname)
94 elif result == "testsuite-success":
95 msg_ops.end_testsuite(testname, "success", reason)
96 elif result == "testsuite-failure":
97 msg_ops.end_testsuite(testname, "failure", reason)
98 elif result == "testsuite-xfail":
99 msg_ops.end_testsuite(testname, "xfail", reason)
100 elif result == "testsuite-error":
101 msg_ops.end_testsuite(testname, "error", reason)
102 elif l.startswith("testsuite: "):
103 msg_ops.start_testsuite(l.split(":", 1)[1].strip())
104 elif l.startswith("testsuite-count: "):
105 msg_ops.testsuite_count(int(l.split(":", 1)[1].strip()))
107 msg_ops.output_msg(l)
110 msg_ops.end_test(open_tests.pop(), "error", 1,
111 "was started but never finished!")
112 statistics['TESTS_ERROR']+=1
114 if statistics['TESTS_ERROR'] > 0:
116 if statistics['TESTS_UNEXPECTED_FAIL'] > 0:
121 def start_test(testname):
122 print "test: %s" % testname
124 def end_test(name, result, reason=None):
126 print "%s: %s [" % (result, name)
130 print "%s: %s" % (result, name)
133 def skip_test(name, reason=None):
134 end_test(name, "skip", reason)
137 def fail_test(name, reason=None):
138 end_test(name, "fail", reason)
141 def success_test(name, reason=None):
142 end_test(name, "success", reason)
144 def xfail_test(name, reason=None):
145 end_test(name, "xfail", reason)
148 (sec, min, hour, mday, mon, year, wday, yday, isdst) = time.localtimet(t)
149 print "time: %04d-%02d-%02d %02d:%02d:%02d" % (year+1900, mon+1, mday, hour, min, sec)
152 # The following are Samba extensions:
153 def start_testsuite(name):
154 print "testsuite: %s" % name
156 def skip_testsuite(name, reason=None):
158 print "skip-testsuite: %s [\n%s\n]" % (name, reason)
160 print "skip-testsuite: %s" % name
162 def end_testsuite(name, result, reason=None):
164 print "testsuite-$result: %s [" % name
168 print "testsuite-$result: %s" % name
170 def testsuite_count(count):
171 print "testsuite-count: %d" % count