Mock a Remote Host in Python

大兔子大兔子 提交于 2019-12-10 18:20:47

问题


I am writing some functions, using paramiko, to execute commands and create files on a remote host. I would like to write some unit tests for them, but I don't know what would be the simplest way to achieve this? This is what I envisage as being an example outline of my code:

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)

I have had a look at the paramiko test modules, but they seem quite complex for my use case and I'm not sure how to go about simplifying them.


回答1:


I think what you really need to mock is paramiko.SSHClientobject. You are unittesting your function my_function, you can assume paramiko module works correctly and the only thing you need to unit test is if my_function calls methods of this paramiko.SSHClient in correct way.

To mock paramiko.SSH module you can use unittest.mock and decorate your test_my_function function with @mock.patch.object(paramiko.SSHClient, sshclientmock). You have to define sshclientmock as some kind of Mock or MagicMock first.

Also in python 2.7 there is some equivalent of unittest.mock but I dont remember where to find it exactly.

EDIT: As @chepner mentioned in comment. For python 2.7 you can find mock module in pypi and install it using pip install mock




回答2:


To answer my own question, I have created: https://github.com/chrisjsewell/atomic-hpc/tree/master/atomic_hpc/mockssh.

As the readme discusses; it is based on 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

The following changes have also been made:

  • revised users parameter, such that either a private_path_key or password can be used
  • added a dirname parameter to the Server context manager, such that the this will be set as the root path for the duration of the context.
  • patched paramiko.sftp_client.SFTPClient.chdir to fix its use with relative paths.

See test_mockssh.py for example uses.




回答3:


If you want to test remote connectivity, remote filesystem structure and remote path navigation you have to set-up a mock host server (a VM maybe). In other words if you want to test your actions on the host you have to mock the host.

If you want to test your actions with the data of the host the easiest way seems to proceed as running.t said in the other answer.




回答4:


I agree with HraBal, because of "Infrastructure as code". You can treat virtual machine as a block of code.

For example:

  1. you can use vagrant or docker to initialize a SSH server and then, and modify your DNS configuration file. target domain 127.0.0.1
  2. put application into the server. and run paramiko to connect target domain and test what you want.

I think it is the benefit that you can do this for all programming languages and not need to reinvent the wheel . In addition, you and your successors will know the detail of the system.

(My English is not very good)



来源:https://stackoverflow.com/questions/45917649/mock-a-remote-host-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!