[TIP] problem running fabric commands with py.test
Hans Sebastian
hnsbstn at gmail.com
Tue Dec 6 17:55:27 PST 2011
Hi all,
I am trying to execute a remote command using fabric in my test run by
py.test. Fabric is a library for using SSH and I myself is quite new to it
and just want to start using it. The problem is when i run it with py.test
I am getting an error, but not when invoking with python. Does anyone
understand what the issue is and how to mitigate it? Below is the output.
Thank you very much.
-hans
(env26)[hsebastian at puri integration]$ py.test test_magic.py
===========================================================================================
test session starts
===========================================================================================
platform darwin -- Python 2.6.1 -- pytest-2.1.1
collected 1 items
test_magic.py F
================================================================================================
FAILURES
=================================================================================================
__________________________________________________________________________________________
TestMagic.test_magic
___________________________________________________________________________________________
self = <test_magic.TestMagic object at 0x10124a8d0>
def test_magic(self):
env.key_filename = os.path.join('test.pem')
env.user = 'ubuntu'
env.host_string = 'ec2-50-56-84-105.compute-1.amazonaws.com'
> output = run('ls -al')
test_magic.py:13:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
@wraps(func)
def host_prompting_wrapper(*args, **kwargs):
while not env.get('host_string', False):
handle_prompt_abort()
host_string = raw_input("No hosts found. Please specify
(single)"
" host string for connection: ")
interpret_host_string(host_string)
> return func(*args, **kwargs)
../../../env26/lib/python2.6/site-packages/fabric/network.py:331:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
command = 'ls -al', shell = True, pty = True, combine_stderr = None
@needs_host
def run(command, shell=True, pty=True, combine_stderr=None):
"""
Run a shell command on a remote host.
If ``shell`` is True (the default), `run` will execute the given
command
string via a shell interpreter, the value of which may be
controlled by
setting ``env.shell`` (defaulting to something similar to
``/bin/bash -l -c
"<command>"``.) Any double-quote (``"``) or dollar-sign (``$``)
characters
in ``command`` will be automatically escaped when ``shell`` is True.
`run` will return the result of the remote program's stdout as a
single
(likely multiline) string. This string will exhibit ``failed`` and
``succeeded`` boolean attributes specifying whether the command
failed or
succeeded, and will also include the return code as the
``return_code``
attribute.
Any text entered in your local terminal will be forwarded to the
remote
program as it runs, thus allowing you to interact with password or
other
prompts naturally. For more on how this works, see
:doc:`/usage/interactivity`.
You may pass ``pty=False`` to forego creation of a pseudo-terminal
on the
remote end in case the presence of one causes problems for the
command in
question. However, this will force Fabric itself to echo any and
all input
you type while the command is running, including sensitive
passwords. (With
``pty=True``, the remote pseudo-terminal will echo for you, and will
intelligently handle password-style prompts.) See :ref:`pseudottys`
for
details.
Similarly, if you need to programmatically examine the stderr
stream of the
remote program (exhibited as the ``stderr`` attribute on this
function's
return value), you may set ``combine_stderr=False``. Doing so has a
high
chance of causing garbled output to appear on your terminal (though
the
resulting strings returned by `~fabric.operations.run` will be
properly
separated). For more info, please read :ref:`combine_streams`.
Examples::
run("ls /var/www/")
run("ls /home/myuser", shell=False)
output = run('ls /var/www/site1')
.. versionadded:: 1.0
The ``succeeded`` and ``stderr`` return value attributes, the
``combine_stderr`` kwarg, and interactive behavior.
.. versionchanged:: 1.0
The default value of ``pty`` is now ``True``.
.. versionchanged:: 1.0.2
The default value of ``combine_stderr`` is now ``None`` instead
of
``True``. However, the default *behavior* is unchanged, as the
global
setting is still ``True``.
"""
> return _run_command(command, shell, pty, combine_stderr)
@needs_host
def sudo(command, shell=True, pty=True, combine_stderr=None, user=None):
../../../env26/lib/python2.6/site-packages/fabric/operations.py:945:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
command = 'ls -al', shell = True, pty = True, combine_stderr = None, sudo =
False, user = None
def _run_command(command, shell=True, pty=True, combine_stderr=True,
sudo=False, user=None):
"""
Underpinnings of `run` and `sudo`. See their docstrings for more
info.
"""
# Set up new var so original argument can be displayed verbatim
later.
given_command = command
# Handle context manager modifications, and shell wrapping
wrapped_command = _shell_wrap(
_prefix_commands(_prefix_env_vars(command), 'remote'),
shell,
_sudo_prefix(user) if sudo else None
)
# Execute info line
which = 'sudo' if sudo else 'run'
if output.debug:
print("[%s] %s: %s" % (env.host_string, which, wrapped_command))
elif output.running:
print("[%s] %s: %s" % (env.host_string, which, given_command))
# Actual execution, stdin/stdout/stderr handling, and termination
stdout, stderr, status = _execute(default_channel(),
wrapped_command, pty,
> combine_stderr)
../../../env26/lib/python2.6/site-packages/fabric/operations.py:864:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def wrapper(*args, **kwargs):
try:
> callable(*args, **kwargs)
../../../env26/lib/python2.6/site-packages/fabric/thread_handling.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
chan = <paramiko.Channel 1 (closed) -> <paramiko.Transport at 0x124a810L
(cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>>, using_pty =
True
def input_loop(chan, using_pty):
while not chan.exit_status_ready():
if win32:
have_char = msvcrt.kbhit()
else:
> r, w, x = select([sys.stdin], [], [], 0.0)
../../../env26/lib/python2.6/site-packages/fabric/io.py:120:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <py._io.capture.DontReadFromInput instance at 0x10124e908>
def fileno(self):
> raise ValueError("redirected Stdin is pseudofile, has no fileno()")
E ValueError: redirected Stdin is pseudofile, has no fileno()
../../../env26/lib/python2.6/site-packages/py/_io/capture.py:346: ValueError
---------------------------------------------------------------------------------------------
Captured stdout
---------------------------------------------------------------------------------------------
[ec2-50-56-84-105.compute-1.amazonaws.com] run: ls -al
[ec2-50-56-84-105.compute-1.amazonaws.com] out: total 40
[ec2-50-56-84-105.compute-1.amazonaws.com] out: drwxr-xr-x 5 ubuntu ubuntu
4096 2011-12-07 00:38 .
[ec2-50-56-84-105.compute-1.amazonaws.com] out: drwxr-xr-x 3 root root
4096 2011-02-01 22:08 ..
[ec2-50-56-84-105.compute-1.amazonaws.com] out: -rw------- 1 ubuntu
ubuntu 37 2011-12-07 00:38 .bash_history
[ec2-50-56-84-105.compute-1.amazonaws.com] out: -rw-r--r-- 1 ubuntu ubuntu
220 2011-02-01 22:08 .bash_logout
[ec2-50-56-84-105.compute-1.amazonaws.com] out: -rw-r--r-- 1 ubuntu ubuntu
3103 2011-02-01 22:08 .bashrc
[ec2-50-56-84-105.compute-1.amazonaws.com] out: drwx------ 2 ubuntu ubuntu
4096 2011-09-29 20:51 .cache
[ec2-50-56-84-105.compute-1.amazonaws.com] out: -rw-r--r-- 1 ubuntu ubuntu
========================================================================================
1 failed in 1.65 seconds
=========================================================================================
(env26)[hsebastian at puri integration]$ cat test_magic.py
from fabric.api import run, env
import os
import logging
logging.basicConfig(filename='magic.log')
class TestMagic(object):
def test_magic(self):
env.key_filename = os.path.join('test.pem')
env.user = 'ubuntu'
env.host_string =
'ec2-50-56-84-105.compute-1.amazonaws.com<http://ec2-50-16-84-105.compute-1.amazonaws.com>
'
output = run('ls -al')
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20111206/7fd6d5a3/attachment.htm>
More information about the testing-in-python
mailing list