Is it possible to setup SFTP (SSH File Transfer Protocol) on temp folder? I want this for testing purposes (first setup SFTP and after tests tear it down).
Or maybe there is some mock approach where I could mimic as if SFTP exists on that temp folder?
Something like:
import tempfile
import unittest
class TestSFTP(unittest.TestCase):
@classmethod
def setupClass(cls):
folder = tempfile.TemporaryDirectory()
# use temp folder and setup temp sftp to be used in tests
# define some test methods and use sftp.
@classmethod
def tearDownClass(cls):
# destroy temp sftp.
P.S. Normally to create SFTP, you need to use sudo, restart some services etc, so such approach would be unfeasible for testing purposes.
Update:
So I was able to set up test class, that it would run sftp server, but I've got issues when I need to stop sftp server properly. Here is the code I've got so far..:
import sftpserver
import paramiko
import os
import sh
import threading
from odoo.tests import common
from odoo.modules.module import get_module_path
def _start_thread(target, args=None, kwargs=None):
"""Run target object in thread, in a background."""
if not args:
args = []
if not kwargs:
kwargs = {}
thread = threading.Thread(target=target, args=args, kwargs=kwargs)
thread.daemon = True
thread.start()
return thread
class TestExchangeCommon(common.SavepointCase):
"""Common class for exchange module tests."""
tests_path = os.path.join(get_module_path('exchange'), 'tests')
rsa_key_path = os.path.join(tests_path, 'extra/test_rsa.key')
@classmethod
def _start_sftp(cls):
sftpserver.start_server('localhost', 3373, cls.rsa_key_path, 'INFO')
@classmethod
def setUpClass(cls):
"""Set up data to be used by all test classes."""
import logging
_logger = logging.getLogger()
super(TestExchangeCommon, cls).setUpClass()
cls.thread = _start_thread(target=cls._start_sftp)
pkey = paramiko.RSAKey.from_private_key_file(cls.rsa_key_path)
cls.transport = paramiko.Transport(('localhost', 3373))
cls.transport.connect(username='admin', password='admin', pkey=pkey)
cls.sftp = paramiko.SFTPClient.from_transport(cls.transport)
_logger.warn(cls.sftp.listdir('.'))
@classmethod
def tearDownClass(cls):
"""Kill sftp server to stop running it in a background."""
cls.sftp.close()
cls.transport.close()
sh.fuser('-k', '3373/tcp') # this kills main application...
In order for sftp server to run, I had to put in a thread, so it would not stall my main application. But when I need to stop sftp server after tests are done, if I kill on port 3373 (sftp server is run), it kills main application too, which is actually run on port 8069. Is there a way to close sftpserver instance properly via python?