comparison mercurial/testing/ps_util.py @ 51992:625cf9621551

tests: add a module that can perform the equivalent of `SIGKILL` on any OS I started with this being Windows specific, but let's push all of the decision making into this function so that it can just be called by the tests. The tradeoff is that this is very specific to sending `SIGKILL`- since `signal.SIGKILL` doesn't exist on Windows, the desired signal can't be passed from the caller. Maybe there's a way, but let's wait until there's a need. We don't use `killdaemons.py` unconditionally because it starts with a more graceful `SIGTERM` on posix.
author Matt Harbison <matt_harbison@yahoo.com>
date Sat, 12 Oct 2024 16:06:37 -0400
parents
children d4e30c15626d
comparison
equal deleted inserted replaced
51991:23cc79e04c28 51992:625cf9621551
1 # This python code can be imported into tests in order to terminate a process
2 # with signal.SIGKILL on posix, or a roughly equivalent procedure on Windows.
3 import os
4 import signal
5 import subprocess
6 import sys
7 import tempfile
8
9 from .. import (
10 encoding,
11 pycompat,
12 )
13
14 from ..utils import procutil
15
16
17 def kill_nt(pid: int, exit_code: int):
18 fd, pidfile = tempfile.mkstemp(
19 prefix=b"sigkill-", dir=encoding.environ[b"HGTMP"], text=False
20 )
21 try:
22 os.write(fd, b'%d\n' % pid)
23 finally:
24 os.close(fd)
25
26 env = dict(encoding.environ)
27 env[b"DAEMON_EXITCODE"] = b"%d" % exit_code
28
29 # Simulate the message written to stderr for this process on non-Windows
30 # platforms, for test consistency.
31 print("Killed!", file=sys.stderr)
32
33 subprocess.run(
34 [
35 encoding.environ[b"PYTHON"],
36 b"%s/killdaemons.py"
37 % encoding.environ[b'RUNTESTDIR_FORWARD_SLASH'],
38 pidfile,
39 ],
40 env=procutil.tonativeenv(env),
41 )
42
43
44 def kill(pid: int):
45 """Kill the process with the given PID with SIGKILL or equivalent."""
46 if pycompat.iswindows:
47 exit_code = 128 + 9
48 kill_nt(pid, exit_code)
49 else:
50 os.kill(pid, signal.SIGKILL)