LazyBoy2/tests/cli_interrupt.py

34 lines
1.6 KiB
Python

"""Double Ctrl-C must exit even while the daemon RPC is stalled."""
import os,signal,socket,subprocess,tempfile,threading,queue
from pathlib import Path
BINARY=Path(__file__).resolve().parents[1]/'target/debug/lazyboy'
for stalled in (False,True):
with tempfile.TemporaryDirectory(prefix='gb-interrupt-',dir='/tmp') as root:
server=socket.socket(socket.AF_UNIX);server.bind(root+'/service.sock');server.listen()
peers=[];stop=threading.Event()
def serve():
while not stop.is_set():
try:peer,_=server.accept()
except OSError:return
peers.append(peer)
if not stalled:
peer.recv(65536);peer.sendall(b'{"events":[],"ok":true}\n');peer.close()
threading.Thread(target=serve,daemon=True).start()
p=subprocess.Popen([str(BINARY),'agent','--name','test'],env={**os.environ,'LAZYBOY_DATA_DIR':root},stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True)
lines=queue.Queue();threading.Thread(target=lambda:[lines.put(l) for l in p.stderr],daemon=True).start()
try:
import time
deadline=time.monotonic()+5
while not peers and time.monotonic()<deadline:time.sleep(.01)
assert peers,'client did not connect'
p.send_signal(signal.SIGINT)
while '3 秒內' not in lines.get(timeout=3):pass
assert p.poll() is None,'first Ctrl-C should keep chat open'
p.send_signal(signal.SIGINT)
assert p.wait(timeout=2)==130
print('PASS double Ctrl-C exits with '+('stalled' if stalled else 'responsive')+' daemon')
finally:
if p.poll() is None:p.kill();p.wait()
stop.set();server.close()
for peer in peers:peer.close()