Skip to content Skip to sidebar Skip to footer

Test Calling Of An External Script Run Via Popen That Expects No Available Data In Stdin Using Pytest

I have an external tool with a command line interface that checks whether any data is provided via stdin by using sys.stdin in select.select([sys.stdin], [], [], 0)[0] and adjusts

Solution 1:

If you are willing to generate and explicitly pass a file descriptor that is not ready for reading in the production code, you can generate a new named pipe via os.pipe and pass its reading end as stdin. Obviously, it is somewhat of a workaround for the strange interface to generate a new pipe with the sole purpose of it being empty. But as long as you don't write anything into the pipe, the pipe should not be ready for reading and thus the select.select call should not pick it up. The internal part could then look somewhat like the code below:

import contextlib
import os
import subprocess

@contextlib.contextmanager
def not_ready_to_read():
    try:
        read_end, write_end = os.pipe()
        yield read_end
    finally:
        os.close(read_end)
        os.close(write_end)

def call_external():
    with not_ready_to_read() as not_ready_stdin:
        popen = subprocess.Popen(["/usr/bin/python3", "external_script.py", "1"],
                                 stdin=not_ready_stdin, stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        print(popen.communicate()[:2])

if __name__ == "__main__":
    call_external()

This can also help you with other situations where the test via select.select erroneously suggests that some data is passed via stdin, such as if you run the script via the slurm job scheduler. Therefore, it's not an adaption of the production code with the sole purpose of enabling the test.

Post a Comment for "Test Calling Of An External Script Run Via Popen That Expects No Available Data In Stdin Using Pytest"