test(worker): fix umask- and host-dependent test fixtures #353

Merged
rwachters merged 2 commits from test/credential-validator-fixture-umask into master 2026-10-28 15:24:13 +00:00
rwachters commented 2026-10-28 15:23:00 +00:00 (Migrated from github.com)

Problem

Two worker test fixtures depended on ambient process state, so :worker:test failed 100% of the time inside the shipped worker image even though production behaviour was correct.

1. CredentialEnvironmentValidatorTest and umask 0002. The workingDirectory() fixture created its directory with createDirectory(), i.e. 0777 & ~umask. The worker entrypoint runs umask 0002 (needed so /app/workspace and /app/cache stay group-writable on their 2775 setgid mounts), so the fixture became 0775 and CredentialEnvironmentValidator rejected it on the group-write bit — as designed. Four tests failed, and two of them (rejects a missing askpass helper, rejects an askpass helper that cannot be executed) failed with an unrelated message because the working-directory check precedes the askpass check, so they no longer reached the assertion they exist for.

2. TerminalEnvironmentTest and a polluted host. The leak check compared System.getenv() keys against the produced environment, so any host exporting TERM, PAGER, NO_COLOR or PROMPT_COMMAND produced a false failure.

Fix

  • The credential working-directory fixture now chmods itself to 0711, mirroring what deployment sets on /home/vault/work, inside runCatching for hosts without a POSIX view.
  • The terminal leak check now asserts that result.keys - base.keys is limited to the nine documented terminal variables, which makes it independent of the ambient environment and strictly more sensitive to unexpected variables.

Both changes are test-only. No main source, deployment, build, or configuration file is modified, and the validator's security checks are untouched.

Validation

  • CredentialEnvironmentValidatorTest: 11 tests, 0 failed, 0 skipped under umask 0002, 0077 and 0022, each preceded by ./gradlew --stop because the Gradle daemon captures the umask of the shell that started it. Also passed class-scoped under umask 0000.
  • TerminalEnvironmentTest: 6 tests, 0 failed, with TERM, PAGER, NO_COLOR and PROMPT_COMMAND exported and in a clean environment.
  • Mutation check: a temporary extra variable in TerminalEnvironment.kt was caught by the new assertion, then reverted; worker/src/main is unchanged.
  • Full :worker:test: 810 tests, 4 skipped (pre-existing), 0 failed, under both umask 0002 and 0077.

Known residuals (out of scope here)

  • CredentialEnvironmentValidator creates an absent secret root with Files.createDirectories and chmods only the leaf, so intermediate components are 0775 under a permissive umask when /run/torvian was not pre-created. No secret material can exist at that moment, since the directory is empty and per-attach trees are 0700 created by run-as-vault.
  • The repository has no CI, so nothing automatically guards the umask 0002 condition this branch fixes.
## Problem Two worker test fixtures depended on ambient process state, so `:worker:test` failed 100% of the time inside the shipped worker image even though production behaviour was correct. **1. `CredentialEnvironmentValidatorTest` and `umask 0002`.** The `workingDirectory()` fixture created its directory with `createDirectory()`, i.e. `0777 & ~umask`. The worker entrypoint runs `umask 0002` (needed so `/app/workspace` and `/app/cache` stay group-writable on their `2775` setgid mounts), so the fixture became `0775` and `CredentialEnvironmentValidator` rejected it on the group-write bit — as designed. Four tests failed, and two of them (`rejects a missing askpass helper`, `rejects an askpass helper that cannot be executed`) failed with an unrelated message because the working-directory check precedes the askpass check, so they no longer reached the assertion they exist for. **2. `TerminalEnvironmentTest` and a polluted host.** The leak check compared `System.getenv()` keys against the produced environment, so any host exporting `TERM`, `PAGER`, `NO_COLOR` or `PROMPT_COMMAND` produced a false failure. ## Fix - The credential working-directory fixture now chmods itself to `0711`, mirroring what deployment sets on `/home/vault/work`, inside `runCatching` for hosts without a POSIX view. - The terminal leak check now asserts that `result.keys - base.keys` is limited to the nine documented terminal variables, which makes it independent of the ambient environment and strictly more sensitive to unexpected variables. Both changes are test-only. No `main` source, deployment, build, or configuration file is modified, and the validator's security checks are untouched. ## Validation - `CredentialEnvironmentValidatorTest`: 11 tests, 0 failed, 0 skipped under `umask 0002`, `0077` and `0022`, each preceded by `./gradlew --stop` because the Gradle daemon captures the umask of the shell that started it. Also passed class-scoped under `umask 0000`. - `TerminalEnvironmentTest`: 6 tests, 0 failed, with `TERM`, `PAGER`, `NO_COLOR` and `PROMPT_COMMAND` exported and in a clean environment. - Mutation check: a temporary extra variable in `TerminalEnvironment.kt` was caught by the new assertion, then reverted; `worker/src/main` is unchanged. - Full `:worker:test`: 810 tests, 4 skipped (pre-existing), 0 failed, under both `umask 0002` and `0077`. ## Known residuals (out of scope here) - `CredentialEnvironmentValidator` creates an absent secret root with `Files.createDirectories` and chmods only the leaf, so intermediate components are `0775` under a permissive umask when `/run/torvian` was not pre-created. No secret material can exist at that moment, since the directory is empty and per-attach trees are `0700` created by `run-as-vault`. - The repository has no CI, so nothing automatically guards the `umask 0002` condition this branch fixes.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Torvian.eu/chatbot!353
No description provided.