Skip to content

Commit 13ba5ed

Browse files
author
Pan
committed
Added codecov cfg, updated cfgs. Code cleanup, more tests.
1 parent 613209c commit 13ba5ed

File tree

10 files changed

+75
-22
lines changed

10 files changed

+75
-22
lines changed

.codecov.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ignore:
2+
- "embedded_server/.*"
3+
- "tests/.*"

.coveragerc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ exclude_lines =
1919
raise NotImplementedError
2020
if __name__ == .__main__.:
2121
logger.debug
22+
continue

.travis.yml

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ jobs:
3232
- if: tag IS present
3333
os: osx
3434
# tag =~ ^\d+\.\d+(\.\d+)?(-\S*)?$
35-
before_install: skip
35+
before_install:
36+
- brew update
3637
install:
3738
- brew install libssh2
3839
- pip install -U delocate twine wheel pip setuptools
@@ -54,14 +55,13 @@ jobs:
5455
fi
5556
language: generic
5657
python: skip
57-
- stage: build_packages
58+
- stage: build system packages
59+
if: tag IS present
5860
os: linux
5961
python: 3.6
6062
before_install: skip
6163
install: skip
62-
script:
63-
- docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
64-
- ./ci/docker/build-packages.sh
64+
script: skip
6565
after_success: skip
6666
before_deploy:
6767
- docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
@@ -76,7 +76,7 @@ jobs:
7676
on:
7777
repo: ParallelSSH/parallel-ssh
7878
tags: true
79-
- stage: deploy_pypi
79+
- stage: deploy pypi sdist
8080
if: tag IS present
8181
os: linux
8282
python: 3.6
@@ -95,7 +95,8 @@ jobs:
9595
distributions: sdist
9696
skip_upload_docs: true
9797
skip_cleanup: true
98-
- stage: build wheels
98+
- stage: build and deploy wheels
99+
if: tag IS present
99100
os: linux
100101
python: 3.6
101102
before_install: skip
@@ -104,10 +105,7 @@ jobs:
104105
script:
105106
- docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" &&
106107
./ci/travis/build-manylinux.sh;
107-
# - if [[ ! -z "$TRAVIS_TAG" ]]; then
108-
# echo "Building wheels for tag ${TRAVIS_TAG}" &&
109-
# docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" &&
110-
# ./ci/travis/build-manylinux.sh;
111-
# fi
112108
after_success:
113-
- twine upload -u $PYPI_U -p $PYPI_P wheelhouse/*.whl
109+
- if [[ ! -z "$TRAVIS_TAG" ]]; then
110+
twine upload -u $PYPI_U -p $PYPI_P wheelhouse/*.whl;
111+
fi

Changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Changes
88
---------
99

1010
* New ``ssh2-python`` (``libssh2``) native library based clients
11+
* Added ``retry_delay`` keyword parameter to parallel clients
1112

1213
Fixes
1314
--------

pssh/base_pssh.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@
2222
import logging
2323

2424
import gevent.pool
25-
import gevent.hub
25+
from gevent.hub import Hub
2626

2727
from .exceptions import HostArgumentException
2828
from .constants import DEFAULT_RETRIES, RETRY_DELAY
2929
from .output import HostOutput
3030

31-
gevent.hub.Hub.NOT_ERROR = (Exception,)
31+
32+
Hub.NOT_ERROR = (Exception,)
3233
logger = logging.getLogger(__name__)
3334

3435
try:
@@ -165,6 +166,8 @@ def get_exit_codes(self, output):
165166
:rtype: None
166167
"""
167168
for host in output:
169+
if output[host] is None:
170+
continue
168171
output[host].exit_code = self.get_exit_code(output[host])
169172

170173
def get_exit_code(self, host_output):

pssh/pssh2_client.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,11 @@
1717

1818
import logging
1919

20-
import gevent.pool
21-
import gevent.hub
22-
2320
from .base_pssh import BaseParallelSSHClient
2421
from .constants import DEFAULT_RETRIES, RETRY_DELAY
2522
from .ssh2_client import SSHClient
2623

2724

28-
gevent.hub.Hub.NOT_ERROR = (Exception,)
2925
logger = logging.getLogger(__name__)
3026

3127

pssh/pssh_client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
from .base_pssh import BaseParallelSSHClient # noqa: E402
3030
from .exceptions import HostArgumentException # noqa: E402
31-
from .constants import DEFAULT_RETRIES # noqa: E402
31+
from .constants import DEFAULT_RETRIES, RETRY_DELAY # noqa: E402
3232
from .ssh_client import SSHClient # noqa: E402
3333

3434

@@ -43,7 +43,7 @@ def __init__(self, hosts, user=None, password=None, port=None, pkey=None,
4343
timeout=120, pool_size=10, proxy_host=None, proxy_port=22,
4444
proxy_user=None, proxy_password=None, proxy_pkey=None,
4545
agent=None, allow_agent=True, host_config=None,
46-
channel_timeout=None):
46+
channel_timeout=None, retry_delay=RETRY_DELAY):
4747
"""
4848
:param hosts: Hosts to connect to
4949
:type hosts: list(str)
@@ -61,6 +61,9 @@ def __init__(self, hosts, user=None, password=None, port=None, pkey=None,
6161
:param num_retries: (Optional) Number of retries for connection attempts
6262
before the client gives up. Defaults to 3.
6363
:type num_retries: int
64+
:param retry_delay: Number of seconds to wait between retries. Defaults
65+
to :py:class:`pssh.constants.RETRY_DELAY`
66+
:type retry_delay: int
6467
:param timeout: (Optional) Number of seconds to wait before connection
6568
and authentication attempt times out. Note that total time before
6669
timeout will be
@@ -111,7 +114,7 @@ def __init__(self, hosts, user=None, password=None, port=None, pkey=None,
111114
self, hosts, user=user, password=password, port=port, pkey=pkey,
112115
allow_agent=allow_agent, num_retries=num_retries,
113116
timeout=timeout, pool_size=pool_size,
114-
host_config=host_config)
117+
host_config=host_config, retry_delay=retry_delay)
115118
self.forward_ssh_agent = forward_ssh_agent
116119
self.proxy_host, self.proxy_port, self.proxy_user, \
117120
self.proxy_password, self.proxy_pkey = proxy_host, proxy_port, \

pssh/ssh2_client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from gevent import sleep, get_hub
2424
from gevent import socket
25+
from gevent.hub import Hub
2526
from ssh2.error_codes import LIBSSH2_ERROR_EAGAIN
2627
from ssh2.exceptions import AuthenticationError, AgentError, \
2728
SessionHandshakeError, SFTPHandleError, SFTPIOError as SFTPIOError_ssh2
@@ -37,6 +38,7 @@
3738
from .native.ssh2 import wait_select, _read_output # , sftp_get, sftp_put
3839

3940

41+
Hub.NOT_ERROR = (Exception,)
4042
host_logger = logging.getLogger('pssh.host_logger')
4143
logger = logging.getLogger(__name__)
4244
THREAD_POOL = get_hub().threadpool

tests/test_pssh_ssh2_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ def test_client_join_consume_output(self):
9797
self.assertTrue(len(stdout) == 0)
9898
self.assertTrue(len(stderr) == 0)
9999
self.assertEqual(expected_exit_code, exit_code)
100+
output = self.client.run_command('echo "me" >&2', use_pty=False)
101+
self.client.join(output, consume_output=True)
102+
exit_code = output[self.host].exit_code
103+
stdout = list(output[self.host]['stdout'])
104+
stderr = list(output[self.host]['stderr'])
105+
self.assertTrue(len(stdout) == 0)
106+
self.assertTrue(len(stderr) == 0)
107+
self.assertEqual(expected_exit_code, exit_code)
100108

101109
def test_client_join_stdout(self):
102110
output = self.client.run_command(self.cmd)
@@ -1122,6 +1130,10 @@ def test_open_channel_failure(self):
11221130
client.host_clients[self.host].session.disconnect()
11231131
self.assertRaises(SessionError, client.host_clients[self.host].open_session)
11241132

1133+
def test_host_no_client(self):
1134+
output = {'blah': None}
1135+
self.client.join(output)
1136+
11251137
# def test_proxy_remote_host_failure_timeout(self):
11261138
# """Test that timeout setting is passed on to proxy to be used for the
11271139
# proxy->remote host connection timeout

tests/test_ssh2_client.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
import logging
44
import time
55

6+
from gevent import socket
7+
68
from .base_ssh2_test import SSH2TestCase
79
from .embedded_server.openssh import OpenSSHServer
810
from pssh.ssh2_client import SSHClient, logger as ssh_logger
11+
from pssh.exceptions import AuthenticationException, ConnectionErrorException
912

1013

1114
ssh_logger.setLevel(logging.DEBUG)
@@ -40,3 +43,34 @@ def test_long_running_cmd(self):
4043
self.client.wait_finished(channel)
4144
exit_code = channel.get_exit_status()
4245
self.assertEqual(exit_code, 2)
46+
47+
def test_manual_auth(self):
48+
client = SSHClient(self.host, port=self.port,
49+
pkey=self.user_key,
50+
num_retries=1)
51+
client.session.disconnect()
52+
del client.session
53+
del client.sock
54+
client.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
55+
client._connect()
56+
client._init()
57+
58+
def test_identity_auth_failure(self):
59+
self.assertRaises(AuthenticationException,
60+
SSHClient, self.host, port=self.port, num_retries=1,
61+
allow_agent=False)
62+
63+
def test_agent_auth_failure(self):
64+
self.assertRaises(AuthenticationException,
65+
SSHClient, self.host, port=self.port, num_retries=1,
66+
allow_agent=True)
67+
68+
def test_password_auth_failure(self):
69+
self.assertRaises(AuthenticationException,
70+
SSHClient, self.host, port=self.port, num_retries=1,
71+
password='blah blah blah')
72+
73+
def test_retry_failure(self):
74+
self.assertRaises(ConnectionErrorException,
75+
SSHClient, self.host, port=12345,
76+
num_retries=2)

0 commit comments

Comments
 (0)