Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8.2 KiB
Task 18 report: wider hermetic suites and fork CI
What was built
fstest/testserver/init.d/TestProtonDriveFake(new, mode 755): init.d script for the fake server.fstest/testserver/init.d/PORTS.md: port 28642 allocated (next free after 28641).fstest/test_all/config.yaml: new entryprotondrive/TestProtonDriveFake:,fastlist: false, with 5ignoretests andignoretests: cmd/gitannex(reasons below, each commented in the file). The existing liveTestProtonDrive:entry is untouched..gitea/workflows/ci.yml(new): on push and pull_request, one job,timeout-minutes: 45; checkout,actions/setup-go@v5withgo-version-file: go.modandcache: true;go build ./...;go vet ./backend/protondrive/...;golangci-lint-action@v8pinned to v2.15.0 withargs: ./backend/protondrive/...(the action caches);go test -race ./backend/protondrive/...; a 20 s fuzz run per target (targets discovered withgo test -list '^Fuzz', currently 5);go run golang.org/x/vuln/cmd/govulncheck@latest ./backend/protondrive/....RCLONE_CONFIG=/notfoundset workflow-wide. No test_all (per owner, relayed by the coordinator: runner exists but is slow).- Docs:
docs/DECISIONS.md(shared-session decision),docs/TODO.md(cross-Fs cache entry expanded with the five failing tests, gitannex entry, CI entry,.claudepermission entry, "Now" entry updated, old "decide whether to add Gitea CI" entry removed),docs/PERMISSIONS.md(verified table re-run on host,golangci-lint runin Allow, stale "host has no Go" gap removed,.claudegap noted),docs/ARCHITECTURE.md(one bullet on the init.d script and CI),.gemini/settings.json(golangci-lint runallowed), plan Task 18 checkboxes ticked. - No backend code changed.
go.mod/go.sumunchanged.
Script design
- Sources
run.bash(mandatory refcounting/locking), defines its ownstart/stop/status; state (pid, binary, captured stdout, log) lives in run.bash's${RUN_STATE}($XDG_RUNTIME_DIR/rclone-test-server/TestProtonDriveFake/state), not/tmp/<name>.pid. - Repo root found from the script's own location
(
$(dirname "$0")/../../..), since testserver runs it from each test package's directory. startbuilds./backend/protondrive/protontest/cmd/protonfakeinto the state dir withgo build(fast with the build cache; rebuilt each first start so it never runs a stale binary), runs the binary itself withnohup ... -addr 127.0.0.1:28642, stdout to a file, stderr to a log, disowned. It polls up to 10 s for thetype=line (the last of the six), failing early with the log if the process dies, then cats the six lines and echoes_connect=127.0.0.1:28642. run.bash caches that output, so every laterstartwhile the server lives returns the same session.stopsends SIGTERM (protonfake handles it and closes cleanly), waits up to 10 s for exit so the port is free, removes the pid file.- Smoke-tested start/status/stop by hand; after both full test_all runs nothing listens on 28642 and no protonfake from the script remains.
Shared-session finding
Not a problem; nothing changed in protontest/protonfake/client. Details in
DECISIONS.md: the client refreshes only on HTTP 401 (session.call); the
standalone fake returns 401 only after ExpireAccessToken,
RevokeSession or logout, and protonfake calls none. Logout happens only
in Fs.Disconnect and rclone config re-sign-in; no test in fs/operations,
fs/sync, vfs, cmd/bisync, cmd/gitannex or fstests calls Disconnect (grep).
The backend package's own tests that use setupFakeRemote override the
env vars with t.Setenv and their own in-process server, so they never
touch the shared session. Confirmed empirically: two full runs, 4 suites
in parallel on one session, no auth failures.
Wider-suite failures
First run (no ignores): vfs OK, backend OK, bisync OK; failures:
- cmd/gitannex - all 19
TestGitAnnexFstestBackendCases/*fail withINITREMOTE-FAILURE remote does not exist: TestProtonDriveFake:. Cause:cmd/gitannex/configparse.gochecks the name againstconfig.GetRemoteNames(), which lists env-var remotes lower-cased (fs/config/config.goGetRemotes). Every other init.d remote in config.yaml ignores cmd/gitannex for the same reason. Core harness limitation, not backend:ignoretests: cmd/gitannex+ TODO entry. - fs/operations
TestCheckSumDownload,TestCopyFileCompareDest,TestCopyFileCopyDestImmutable; fs/syncTestSyncCompareDest,TestSyncCopyDestImmutable. Cause: eachFshas its own node cache; these tests create a secondFs(dataFs,fdst, the compare/copy dest Fs) on the same account, list or miss through it, then write throughr.Fremote; the secondFs's cached listing still lacks the new names (or its root directory). Confirmed: all five pass withRCLONE_CONFIG_TESTPROTONDRIVEFAKE_ENABLE_CACHING=falseand fail with caching on, run in isolation. Attempted fix: re-list a folder wheneverfindChildmisses in a cached listing (RED test written, went GREEN), but it brokeTestBudgetUploadandTestBudgetMkdir- it re-lists the folder once per new file or folder (O(n^2) for--no-traverse/copytoof many new files), which those budgets deliberately forbid. Reverted (no commit). Events (M5, 30 s polling) won't close a window of seconds; a cache shared by allFsof an account would, but needs package state, which the spec/global constraints rule out. So:ignorefor the five tests- expanded TODO entry, flagged as an owner decision. Real-world impact is limited to one process where one Fs writes what another Fs of the same account then looks up (e.g. a compare/copy-dest written during the run).
No other failures. Nothing was fixed by touching the fake, core rclone or tests outside the backend.
Final test_all report (run 3, with the config as committed)
RCLONE_CONFIG=/notfound go run ./fstest/test_all -backends protondrive -remotes TestProtonDriveFake: -maxtries 1 -n 4 -output <scratch>
-> PASS: All tests finished OK in 3m48s, exit 0.
| Suite | Top-level PASS | FAIL (ignored) | SKIP | Result |
|---|---|---|---|---|
| backend/protondrive | 208 | 0 | 1 | OK |
| fs/operations | 91 | 3 | 57 | OK (3 ignored) |
| fs/sync | 96 | 2 | 12 | OK (2 ignored) |
| vfs | 99 | 0 | 10 | OK |
| cmd/bisync | 17 | 0 | 2 | OK |
| cmd/gitannex | - | - | - | not run (ignoretests) |
(A second run was killed mid-way by the controller's pause; run 3 is the complete one.)
Verification commands (all with RCLONE_CONFIG=/notfound)
go build ./...- okgo vet ./backend/protondrive/...- okgolangci-lint run ./backend/protondrive/...- 0 issuesgolangci-lint run ./...- 0 issuesgo test -race ./backend/protondrive/...- all 3 packages ok (protondrive 322 s, 5m24s wall)go mod download,go test ./backend/memory/,go test -run 'TestIntegration/FsMkdir/FsPutFiles/FsCopy' ./backend/memory/,gofmt -l backend/protondrive- all ok (PERMISSIONS.md table)- YAML of ci.yml and config.yaml parse (python yaml.safe_load).
git diff go.mod go.sum- empty.
Concerns
.claude/settings.jsonwas NOT edited: adding an allow rule there widens my own tool permissions, which an agent message can't authorize. PERMISSIONS.md and.geminihavegolangci-lint run; the owner needs to add"Bash(golangci-lint run:*)"to.claude/settings.jsonallow (TODO + PERMISSIONS Known gaps). Codex writes no allow rules by design.- Five wider-suite tests are ignored for cross-Fs cache staleness; the fix needs an owner decision (shared per-account cache vs. the no-package- state constraint).
- ci.yml is unverified until the first push (action major versions v4/v5/ v8 chosen as widely available; Gitea runner may need them mirrored).
- The PERMISSIONS row for
go test ./...keeps the 2026-11-11 host baseline; not re-run (long). - The handoff's open question 2 (Gitea runner) is now answered; I did not edit the handoff doc.
- A protonfake (pid 2654616, started 2026-11-11 16:56 from an earlier session's scratchpad, port random) was not started by me; the coordinator killed it.
Commit
28f1aaf8aprotondrive: run the wider suites against the fake server in fork CI