3 # Pretty-format subunit output
4 # Copyright (C) 2008-2010 Jelmer Vernooij <jelmer@samba.org>
5 # Published under the GNU GPL, v3 or later
14 class PlainFormatter(object):
16 def __init__(self
, summaryfile
, verbose
, immediate
, statistics
,
18 self
.verbose
= verbose
19 self
.immediate
= immediate
20 self
.statistics
= statistics
21 self
.start_time
= None
23 self
.suitesfailed
= []
26 self
.summaryfile
= summaryfile
29 self
._progress
_level
= 0
30 self
.totalsuites
= totaltests
32 def progress(self
, offset
, whence
):
33 if whence
== subunit
.PROGRESS_POP
:
34 self
._progress
_level
-= 1
35 elif whence
== subunit
.PROGRESS_PUSH
:
36 self
._progress
_level
+= 1
37 elif whence
== subunit
.PROGRESS_SET
:
38 if self
._progress
_level
== 0:
39 self
.totalsuites
= offset
40 elif whence
== subunit
.PROGRESS_CUR
:
41 raise NotImplementedError
43 def report_time(self
, time
):
44 if self
.start_time
is None:
45 self
.start_time
= time
48 def start_testsuite(self
, name
):
51 testsuite_start_time
= self
.last_time
53 duration
= testsuite_start_time
- self
.start_time
56 self
.test_output
[name
] = ""
58 out
= "[%d" % self
.index
59 if self
.totalsuites
is not None:
60 out
+= "/%d" % self
.totalsuites
61 out
+= " in %ds" % duration
63 out
+= ", %d errors" % (len(self
.suitesfailed
),)
66 sys
.stdout
.write(out
+ "\n")
68 sys
.stdout
.write(out
+ ": ")
70 def output_msg(self
, output
):
72 sys
.stdout
.write(output
)
73 elif self
.name
is not None:
74 self
.test_output
[self
.name
] += output
76 sys
.stdout
.write(output
)
78 def control_msg(self
, output
):
79 #$self->output_msg($output)
82 def end_testsuite(self
, name
, result
, reason
):
86 if not name
in self
.test_output
:
87 print "no output for name[%s]" % name
89 if result
in ("success", "xfail"):
92 self
.output_msg("ERROR: Testsuite[%s]\n")
93 if reason
is not None:
94 self
.output_msg("REASON: %s\n" % (name
, reason
or ''))
95 self
.suitesfailed
.append(name
)
96 if self
.immediate
and not self
.verbose
:
97 out
+= self
.test_output
[name
]
100 if not self
.immediate
:
104 out
+= " " + result
.upper() + "\n"
106 sys
.stdout
.write(out
)
108 def start_test(self
, testname
):
111 def end_test(self
, testname
, result
, unexpected
, reason
):
113 self
.test_output
[self
.name
] = ""
114 if not self
.immediate
:
119 'success': '.'}.get(result
, "?(%s)" % result
))
124 reason
= reason
.strip()
126 self
.test_output
[self
.name
] += "UNEXPECTED(%s): %s\nREASON: %s\n" % (result
, testname
, reason
)
128 if self
.immediate
and not self
.verbose
:
129 print self
.test_output
[self
.name
]
130 self
.test_output
[self
.name
] = ""
132 if not self
.immediate
:
136 'success': 'S'}.get(result
, "?"))
139 f
= open(self
.summaryfile
, 'w+')
141 if self
.suitesfailed
:
142 f
.write("= Failed tests =\n")
144 for suite
in self
.suitesfailed
:
145 f
.write("== %s ==\n" % suite
)
146 f
.write(self
.test_output
[suite
]+"\n\n")
150 if not self
.immediate
and not self
.verbose
:
151 for suite
in self
.suitesfailed
:
153 print "FAIL: %s" % suite
154 print self
.test_output
[suite
]
157 f
.write("= Skipped tests =\n")
158 for reason
in self
.skips
.keys():
159 f
.write(reason
+ "\n")
160 for name
in self
.skips
[reason
]:
161 f
.write("\t%s\n" % name
)
165 print "\nA summary with detailed information can be found in:"
166 print " %s" % self
.summaryfile
168 if not self
.suitesfailed
:
169 ok
= (self
.statistics
['TESTS_EXPECTED_OK'] +
170 self
.statistics
['TESTS_EXPECTED_FAIL'])
171 print "\nALL OK (%d tests in %d testsuites)" % (ok
, self
.suites_ok
)
173 print "\nFAILED (%d failures and %d errors in %d testsuites)" % (
174 self
.statistics
['TESTS_UNEXPECTED_FAIL'],
175 self
.statistics
['TESTS_ERROR'],
176 len(self
.suitesfailed
))
178 def skip_testsuite(self
, name
, reason
="UNKNOWN"):
179 self
.skips
.setdefault(reason
, []).append(name
)
183 parser
= optparse
.OptionParser("format-subunit [options]")
184 parser
.add_option("--verbose", action
="store_true",
186 parser
.add_option("--immediate", action
="store_true",
187 help="Show failures immediately, don't wait until test run has finished")
188 parser
.add_option("--prefix", type="string", default
=".",
189 help="Prefix to write summary to")
191 opts
, args
= parser
.parse_args()
195 'TESTS_UNEXPECTED_OK': 0,
196 'TESTS_EXPECTED_OK': 0,
197 'TESTS_UNEXPECTED_FAIL': 0,
198 'TESTS_EXPECTED_FAIL': 0,
203 def handle_sigint(sig
, stack
):
205 signal
.signal(signal
.SIGINT
, handle_sigint
)
207 msg_ops
= PlainFormatter(os
.path
.join(opts
.prefix
, "summary"), opts
.verbose
,
208 opts
.immediate
, statistics
)
210 expected_ret
= subunithelper
.parse_results(msg_ops
, statistics
, sys
.stdin
)
214 sys
.exit(expected_ret
)