Test Calling Of An External Script Run Via Popen That Expects No Available Data In Stdin Using Pytest
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"