Skip to content

Commit f1d46fc

Browse files
authored
Upgrade (#398)
* Fixed issue with stdin flush for libssh clients * Updated changelog * Updated sshd template * Updated versioneer * Updated logging * Refactored tests, imports * Updated CI cfg * Updated docstrings * Updated imports * Updated readme * Prettify tests
1 parent c7fc51a commit f1d46fc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1296
-610
lines changed

.circleci/config.yml

+12-21
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
version: 2.1
22

3-
orbs:
4-
python: circleci/[email protected]
53

64
jobs:
75
python_test:
86
parameters:
97
python_ver:
108
type: string
11-
default: "3.6"
9+
default: "3.10"
1210
docker:
13-
- image: circleci/python:<< parameters.python_ver >>
11+
- image: cimg/python:<< parameters.python_ver >>
1412
steps:
1513
- checkout
16-
- python/load-cache:
17-
dependency-file: requirements_dev.txt
18-
key: depsv3-{{ .Branch }}.{{ arch }}-PY<< parameters.python_ver >>
1914
- run:
2015
name: Deps
2116
command: |
@@ -24,23 +19,25 @@ jobs:
2419
- run:
2520
command: |
2621
pip install -U -r requirements_dev.txt
22+
set -x
23+
eval "$(ssh-agent -s)"
2724
name: Build
28-
- python/save-cache:
29-
dependency-file: requirements_dev.txt
30-
key: depsv3-{{ .Branch }}.{{ arch }}-PY<< parameters.python_ver >>
3125
- run:
3226
command: |
3327
python setup.py check --restructuredtext
3428
name: Check readme
3529
- run:
3630
command: |
3731
flake8 pssh
32+
flake8 tests ci/integration_tests
3833
name: flake
3934
- run:
4035
command: |
41-
set -x
42-
eval "$(ssh-agent -s)"
4336
pytest
37+
name: Test
38+
- run:
39+
command: |
40+
pytest ci/integration_tests
4441
name: Integration tests
4542
- run:
4643
command: |
@@ -59,22 +56,16 @@ jobs:
5956

6057
release:
6158
docker:
62-
- image: circleci/python:3.8
59+
- image: cimg/python:3.10
6360
steps:
6461
- checkout
65-
- python/load-cache:
66-
key: releasedepsv1-{{ .Branch }}.{{ arch }}
67-
dependency-file: requirements.txt
6862
- run:
6963
name: Deps
7064
command: |
7165
sudo apt-get update
7266
sudo apt-get install python3-pip
7367
pip install -U pip
7468
pip install -U twine
75-
- python/save-cache:
76-
key: releasedepsv1-{{ .Branch }}.{{ arch }}
77-
dependency-file: requirements.txt
7869
- run:
7970
name: Build Wheels/Source Dist
8071
command: |
@@ -94,10 +85,10 @@ workflows:
9485
matrix:
9586
parameters:
9687
python_ver:
97-
- "3.6"
9888
- "3.8"
99-
- "3.9"
10089
- "3.10"
90+
- "3.11"
91+
- "3.12"
10192
filters:
10293
tags:
10394
ignore: /.*/

.codecov.yml

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ coverage:
99
ignore:
1010
- "embedded_server/.*"
1111
- "tests/.*"
12+
- "ci/integration_tests/.*"

.gitignore

+4-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pypy
4545
# Documentation builds
4646
doc/_build
4747

48-
tests/unit_test_cert_key-cert.pub
49-
tests/embedded_server/principals
50-
tests/embedded_server/sshd_config_*
51-
tests/embedded_server/*.pid
48+
ci/integration_tests/int_test_cert_key-cert.pub
49+
ci/integration_tests/embedded_server/principals
50+
ci/integration_tests/embedded_server/sshd_config_*
51+
ci/integration_tests/embedded_server/*.pid

Changelog.rst

+19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
Change Log
22
============
33

4+
5+
2.13.0
6+
+++++++
7+
8+
Changes
9+
-------
10+
11+
* Minimum version updates for ``ssh2-python`` and `ssh-python``.
12+
* Added support for Python 3.12+, removed support for Python <3.8.
13+
* Package tests under top level ``tests`` directory are now cross platform and may be run by vendors.
14+
Project CI specific ntegration tests moved into their own space.
15+
16+
17+
Fixes
18+
------
19+
20+
* Calling ``HostOutput.stdin.flush`` with a ``pssh.clients.ssh`` client would raise exception.
21+
22+
423
2.12.0
524
+++++++
625

MANIFEST.in

+8
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,12 @@ include pssh/_version.py
33
include LICENSE
44
include COPYING
55
include COPYING.LESSER
6+
exclude .codecov.yml
7+
exclude .coveragerc
8+
exclude .git*
9+
exclude .pre-commit*
10+
exclude .readthedocs.yml
611
recursive-exclude tests *
12+
recursive-exclude ci *
13+
recursive-exclude .circleci *
14+
recursive-exclude .github *

README.rst

+3-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Native code based clients with extremely high performance, making use of C libra
2525
:alt: Latest documentation
2626

2727
.. _`read the docs`: https://parallel-ssh.readthedocs.org/en/latest/
28+
.. _`SFTP and SCP documentation`: https://parallel-ssh.readthedocs.io/en/latest/advanced.html#sftp-scp
2829

2930
************
3031
Installation
@@ -239,7 +240,7 @@ To copy a local file to remote hosts in parallel with SCP:
239240
cmds = client.scp_send('../test', 'test_dir/test')
240241
joinall(cmds, raise_error=True)
241242
242-
See `SFTP and SCP documentation <https://parallel-ssh.readthedocs.io/en/latest/advanced.html#sftp-scp>`_ for more examples.
243+
See `SFTP and SCP documentation`_ for more examples.
243244

244245

245246
*****
@@ -275,8 +276,4 @@ In addition, per-host configurable file name functionality is provided for both
275276

276277
Directory recursion is supported in both cases via the ``recurse`` parameter - defaults to off.
277278

278-
See `SFTP and SCP documentation <https://parallel-ssh.readthedocs.io/en/latest/advanced.html#sftp-scp>`_ for more examples.
279-
280-
281-
.. image:: https://ga-beacon.appspot.com/UA-9132694-7/parallel-ssh/README.rst?pixel
282-
:target: https://github.com/igrigorik/ga-beacon
279+
See `SFTP and SCP documentation`_ for more examples.
File renamed without changes.
File renamed without changes.
File renamed without changes.

tests/embedded_server/sshd_config.tmpl renamed to ci/integration_tests/embedded_server/sshd_config.tmpl

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ HostCertificate {{parent_dir}}/ca_host_key-cert.pub
88
TrustedUserCAKeys {{parent_dir}}/ca_user_key.pub
99
AuthorizedPrincipalsFile {{parent_dir}}/principals
1010

11+
MaxAuthTries 999
12+
MaxSessions 999
13+
MaxStartups 999
14+
# PerSourceMaxStartups 999
15+
# PerSourcePenaltyExemptList *.*.*.*
16+
17+
1118
AcceptEnv LANG LC_*
1219
Subsystem sftp internal-sftp
1320
AuthorizedKeysFile {{parent_dir}}/authorized_keys
14-
MaxSessions 100
1521
PidFile {{parent_dir}}/{{random_server}}.pid
File renamed without changes.
File renamed without changes.

tests/native/test_parallel_client.py renamed to ci/integration_tests/native/test_parallel_client.py

+41-37
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,14 @@ def test_pssh_client_run_command_get_output(self):
246246
(stderr,
247247
expected_stderr,))
248248

249-
def test_pssh_client_run_long_command(self):
250-
expected_lines = 5
251-
output = self.client.run_command(self.long_cmd(expected_lines))
252-
self.client.join(output)
253-
stdout = list(output[0].stdout)
254-
self.assertTrue(len(stdout) == expected_lines,
255-
msg="Expected %s lines of response, got %s" % (
256-
expected_lines, len(stdout)))
249+
# def test_pssh_client_run_long_command(self):
250+
# expected_lines = 5
251+
# output = self.client.run_command(self.long_cmd(expected_lines))
252+
# self.client.join(output)
253+
# stdout = list(output[0].stdout)
254+
# self.assertTrue(len(stdout) == expected_lines,
255+
# msg="Expected %s lines of response, got %s" % (
256+
# expected_lines, len(stdout)))
257257

258258
def test_pssh_client_auth_failure(self):
259259
client = ParallelSSHClient([self.host], port=self.port,
@@ -328,29 +328,29 @@ def test_zero_timeout(self):
328328
cmd = spawn(client.run_command, 'sleep .1', stop_on_errors=False)
329329
output = cmd.get(timeout=.3)
330330
self.assertTrue(output[0].exception is None)
331-
332-
def test_pssh_client_long_running_command_exit_codes(self):
333-
expected_lines = 2
334-
output = self.client.run_command(self.long_cmd(expected_lines))
335-
self.assertIsNone(output[0].exit_code)
336-
self.assertFalse(self.client.finished(output))
337-
self.client.join(output, consume_output=True)
338-
self.assertTrue(self.client.finished(output))
339-
self.assertEqual(output[0].exit_code, 0)
340-
stdout = list(output[0].stdout)
341-
self.assertEqual(len(stdout), 0)
342-
343-
def test_pssh_client_long_running_command_exit_codes_no_stdout(self):
344-
expected_lines = 2
345-
output = self.client.run_command(self.long_cmd(expected_lines))
346-
self.assertEqual(len(output), len(self.client.hosts))
347-
self.assertIsNone(output[0].exit_code)
348-
self.assertFalse(self.client.finished(output))
349-
self.client.join(output)
350-
self.assertTrue(self.client.finished(output))
351-
self.assertEqual(output[0].exit_code, 0)
352-
stdout = list(output[0].stdout)
353-
self.assertEqual(expected_lines, len(stdout))
331+
#
332+
# def test_pssh_client_long_running_command_exit_codes(self):
333+
# expected_lines = 2
334+
# output = self.client.run_command(self.long_cmd(expected_lines))
335+
# self.assertIsNone(output[0].exit_code)
336+
# self.assertFalse(self.client.finished(output))
337+
# self.client.join(output, consume_output=True)
338+
# self.assertTrue(self.client.finished(output))
339+
# self.assertEqual(output[0].exit_code, 0)
340+
# stdout = list(output[0].stdout)
341+
# self.assertEqual(len(stdout), 0)
342+
#
343+
# def test_pssh_client_long_running_command_exit_codes_no_stdout(self):
344+
# expected_lines = 2
345+
# output = self.client.run_command(self.long_cmd(expected_lines))
346+
# self.assertEqual(len(output), len(self.client.hosts))
347+
# self.assertIsNone(output[0].exit_code)
348+
# self.assertFalse(self.client.finished(output))
349+
# self.client.join(output)
350+
# self.assertTrue(self.client.finished(output))
351+
# self.assertEqual(output[0].exit_code, 0)
352+
# stdout = list(output[0].stdout)
353+
# self.assertEqual(expected_lines, len(stdout))
354354

355355
def test_pssh_client_retries(self):
356356
"""Test connection error retries"""
@@ -945,7 +945,7 @@ def test_host_config(self):
945945
host_config=host_config,
946946
num_retries=1)
947947
output = client.run_command(self.cmd, stop_on_errors=False)
948-
948+
949949
client.join(output)
950950
self.assertEqual(len(hosts), len(output))
951951
try:
@@ -1121,7 +1121,7 @@ def test_pty(self):
11211121
expected_stdout = []
11221122
# With a PTY, stdout and stderr are combined into stdout
11231123
self.assertEqual(expected_stderr, stdout)
1124-
self.assertEqual([], stderr)
1124+
self.assertEqual(expected_stdout, stderr)
11251125
self.assertTrue(exit_code == 0)
11261126

11271127
def test_output_attributes(self):
@@ -1442,11 +1442,10 @@ def test_scp_send_dir(self):
14421442
remote_test_dir, remote_filepath = 'remote_test_dir', 'test_file_copy'
14431443
with open(local_filename, 'w') as file_h:
14441444
file_h.writelines([test_file_data + os.linesep])
1445-
remote_filename = os.path.sep.join([remote_test_dir, remote_filepath])
1446-
remote_file_abspath = os.path.expanduser('~/' + remote_filename)
1445+
remote_filename_relpath = os.path.sep.join([remote_test_dir, remote_filepath])
14471446
remote_test_dir_abspath = os.path.expanduser('~/' + remote_test_dir)
14481447
try:
1449-
cmds = self.client.scp_send(local_filename, remote_filename)
1448+
cmds = self.client.scp_send(local_filename, remote_filename_relpath)
14501449
joinall(cmds, raise_error=True)
14511450
except Exception as ex:
14521451
self.assertIsInstance(ex, SCPError)
@@ -1558,8 +1557,10 @@ def test_scp_bad_copy_args(self):
15581557

15591558
def test_scp_send_exc(self):
15601559
client = ParallelSSHClient([self.host], pkey=self.user_key, num_retries=1)
1560+
15611561
def _scp_send(*args):
15621562
raise Exception
1563+
15631564
def _client_send(*args):
15641565
return client._handle_greenlet_exc(_scp_send, 'fake')
15651566
client._scp_send = _client_send
@@ -1568,8 +1569,10 @@ def _client_send(*args):
15681569

15691570
def test_scp_recv_exc(self):
15701571
client = ParallelSSHClient([self.host], pkey=self.user_key, num_retries=1)
1572+
15711573
def _scp_recv(*args):
15721574
raise Exception
1575+
15731576
def _client_recv(*args):
15741577
return client._handle_greenlet_exc(_scp_recv, 'fake')
15751578
client._scp_recv = _client_recv
@@ -1899,8 +1902,9 @@ def test_read_multi_same_hosts(self):
18991902
self.client.run_command(self.cmd),
19001903
]
19011904
for output in outputs:
1902-
for host_out in output:
1905+
for i, host_out in enumerate(output):
19031906
stdout = list(host_out.stdout)
1907+
self.assertEqual(host_out.client.host, hosts[i])
19041908
self.assertListEqual(stdout, [self.resp])
19051909

19061910
@patch('pssh.clients.base.single.socket')

0 commit comments

Comments
 (0)