Search code examples
pythonbashsshparamikocurses

Blackbox test with python of a ncurses python app via Paramiko


I'm in the strange position of being both the developer of a python utility for our project, and the tester of it. The app is ready and now I want to write a couple of blackbox tests that connect to the server where it resides (the server itself is the product that we commercialize), and launch the python application.

The python app allows a minimal command line scripting (some parameters automatically launch functions that otherwise would require user interaction at the main menu). For the residual user interactions, I usually try bash syntax like this:

./app -f <<< $'parameter1\nparameter2\n\n'

And finally I redirect everything to >/dev/null. If I do manual checks at the command line on the server (where I connect via SSH), everything works smoothly. The app launch lasts 30 seconds, and after 30 seconds I'm correctly returned to the prompt.

Now to the blackbox testing part. Here I'm also using python (Py.test framework), but the test code resides on another machine. The test runner machine will connect to the Server under test via Paramiko libraries. I've already used this a lot in scripting other functionalities of the product, and it works quite well.

But the problem in this case is that the app under test that I wrote in python uses the NCurses library in its normal behaviour ("import curses"), and apparently when trying to launch this in the Py.test script:

import paramiko
...
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.load_system_host_keys()
client.connect(myhost, myuser, mypass, mytimeout)
client.exec_command("./app -f <<< $'parameter1\nparameter2\n\n' >/dev/null")

Regardless the redirection to /dev/null, the .exec_command() prints this to standard error out with a message about the curses initialization:

...
File "/my/path/to/app", line xxx, in curses_screen
  scr = curses.initscr()
...
_curses.error: setupterm: could not find terminal

and finally the py.test script fails because the app execution crashed.

Is there some conflicts between curses (used by the app under test) and paramiko (used by the test script)? As I said, if I connect manually via SSH to the server where the app resides and launch the command line manually with the silent redirection to /dev/null, it works as I would expect.


Solution

  • ncurses really would like to do input/output to a terminal. /dev/null is not a terminal, and some terminal I/O mode changes will fail in that case. Occasionally someone connects the I/O to a socket, and ncurses will (usually) work in that situation.

    In your environment, besides the lack of a terminal, it is possible that TERM is unset. That will make setupterm fail.