Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f7aa8a5

Browse files
committed
distinguish capture_output from buffer_output
allow capturing output without silencing it, which is useful for slimerjs, which requires looking at output to determine failure.
1 parent ccb6443 commit f7aa8a5

2 files changed

Lines changed: 18 additions & 12 deletions

File tree

IPython/testing/iptest.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from nose.util import safe_str
3636

3737
from IPython.utils.process import is_cmd_found
38+
from IPython.utils.py3compat import bytes_to_str
3839
from IPython.utils.importstring import import_item
3940
from IPython.testing.plugin.ipdoctest import IPythonDoctest
4041
from IPython.external.decorators import KnownFailure, knownfailureif
@@ -345,8 +346,9 @@ def wantDirectory(self, directory):
345346
class StreamCapturer(Thread):
346347
daemon = True # Don't hang if main thread crashes
347348
started = False
348-
def __init__(self):
349+
def __init__(self, echo=False):
349350
super(StreamCapturer, self).__init__()
351+
self.echo = echo
350352
self.streams = []
351353
self.buffer = BytesIO()
352354
self.readfd, self.writefd = os.pipe()
@@ -361,6 +363,8 @@ def run(self):
361363

362364
with self.buffer_lock:
363365
self.buffer.write(chunk)
366+
if self.echo:
367+
sys.stdout.write(bytes_to_str(chunk))
364368

365369
os.close(self.readfd)
366370
os.close(self.writefd)

IPython/testing/iptestcontroller.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,24 @@ def setup(self):
8181
"""
8282
pass
8383

84-
def launch(self, buffer_output=False):
84+
def launch(self, buffer_output=False, capture_output=False):
8585
# print('*** ENV:', self.env) # dbg
8686
# print('*** CMD:', self.cmd) # dbg
8787
env = os.environ.copy()
8888
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)
9397

9498
def wait(self):
95-
self.stdout, _ = self.process.communicate()
99+
self.process.wait()
100+
self.stdout_capturer.halt()
101+
self.stdout = self.stdout_capturer.get_buffer()
96102
return self.process.returncode
97103

98104
def print_extra_info(self):
@@ -224,7 +230,6 @@ class JSController(TestController):
224230

225231
requirements = ['zmq', 'tornado', 'jinja2', 'casperjs', 'sqlite3',
226232
'jsonschema']
227-
display_slimer_output = False
228233

229234
def __init__(self, section, xunit=True, engine='phantomjs', url=None):
230235
"""Create new test runner."""
@@ -279,8 +284,7 @@ def launch(self, buffer_output):
279284
# If the engine is SlimerJS, we need to buffer the output because
280285
# SlimerJS does not support exit codes, so CasperJS always returns 0.
281286
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)
284288

285289
else:
286290
return super(JSController, self).launch(buffer_output=buffer_output)
@@ -292,8 +296,6 @@ def wait(self, *pargs, **kwargs):
292296
# errors. Otherwise, just return the return code.
293297
if self.engine == 'slimerjs':
294298
stdout = bytes_to_str(self.stdout)
295-
if self.display_slimer_output:
296-
print(stdout)
297299
if ret != 0:
298300
# This could still happen e.g. if it's stopped by SIGINT
299301
return ret

0 commit comments

Comments
 (0)