mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-23 14:40:37 +08:00
333032f626
This runs in 100ms increments, so there's not a lot of harm in trying longer - it should take the same time everywhere it succeeded before. But I've reproduced failures on FreeBSD 13 on sr.ht, so there's at least one platform where a total time of 1 second isn't enough. Now we do 50 tries, which is 5 seconds.
83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
from pexpect_helper import SpawnedProc
|
|
import subprocess
|
|
import sys
|
|
import signal
|
|
import time
|
|
import os
|
|
|
|
sp = SpawnedProc()
|
|
send, sendline, sleep, expect_prompt, expect_re = (
|
|
sp.send,
|
|
sp.sendline,
|
|
sp.sleep,
|
|
sp.expect_prompt,
|
|
sp.expect_re,
|
|
)
|
|
|
|
# Helper to print an error and exit.
|
|
def error_and_exit(text):
|
|
keys = sp.colors()
|
|
print("{RED}Test failed: {NORMAL}{TEXT}".format(TEXT=text, **keys))
|
|
sys.exit(1)
|
|
|
|
|
|
fish_pid = sp.spawn.pid
|
|
|
|
# Launch fish_test_helper.
|
|
expect_prompt()
|
|
exe_path = os.environ.get("fish_test_helper")
|
|
sp.sendline(exe_path + " nohup_wait")
|
|
|
|
# We expect it to transfer tty ownership to fish_test_helper.
|
|
sleep(0.1)
|
|
tty_owner = os.tcgetpgrp(sp.spawn.child_fd)
|
|
if fish_pid == tty_owner:
|
|
os.kill(fish_pid, signal.SIGKILL)
|
|
error_and_exit(
|
|
"Test failed: outer fish %d did not transfer tty owner to fish_test_helper"
|
|
% (fish_pid)
|
|
)
|
|
|
|
|
|
# Now we are going to tell fish to exit.
|
|
# It must not hang. But it might hang when trying to restore the tty.
|
|
os.kill(fish_pid, signal.SIGTERM)
|
|
|
|
# Loop a bit until the process exits (correct) or stops (incorrrect).
|
|
# When it exits it should be due to the SIGTERM that we sent it.
|
|
for i in range(50):
|
|
pid, status = os.waitpid(fish_pid, os.WUNTRACED | os.WNOHANG)
|
|
if pid == 0:
|
|
# No process ready yet, loop again.
|
|
sleep(0.1)
|
|
elif pid != fish_pid:
|
|
# Some other process exited (??)
|
|
os.kill(fish_pid, signal.SIGKILL)
|
|
error_and_exit(
|
|
"unexpected pid returned from waitpid. Got %d, expected %d"
|
|
% (pid, fish_pid)
|
|
)
|
|
elif os.WIFSTOPPED(status):
|
|
# Our pid stopped instead of exiting.
|
|
# Probably it stopped because of its tcsetpgrp call during exit.
|
|
# Kill it and report a failure.
|
|
os.kill(fish_pid, signal.SIGKILL)
|
|
error_and_exit("pid %d stopped instead of exiting on SIGTERM" % pid)
|
|
elif not os.WIFSIGNALED(status):
|
|
error_and_exit("pid %d did not signal-exit" % pid)
|
|
elif os.WTERMSIG(status) != signal.SIGTERM:
|
|
error_and_exit(
|
|
"pid %d signal-exited with %d instead of %d (SIGTERM)"
|
|
% (os.WTERMSIG(status), signal.SIGTERM)
|
|
)
|
|
else:
|
|
# Success!
|
|
sys.exit(0)
|
|
else:
|
|
# Our loop completed without the process being returned.
|
|
error_and_exit("fish with pid %d hung after SIGTERM" % fish_pid)
|
|
|
|
# Should never get here.
|
|
error_and_exit("unknown, should be unreachable")
|