0
  1. I have a session scoped fixture in conftest.py creating a telnet connection to some host
  2. The tests use this fixture to send commands to the host
  3. Some of the tests need to reset the connection (close and reconnect)

All the subsequent tests after the one that performed the connection reset will get the original (dead) telnet handle. Is there a way to deal with this situation beside creating a global connection handle (in conftest for ex)?

conftest.py

@pytest.fixture(scope='session')
def cli(device_params):
    with telnetlib.Telnet(**device_params) as device_handle:
        yield device_handle

test_x.py

def test_foo(cli):
    ...
    cli.reset()
    ...

def test_bar(cli):
    ...
    cli.send_command('cmd')
    ...
  buf = self.sock.recv(50)
  ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
KingUnique
  • 25
  • 5
  • 2
    Aren't you introducing some danger of issues caused by non-deterministic test order? Wouldn't it be better just to use a fresh connection every time, even if it makes the tests a little slower? I don't think there's a good general way to re-open a closed socket object, so I think if you really need to do this you'd need your fixture to reference a global connection object with some logic to recycle it when the conn is closed. But for what its worth, it seems like a bad idea. – Tom Dalton Aug 12 '19 at 12:53

1 Answers1

0

I came up with the following solution (using closure). Seems to work quite well.

@pytest.fixture(scope='session')
def session(params):
    """
    workflow example:

    session('cli').send_command('some telnet command')
    session('reset') <- resets telent connection
    session('cli').send_command('another telnet command')
    """
    session_handle = {'cli': _create_session(params, 'cli')}
    def _kill_session():
        for handle in session_handle.values():
            # terminate telnet connection
    request.addfinalizer(_kill_session) 

    def _get_handle(cmd):
        nonlocal session_handle
        if cmd == 'reset':
            # Telnet session reset trigger goes here
            _kill_session()
            session_handle['cli'] = _create_session(params, 'cli')
        else:
            return session_handle[cmd]
    return _get_handle

def _create_session(params, session_type):
    # Establish a telnet connection
    return session_handle
KingUnique
  • 25
  • 5