Skip to main content

Allows to mock SFTP servers' connection and contents for testing

Project description

License: MIT Tests

sftpmock

Allows you to test behavior that relies on external SFTP servers to function. This means you can "replace" the external server with a local, mocked version of it, testing behavior that relies on certain files being or not being present on said server.

We do this by locally modifying paramiko.Transport.__init__ to redirect real server addresses to internal mocked servers.

This was inspired by httmock's implementation, check them out!

How to use

Applying the mock

You can use sftpmock both as a decorator, or as a context manager, like so:

# DECORATOR
@with_sftpmock({})
def test_function():
    # Do your asserts here

# CONTEXT MANAGER
def test_function():
    with SFTPMock({}):
        # Do your asserts here

Servers

On both of the methods, sftpmock expects a server_contents input dict. This dictionary follows this syntax:

{
    "mockedserver.com": {
        "folder": {
            "sub_folder": {
                "file.txt": "file content"
            }
        }
    }
}

The folder structure has no depth limit and can contain any number of files.

You may also mock more than one server if needed.

Examples

General use

Normally you'd use sftpmock like this:

@with_sftpmock({
    "test.com": {"a_folder": {"coisa.txt": "some text"}}
})
def test_function():
    # Do your asserts here

Calling paramiko.Transport on test function

If you need to call paramiko.Transport directly on the test function, you need to import it on the function. This makes sure the mocked version of Transport is used.

On other use cases this is not necessary.

@with_sftpmock({
    "test.com": {"a_folder": {"coisa.txt": "some text"}}
})
def test_function():
    from paramiko import Transport

    with Transport(("test.com", 22)) as transport:
        # Do your asserts here

Mocking multiple servers

If you need to mock more than one server, simply include it on the input dict.

@with_sftpmock({
    "test.com": {"a_folder": {"coisa.txt": "some text"}},
    "otherdomain.com": {"a_folder": {"another.txt": "another text"}}
})
def test_function():
    # Do your asserts here

Using a socket

If you use Python sockets, you may run into errors when the socket still tries to connect to the real server, even though sftpmock ignores that connection.

One way to circumvent that is by using unnitest.mock to prevent that initial socket connection. From there, sftpmock works as expected.

import socket

@with_sftpmock({
    "test.com": {"a_folder": {"test.txt": "some text"}},
})
@mock.patch('socket.socket', spec=socket.socket)
def test_function(self, mock_socket):
    from paramiko import Transport

    mock_socket.return_value.getsockname.return_value = ("test.com", 22)

    serversocket = socket.socket()

    serversocket.connect(("test.com", 22))

    with Transport(serversocket) as transport:
        # Do your asserts here

Known Issues / Limitations

  • Trying to test transport.sock hostname and ports may result in errors, as they are replaced by localhost and a random local port
  • SSHClient may be replaced by a local server, as it also uses paramiko.Transport (need to test this still)
  • If you are using sockets to init a Transport, you may need to mock them first
  • If the SFTP servers being tested are actually localhost, this won't work

Future improvements

  • Not depend on pytest-sftpserver package
  • Allow for server port differentiation
  • Avoid affecting SSHClient

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sftpmock-1.0.0.tar.gz (5.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sftpmock-1.0.0-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file sftpmock-1.0.0.tar.gz.

File metadata

  • Download URL: sftpmock-1.0.0.tar.gz
  • Upload date:
  • Size: 5.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for sftpmock-1.0.0.tar.gz
Algorithm Hash digest
SHA256 e9536fae9860bd257656a01d2dd7e9f2f6d871013a232de5ce0c0df1c44215df
MD5 580fb9864293d99f198f8200441f79ee
BLAKE2b-256 70ac9b218c5f5be76ff13ba27b00a2071aaeb3be4ca8cf6520adbd12d8cd92b6

See more details on using hashes here.

File details

Details for the file sftpmock-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: sftpmock-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for sftpmock-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d9231b8ff69eac4b429cc857a577e1192db0dff076376e1a6f699b3271eaab4b
MD5 146bd03749441226ba8788659684f7ef
BLAKE2b-256 bd7d5a4e67394697ec594b75864a74d7e3425a98c6b9e4e23a7e9e4ef6ef9ac3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page