summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/selfmount.py35
1 files changed, 34 insertions, 1 deletions
diff --git a/test/selfmount.py b/test/selfmount.py
index 5aa9749a..61d32523 100644
--- a/test/selfmount.py
+++ b/test/selfmount.py
@@ -372,8 +372,41 @@ def run(binary):
check(codes == ['124', '0'] and client.read(f'/pane/{edited}/body') == b'aPPle\npear\napple\npear\n',
f'an interrupted Edit changes nothing, and the next runs ({codes!r}, {client.read(f"/pane/{edited}/body")!r})')
client.write('/exec', b'Msg still here\n')
- text = ''.join(cell[0] for cell in client.screen()['cells'])
+ # The terminal is read as it is waited on: a frame the editor
+ # cannot write out (its pty full) is a frame /screen does not have.
+ deadline = time.monotonic() + 8
+ while 'still here' not in (text := ''.join(cell[0] for cell in client.screen()['cells'])) and time.monotonic() < deadline:
+ drain()
+ time.sleep(.1)
check('still here' in text, 'the editor answers after all of that')
+ # A filter that writes its own pane's ctl through the mount. Both
+ # sides with `<>` run at once; a `>` or `>>` open on either side
+ # waits in the kernel for the other write, and the command is
+ # stopped at its 10 s limit: the Edit's write is answered then,
+ # never held by a command it cannot kill.
+ loop_pane = env_pane # the screen has no room for another
+ client.write(f'/pane/{loop_pane}/body', b'x\n', truncate=True)
+ inner = Path(f'/tmp/{name}.inner')
+ timed = Path(f'/tmp/{name}.timed')
+ for outer_open, inner_open, quick in [('3<>', '1<>', True), ('>', '>', False), ('>>', '>', False),
+ ('3<>', '>>', False), ('>', '>>', False)]:
+ # `clean`, which says nothing: a stopped filter's write still
+ # lands once the Edit's is answered.
+ inner.write_text(f'echo clean {inner_open} "$PARDES_MOUNT/pane/$winid/ctl"\n')
+ edit = f'Edit 1 > sh {inner}'
+ write = (f"exec 3<>{mount}/pane/{loop_pane}/ctl; echo '{edit}' >&3; rc=$?; exec 3>&-"
+ if outer_open == '3<>' else f"echo '{edit}' {outer_open} {mount}/pane/{loop_pane}/ctl; rc=$?")
+ ran = run((f"s=$(date +%s%N); {write}; e=$(date +%s%N); "
+ f"echo $rc $(( (e - s) / 1000000 )) > {timed}\n").encode())
+ rc_ms = timed.read_text().split() if timed.exists() else ['?', '-1']
+ timed.unlink(missing_ok=True)
+ ms = int(rc_ms[1])
+ ok = ms >= 0 and (ms < 2000 if quick else ms < 13000)
+ check(ran == '0' and ok, f'outer {outer_open}, filter {inner_open} on its own ctl: answered in {ms} ms (rc {rc_ms[0]})')
+ inner.unlink(missing_ok=True)
+ client.write('/exec', b'Msg after the stopped filters\n')
+ check('msg ' in client.read('/log').decode().split('after the stopped filters')[0][-40:],
+ 'and the editor answers after them')
finally:
os.kill(pid, signal.SIGTERM)
time.sleep(.2)