Files
esh-pfi-infrastructure/scripts/oneoff/albok-browse-withdrawal/setup-replica.py
T
vh 172d893cdf test(albok): sshfs pathname-withdrawal test for the .browse/ view passes (unit 4.3 exposure gate)
Replica of a browse view on nh3-albok, Linux sshfs 3.7.3 client in an ephemeral
container on nh3-dev, N=5 per condition. Fresh open of a never-opened child
through a cached listing: ENOENT 5/5 with sshfs defaults and 5/5 with hour-long
client caches. Null control (no rename) opens 5/5; held fd and failed-rename
positive controls read 5/5. Replica removed afterwards.

Also closes the post-clear checks in persistent-memory: fv-ml1 GPU 0/1 plateau,
nh3-nas usage, and the mislabelled sfsrv-ana pre-pbs4 item.
2026-10-09 20:23:30 -07:00

52 lines
1.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""Build a replica of an albok browse view on the share host (nh3-albok).
Run ON the server as infra-ops, no sudo:
ssh infra-ops@10.100.50.44 python3 - < setup-replica.py > manifest.json
Why a replica and not the live view: the test renames `.browse/` away. On a live
wing that rename races albok-service's own link()/unlink() calls, and a failed
mandatory unlink withholds the wing (BROWSE_WITHHELD marker + a failed write
transaction). The replica has the same shape as the real view
(`<wing>/.browse/<locator>` -> relative symlink `../../<id[:2]>/<id>/<blob>`), sits
on the same filesystem (root ext4), and is served by the same sftp-server, which
is what the withdrawal property depends on.
Content is deterministic per object, so the client can verify bytes without
fetching a reference copy.
"""
import hashlib
import json
import os
import uuid
ROOT = "/home/infra-ops/albok-browse-test/wing"
COUNT = 60
SIZE = 1 << 20 # 1 MiB: larger than FUSE readahead, so a late read must reach the server
def content(i: int, oid: str) -> bytes:
line = f"replica object {i} {oid}\n".encode()
return (line * (SIZE // len(line) + 1))[:SIZE]
os.makedirs(ROOT, exist_ok=False) # refuse to run over an existing replica
link_dir = os.path.join(ROOT, ".browse", "stash")
os.makedirs(link_dir)
objs = []
for i in range(COUNT):
oid = uuid.uuid4().hex
obj_dir = os.path.join(ROOT, oid[:2], oid)
os.makedirs(obj_dir)
name = f"doc{i:02d}.md"
blob = os.path.join(obj_dir, name)
data = content(i, oid)
with open(blob, "wb") as f:
f.write(data)
os.chmod(blob, 0o640)
os.symlink(os.path.relpath(blob, link_dir), os.path.join(link_dir, name))
objs.append({"i": i, "id": oid, "name": name, "size": SIZE,
"sha256": hashlib.sha256(data).hexdigest()})
print(json.dumps({"root": ROOT, "size": SIZE, "objects": objs}))