diff options
Diffstat (limited to '9proc/test')
| -rwxr-xr-x | 9proc/test/adv_linux_probe.py | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/9proc/test/adv_linux_probe.py b/9proc/test/adv_linux_probe.py index 186f008..c921ebb 100755 --- a/9proc/test/adv_linux_probe.py +++ b/9proc/test/adv_linux_probe.py @@ -289,6 +289,40 @@ def attack_signals(server): ok("SIGTERM unlinks the unix socket (clean stop path)", not os.path.exists(path)) s.stop() + # A server killed outright leaves its socket behind. The next server + # of the same name must recognise the corpse and take the name over: + # the listener probes the path, and a probe that cannot tell answers + # "live", so a caller that hands it the whole 108-byte sun_path array + # instead of the path turns every stale socket into AlreadyListening. + s = Srv(server) + client(s.path, timeout=5) + stale = s.path + s.proc.send_signal(signal.SIGKILL) + s.proc.wait(timeout=5) + ok("SIGKILL leaves the socket behind", os.path.exists(stale)) + taker = subprocess.Popen([server, "--unix", stale], stderr=subprocess.PIPE) + try: + # The path exists throughout (the corpse, then the new socket), so + # the connect itself is the readiness signal. + err, c = None, None + for _ in range(250): + try: + c = client(stale, timeout=10) + break + except OSError as e: + err = e + time.sleep(0.02) + ok("a fresh server takes over a stale socket path", + c is not None and rd(c, [b"build", b"zig_version"])[0] == Rread, + err or taker.poll()) + except Exception as e: + ok("a fresh server takes over a stale socket path", False, e) + finally: + taker.kill() + taker.wait(timeout=5) + if os.path.exists(stale): + os.unlink(stale) + def attack_probe(ns, server): print("# probe loop and admission") |
