Skip to content

Commit 4d1fb86

Browse files
committed
Strong timeout handle. Do not produce fake positive scenarios
(cherry picked from commit 41b65a2)
1 parent be0bb30 commit 4d1fb86

File tree

2 files changed

+5
-25
lines changed

2 files changed

+5
-25
lines changed

exec_helpers/subprocess_runner.py

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -148,31 +148,15 @@ def close_streams() -> None:
148148

149149
try:
150150
exit_code = async_result.interface.wait(timeout=timeout) # Wait real timeout here
151-
except subprocess.TimeoutExpired:
152-
exit_code = async_result.interface.poll() # Update exit code
153-
154-
# Process closed?
155-
if exit_code is not None:
156151
concurrent.futures.wait([stdout_future, stderr_future], timeout=0.1) # Minimal timeout to complete polling
157152
result.exit_code = exit_code
158-
close_streams()
159153
return result
160-
# Kill not ended process and wait for close
161-
try:
154+
except subprocess.TimeoutExpired:
162155
# kill -9 for all subprocesses
163156
_subprocess_helpers.kill_proc_tree(async_result.interface.pid)
164-
async_result.interface.kill() # kill -9
165-
# Force stop cycle if no exit code after kill
166-
except OSError:
167157
exit_code = async_result.interface.poll()
168-
if exit_code is not None and exit_code not in {-9, -15}: # Nothing to kill
169-
self.logger.warning(
170-
"{!s} has been completed just after timeout: please validate timeout.".format(command)
171-
)
172-
concurrent.futures.wait([stdout_future, stderr_future], timeout=0.1)
173-
result.exit_code = exit_code
174-
return result
175-
raise # Some other error
158+
if exit_code is None:
159+
async_result.interface.kill() # kill -9
176160
finally:
177161
stdout_future.cancel()
178162
stderr_future.cancel()

test/test_subprocess_special.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,10 @@ def read_stream(stream: FakeFileStream):
7676
"no_stdout": dict(),
7777
"IOError_on_stdout_read": dict(stdout=(b" \n", b"2\n", IOError())),
7878
"TimeoutError": dict(
79-
ec=(timeout_expired_exc,), poll=(None, None, None,), stdout=(), expect_exc=exec_helpers.ExecHelperTimeoutError
80-
),
81-
"TimeoutError_closed": dict(
82-
ec=(timeout_expired_exc, 0), poll=(None, 0), stdout=(b" \n", b"2\n", b"3\n", b" \n"), kill=(OSError(),)
79+
ec=(timeout_expired_exc,), poll=(None,), stdout=(), expect_exc=exec_helpers.ExecHelperTimeoutError
8380
),
8481
"TimeoutError_no_kill": dict(
85-
ec=(timeout_expired_exc,), poll=(None, None, None,), stdout=(), kill=(OSError(),), expect_exc=OSError
82+
ec=(timeout_expired_exc,), poll=(None,), stdout=(), kill=(OSError(),), expect_exc=OSError
8683
),
8784
"stdin_closed_PIPE_windows": dict(stdout=(b" \n", b"2\n", b"3\n", b" \n"), stdin="Warning", write=einval_exc),
8885
"stdin_broken_PIPE": dict(stdout=(b" \n", b"2\n", b"3\n", b" \n"), stdin="Warning", write=epipe_exc),
@@ -113,7 +110,6 @@ def pytest_generate_tests(metafunc):
113110
"no_stdout",
114111
"IOError_on_stdout_read",
115112
"TimeoutError",
116-
"TimeoutError_closed",
117113
"TimeoutError_no_kill",
118114
"stdin_closed_PIPE_windows",
119115
"stdin_broken_PIPE",

0 commit comments

Comments
 (0)