Skip to content

Commit cd59fab

Browse files
author
Dan
committed
Updated part failure test to also check for presence of (correct) exception in output for failed host. Added enable host logger function to pssh module
1 parent de59418 commit cd59fab

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

pssh.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ class SSHException(Exception):
6464
pass
6565

6666

67+
def enable_host_logger():
68+
"""Enables host logger for logging stdout from remote servers as it
69+
becomes available
70+
"""
71+
if logging.StreamHandler in [type(h) for h in host_logger.handlers]:
72+
logger.warning("Host logger already has a StreamHandler attached")
73+
return
74+
handler = logging.StreamHandler()
75+
host_log_format = logging.Formatter('%(message)s')
76+
handler.setFormatter(host_log_format)
77+
host_logger.addHandler(handler)
78+
host_logger.setLevel(logging.INFO)
79+
80+
6781
class SSHClient(object):
6882
"""Wrapper class over paramiko.SSHClient with sane defaults
6983
Honours ~/.ssh/config and /etc/ssh/ssh_config entries for host username \
@@ -540,22 +554,24 @@ def get_output(self, cmd, output):
540554
541555
:param cmd: Command to get output from
542556
:type cmd: :mod:`gevent.Greenlet`
543-
:rtype: Dictionary with host as key as in:
557+
:param output: Dictionary containing output to be updated with output
558+
from cmd
559+
:type output: dict
560+
:rtype: None
544561
562+
`output` parameter is modified in-place and has the following structure
563+
545564
::
546565
547566
{'myhost1': {'exit_code': exit code if ready else None,
548567
'channel' : SSH channel of command,
549568
'stdout' : <iterable>,
550569
'stderr' : <iterable>,
551-
'cmd' : <greenlet>}}
570+
'cmd' : <greenlet>,
571+
'exception' : <exception object if applicable>}}
552572
553573
Stdout and stderr are also logged via the logger named ``host_logger``
554-
which is enabled by default.
555-
``host_logger`` output can be disabled by removing its handler.
556-
557-
>>> logger = logging.getLogger('pssh.host_logger')
558-
>>> for handler in logger.handlers: logger.removeHandler(handler)
574+
which can be enabled by calling ``enable_host_logger``
559575
560576
**Example usage**:
561577

tests/test_pssh_client.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,7 @@ def test_pssh_client_hosts_list_part_failure(self):
194194
host in the host list has a failure"""
195195
server2_socket = make_socket('127.0.0.2', port=self.listen_port)
196196
server2_port = server2_socket.getsockname()[1]
197-
server1 = start_server({ self.fake_cmd : self.fake_resp },
198-
self.listen_socket, fail_auth=True)
199-
server2 = start_server({ self.fake_cmd : self.fake_resp },
200-
server2_socket)
197+
server2 = start_server(server2_socket, fail_auth=True)
201198
hosts = ['127.0.0.1', '127.0.0.2']
202199
client = ParallelSSHClient(hosts,
203200
port=self.listen_port,
@@ -206,13 +203,21 @@ def test_pssh_client_hosts_list_part_failure(self):
206203
output = client.run_command(self.fake_cmd,
207204
stop_on_errors=False)
208205
self.assertTrue(hosts[0] in output,
209-
msg="Failed host does not exist in output - output is %s" % (output,))
210-
self.assertTrue(hosts[1] in output,
211206
msg="Successful host does not exist in output - output is %s" % (output,))
207+
self.assertTrue(hosts[1] in output,
208+
msg="Failed host does not exist in output - output is %s" % (output,))
209+
self.assertTrue('exception' in output[hosts[1]],
210+
msg="Failed host %s has no exception in output - %s" % (hosts[1], output,))
211+
try:
212+
raise output[hosts[1]]['exception']
213+
except AuthenticationException:
214+
pass
215+
else:
216+
raise Exception("Expected AuthenticationException, got %s instead" % (
217+
output[hosts[1]]['exception'],))
212218
del client
213-
server1.kill()
214219
server2.kill()
215-
220+
216221
def test_pssh_client_ssh_exception(self):
217222
listen_socket = make_socket('127.0.0.1')
218223
listen_port = listen_socket.getsockname()[1]

0 commit comments

Comments
 (0)