test: BATS coverage for etc/profile.d/uwelcome.sh — tests/test_uwelcome_profile.bats - #1118
Conversation
system_files/shared/etc/profile.d/uwelcome.sh runs in every login shell on every image but had zero test coverage: tests/test_profile_d.bats covers only caffeinate.sh, and no other suite references the file. Adds tests/test_uwelcome_profile.bats (9 tests) covering the three behaviours the script actually implements: - legacy ~/.config/no-show-user-motd marker migration to ~/.config/uwelcome/disabled, including the no-marker and pre-existing- directory cases - the root skip guard (id -u = 0), which exists so root shells never stall on the portal lookup - the UWELCOME_SHOWN double-greeting guard, including the export that stops a chained shell (bash login shell starting fish) from greeting twice Wired into the Justfile test recipe next to the existing test_profile_d.bats line. Verified with bats 1.14.0: 9/9 pass, and removing the root guard from uwelcome.sh turns two of them red. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: sec-check[bot] <sec-check[bot]@users.noreply.github.com>
|
The tests are sound — I mutation-tested all four behaviours in Stubbing The question is whether this should be a new file. Against that, roughly four of the nine here are restatements: "legacy marker migrates" ≈ 2/3, "no config dir when marker absent" ≈ 4, "runs for a non-root user" ≈ 1, "skipped when UWELCOME_SHOWN is set" ≈ 8. The genuinely new coverage is the root guard (5), the export/chained-shell case (7), root-still-migrates (8), the empty-string case (9), and preserving an existing uwelcome dir (3). Those are worth having — because the existing file predates the root guard, and its comment is now stale: That's no longer true for root. I'd rather see the five new cases folded into Verified: base Generated by Claude Code |
Danathar
left a comment
There was a problem hiding this comment.
Ran bats tests/test_uwelcome_profile.bats at head: 9/9 pass. Executes etc/profile.d/uwelcome.sh under a sandboxed HOME with uwelcome stubbed, and covers the legacy-marker migration, the root skip, and the UWELCOME_SHOWN double-greeting guard. Closes the #1117 gap.
Same caveat as #1106/#1138: registered in the Justfile only; unit-tests.yml needs the line added by a human (#1105).
|
Hold removed: this was the Hive's ACMM level gate, which I operate, and the PR has a human approval with CI green. Ready for a maintainer to merge. |
There was a problem hiding this comment.
correctness
- Tests 5 and 8 can pass vacuously on a real Bluefin host.
setup()(tests/test_uwelcome_profile.bats:9-23) never unsetsUWELCOME_SHOWN, and the tests "uwelcome is skipped for root" (line 86) and "root still gets the legacy marker migrated" (line 116) don't either. If the bats process inheritsUWELCOME_SHOWN=1from a login shell that already sourceduwelcome.sh— exactly the machines this repo builds — the greeting is skipped by the[ -z "${UWELCOME_SHOWN-}" ]guard, not the root guard, so the PR's mutation claim (deleting the root guard turns 5/8 red) only holds in a clean environment. Fix:unset UWELCOME_SHOWNinsetup().
intent-alignment
- The new suite is only wired into the Justfile (Justfile:26);
.github/workflows/unit-tests.ymlruns each bats suite as an explicit step and gains no step fortest_uwelcome_profile.bats, so CI never executes these tests. The PR body scopes this out deliberately (tracked by #968/#1105/#1106), but until that lands the coverage #1117 asked for is local-only.
style
! called(lines 92, 102, 124) only asserts because it happens to be the last command in each test — bash's errexit ignores!-inverted failures elsewhere.[ ! -f "${WORKDIR}/calls" ]would be robust to future edits.
No findings from: security, docs-currency.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.78
unset UWELCOME_SHOWN in setup() so root-guard tests exercise the root branch instead of passing vacuously when the bats process inherits UWELCOME_SHOWN=1 from a Bluefin login shell. Replace '! called' with a not_called helper: errexit ignores failures of !-inverted commands, so the assertion only held as the final command. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
intent-alignment
- (low) The new suite is wired into
Justfile:26but not.github/workflows/unit-tests.yml, which enumerates bats suites step-by-step (e.g. lines 72–121) and runstests/test_profile_d.batsat line 112 without the new file. Until #1106 lands, CI never executes this coverage — it only runs via localjust test. The PR body discloses this, but a maintainer merging for "coverage" should know the gate is local-only; adding one workflow step here would close it without touching the drift cleanup.
style
- (low)
stub_id(tests/test_uwelcome_profile.bats:33–39) relies on the unquoted<< MOCKheredoc expanding"$1"at generation time, baking the uid literal into the stub. It works, but unlike theuwelcomemock above it (line 13 comment), nothing flags the intentional unquoted delimiter — a future editor quoting'MOCK'for consistency withtests/test_profile_d.bats:14would silently break everyid-dependent test.
Verified at d2ab58c: suite passes 9/9 locally, and the PR body's mutation claim reproduces (removing the root guard from uwelcome.sh:13 fails exactly tests 5 and 8). Justfile insertion point matches the stated conflict-avoidance placement.
No findings from: correctness, security, docs-currency.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.78
Danathar
left a comment
There was a problem hiding this comment.
Re-approved at d2ab58c after the push dismissed my approval of b90f1a8. The one new commit hardens the suite: it unsets UWELCOME_SHOWN inherited from a Bluefin login shell, which would have made both root-guard tests pass vacuously, and replaces ! called with a not_called helper because errexit ignores a failed !-inverted command that is not the last line. Both are correct bats practice. Nine tests, CI green.
castrojo
left a comment
There was a problem hiding this comment.
LGTM. Thorough BATS suite for uwelcome.sh profile behavior and migration.
Test Improvement
Adds BATS coverage for
system_files/shared/etc/profile.d/uwelcome.sh, which previously had none.Closes #1117
Files claimed by this PR:
tests/test_uwelcome_profile.bats(new file, 9 tests)Justfile— one added line,bats tests/test_uwelcome_profile.bats, inserted directly after the existingbats tests/test_profile_d.batsline (not at the end of the recipe, to stay clear of common#1064, which appends itstest_apps_just.batsline there)Cluster: login-shell
etc/profile.dcoverage.Why
tests/test_profile_d.batsis named generically but covers onlycaffeinate.sh— its header says so and it defines a singleCAFFEINATE_SCRIPTpath. Nothing intests/referenceduwelcome.sh, even though it is sourced by every login shell on every image built from common.What is covered
uwelcome.sh~/.config/no-show-user-motdto~/.config/uwelcome/disabledmigrationuwelcome/dir preserved, migration still runs for root[ "$(id -u)" != "0" ]— exists because the portal lookup can stall the promptUWELCOME_SHOWNdouble-greeting guardexportis proven by a chainedbash -c '. profile; bash profile'asserting exactly one invocationidanduwelcomeare stubbed onPATHin amktemp -dworkdir, matching the mock style already used intests/test_profile_d.batsandtests/test_bonedigger_report.bats. No network, no root, no systemd.Verification
bats tests/test_uwelcome_profile.batsgives 9/9 pass (bats 1.14.0)[ "$(id -u)" != "0" ] &&guard fromuwelcome.shturns tests 5 and 8 red, confirming the suite actually asserts behaviour rather than passing vacuously.Explicitly not claimed here
The
unit-tests.yml/ Justfile test-catalog drift (12 suites in the Justfile that CI never runs, plus fully orphanedtests/test_image_repo.bats) is already tracked by #968 and #1105 and owned by common#1106 — this PR does not touch.github/workflows/unit-tests.yml,tests/test_ujust.bats,tests/test_shared_just.bats, ortests/test_apps_just.bats.Filed by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.78