summaryrefslogtreecommitdiff
path: root/test/selfmount.py
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 20:50:48 -0300
committerGabriel Schneider <[email protected]>2026-10-01 22:07:48 -0300
commit406f483288c7689bdd2e1f3f68b276c61ca9412a (patch)
treeb6398fb9974b91441563fd655d18ddaf182a2a5a /test/selfmount.py
parentb55cb01d2777760ed79b545dfca7115837591577 (diff)
downloadpardes-406f483288c7689bdd2e1f3f68b276c61ca9412a.tar.gz
pardes-406f483288c7689bdd2e1f3f68b276c61ca9412a.zip
An Edit's held write: < | > commands no longer block their 9P connection (answered like a held read, so a status read or a filter reading the session's own mount runs beside it), a Tflush or hang-up of the write kills the commands' process groups and changes nothing; e loads by Get's way (asked once, clean after, undo puts the name back); ~ in e r w f B; B checks every name first; an Edit that runs commands is a write of its own, refused up front with other lines; Edit's +Errors output keeps the keyboard where it was; X goes in pane order; a refused write open says its errno; the reference's Coming from acme rows say what Get file's undo, failure and directory refusal, Putall's answer, Zerox across Dump and Incl's directories now do
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/selfmount.py')
-rw-r--r--test/selfmount.py26
1 files changed, 26 insertions, 0 deletions
diff --git a/test/selfmount.py b/test/selfmount.py
index 0111e6ac..c8a81df9 100644
--- a/test/selfmount.py
+++ b/test/selfmount.py
@@ -291,6 +291,32 @@ def run(binary):
said_many = many.read_text() if many.exists() else ''
many.unlink(missing_ok=True)
check(ran == '9' and 'Too many open files' in said_many, f'an open past the 64 records is EMFILE ({ran!r}, {said_many[-80:]!r})')
+ # An Edit whose command runs is held, not waited on: through the
+ # mount, a status read beside a slow one answers at once, and a
+ # command that reads this session's own tree runs.
+ edited = int(client.read('/pane/new'))
+ client.write(f'/pane/{edited}/body', b'pear\napple\n')
+ took = Path(f'/tmp/{name}.took')
+ ran = run((f"echo 'Edit , | sleep 3; sort' > {mount}/pane/{edited}/ctl & sleep .5; "
+ f"s=$(date +%s%N); timeout 5 cat {mount}/status > /dev/null; e=$(date +%s%N); "
+ f"echo $(( (e - s) / 1000000 )) > {took}; wait\n").encode())
+ ms = int(took.read_text()) if took.exists() else -1
+ took.unlink(missing_ok=True)
+ check(ran == '0' and 0 <= ms < 1000, f'a status read beside a slow Edit answers at once ({ms} ms)')
+ check(client.read(f'/pane/{edited}/body') == b'apple\npear\n', 'and the slow Edit applied')
+ ran = run(f"echo 'Edit $ < cat {mount}/pane/{edited}/body' > {mount}/pane/{edited}/ctl\n".encode())
+ check(ran == '0' and client.read(f'/pane/{edited}/body') == b'apple\npear\napple\npear\n',
+ f'an Edit whose command reads the session through its mount ({ran!r})')
+ # An interrupted Edit write is flushed: its command is stopped and
+ # nothing changes, and the next Edit runs.
+ flushed = Path(f'/tmp/{name}.flushed')
+ ran = run((f"timeout -s INT 1 sh -c \"echo 'Edit , | sleep 4; tr a-z A-Z' > {mount}/pane/{edited}/ctl\"; "
+ f"echo $? > {flushed}; sleep 1; echo 'Edit 1 | tr p P' > {mount}/pane/{edited}/ctl; echo $? >> {flushed}\n").encode())
+ codes = flushed.read_text().split() if flushed.exists() else []
+ flushed.unlink(missing_ok=True)
+ time.sleep(4.5)
+ 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'])
check('still here' in text, 'the editor answers after all of that')