Merge lp:~lifeless/subunit/nopassthrough into lp:~subunit/subunit/trunk
- nopassthrough
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~lifeless/subunit/nopassthrough |
Merge into: | lp:~subunit/subunit/trunk |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~lifeless/subunit/nopassthrough |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Jonathan Lange | Approve | ||
Review via email: mp+9557@code.launchpad.net |
Commit message
Description of the change
Robert Collins (lifeless) wrote : | # |
- 76. By Robert Collins
-
Fix optparse sense inversion in new option.
Jonathan Lange (jml) wrote : | # |
> This adds --no-passthrough to most filers, which is useful for ensuring there
> is no noise in a stream. This is important for some uses, like when outputting
> structured data other programs will be reading.
Hey Rob,
This seems like a good feature & I can't fault the code. From the description in the MP though, I was expecting the behaviour to be that --no-passthrough makes the script error out when there is noise.
Perhaps the option should be 'discard-noise' or something similar?
jml
Jelmer Vernooij (jelmer) wrote : | # |
Other than the two space issue this seems fine to me.
Bonus points for a test that proves that only non-subunit data is written to the output stream.
Robert Collins (lifeless) wrote : | # |
On Tue, 2009-08-04 at 08:53 +0000, Jonathan Lange wrote:
> Review: Approve
> > This adds --no-passthrough to most filers, which is useful for ensuring there
> > is no noise in a stream. This is important for some uses, like when outputting
> > structured data other programs will be reading.
>
> Hey Rob,
>
> This seems like a good feature & I can't fault the code. From the description in the MP though, I was expecting the behaviour to be that --no-passthrough makes the script error out when there is noise.
>
> Perhaps the option should be 'discard-noise' or something similar?
disard-passthrough perhaps?
I hesitate to call the other content 'noise' - its typically things like
'make' output, or extra debugging that faulty tests aren't capturing.
So I'd like a neutral name for it.
-Rob
Robert Collins (lifeless) wrote : | # |
I've landed this with the current name, on the basis that we have a week or so to change it before I do a 0.2 release.
Jonathan Lange (jml) wrote : | # |
On Wed, Aug 5, 2009 at 1:18 AM, Robert Collins<email address hidden> wrote:
> On Tue, 2009-08-04 at 08:53 +0000, Jonathan Lange wrote:
>> Review: Approve
>> > This adds --no-passthrough to most filers, which is useful for ensuring there
>> > is no noise in a stream. This is important for some uses, like when outputting
>> > structured data other programs will be reading.
>>
>> Hey Rob,
>>
>> This seems like a good feature & I can't fault the code. From the description in the MP though, I was expecting the behaviour to be that --no-passthrough makes the script error out when there is noise.
>>
>> Perhaps the option should be 'discard-noise' or something similar?
>
> disard-passthrough perhaps?
>
> I hesitate to call the other content 'noise' - its typically things like
> 'make' output, or extra debugging that faulty tests aren't capturing.
>
> So I'd like a neutral name for it.
>
I agree. I'm stumped for the right noun though.
jml
Preview Diff
1 | === modified file 'NEWS' |
2 | --- NEWS 2009-08-01 22:10:25 +0000 |
3 | +++ NEWS 2009-08-02 22:55:36 +0000 |
4 | @@ -10,6 +10,10 @@ |
5 | |
6 | IMPROVEMENTS: |
7 | |
8 | + * A number of filters now support ``--no-passthrough`` to cause all |
9 | + non-subunit content to be discarded. This is useful when precise control |
10 | + over what is output is required - such as with subunit2junitxml. |
11 | + |
12 | * Subunit streams can now include optional, incremental lookahead |
13 | information about progress. This allows reporters to make estimates |
14 | about completion, when such information is available. See the README |
15 | |
16 | === modified file 'filters/subunit-filter' |
17 | --- filters/subunit-filter 2009-03-01 21:39:53 +0000 |
18 | +++ filters/subunit-filter 2009-08-02 22:55:36 +0000 |
19 | @@ -26,7 +26,12 @@ |
20 | import sys |
21 | import unittest |
22 | |
23 | -from subunit import ProtocolTestCase, TestResultFilter, TestProtocolClient |
24 | +from subunit import ( |
25 | + DiscardStream, |
26 | + ProtocolTestCase, |
27 | + TestProtocolClient, |
28 | + TestResultFilter, |
29 | + ) |
30 | |
31 | parser = OptionParser(description=__doc__) |
32 | parser.add_option("--error", action="store_false", |
33 | @@ -37,6 +42,8 @@ |
34 | help="include failures", default=False, dest="failure") |
35 | parser.add_option("-f", "--no-failure", action="store_true", |
36 | help="include failures", dest="failure") |
37 | +parser.add_option("--no-passthrough", action="store_true", |
38 | + help="Hide all non subunit input.", default=True, dest="no_passthrough") |
39 | parser.add_option("-s", "--success", action="store_false", |
40 | help="include successes", dest="success") |
41 | parser.add_option("--no-skip", action="store_true", |
42 | @@ -45,8 +52,13 @@ |
43 | help="exclude successes", default=True, dest="success") |
44 | (options, args) = parser.parse_args() |
45 | result = TestProtocolClient(sys.stdout) |
46 | -result = TestResultFilter(result, filter_error=options.error, filter_failure=options.failure, |
47 | - filter_success=options.success, filter_skip=options.skip) |
48 | -test = ProtocolTestCase(sys.stdin) |
49 | +result = TestResultFilter(result, filter_error=options.error, |
50 | + filter_failure=options.failure, filter_success=options.success, |
51 | + filter_skip=options.skip) |
52 | +if options.no_passthrough: |
53 | + passthrough_stream = DiscardStream() |
54 | +else: |
55 | + passthrough_stream = None |
56 | +test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream) |
57 | test.run(result) |
58 | sys.exit(0) |
59 | |
60 | === modified file 'filters/subunit-ls' |
61 | --- filters/subunit-ls 2009-07-20 10:12:42 +0000 |
62 | +++ filters/subunit-ls 2009-08-02 22:55:36 +0000 |
63 | @@ -23,7 +23,7 @@ |
64 | import sys |
65 | import unittest |
66 | |
67 | -from subunit import ProtocolTestCase |
68 | +from subunit import DiscardStream, ProtocolTestCase |
69 | |
70 | class TestIdPrintingResult(unittest.TestResult): |
71 | |
72 | @@ -79,9 +79,15 @@ |
73 | parser.add_option("--times", action="store_true", |
74 | help="list the time each test took (requires a timestamped stream)", |
75 | default=False) |
76 | +parser.add_option("--no-passthrough", action="store_true", |
77 | + help="Hide all non subunit input.", default=True, dest="no_passthrough") |
78 | (options, args) = parser.parse_args() |
79 | result = TestIdPrintingResult(sys.stdout, options.times) |
80 | -test = ProtocolTestCase(sys.stdin) |
81 | +if options.no_passthrough: |
82 | + passthrough_stream = DiscardStream() |
83 | +else: |
84 | + passthrough_stream = None |
85 | +test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream) |
86 | test.run(result) |
87 | if result.wasSuccessful(): |
88 | exit_code = 0 |
89 | |
90 | === modified file 'filters/subunit-stats' |
91 | --- filters/subunit-stats 2009-02-15 11:55:00 +0000 |
92 | +++ filters/subunit-stats 2009-08-02 22:55:36 +0000 |
93 | @@ -19,13 +19,22 @@ |
94 | |
95 | """Filter a subunit stream to get aggregate statistics.""" |
96 | |
97 | +from optparse import OptionParser |
98 | import sys |
99 | import unittest |
100 | |
101 | -from subunit import ProtocolTestCase, TestResultStats |
102 | +from subunit import DiscardStream, ProtocolTestCase, TestResultStats |
103 | |
104 | +parser = OptionParser(description=__doc__) |
105 | +parser.add_option("--no-passthrough", action="store_true", |
106 | + help="Hide all non subunit input.", default=True, dest="no_passthrough") |
107 | +(options, args) = parser.parse_args() |
108 | result = TestResultStats(sys.stdout) |
109 | -test = ProtocolTestCase(sys.stdin) |
110 | +if options.no_passthrough: |
111 | + passthrough_stream = DiscardStream() |
112 | +else: |
113 | + passthrough_stream = None |
114 | +test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream) |
115 | test.run(result) |
116 | result.formatStats() |
117 | if result.wasSuccessful(): |
118 | |
119 | === modified file 'filters/subunit2junitxml' |
120 | --- filters/subunit2junitxml 2009-08-01 08:01:27 +0000 |
121 | +++ filters/subunit2junitxml 2009-08-02 22:55:36 +0000 |
122 | @@ -19,10 +19,11 @@ |
123 | |
124 | """Filter a subunit stream to get aggregate statistics.""" |
125 | |
126 | +from optparse import OptionParser |
127 | import sys |
128 | import unittest |
129 | |
130 | -from subunit import ProtocolTestCase |
131 | +from subunit import DiscardStream, ProtocolTestCase |
132 | try: |
133 | from junitxml import JUnitXmlResult |
134 | except ImportError: |
135 | @@ -30,8 +31,16 @@ |
136 | "http://pypi.python.org/pypi/junitxml) is required for this filter.") |
137 | raise |
138 | |
139 | +parser = OptionParser(description=__doc__) |
140 | +parser.add_option("--no-passthrough", action="store_true", |
141 | + help="Hide all non subunit input.", default=True, dest="no_passthrough") |
142 | +(options, args) = parser.parse_args() |
143 | result = JUnitXmlResult(sys.stdout) |
144 | -test = ProtocolTestCase(sys.stdin) |
145 | +if options.no_passthrough: |
146 | + passthrough_stream = DiscardStream() |
147 | +else: |
148 | + passthrough_stream = None |
149 | +test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream) |
150 | result.startTestRun() |
151 | test.run(result) |
152 | result.stopTestRun() |
153 | |
154 | === modified file 'filters/subunit2pyunit' |
155 | --- filters/subunit2pyunit 2009-07-28 21:44:28 +0000 |
156 | +++ filters/subunit2pyunit 2009-08-02 22:55:36 +0000 |
157 | @@ -23,14 +23,20 @@ |
158 | import sys |
159 | import unittest |
160 | |
161 | -from subunit import ProtocolTestCase, TestProtocolServer |
162 | +from subunit import DiscardStream, ProtocolTestCase, TestProtocolServer |
163 | |
164 | parser = OptionParser(description=__doc__) |
165 | +parser.add_option("--no-passthrough", action="store_true", |
166 | + help="Hide all non subunit input.", default=True, dest="no_passthrough") |
167 | parser.add_option("--progress", action="store_true", |
168 | help="Use bzrlib's test reporter (requires bzrlib)", |
169 | default=False) |
170 | (options, args) = parser.parse_args() |
171 | -test = ProtocolTestCase(sys.stdin) |
172 | +if options.no_passthrough: |
173 | + passthrough_stream = DiscardStream() |
174 | +else: |
175 | + passthrough_stream = None |
176 | +test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream) |
177 | if options.progress: |
178 | from bzrlib.tests import TextTestRunner |
179 | from bzrlib import ui |
180 | |
181 | === modified file 'python/subunit/__init__.py' |
182 | --- python/subunit/__init__.py 2009-07-28 13:32:10 +0000 |
183 | +++ python/subunit/__init__.py 2009-08-02 22:55:36 +0000 |
184 | @@ -63,6 +63,13 @@ |
185 | return new_tags, gone_tags |
186 | |
187 | |
188 | +class DiscardStream(object): |
189 | + """A filelike object which discards what is written to it.""" |
190 | + |
191 | + def write(self, bytes): |
192 | + pass |
193 | + |
194 | + |
195 | class TestProtocolServer(object): |
196 | """A class for receiving results from a TestProtocol client. |
197 | |
198 | @@ -77,19 +84,19 @@ |
199 | READING_XFAIL = 5 |
200 | READING_SUCCESS = 6 |
201 | |
202 | - def __init__(self, client, stream=sys.stdout): |
203 | + def __init__(self, client, stream=None): |
204 | """Create a TestProtocol server instance. |
205 | |
206 | - client should be an object that provides |
207 | - - startTest |
208 | - - addSuccess |
209 | - - addFailure |
210 | - - addError |
211 | - - stopTest |
212 | - methods, i.e. a TestResult. |
213 | + :param client: An object meeting the unittest.TestResult protocol. |
214 | + :param stream: The stream that lines received which are not part of the |
215 | + subunit protocol should be written to. This allows custom handling |
216 | + of mixed protocols. By default, sys.stdout will be used for |
217 | + convenience. |
218 | """ |
219 | self.state = TestProtocolServer.OUTSIDE_TEST |
220 | self.client = client |
221 | + if stream is None: |
222 | + stream = sys.stdout |
223 | self._stream = stream |
224 | self.tags = set() |
225 | |
226 | @@ -701,8 +708,16 @@ |
227 | class ProtocolTestCase(object): |
228 | """A test case which reports a subunit stream.""" |
229 | |
230 | - def __init__(self, stream): |
231 | + def __init__(self, stream, passthrough=None): |
232 | + """Create a ProtocolTestCase reading from stream. |
233 | + |
234 | + :param stream: A filelike object which a subunit stream can be read |
235 | + from. |
236 | + :param passthrough: A stream pass non subunit input on to. If not |
237 | + supplied, the TestProtocolServer default is used. |
238 | + """ |
239 | self._stream = stream |
240 | + self._passthrough = passthrough |
241 | |
242 | def __call__(self, result=None): |
243 | return self.run(result) |
244 | @@ -710,7 +725,7 @@ |
245 | def run(self, result=None): |
246 | if result is None: |
247 | result = self.defaultTestResult() |
248 | - protocol = TestProtocolServer(result) |
249 | + protocol = TestProtocolServer(result, self._passthrough) |
250 | line = self._stream.readline() |
251 | while line: |
252 | protocol.lineReceived(line) |
253 | |
254 | === modified file 'python/subunit/tests/test_test_protocol.py' |
255 | --- python/subunit/tests/test_test_protocol.py 2009-07-28 13:32:10 +0000 |
256 | +++ python/subunit/tests/test_test_protocol.py 2009-08-02 22:55:36 +0000 |
257 | @@ -131,6 +131,7 @@ |
258 | class TestTestImports(unittest.TestCase): |
259 | |
260 | def test_imports(self): |
261 | + from subunit import DiscardStream |
262 | from subunit import TestProtocolServer |
263 | from subunit import RemotedTestCase |
264 | from subunit import RemoteError |
265 | @@ -139,6 +140,12 @@ |
266 | from subunit import TestProtocolClient |
267 | |
268 | |
269 | +class TestDiscardStream(unittest.TestCase): |
270 | + |
271 | + def test_write(self): |
272 | + subunit.DiscardStream().write("content") |
273 | + |
274 | + |
275 | class TestTestProtocolServerPipe(unittest.TestCase): |
276 | |
277 | def test_story(self): |
278 | @@ -194,7 +201,6 @@ |
279 | class TestTestProtocolServerPassThrough(unittest.TestCase): |
280 | |
281 | def setUp(self): |
282 | - from StringIO import StringIO |
283 | self.stdout = StringIO() |
284 | self.test = subunit.RemotedTestCase("old mcdonald") |
285 | self.client = MockTestProtocolServerClient() |
This adds --no-passthrough to most filers, which is useful for ensuring there is no noise in a stream. This is important for some uses, like when outputting structured data other programs will be reading.