@mock.patch("yardstick.ssh.open", create=True)
def test__put_file_shell(self, mock_open):
- self.test_client.run = mock.Mock()
- self.test_client._put_file_shell("localfile", "remotefile", 0o42)
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile", "remotefile", 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > "remotefile"&& chmod -- 042 "remotefile"',
+ stdin=mock_open.return_value.__enter__.return_value)
- self.test_client.run.assert_called_once_with(
- 'cat > remotefile && chmod -- 042 remotefile',
- stdin=mock_open.return_value.__enter__.return_value)
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell_space(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile",
+ "filename with space", 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > "filename with space"&& chmod -- 042 "filename with '
+ 'space"',
+ stdin=mock_open.return_value.__enter__.return_value)
+
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell_tilde(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile", "~/remotefile", 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > ~/"remotefile"&& chmod -- 042 ~/"remotefile"',
+ stdin=mock_open.return_value.__enter__.return_value)
+
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell_tilde_spaces(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile", "~/file with space",
+ 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > ~/"file with space"&& chmod -- 042 ~/"file with space"',
+ stdin=mock_open.return_value.__enter__.return_value)
@mock.patch("yardstick.ssh.os.stat")
def test__put_file_sftp(self, mock_stat):
import select
import socket
import time
+import re
import logging
import paramiko
raise SSHError("Socket error.")
exit_status = session.recv_exit_status()
- if 0 != exit_status and raise_on_error:
+ if exit_status != 0 and raise_on_error:
fmt = "Command '%(cmd)s' failed with exit_status %(status)d."
details = fmt % {"cmd": cmd, "status": exit_status}
if stderr_data:
mode = 0o777 & os.stat(localpath).st_mode
sftp.chmod(remotepath, mode)
+ TILDE_EXPANSIONS_RE = re.compile("(^~[^/]*/)?(.*)")
+
def _put_file_shell(self, localpath, remotepath, mode=None):
# quote to stop wordpslit
- cmd = ['cat > %s' % remotepath]
+ tilde, remotepath = self.TILDE_EXPANSIONS_RE.match(remotepath).groups()
+ if not tilde:
+ tilde = ''
+ cmd = ['cat > %s"%s"' % (tilde, remotepath)]
if mode is not None:
# use -- so no options
- cmd.append('chmod -- 0%o %s' % (mode, remotepath))
+ cmd.append('chmod -- 0%o %s"%s"' % (mode, tilde, remotepath))
with open(localpath, "rb") as localfile:
# only chmod on successful cat
- cmd = " && ".join(cmd)
- self.run(cmd, stdin=localfile)
+ self.run("&& ".join(cmd), stdin=localfile)
def put_file(self, localpath, remotepath, mode=None):
"""Copy specified local file to the server.
:param remotepath: Remote filename.
:param mode: Permissions to set after upload
"""
- import socket
try:
self._put_file_sftp(localpath, remotepath, mode=mode)
except (paramiko.SSHException, socket.error):