Files
rclone/docs/plans/001-protondrive-tier1-workspace/task-18-report.md
T
2026-11-12 15:12:51 +01:00

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 entry protondrive / TestProtonDriveFake:, fastlist: false, with 5 ignore tests and ignoretests: cmd/gitannex (reasons below, each commented in the file). The existing live TestProtonDrive: entry is untouched.
  • .gitea/workflows/ci.yml (new): on push and pull_request, one job, timeout-minutes: 45; checkout, actions/setup-go@v5 with go-version-file: go.mod and cache: true; go build ./...; go vet ./backend/protondrive/...; golangci-lint-action@v8 pinned to v2.15.0 with args: ./backend/protondrive/... (the action caches); go test -race ./backend/protondrive/...; a 20 s fuzz run per target (targets discovered with go test -list '^Fuzz', currently 5); go run golang.org/x/vuln/cmd/govulncheck@latest ./backend/protondrive/.... RCLONE_CONFIG=/notfound set 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, .claude permission entry, "Now" entry updated, old "decide whether to add Gitea CI" entry removed), docs/PERMISSIONS.md (verified table re-run on host, golangci-lint run in Allow, stale "host has no Go" gap removed, .claude gap noted), docs/ARCHITECTURE.md (one bullet on the init.d script and CI), .gemini/settings.json (golangci-lint run allowed), plan Task 18 checkboxes ticked.
  • No backend code changed. go.mod/go.sum unchanged.

Script design

  • Sources run.bash (mandatory refcounting/locking), defines its own start/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.
  • start builds ./backend/protondrive/protontest/cmd/protonfake into the state dir with go build (fast with the build cache; rebuilt each first start so it never runs a stale binary), runs the binary itself with nohup ... -addr 127.0.0.1:28642, stdout to a file, stderr to a log, disowned. It polls up to 10 s for the type= 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 later start while the server lives returns the same session.
  • stop sends 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:

  1. cmd/gitannex - all 19 TestGitAnnexFstestBackendCases/* fail with INITREMOTE-FAILURE remote does not exist: TestProtonDriveFake:. Cause: cmd/gitannex/configparse.go checks the name against config.GetRemoteNames(), which lists env-var remotes lower-cased (fs/config/config.go GetRemotes). 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.
  2. fs/operations TestCheckSumDownload, TestCopyFileCompareDest, TestCopyFileCopyDestImmutable; fs/sync TestSyncCompareDest, TestSyncCopyDestImmutable. Cause: each Fs has its own node cache; these tests create a second Fs (dataFs, fdst, the compare/copy dest Fs) on the same account, list or miss through it, then write through r.Fremote; the second Fs's cached listing still lacks the new names (or its root directory). Confirmed: all five pass with RCLONE_CONFIG_TESTPROTONDRIVEFAKE_ENABLE_CACHING=false and fail with caching on, run in isolation. Attempted fix: re-list a folder whenever findChild misses in a cached listing (RED test written, went GREEN), but it broke TestBudgetUpload and TestBudgetMkdir - it re-lists the folder once per new file or folder (O(n^2) for --no-traverse/copyto of 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 all Fs of an account would, but needs package state, which the spec/global constraints rule out. So: ignore for 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 ./... - ok
  • go vet ./backend/protondrive/... - ok
  • golangci-lint run ./backend/protondrive/... - 0 issues
  • golangci-lint run ./... - 0 issues
  • go 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.json was NOT edited: adding an allow rule there widens my own tool permissions, which an agent message can't authorize. PERMISSIONS.md and .gemini have golangci-lint run; the owner needs to add "Bash(golangci-lint run:*)" to .claude/settings.json allow (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

  • 28f1aaf8a protondrive: run the wider suites against the fake server in fork CI