在 Python 中模拟远程主机
Mock a Remote Host in Python
我正在使用 paramiko 编写一些函数来执行命令并在远程主机上创建文件。我想为他们写一些单元测试,但我不知道实现这个目标的最简单方法是什么?这就是我设想的代码示例大纲:
import os
import paramiko
import pytest
def my_function(hostname, relpath='.', **kwargs):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, **kwargs)
sftp = ssh.open_sftp()
sftp.chdir(relpath)
stdin, stdout, stderr = ssh.exec_command("echo hallo > test.txt")
@pytest.fixture("module")
def mock_remote_host():
# start a remote host here with a local test path
try:
yield hostname, testpath, {"username":"bob", "password":"1234"}
finally:
# delete the test path
# close the remote host
def test_my_function(mock_remote_host):
hostname, dirpath, kwargs = mock_remote_host
my_function(hostname, **kwargs)
filepath = os.path.join(dirpath, 'test.txt')
assert os.path.exists(filepath)
我看过 paramiko test modules,但它们对于我的用例来说似乎相当复杂,我不确定如何简化它们。
我认为你真正需要模拟的是 paramiko.SSHClient
对象。您正在对函数 my_function
进行单元测试,您可以假设 paramiko
模块正常工作,并且您唯一需要进行单元测试的是 my_function
是否以正确的方式调用此 paramiko.SSHClient
的方法.
要模拟 paramiko.SSH
模块,您可以使用 unittest.mock 并使用 @mock.patch.object(paramiko.SSHClient, sshclientmock)
装饰您的 test_my_function
函数。您必须先将 sshclientmock
定义为某种 Mock
或 MagicMock
。
在 python 2.7 中也有一些 unittest.mock
的等价物,但我不记得在哪里可以找到它。
编辑:正如@chepner 在评论中提到的那样。对于 python 2.7,您可以在 pypi 中找到 mock
模块并使用 pip install mock
安装它
如果你想测试远程连接、远程文件系统结构和远程路径导航,你必须设置一个模拟主机服务器(可能是一个虚拟机)。换句话说,如果你想测试你在主机上的操作,你必须模拟主机。
如果你想用主机的数据测试你的操作,最简单的方法似乎是running.t在另一个答案中说的那样。
为了回答我自己的问题,我创建了:https://github.com/chrisjsewell/atomic-hpc/tree/master/atomic_hpc/mockssh。
正如自述文件所讨论的;它基于 https://github.com/carletes/mock-ssh-server/tree/master/mockssh with additions made (to implement more sftp functions) based on https://github.com/rspivak/sftpserver
还进行了以下更改:
- 修改了
users
参数,以便可以使用 private_path_key 或密码
- 向
Server
上下文管理器添加了一个 dirname
参数,以便在上下文持续期间将其设置为根路径。
- 修补
paramiko.sftp_client.SFTPClient.chdir
以修复其与相对路径的使用。
请参阅 test_mockssh.py 示例。
我同意 HraBal,因为 "Infrastructure as code"。您可以将虚拟机视为一段代码。
例如:
- 你可以使用vagrant或者docker初始化一个SSH服务器,然后修改你的DNS配置文件。
target domain 127.0.0.1
- 将应用程序放入服务器。和 运行 paramiko 连接
target domain
并测试你想要的。
我认为好处是你可以对所有编程语言都这样做,而不需要重新发明轮子。此外,您和您的继任者将了解该系统的详细信息。
(我的英文不是很好)
我正在使用 paramiko 编写一些函数来执行命令并在远程主机上创建文件。我想为他们写一些单元测试,但我不知道实现这个目标的最简单方法是什么?这就是我设想的代码示例大纲:
import os
import paramiko
import pytest
def my_function(hostname, relpath='.', **kwargs):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, **kwargs)
sftp = ssh.open_sftp()
sftp.chdir(relpath)
stdin, stdout, stderr = ssh.exec_command("echo hallo > test.txt")
@pytest.fixture("module")
def mock_remote_host():
# start a remote host here with a local test path
try:
yield hostname, testpath, {"username":"bob", "password":"1234"}
finally:
# delete the test path
# close the remote host
def test_my_function(mock_remote_host):
hostname, dirpath, kwargs = mock_remote_host
my_function(hostname, **kwargs)
filepath = os.path.join(dirpath, 'test.txt')
assert os.path.exists(filepath)
我看过 paramiko test modules,但它们对于我的用例来说似乎相当复杂,我不确定如何简化它们。
我认为你真正需要模拟的是 paramiko.SSHClient
对象。您正在对函数 my_function
进行单元测试,您可以假设 paramiko
模块正常工作,并且您唯一需要进行单元测试的是 my_function
是否以正确的方式调用此 paramiko.SSHClient
的方法.
要模拟 paramiko.SSH
模块,您可以使用 unittest.mock 并使用 @mock.patch.object(paramiko.SSHClient, sshclientmock)
装饰您的 test_my_function
函数。您必须先将 sshclientmock
定义为某种 Mock
或 MagicMock
。
在 python 2.7 中也有一些 unittest.mock
的等价物,但我不记得在哪里可以找到它。
编辑:正如@chepner 在评论中提到的那样。对于 python 2.7,您可以在 pypi 中找到 mock
模块并使用 pip install mock
如果你想测试远程连接、远程文件系统结构和远程路径导航,你必须设置一个模拟主机服务器(可能是一个虚拟机)。换句话说,如果你想测试你在主机上的操作,你必须模拟主机。
如果你想用主机的数据测试你的操作,最简单的方法似乎是running.t在另一个答案中说的那样。
为了回答我自己的问题,我创建了:https://github.com/chrisjsewell/atomic-hpc/tree/master/atomic_hpc/mockssh。
正如自述文件所讨论的;它基于 https://github.com/carletes/mock-ssh-server/tree/master/mockssh with additions made (to implement more sftp functions) based on https://github.com/rspivak/sftpserver
还进行了以下更改:
- 修改了
users
参数,以便可以使用 private_path_key 或密码 - 向
Server
上下文管理器添加了一个dirname
参数,以便在上下文持续期间将其设置为根路径。 - 修补
paramiko.sftp_client.SFTPClient.chdir
以修复其与相对路径的使用。
请参阅 test_mockssh.py 示例。
我同意 HraBal,因为 "Infrastructure as code"。您可以将虚拟机视为一段代码。
例如:
- 你可以使用vagrant或者docker初始化一个SSH服务器,然后修改你的DNS配置文件。
target domain 127.0.0.1
- 将应用程序放入服务器。和 运行 paramiko 连接
target domain
并测试你想要的。
我认为好处是你可以对所有编程语言都这样做,而不需要重新发明轮子。此外,您和您的继任者将了解该系统的详细信息。
(我的英文不是很好)