pexpectpxssh

why pxssh.before behaves different when used with py.test.?


from pexpect import pxssh
import getpass
import time
import sys
s=pxssh.pxssh()

class Testinstall:

    def setup_class(cls):
        cls.s=pxssh.pxssh()
        cls.s.login('10.10.62.253', 'User','PW',auto_prompt_reset=False)

    def teardown_class(cls):
        cls.s.logout()

    def test_cleanup(cls):
        cls.s.sendline('cat test.py')
        cls.s.prompt(timeout=10)
        cls.s.sendline('cat profiles.conf')
        cls.s.prompt(timeout=10)
        print('s.before')
        print (cls.s.before)
        print('s.after')
        print(cls.s.after)

In above code print(cls.s.before) prints, output of both cat commands. As per expectation it should only print output of the 2nd cat command i.e cat profiles.conf. When tried in python session in shell it shows output of only second cat command ( as per expectation)


Solution

  • If you use auto_prompt_reset=False for pxssh.login() then you cannot use pxssh.prompt(). According to the doc:

    pxssh uses a unique prompt in the prompt() method. If the original prompt is not reset then this will disable the prompt() method unless you manually set the PROMPT attribute.

    So for your code, both prompt() would time out and .before would have all output and .after would be pexpect.exceptions.TIMEOUT.


    The doc also says that

    Calling prompt() will erase the contents of the before attribute even if no prompt is ever matched.

    but this is NOT true based on my testing:

    >>> from pexpect import pxssh
    >>> ssh = pxssh.pxssh()
    >>> ssh.login('127.0.0.1', 'root', 'passwd')
    True
    >>> ssh.PROMPT = 'not-the-real-prompt'
    >>> ssh.sendline('hello')
    6
    >>> ssh.prompt(timeout=1)
    False
    >>> ssh.before
    'hello\r\n-bash: hello: command not found\r\n[PEXPECT]# '
    >>> ssh.after
    <class 'pexpect.exceptions.TIMEOUT'>
    >>> ssh.sendline('world')
    6
    >>> ssh.prompt(timeout=1)
    False
    >>> ssh.before
    'hello\r\n-bash: hello: command not found\r\n[PEXPECT]# world\r\n-bash: world: command not found\r\n[PEXPECT]# '
    >>> ssh.after
    <class 'pexpect.exceptions.TIMEOUT'>
    >>>
    

    From the result you can see .before is not erased for the 2nd prompt(). Instead it's appended with the new output.