Show More
@@ -35,6 +35,7 b' from nose.plugins import Plugin' | |||
|
35 | 35 | from nose.util import safe_str |
|
36 | 36 | |
|
37 | 37 | from IPython.utils.process import is_cmd_found |
|
38 | from IPython.utils.py3compat import bytes_to_str | |
|
38 | 39 | from IPython.utils.importstring import import_item |
|
39 | 40 | from IPython.testing.plugin.ipdoctest import IPythonDoctest |
|
40 | 41 | from IPython.external.decorators import KnownFailure, knownfailureif |
@@ -345,8 +346,9 b' class ExclusionPlugin(Plugin):' | |||
|
345 | 346 | class StreamCapturer(Thread): |
|
346 | 347 | daemon = True # Don't hang if main thread crashes |
|
347 | 348 | started = False |
|
348 | def __init__(self): | |
|
349 | def __init__(self, echo=False): | |
|
349 | 350 | super(StreamCapturer, self).__init__() |
|
351 | self.echo = echo | |
|
350 | 352 | self.streams = [] |
|
351 | 353 | self.buffer = BytesIO() |
|
352 | 354 | self.readfd, self.writefd = os.pipe() |
@@ -361,6 +363,8 b' class StreamCapturer(Thread):' | |||
|
361 | 363 | |
|
362 | 364 | with self.buffer_lock: |
|
363 | 365 | self.buffer.write(chunk) |
|
366 | if self.echo: | |
|
367 | sys.stdout.write(bytes_to_str(chunk)) | |
|
364 | 368 | |
|
365 | 369 | os.close(self.readfd) |
|
366 | 370 | os.close(self.writefd) |
@@ -81,18 +81,24 b' class TestController(object):' | |||
|
81 | 81 | """ |
|
82 | 82 | pass |
|
83 | 83 | |
|
84 | def launch(self, buffer_output=False): | |
|
84 | def launch(self, buffer_output=False, capture_output=False): | |
|
85 | 85 | # print('*** ENV:', self.env) # dbg |
|
86 | 86 | # print('*** CMD:', self.cmd) # dbg |
|
87 | 87 | env = os.environ.copy() |
|
88 | 88 | env.update(self.env) |
|
89 | output = subprocess.PIPE if buffer_output else None | |
|
90 | stdout = subprocess.STDOUT if buffer_output else None | |
|
91 | self.process = subprocess.Popen(self.cmd, stdout=output, | |
|
92 | stderr=stdout, env=env) | |
|
89 | if buffer_output: | |
|
90 | capture_output = True | |
|
91 | self.stdout_capturer = c = StreamCapturer(echo=not buffer_output) | |
|
92 | c.start() | |
|
93 | stdout = c.writefd if capture_output else None | |
|
94 | stderr = subprocess.STDOUT if capture_output else None | |
|
95 | self.process = subprocess.Popen(self.cmd, stdout=stdout, | |
|
96 | stderr=stderr, env=env) | |
|
93 | 97 | |
|
94 | 98 | def wait(self): |
|
95 |
self. |
|
|
99 | self.process.wait() | |
|
100 | self.stdout_capturer.halt() | |
|
101 | self.stdout = self.stdout_capturer.get_buffer() | |
|
96 | 102 | return self.process.returncode |
|
97 | 103 | |
|
98 | 104 | def print_extra_info(self): |
@@ -224,7 +230,6 b' class JSController(TestController):' | |||
|
224 | 230 | |
|
225 | 231 | requirements = ['zmq', 'tornado', 'jinja2', 'casperjs', 'sqlite3', |
|
226 | 232 | 'jsonschema'] |
|
227 | display_slimer_output = False | |
|
228 | 233 | |
|
229 | 234 | def __init__(self, section, xunit=True, engine='phantomjs', url=None): |
|
230 | 235 | """Create new test runner.""" |
@@ -279,8 +284,7 b' class JSController(TestController):' | |||
|
279 | 284 | # If the engine is SlimerJS, we need to buffer the output because |
|
280 | 285 | # SlimerJS does not support exit codes, so CasperJS always returns 0. |
|
281 | 286 | if self.engine == 'slimerjs' and not buffer_output: |
|
282 | self.display_slimer_output = True | |
|
283 | return super(JSController, self).launch(buffer_output=True) | |
|
287 | return super(JSController, self).launch(capture_output=True) | |
|
284 | 288 | |
|
285 | 289 | else: |
|
286 | 290 | return super(JSController, self).launch(buffer_output=buffer_output) |
@@ -292,8 +296,6 b' class JSController(TestController):' | |||
|
292 | 296 | # errors. Otherwise, just return the return code. |
|
293 | 297 | if self.engine == 'slimerjs': |
|
294 | 298 | stdout = bytes_to_str(self.stdout) |
|
295 | if self.display_slimer_output: | |
|
296 | print(stdout) | |
|
297 | 299 | if ret != 0: |
|
298 | 300 | # This could still happen e.g. if it's stopped by SIGINT |
|
299 | 301 | return ret |
General Comments 0
You need to be logged in to leave comments.
Login now