summaryrefslogtreecommitdiff
path: root/test/v9fs.py
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-20 00:36:50 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commitc1990b3e6e196ad41379aa432bf3ccca8a65d9f0 (patch)
treed7ad5afe559f7f56464b14c3122242fa3f16399b /test/v9fs.py
parent717afaf3177a2e0925b18ae3445119efe808b129 (diff)
downloadpardes-c1990b3e6e196ad41379aa432bf3ccca8a65d9f0.tar.gz
pardes-c1990b3e6e196ad41379aa432bf3ccca8a65d9f0.zip
Flatten the 9P control tree and move it out of fs.zig
The served tree loses the self/ level: /index /ctl /new /log /screen /listeners /pane/<n>/... /os, with /src only in -Dembed-sources=true builds (default off, on for esp32p4). ctl speaks the editor's own language with two lowercase verbs, look TEXT and exec TEXT, plus acme's addr verbs; the new/ factory directory becomes one clone file; cons is gone (exec Msg); name and sel are files; stats report real lengths, modes and mtimes; /log streams pane new/del/rename/save events. The tree code lives in src/ninep/ (tree, pane, ctl, addr, pty, events, screen, sources); fs.zig keeps host access, mounts, resolution and find/grep. Same engine and transports. README (fs-help.txt) and docs rewritten; tests updated and extended. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'test/v9fs.py')
-rw-r--r--test/v9fs.py33
1 files changed, 17 insertions, 16 deletions
diff --git a/test/v9fs.py b/test/v9fs.py
index 7dc88195..16916d0b 100644
--- a/test/v9fs.py
+++ b/test/v9fs.py
@@ -42,25 +42,26 @@ def worker(mountpoint, socket, uid, gid, original_namespace):
assert len(mounted) == 1 and ' - 9p ' in mounted[0], mounted
assert not any(field.startswith(('shared:', 'master:')) for field in mounted[0].split()[6:])
- assert set(os.listdir(mountpoint)) == {'os', 'self'}
- tree = mountpoint / 'self'
- assert {'index', 'pane', 'new', 'screen'} <= set(os.listdir(tree))
+ tree = mountpoint
+ assert {'os', 'index', 'pane', 'new', 'ctl', 'log', 'screen', 'README'} <= set(os.listdir(tree))
+ assert 'self' not in os.listdir(tree)
# A direct connection provides independent evidence for VFS reads/writes.
with Client(socket) as client:
- assert (tree / 'index').read_bytes() == client.read('/self/index')
+ assert (tree / 'index').read_bytes() == client.read('/index')
assert (tree / 'pane/1/body').read_bytes() == b'initial\n'
- before = client.read('/self/index')
- subprocess.run(['ls', '-l', str(tree / 'new')], check=True, capture_output=True, timeout=5)
- assert {'README', 'ctl', 'body'} <= set(os.listdir(tree / 'new'))
- assert (tree / 'new/README').read_bytes() == (tree / 'README').read_bytes()
- assert client.read('/self/index') == before, 'browsing created panes'
- serial = int((tree / 'new/ctl').read_bytes().split()[0])
- another = int((tree / 'new/ctl').read_bytes().split()[0])
+ before = client.read('/index')
+ subprocess.run(['ls', '-l', str(tree), str(tree / 'pane' / '1')], check=True, capture_output=True, timeout=5)
+ subprocess.run(['find', str(tree / 'pane'), str(tree / 'new'), '-ls'], check=True, capture_output=True, timeout=5)
+ assert (tree / 'README').read_bytes() == client.read('/README')
+ assert (tree / 'new').stat().st_size == 0
+ assert client.read('/index') == before, 'browsing created panes'
+ serial = int((tree / 'new').read_bytes().split()[0])
+ another = int((tree / 'new').read_bytes().split()[0])
assert serial != another, 'cached factory reused a pane'
- client.write(f'/self/pane/{another}/ctl', b'delete\n')
+ client.write(f'/pane/{another}/ctl', b'exec Del\n')
pane = tree / 'pane' / str(serial)
- wire = f'/self/pane/{serial}'
+ wire = f'/pane/{serial}'
assert str(serial) in os.listdir(tree / 'pane')
assert serial in [int(row.split()[0]) for row in (tree / 'index').read_bytes().splitlines()]
@@ -76,7 +77,7 @@ def worker(mountpoint, socket, uid, gid, original_namespace):
assert client.read(wire + '/body') == b'v9fs update\nappended\n'
# Exercise an actual shell redirection, including its O_TRUNC open.
- subprocess.run(['/bin/sh', '-c', 'printf "name kernel-probe\\n" > "$1/ctl"',
+ subprocess.run(['/bin/sh', '-c', 'printf "kernel-probe\\n" > "$1/name"',
'v9fs-probe', str(pane)], check=True, timeout=5)
tag = client.read(wire + '/tag')
assert tag.split(maxsplit=1)[0] == str(socket.parent / 'kernel-probe').encode(), tag
@@ -100,7 +101,7 @@ def worker(mountpoint, socket, uid, gid, original_namespace):
# Reading OS files through the exported tree does not recurse through
# the mount: the core still lives in the supervisor's namespace.
assert (mountpoint / 'os' / str(socket.parent).lstrip('/') / 'kernel.txt').read_bytes() == b'initial\n'
- write_existing(pane / 'ctl', b'delete\n')
+ write_existing(pane / 'ctl', b'exec Del\n')
assert serial not in [int(row.split()[0]) for row in (tree / 'index').read_bytes().splitlines()]
print('v9fs: namespace isolation, privilege drop, inherited mount, directory refresh, '
@@ -154,7 +155,7 @@ def run(binary, helper):
print(run_helper(command), end='')
assert os.readlink('/proc/self/ns/mnt') == namespace
assert list(target.iterdir()) == [], 'mount escaped its private namespace'
- assert client.read('/self/pane/1/body') == b'initial\n', 'core stopped serving after probe exit'
+ assert client.read('/pane/1/body') == b'initial\n', 'core stopped serving after probe exit'
print('v9fs: supervisor namespace unchanged and session cleanup passed')