mirror of
https://github.com/ceph/ceph
synced 2025-02-23 11:07:35 +00:00
Support PIPE for stdout and stderr, too.
This commit is contained in:
parent
a988083c4b
commit
37cbd7abc7
@ -190,7 +190,7 @@ def run(
|
||||
:param args: command to run
|
||||
:type args: list of string
|
||||
:param stdin: Standard input to send; either a string, a file-like object, None, or `PIPE`. `PIPE` means caller is responsible for closing stdin, or command may never exit.
|
||||
:param stdout: What to do with standard output. Either a file-like object, a `logging.Logger`, or `None` for copying to default log.
|
||||
:param stdout: What to do with standard output. Either a file-like object, a `logging.Logger`, `PIPE`, or `None` for copying to default log. `PIPE` means caller is responsible for reading, or command may never exit.
|
||||
:param stderr: What to do with standard error. See `stdout`.
|
||||
:param logger: If logging, write stdout/stderr to "out" and "err" children of this logger. Defaults to logger named after this module.
|
||||
:param check_status: Whether to raise CalledProcessError on non-zero exit status, and . Defaults to True. All signals and connection loss are made to look like SIGHUP.
|
||||
@ -210,19 +210,29 @@ def run(
|
||||
if logger is None:
|
||||
logger = log
|
||||
|
||||
if stderr is None:
|
||||
stderr = logger.getChild('err')
|
||||
g_err = gevent.spawn(copy_file_to, r.stderr, stderr)
|
||||
r.stderr = stderr
|
||||
g_err = None
|
||||
if stderr is not PIPE:
|
||||
if stderr is None:
|
||||
stderr = logger.getChild('err')
|
||||
g_err = gevent.spawn(copy_file_to, r.stderr, stderr)
|
||||
r.stderr = stderr
|
||||
else:
|
||||
assert not wait, "Using PIPE for stderr without wait=False would deadlock."
|
||||
|
||||
if stdout is None:
|
||||
stdout = logger.getChild('out')
|
||||
g_out = gevent.spawn(copy_file_to, r.stdout, stdout)
|
||||
r.stdout = stdout
|
||||
g_out = None
|
||||
if stdout is not PIPE:
|
||||
if stdout is None:
|
||||
stdout = logger.getChild('out')
|
||||
g_out = gevent.spawn(copy_file_to, r.stdout, stdout)
|
||||
r.stdout = stdout
|
||||
else:
|
||||
assert not wait, "Using PIPE for stdout without wait=False would deadlock."
|
||||
|
||||
def _check_status(status):
|
||||
g_err.get()
|
||||
g_out.get()
|
||||
if g_err is not None:
|
||||
g_err.get()
|
||||
if g_out is not None:
|
||||
g_out.get()
|
||||
if g_in is not None:
|
||||
g_in.get()
|
||||
|
||||
|
@ -309,6 +309,76 @@ def test_run_stdin_pipe():
|
||||
eq(got, 0)
|
||||
|
||||
|
||||
@nose.with_setup(fudge.clear_expectations)
|
||||
@fudge.with_fakes
|
||||
def test_run_stdout_pipe():
|
||||
ssh = fudge.Fake('SSHConnection')
|
||||
cmd = ssh.expects('exec_command')
|
||||
cmd.with_args("foo")
|
||||
in_ = fudge.Fake('ChannelFile').is_a_stub()
|
||||
out = fudge.Fake('ChannelFile').is_a_stub()
|
||||
err = fudge.Fake('ChannelFile').is_a_stub()
|
||||
cmd.returns((in_, out, err))
|
||||
out.expects('read').with_args().returns('one')
|
||||
out.expects('read').with_args().returns('two')
|
||||
out.expects('read').with_args().returns('')
|
||||
err.expects('xreadlines').with_args().returns([])
|
||||
logger = fudge.Fake('logger').is_a_stub()
|
||||
channel = fudge.Fake('channel')
|
||||
out.has_attr(channel=channel)
|
||||
channel.expects('recv_exit_status').with_args().returns(0)
|
||||
r = run.run(
|
||||
client=ssh,
|
||||
logger=logger,
|
||||
args=['foo'],
|
||||
stdout=run.PIPE,
|
||||
wait=False,
|
||||
)
|
||||
eq(r.command, 'foo')
|
||||
assert isinstance(r.exitstatus, gevent.event.AsyncResult)
|
||||
eq(r.exitstatus.ready(), False)
|
||||
eq(r.stdout.read(), 'one')
|
||||
eq(r.stdout.read(), 'two')
|
||||
eq(r.stdout.read(), '')
|
||||
got = r.exitstatus.get()
|
||||
eq(got, 0)
|
||||
|
||||
|
||||
@nose.with_setup(fudge.clear_expectations)
|
||||
@fudge.with_fakes
|
||||
def test_run_stderr_pipe():
|
||||
ssh = fudge.Fake('SSHConnection')
|
||||
cmd = ssh.expects('exec_command')
|
||||
cmd.with_args("foo")
|
||||
in_ = fudge.Fake('ChannelFile').is_a_stub()
|
||||
out = fudge.Fake('ChannelFile').is_a_stub()
|
||||
err = fudge.Fake('ChannelFile').is_a_stub()
|
||||
cmd.returns((in_, out, err))
|
||||
out.expects('xreadlines').with_args().returns([])
|
||||
err.expects('read').with_args().returns('one')
|
||||
err.expects('read').with_args().returns('two')
|
||||
err.expects('read').with_args().returns('')
|
||||
logger = fudge.Fake('logger').is_a_stub()
|
||||
channel = fudge.Fake('channel')
|
||||
out.has_attr(channel=channel)
|
||||
channel.expects('recv_exit_status').with_args().returns(0)
|
||||
r = run.run(
|
||||
client=ssh,
|
||||
logger=logger,
|
||||
args=['foo'],
|
||||
stderr=run.PIPE,
|
||||
wait=False,
|
||||
)
|
||||
eq(r.command, 'foo')
|
||||
assert isinstance(r.exitstatus, gevent.event.AsyncResult)
|
||||
eq(r.exitstatus.ready(), False)
|
||||
eq(r.stderr.read(), 'one')
|
||||
eq(r.stderr.read(), 'two')
|
||||
eq(r.stderr.read(), '')
|
||||
got = r.exitstatus.get()
|
||||
eq(got, 0)
|
||||
|
||||
|
||||
def test_quote_simple():
|
||||
got = run.quote(['a b', ' c', 'd e '])
|
||||
eq(got, "'a b' ' c' 'd e '")
|
||||
|
Loading…
Reference in New Issue
Block a user