summaryrefslogtreecommitdiff
path: root/9ns/test/integration.sh
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-19 23:55:47 -0300
committerGabriel Schneider <[email protected]>2026-09-19 23:55:47 -0300
commit3e9f8805f293f622bb885cf849b5ce47dc062ad1 (patch)
tree0f31107fd20e7a9aa065826c891d2d326efc2309 /9ns/test/integration.sh
parentba996acfcad1698adbf4a1834fe50e73b1c6cab9 (diff)
downloadcloud9-3e9f8805f293f622bb885cf849b5ce47dc062ad1.tar.gz
cloud9-3e9f8805f293f622bb885cf849b5ce47dc062ad1.zip
9ns: --name and /mnt/9p/<name> mounts, qid.path as inode number, interrupts as Tflush
- --name NAME (default derived from the transport: socket basename, tcp-IP-PORT, spawned command, fdN) mounts at /mnt/9p/<name>; --mount still overrides. ensureMountpoint walks down and creates missing components, shadowing the deepest unwritable ancestor. NINE_MOUNT is the only exported variable. - The inode number reported to the kernel is the 9P qid.path for every node, root included; a server handing qid.path 1 to a file (Pardes /self) no longer collides with the root. - FUSE_INTERRUPT for the request in flight becomes Tflush; a blocked read returns EINTR when the server answers the flush, chunked transfers return short counts, other requests arriving meanwhile are stashed and served next. Servers ignoring Tflush still block until they answer. - 9ns-test now covers nine/bridge/fuse; new adv_bridge_interrupt suite (28); 9ns-itest grows to 88 checks. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to '9ns/test/integration.sh')
-rwxr-xr-x9ns/test/integration.sh27
1 files changed, 25 insertions, 2 deletions
diff --git a/9ns/test/integration.sh b/9ns/test/integration.sh
index 5e0ad13..32d132a 100755
--- a/9ns/test/integration.sh
+++ b/9ns/test/integration.sh
@@ -10,6 +10,8 @@ TMP=$(mktemp -d "${TMPDIR:-/tmp}/9ns-itest.XXXXXX")
PIDS=()
FAILED=0
PASSED=0
+# The suites pin the mountpoint with --mount; the default is /mnt/9p/<name>
+# (see the "# mount names" section below).
M=/mnt/9p
cleanup() {
@@ -39,8 +41,8 @@ wait_socket() { # path
return 1
}
-# run_in "<shell script>" — run inside a namespace with the current transport ($TRANSPORT array).
-run_in() { timeout 60 "$NS" "${TRANSPORT[@]}" -- sh -c "$1" 2>"$TMP/stderr"; }
+# run_in "<shell script>" — run inside a namespace with the current transport ($TRANSPORT array), mounted on $M.
+run_in() { timeout 60 "$NS" "${TRANSPORT[@]}" --mount "$M" -- sh -c "$1" 2>"$TMP/stderr"; }
# --- scratch battery: works against any writable 9P tree rooted at $1 (relative to mount) ---
scratch_battery() { # label scratchdir
@@ -111,6 +113,26 @@ mkdir -p "$TMP/mnt"
expect_eq "--mount existing dir" "ok" "$(timeout 60 "$NS" --unix "$SOCK" --mount "$TMP/mnt" -- sh -c "[ -f $TMP/mnt/README ] && echo ok")"
expect_eq "--mount relative" "ok" "$(cd "$TMP" && timeout 60 "$NS" --unix "$SOCK" --mount rel -- sh -c "[ -f $TMP/rel/README ] && echo ok")"
expect_eq "--mount missing under /" "125" "$(timeout 60 "$NS" --unix "$SOCK" --mount /nonexistent-9ns-dir -- true 2>/dev/null; echo $?)"
+expect_eq "--mount beats --name" "$TMP/mnt" "$(timeout 60 "$NS" --unix "$SOCK" --name zz --mount "$TMP/mnt" -- sh -c 'echo $NINE_MOUNT')"
+
+echo "# mount names (default mountpoint /mnt/9p/<name>)"
+mkdir -p "$TMP/n"
+"$PROC" --unix "$TMP/n/foo.sock" &
+PIDS+=($!)
+wait_socket "$TMP/n/foo.sock" || echo "foo.sock missing"
+named() { timeout 60 "$NS" --unix "$TMP/n/foo.sock" "$@"; }
+expect_eq "unix socket foo.sock -> /mnt/9p/foo" "/mnt/9p/foo" "$(named -- sh -c 'echo $NINE_MOUNT')"
+expect_eq "default mount is served" "ok" "$(named -- sh -c '[ -f /mnt/9p/foo/README ] && grep -q "^9ns /mnt/9p/foo fuse" /proc/self/mounts && echo ok')"
+expect_eq "default mount keeps /mnt entries" "$(ls -A /mnt | sort | tr '\n' ' ')" "$(named -- sh -c "ls -A /mnt | grep -v '^9p\$' | sort | tr '\n' ' '")"
+expect_eq "--name bar -> /mnt/9p/bar" "/mnt/9p/bar ok" "$(named --name bar -- sh -c 'echo $NINE_MOUNT; [ -f /mnt/9p/bar/README ] && echo ok' | tr '\n' ' ' | sed 's/ $//')"
+expect_eq "--name=bar form" "/mnt/9p/bar" "$(named --name=bar -- sh -c 'echo $NINE_MOUNT')"
+expect_eq "--name a/b is a usage error" "125" "$(named --name a/b -- true 2>/dev/null; echo $?)"
+expect_eq "--name . is a usage error" "125" "$(named --name . -- true 2>/dev/null; echo $?)"
+expect_eq "--name '' is a usage error" "125" "$(named --name '' -- true 2>/dev/null; echo $?)"
+expect_eq "nested, two names: both under /mnt/9p" "a b both /mnt/9p/b" "$(named --name a -- "$NS" --unix "$TMP/n/foo.sock" --name b -- sh -c 'ls /mnt/9p | tr "\n" " "; [ -f /mnt/9p/a/README ] && [ -f /mnt/9p/b/README ] && echo both; echo $NINE_MOUNT' 2>/dev/null | tr '\n' ' ' | sed 's/ $//')"
+expect_eq "nested, same name: inner shadows outer" "2 /mnt/9p/a" "$(named --name a -- "$NS" --unix "$TMP/n/foo.sock" --name a -- sh -c 'grep -c "^9ns /mnt/9p/a fuse" /proc/self/mounts; [ -f /mnt/9p/a/README ] && echo $NINE_MOUNT' 2>/dev/null | tr '\n' ' ' | sed 's/ $//')"
+expect_eq "--spawn default name is the command basename" "/mnt/9p/9proc-demo" "$(timeout 60 "$NS" --spawn "$PROC --stdio" -- sh -c 'echo $NINE_MOUNT')"
+expect_eq "host mount table untouched by named mounts" "no" "$(grep -q " /mnt/9p" /proc/self/mountinfo && echo yes || echo no)"
echo "# lifecycle"
START=$(date +%s)
@@ -131,6 +153,7 @@ PIDS+=($!)
sleep 0.3
TRANSPORT=(--tcp "127.0.0.1:$PORT")
expect_eq "tcp: zig_version" "$(zig version)" "$(run_in "cat $M/build/zig_version")"
+expect_eq "tcp: default name" "/mnt/9p/tcp-127.0.0.1-$PORT" "$(timeout 60 "$NS" --tcp "127.0.0.1:$PORT" -- sh -c 'echo $NINE_MOUNT')"
expect_eq "tcp: scratch" "tcp" "$(run_in "echo tcp > $M/scratch/t && cat $M/scratch/t && rm $M/scratch/t")"
echo "# server death"