-
-
Notifications
You must be signed in to change notification settings - Fork 635
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add hack to make sure testing session is killed
currently tests are interupted between retries using SIGTERM. This is not always successful and results in simultaneous runs of the tests. expand use of on_retry_command
- Loading branch information
leej3
committed
May 13, 2024
1 parent
f32a215
commit f37e188
Showing
9 changed files
with
157 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import os | ||
import signal | ||
import time | ||
|
||
import psutil | ||
|
||
|
||
def kill_process_group(pid_file): | ||
if not os.path.isfile(pid_file) or os.stat(pid_file).st_size == 0: | ||
print(f"File {pid_file} does not exist or is empty") | ||
return 1 | ||
|
||
with open(pid_file, "r") as file: | ||
pgid = int(file.read().strip()) | ||
|
||
if os.name != "posix": | ||
return kill_process_group_win(pid_file) | ||
|
||
try: | ||
# Check if the process group exists by sending a dummy signal (0) | ||
os.killpg(pgid, 0) | ||
except ProcessLookupError: | ||
print(f"Process group {pgid} does not exist") | ||
return 1 | ||
|
||
# Send INT signal to the process group | ||
sigtype = "interrupt" | ||
os.killpg(pgid, signal.SIGINT) | ||
# Poll process existence and kill forcefully if necessary | ||
try: | ||
trying = 5 | ||
while trying > 0: | ||
time.sleep(0.5) | ||
os.killpg(pgid, 0) | ||
trying -= 0.5 | ||
if trying == 0.5 and sigtype == "interrupt": | ||
sigtype = "kill" | ||
trying = 2 | ||
os.killpg(pgid, signal.SIGKILL) | ||
|
||
except ProcessLookupError: | ||
print(f"Process group killed successfully with {sigtype} signal") | ||
return 0 | ||
|
||
print(f"Failed to kill process group {pgid}") | ||
return 1 | ||
|
||
|
||
def kill_process_group_win(pid_file): | ||
if not os.path.isfile(pid_file) or os.stat(pid_file).st_size == 0: | ||
print(f"File {pid_file} does not exist or is empty") | ||
return 1 | ||
|
||
with open(pid_file, "r") as file: | ||
pid = int(file.read().strip()) | ||
|
||
try: | ||
proc = psutil.Process(pid) | ||
except psutil.NoSuchProcess: | ||
print(f"Process {pid} does not exist") | ||
return 1 | ||
|
||
# Try to terminate the process | ||
try: | ||
proc.terminate() # Sends SIGTERM on Unix, TerminateProcess on Windows | ||
proc.wait(timeout=3) # Wait up to 3 seconds for the process to terminate | ||
except psutil.TimeoutExpired: | ||
# Process did not terminate in time, kill it | ||
try: | ||
proc.kill() | ||
proc.wait(timeout=1) # Wait for the process to be killed | ||
print("Process killed successfully with kill signal") | ||
return 0 | ||
except Exception as e: | ||
print(f"Failed to kill process {pid}: {e}") | ||
return 1 | ||
except Exception as e: | ||
print(f"Error when attempting to terminate process {pid}: {e}") | ||
return 1 | ||
|
||
print("Process terminated successfully with terminate signal") | ||
return 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import os | ||
import sys | ||
import time | ||
from unittest.mock import patch | ||
|
||
from .kill_process_group import kill_process_group | ||
|
||
|
||
# Attempt at creating interuptible command failed | ||
# command = """setsid sh -c 'trap "" SIGINT SIGTERM; sleep 1000' >/dev/null 2>&1 & echo $! > .kpg_testing.pid""" | ||
def test_kill_process_group_existing_persistent(): | ||
pid_file = ".kpg_testing.pid" | ||
os.system("setsid sh -c 'sleep 1000' >/dev/null 2>&1 & echo $! > .kpg_testing.pid") | ||
time.sleep(1) | ||
message = "Process group killed successfully with kill signal" | ||
with patch("builtins.print") as mock_print: | ||
assert kill_process_group(pid_file) == 0 | ||
mock_print.assert_called_with(message) | ||
|
||
|
||
def test_kill_process_group_nonexistent_process(): | ||
pid_file = ".kpg_testing.pid" | ||
with open(pid_file, "w") as file: | ||
file.write("12345") | ||
message = "Process group 12345 does not exist" | ||
with patch("builtins.print") as mock_print: | ||
assert kill_process_group(pid_file) == 1 | ||
mock_print.assert_called_with(message) | ||
|
||
|
||
def test_kill_process_group_no_file(): | ||
pid_file = ".kpg_testing_nonexistent.pid" | ||
message = "File .kpg_testing_nonexistent.pid does not exist or is empty" | ||
with patch("builtins.print") as mock_print: | ||
assert kill_process_group(pid_file) == 1 | ||
mock_print.assert_called_with(message) | ||
|
||
|
||
if __name__ == "__main__": | ||
if len(sys.argv) == 2: | ||
pid_file = sys.argv[1] | ||
result = kill_process_group(pid_file) | ||
sys.exit(result) | ||
else: | ||
print("Please provide the path to the PID file as a command line argument.") | ||
print("Example: python kill_process_group.py /path/to/pid_file") |