Skip to content

Commit 9717fe3

Browse files
cpeelcj-timothy-sampsonPanos
authored
Add scp-without-sftp test case (#188)
* Changed native client SCP send to not try to create remote directory when recurse is off - resolves #157 * Updated changelog Co-authored-by: Tim Sampson <timothy.sampson@cujo.com> Co-authored-by: Panos <zuboci@yandex.com>
1 parent aa3e90b commit 9717fe3

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

Changelog.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Change Log
22
============
33

4-
1.12.2
5-
++++++
4+
1.12.2 (unreleased)
5+
+++++++++++++++++++
66

77
Fixes
88
------
99

1010
* `ParallelSSHClient.copy_file` with recurse enabled and absolute destination path would create empty directory in home directory of user - #197.
1111
* `ParallelSSHClient.copy_file` and `scp_recv` with recurse enabled would not create remote directories when copying empty local directories.
12+
* `ParallelSSHClient.scp_send` would require SFTP when recurse is off and remote destination path contains directory - #157.
1213

1314
1.12.1
1415
++++++

pssh/clients/native/single.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,8 @@ def scp_recv(self, remote_file, local_file, recurse=False, sftp=None,
484484
:raises: :py:class:`IOError` on local file IO errors.
485485
:raises: :py:class:`OSError` on local OS errors like permission denied.
486486
"""
487-
sftp = self._make_sftp() if (sftp is None and recurse) else sftp
488487
if recurse:
488+
sftp = self._make_sftp() if sftp is None else sftp
489489
try:
490490
self._eagain(sftp.stat, remote_file)
491491
except (SFTPHandleError, SFTPProtocolError):
@@ -575,13 +575,14 @@ def scp_send(self, local_file, remote_file, recurse=False, sftp=None):
575575
elif os.path.isdir(local_file) and not recurse:
576576
raise ValueError("Recurse must be True if local_file is a "
577577
"directory.")
578-
destination = self._remote_paths_split(remote_file)
579-
if destination is not None:
580-
sftp = self._make_sftp() if sftp is None else sftp
581-
try:
582-
self._eagain(sftp.stat, destination)
583-
except (SFTPHandleError, SFTPProtocolError):
584-
self.mkdir(sftp, destination)
578+
if recurse:
579+
destination = self._remote_paths_split(remote_file)
580+
if destination is not None:
581+
sftp = self._make_sftp() if sftp is None else sftp
582+
try:
583+
self._eagain(sftp.stat, destination)
584+
except (SFTPHandleError, SFTPProtocolError):
585+
self.mkdir(sftp, destination)
585586
self._scp_send(local_file, remote_file)
586587
logger.info("SCP local file %s to remote destination %s:%s",
587588
local_file, self.host, remote_file)

tests/native/test_parallel_client.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,10 @@ def test_file_read_no_timeout(self):
13191319
self.assertListEqual(_contents, _out)
13201320

13211321
def test_scp_send_dir(self):
1322+
"""
1323+
Attempting to copy into a non-existent remote directory via scp_send()
1324+
without recurse=True should raise an SCPError.
1325+
"""
13221326
test_file_data = 'test'
13231327
local_filename = 'test_file'
13241328
remote_test_dir, remote_filepath = 'remote_test_dir', 'test_file_copy'
@@ -1330,7 +1334,30 @@ def test_scp_send_dir(self):
13301334
try:
13311335
cmds = self.client.scp_send(local_filename, remote_filename)
13321336
joinall(cmds, raise_error=True)
1333-
time.sleep(.2)
1337+
except Exception as ex:
1338+
self.assertIsInstance(ex, SCPError)
1339+
finally:
1340+
try:
1341+
os.unlink(local_filename)
1342+
except OSError:
1343+
pass
1344+
try:
1345+
shutil.rmtree(remote_test_dir_abspath)
1346+
except OSError:
1347+
pass
1348+
1349+
def test_scp_send_dir_recurse(self):
1350+
test_file_data = 'test'
1351+
local_filename = 'test_file'
1352+
remote_test_dir, remote_filepath = 'remote_test_dir', 'test_file_copy'
1353+
with open(local_filename, 'w') as file_h:
1354+
file_h.writelines([test_file_data + os.linesep])
1355+
remote_filename = os.path.sep.join([remote_test_dir, remote_filepath])
1356+
remote_file_abspath = os.path.expanduser('~/' + remote_filename)
1357+
remote_test_dir_abspath = os.path.expanduser('~/' + remote_test_dir)
1358+
try:
1359+
cmds = self.client.scp_send(local_filename, remote_filename, recurse=True)
1360+
joinall(cmds, raise_error=True)
13341361
self.assertTrue(os.path.isdir(remote_test_dir_abspath))
13351362
self.assertTrue(os.path.isfile(remote_file_abspath))
13361363
remote_file_data = open(remote_file_abspath, 'r').read()

0 commit comments

Comments
 (0)