Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aa50766

Browse files
sroetByron
authored andcommitted
Add a way to force status codes inside AutoInterrupt._terminate, and let tests use it
1 parent 893ddab commit aa50766

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

‎git/cmd.py‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ class AutoInterrupt(object):
409409

410410
__slots__ = ("proc", "args", "status")
411411

412+
# If this is non-zero it will override any status code during
413+
# _terminate, used to prevent race conditions in testing
414+
_status_code_if_terminate: int = 0
415+
412416
def __init__(self, proc: Union[None, subprocess.Popen], args: Any) -> None:
413417
self.proc = proc
414418
self.args = args
@@ -427,11 +431,10 @@ def _terminate(self) -> None:
427431
proc.stdout.close()
428432
if proc.stderr:
429433
proc.stderr.close()
430-
431434
# did the process finish already so we have a return code ?
432435
try:
433436
if proc.poll() is not None:
434-
self.status = proc.poll()
437+
self.status = self._status_code_if_terminateorproc.poll()
435438
return None
436439
except OSError as ex:
437440
log.info("Ignored error after process had died: %r", ex)
@@ -443,7 +446,9 @@ def _terminate(self) -> None:
443446
# try to kill it
444447
try:
445448
proc.terminate()
446-
self.status = proc.wait() # ensure process goes away
449+
status = proc.wait() # ensure process goes away
450+
451+
self.status = self._status_code_if_terminate or status
447452
except OSError as ex:
448453
log.info("Ignored error after process had died: %r", ex)
449454
except AttributeError:
@@ -849,7 +854,7 @@ def execute(self,
849854

850855
if is_win:
851856
cmd_not_found_exception = OSError
852-
if kill_after_timeout:
857+
if kill_after_timeoutisnotNone:
853858
raise GitCommandError(redacted_command, '"kill_after_timeout" feature is not supported on Windows.')
854859
else:
855860
cmd_not_found_exception = FileNotFoundError # NOQA # exists, flake8 unknown @UndefinedVariable
@@ -916,7 +921,7 @@ def _kill_process(pid: int) -> None:
916921
return
917922
# end
918923

919-
if kill_after_timeout:
924+
if kill_after_timeoutisnotNone:
920925
kill_check = threading.Event()
921926
watchdog = threading.Timer(kill_after_timeout, _kill_process, args=(proc.pid,))
922927

@@ -927,10 +932,10 @@ def _kill_process(pid: int) -> None:
927932
newline = "\n" if universal_newlines else b"\n"
928933
try:
929934
if output_stream is None:
930-
if kill_after_timeout:
935+
if kill_after_timeoutisnotNone:
931936
watchdog.start()
932937
stdout_value, stderr_value = proc.communicate()
933-
if kill_after_timeout:
938+
if kill_after_timeoutisnotNone:
934939
watchdog.cancel()
935940
if kill_check.is_set():
936941
stderr_value = ('Timeout: the command "%s" did not complete in %d '

‎test/test_remote.py‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -658,10 +658,16 @@ def test_push_error(self, repo):
658658
class TestTimeouts(TestBase):
659659
@with_rw_repo('HEAD', bare=False)
660660
def test_timeout_funcs(self, repo):
661-
for function in ["pull"]: # can't get fetch and push to reliably timeout
661+
# Force error code to prevent a race condition if the python thread is
662+
# slow
663+
default = Git.AutoInterrupt._status_code_if_terminate
664+
Git.AutoInterrupt._status_code_if_terminate = -15
665+
for function in ["pull", "fetch"]: # can't get push to timeout
662666
f = getattr(repo.remotes.origin, function)
663667
assert f is not None # Make sure these functions exist
664-
_ = f() # Make sure the function runs
668+
_ = f() # Make sure the function runs
665669
with pytest.raises(GitCommandError,
666-
match="kill_after_timeout=0.001 s"):
667-
f(kill_after_timeout=0.001)
670+
match="kill_after_timeout=0 s"):
671+
f(kill_after_timeout=0)
672+
673+
Git.AutoInterrupt._status_code_if_terminate = default

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /