def test_communicate_teeing_retrieves_stdout_and_stderr() -> None: process = subprocess.Popen( [ "/bin/bash", "-c", """ echo "1out" echo >&2 "1err" sleep 0.05 echo >&2 "2err" echo "2out" sleep 0.05 echo "3out" sleep 0.05 echo >&2 "3err" sleep 0.05 exit 1 """, ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) process_handler = SubprocessProcessHandler(process) assert process_handler.communicate_teeing_stdout_and_stderr() == ( dedent("""\ 1out 2out 3out """).encode(), dedent("""\ 1err 2err 3err """).encode(), )
def join(self, stdin_data: bytes | str | None = None, tee_output: bool = False) -> PantsResult: """Wait for the pants process to complete, and return a PantsResult for it.""" communicate_fn = self.process.communicate if tee_output: # TODO: MyPy complains that SubprocessProcessHandler.communicate_teeing_stdout_and_stderr does # not have the same type signature as subprocess.Popen.communicate_teeing_stdout_and_stderr. # It's possibly not worth trying to fix this because the type stubs for subprocess.Popen are # very complex and also not very precise, given how many different configurations Popen can # take. communicate_fn = SubprocessProcessHandler( self.process ).communicate_teeing_stdout_and_stderr # type: ignore[assignment] if stdin_data is not None: stdin_data = ensure_binary(stdin_data) (stdout, stderr) = communicate_fn(stdin_data) if self.process.returncode != PANTS_SUCCEEDED_EXIT_CODE: render_logs(self.workdir) return PantsResult( command=self.command, exit_code=self.process.returncode, stdout=stdout.decode(), stderr=stderr.decode(), workdir=self.workdir, pid=self.process.pid, )
def test_exit_0(self): process = subprocess.Popen(["/bin/sh", "-c", "exit 0"]) process_handler = SubprocessProcessHandler(process) self.assertEqual(process_handler.wait(), 0)
def test_exit_1() -> None: process = subprocess.Popen(["/bin/sh", "-c", "exit 1"]) process_handler = SubprocessProcessHandler(process) assert process_handler.wait() == 1