def test_when_input_is_closed_reading_any_output_gives_empty_string(): with nested(Pipe(), Pipe(), Pipe()) as (p1, p2, p3): with tee(p1.read_fd, (p2.write_fd, p3.write_fd)).background(): p1.close_write() assert os.read(p2.read_fd, 4096) == '' assert os.read(p3.read_fd, 4096) == '' assert p2.write_closed assert p3.write_closed
def test_tee_can_capture_subprocess_output_and_send_to_stdout(): with nested(Pipe(), Pipe()) as (in_pipe, out_pipe): with tee(in_pipe.read_fd, (sys.stdout.fileno(), out_pipe.write_fd)).background(): echo = subprocess.Popen(['echo', 'hello'], stdout=in_pipe.write_fd) echo.wait() os.close(in_pipe.write_fd) captured_output = os.read(out_pipe.read_fd, 8192) assert captured_output == 'hello\n'
def test_can_tee_to_stdout_and_a_simple_pipe(): with nested(Pipe(), Pipe()) as (p1, p2): with tee(p1.read_fd, (sys.stdout.fileno(), p2.write_fd)).background(): # Write to input pipe, the output should show up on one output # pipe and stdout (though there's no easy way to check this) os.write(p1.write_fd, 'foobar') os.close(p1.write_fd) assert os.read(p2.read_fd, 6) == 'foobar'
def test_tee_can_handle_pipe_closures_gracefully(): with nested(Pipe(), Pipe(), Pipe()) as (p1, p2, p3): with tee(p1.read_fd, (p2.write_fd, p3.write_fd)).background(): os.write(p1.write_fd, "Hello!\n") p1.close_write() assert p2.write_closed assert p3.write_closed assert os.read(p2.read_fd, 100) == "Hello!\n" assert os.read(p3.read_fd, 100) == "Hello!\n"
def test_can_tee_to_two_pipes(): with nested(Pipe(), Pipe(), Pipe()) as (p1, p2, p3): with tee(p1.read_fd, (p2.write_fd, p3.write_fd)).background(): # Write to input pipe, the output should show up on one output # pipe and stdout (though there's no easy way to check this) os.write(p1.write_fd, 'foobar') os.close(p1.write_fd) assert os.read(p2.read_fd, 6) == 'foobar' assert os.read(p3.read_fd, 6) == 'foobar'
def test_pipe_closes_fds_on_garbage_collection(): pipe = Pipe() ident = id(pipe) read_fd, write_fd = pipe.read_fd, pipe.write_fd # Check that the pipe gets collected. assert object_exists(ident) del pipe gc.collect() assert not object_exists(ident) ensure_fd_closed(read_fd) ensure_fd_closed(write_fd)
def test_multiple_closes_are_a_noop(): pipe = Pipe() pipe.close() pipe.close() ensure_pipe_closed(pipe)
def test_close_closes_both_fds(): pipe = Pipe() pipe.close() ensure_pipe_closed(pipe)
def test_closed_indicates_whether_an_fd_is_closed(): pipe = Pipe() os.close(pipe.read_fd) assert pipe.read_closed os.close(pipe.write_fd) assert pipe.write_closed
def test_pipe_as_context_manager_closes_its_file_descriptors(): with Pipe() as pipe: pass ensure_pipe_closed(pipe)
def test_non_blocking_pipes_raise_EAGAIN_when_no_data_are_ready_to_read(): pipe = Pipe(non_blocking=True) with assert_raises(IOError) as cm: pipe.read_file.read() assert cm.exception.errno == errno.EAGAIN
def test_smoke_test_pipe(): pipe = Pipe() pipe.write_file.write('FooBar\n') pipe.write_file.flush() assert pipe.read_file.readline() == 'FooBar\n'
def test_pipe_gets_read_and_write_file_handles(): pipe = Pipe() assert hasattr(pipe.read_file, 'read') assert hasattr(pipe.write_file, 'write')
def test_pipe_gets_read_and_write_file_descriptors(): pipe = Pipe() assert isinstance(pipe.read_fd, int) assert isinstance(pipe.write_fd, int)