summaryrefslogtreecommitdiff
path: root/test/fs.py
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 02:11:15 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit3db73735e9a8d88878bc9ee343f226c033320913 (patch)
tree93c52cd0d4d2008d765c862651464684e15006d6 /test/fs.py
parentb29de1d4e78466a15f5d3dc0916410cba1445c5f (diff)
downloadpardes-3db73735e9a8d88878bc9ee343f226c033320913.tar.gz
pardes-3db73735e9a8d88878bc9ee343f226c033320913.zip
A command line cut across writes runs once whole, and look/exec answer per open
A mount cuts a write at its message size, and each piece ran on its own: a line cut at the boundary ran as shell commands and a 50 KB Edit block broke. An open of look, exec, tagexec, any ctl or a column's exec now keeps an unfinished last line, or an Edit block still open, until its next write or its release, and never runs a fragment. The same open record holds what its last write touched, which a read on it answers (as /net/tcp/clone does); an open that never wrote reads the session's last as of its open. A release that runs a held line waits for quiet and counts as a change; a clicked line with a control character is still refused at its write. Tested in unit tests, fs.py (python client, 8 KiB) and selfmount.py (the kernel mount, a 1000-line seq burst and a 50 KB Edit block). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/fs.py')
-rw-r--r--test/fs.py24
1 files changed, 24 insertions, 0 deletions
diff --git a/test/fs.py b/test/fs.py
index 0e38f950..bdfc3fcb 100644
--- a/test/fs.py
+++ b/test/fs.py
@@ -531,8 +531,32 @@ def signal_cleans_up(binary):
assert not address.exists() and not detached.exists(), (sig, list(root.iterdir()))
+def cut_writes(binary):
+ """A write bigger than a 9P message comes as several, cut anywhere: each
+ command line runs once, whole, an Edit block once it ends, and a last
+ line with no newline when the open closes. Never a fragment."""
+ with tempfile.TemporaryDirectory(prefix='pardes-cut-') as directory:
+ with session(binary, Path(directory), 'cut') as (client, _):
+ burst = b''.join(b'Msg burst-%04d\n' % i for i in range(1000))
+ assert len(burst) > client.msize
+ client.write('/exec', burst)
+ log = client.read('/log').decode()
+ said = [line.split(' ', 2)[2] for line in log.splitlines() if line.startswith('msg ') and 'burst-' in line]
+ assert said == ['burst-%04d' % i for i in range(1000)], said[:3] + said[-3:]
+ assert '\nrun ' not in log and 'exit 127' not in log, log[-400:]
+ client.write('/exec', b'Msg no-newline-at-end')
+ assert 'msg ' in client.read('/log').decode().split('no-newline-at-end')[0][-40:]
+ serial = new_pane(client, b'')
+ block = b'Edit ,a\n' + b''.join(b'line %05d of the block\n' % i for i in range(2500)) + b'.\n'
+ assert len(block) > 50000
+ client.write(f'/pane/{serial}/ctl', block)
+ body = client.read(f'/pane/{serial}/body').decode().splitlines()
+ assert body == ['line %05d of the block' % i for i in range(2500)], (len(body), body[:2])
+
+
def test(binary, quic=False):
started = time.monotonic()
+ cut_writes(binary)
run_file(binary)
exit_answers(binary)
unattended_messages_expire(binary)