Skip to content

fix(test): keep a caller's ZPFX out of the test shell - #144

Merged
ss-o merged 2 commits into
mainfrom
fix/test-zpfx
Oct 15, 2026
Merged

ss-o merged 2 commits into
mainfrom
fix/test-zpfx

Conversation

@ss-o

@ss-o ss-o commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Summary

  • zi_test gave the inner shell its own HOME, ZDOTDIR and XDG directories but passed an exported ZPFX through. Any developer whose shell loads Zi exports ZPFX, so a local make test ran Zi against the developer's own prefix: the ice suite's sbin case wrote an fzf shim into the real polaris/bin, pointing at test data the next run deletes. After that every login shell of that developer failed on fzf (seen on 2026-10-15). The same leak is why sbin ice failed locally while passing in CI: its artifact check looks under ${ZI_DATA}/polaris.
  • The inner shell now gets ZPFX="${ZI_DATA}/polaris", the path Zi would derive itself and the one the docs and tests/ice.zunit already assume.
  • A new shell-state case exports a different ZPFX, runs zi_test, and checks from a fixture that the inner ZPFX is ${ZI[HOME_DIR]}/polaris.
  • The same applied to GOPATH: tests/plugins.zunit runs go install in an atclone, which with an exported GOPATH built go-md2man into the developer's own Go bin directory. zi_test now sets GOPATH="${HOME}/go" under the test home, which is what CI already gets (it exports no GOPATH) and what the helper's path line assumes. The shell-state case checks both variables, and its comparison is quoted so a data path with pattern characters compares literally.
  • docs/writing-tests.md says what zi_test isolates and that PATH and FPATH are still inherited.

CI does not export ZPFX, so CI results do not change.

Closes #145

Verification

All runs with ZPFX, ZI_DATA and TMPDIR pointed at a scratch directory, and the real Zi prefix checked unchanged afterwards:

  • Before the helper change, the new case fails (zpfx-leaked: ZPFX=.../caller-polaris); the other four shell-state cases pass.
  • With it, make test FILE=shell-state passes 5 of 5 and make test FILE=ice passes 5 of 5, including sbin ice, which failed locally before; nothing is written to the outer ZPFX after the change.
  • With only the GOPATH line removed, the case fails on GOPATH; with it, shell-state 5 of 5 and plugins 3 of 3 (including the go install case) pass with an exported decoy GOPATH and ZPFX, and nothing is written to either decoy or to the real Go and Zi directories.
  • zsh -f -n passes on tests/helpers.zsh and the new fixture.

Agent handoff

No handoff needed.

ss-o added 2 commits October 15, 2026 06:59
zi_test isolated HOME, ZDOTDIR and the XDG directories but passed an
exported ZPFX through. Run from a shell that loads Zi, the ice suite's
sbin case wrote its shim into the developer's own polaris/bin, pointing
at test data the next run deletes, which broke that developer's login
shell and failed the suite's own artifact check under ZI_DATA.

Set ZPFX under ZI_DATA in the inner shell, add a shell-state case that
exports a different ZPFX and checks the inner one, and say what zi_test
isolates in docs/writing-tests.md.
The plugins suite runs `go install' in an atclone. With an exported
GOPATH it built into the developer's own Go bin directory and module
cache; CI exports none, so Go used $HOME/go, the test home the helper
already puts on PATH. Set GOPATH there explicitly, check it in the
shell-state case, and quote the fixture's comparison so a data path
with pattern characters is compared literally.

@ss-o ss-o left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback review under ADR-0026: Copilot request not registered on 26a9bfd

Sole-maintainer exception (ADR-0035). zd is Class 1 and Copilot is configured. Copilot requests at 2026-10-15T05:59:58Z (on e1464cd) and 06:09:33Z on this head both returned no requested reviewer; there is no Copilot review_requested event or review, cause unconfirmed. The maintainer declared that no second human reviewer is available and elected the sole-maintainer exception for #144 at 26a9bfd.

Verdict: no blocking findings. One optional docs suggestion is tracked outside this pull request.

Note

This review was executed by the agent workflow that authored the change. It and the separate reviews below are not a second human review or proof of independent judgment.

Separate reviews. A separate read-only reviewing session reviewed e1464cd and approved with a suggestion (quote the fixture's pattern) and a related leak (GOPATH, used by the go install in tests/plugins.zunit). Both were fixed in 26a9bfd. The same session then reviewed exactly 26a9bfd and approved, with one suggestion: GOBIN and GOMODCACHE are still inherited, so the docs' "stays under $ZI_DATA" holds only while the caller exports neither. Disposition: tracked as a follow-up; setting them here would be a further head for a case no current caller hits.

Checklist

  • Source contracts: zi_test now passes ZPFX="${ZI_DATA}/polaris" (what Zi derives itself, and what tests/ice.zunit and the docs assume) and GOPATH="${HOME}/go" under the test home (Go's default when nothing is exported, and the directory the helper already puts on path). The docs sentence matches the helper and names PATH and FPATH as still inherited.
  • Failure paths: the new shell-state case exports decoy ZPFX and GOPATH with local -x, scoped to the test function and its subshell. With either helper line removed it fails naming the leaked value; with both it passes. The comparison is quoted, so a data path with pattern characters compares literally.
  • Cleanup: the read-only Go module cache now created under the test home is removed by the existing chmod -R u+rwX then rm -rf in setup and teardown; verified empty after plugins.
  • CI and image: no workflow, Dockerfile or docker/** change. CI exports neither variable, so its effective values are unchanged; merging publishes no image.
  • Supply chain: no dependency, action or download source changes.

Checks on this head: 45 succeed, 3 skipped by design, none failing.

Verification. Locally, with decoy ZPFX and GOPATH exported: shell-state 5 of 5, ice 5 of 5 (including sbin ice, which failed locally before because of this leak) and plugins 3 of 3; nothing was written to either decoy or to the real Zi and Go directories. Limits: annexes, compat, packages, snippets and utils were not rerun locally for this change (CI ran them); the docker matrix was not run locally.

Recovery. Revert the squash commit; only test helpers, a fixture and one docs sentence change.

@ss-o
ss-o merged commit 6405bd8 into main Oct 15, 2026
48 checks passed
@ss-o
ss-o deleted the fix/test-zpfx branch October 15, 2026 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local test runs install sbin shims into the caller's ZPFX

1 participant