Skip to content

Add automated test for docker-entrypoint.sh - #17

Merged
dmccoystephenson merged 2 commits into
mainfrom
feature/entrypoint-test
Sep 7, 2026
Merged

dmccoystephenson merged 2 commits into
mainfrom
feature/entrypoint-test

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

  • docker-entrypoint-test.sh is added: a POSIX shell test that puts a stub java on PATH (one that prints its arguments rather than starting a JVM), runs docker-entrypoint.sh under seven environment combinations, and asserts the argument list the entrypoint builds.
  • Each argument is printed wrapped in brackets by the stub, so a value containing a space is distinguishable from two separate arguments — without that, the space case would be a false negative.
  • Cases covered: no variables set; BACKUP_DIRECTORY, SCHEDULED_USERS and BACKUP_INTERVAL_MS each set individually; all three set together (argument order asserted); all three set to the empty string, which must add no arguments; and a value containing a space.
  • A Test entrypoint script step is added to the docker-build job in .github/workflows/build.yml, so the script is executed on every pull request rather than only copied into an image.
  • README.md gains an Entrypoint Script Test subsection alongside the existing Unit Tests subsection, CONTRIBUTING.md's Testing section documents how to run it, and CHANGELOG.md's [Unreleased] section records the addition.

Before this change, neither CI job executed the entrypoint: build runs mvn clean verify, which cannot run a shell script, and docker-build only confirms the script is copied and made executable. A typo in a property name would not have been caught until a container came up misconfigured.

Test plan

  • mvn -B test — 54 tests run, 0 failures, 1 skipped (pre-existing skip in GitHubServiceTest), BUILD SUCCESS
  • sh docker-entrypoint-test.sh — 7 of 7 cases pass, exit 0
  • Mutation check 1: -Dbackup.scheduled.interval.ms= renamed to -Dbackup.scheduled.intervalms= in docker-entrypoint.sh → 2 cases FAIL, exit 1; restored → all pass
  • Mutation check 2: the [ -n "$SCHEDULED_USERS" ] guard replaced with if true → 5 cases FAIL including the empty-value case, exit 1; restored → all pass
  • Not verified locally: the docker-build job itself, since Docker is unavailable in this environment. The new CI step is plain sh on ubuntu-latest and needs no container, and the script was executed directly under /bin/sh; the CI run on this PR head is the anchor for the workflow wiring.

Notes

shellcheck, mentioned as optional in the issue, is deliberately not added here: it could not be run locally to confirm docker-entrypoint.sh passes cleanly, so wiring it into CI would have risked a red run for reasons unrelated to this change. It is left as a separate, independently verifiable step.

.github/workflows/build.yml is on this loop's do-not-auto-merge list, so this pull request is left open for maintainer review rather than merged autonomously.

Issues deferred this cycle

Closes #13

This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

dmccoystephenson and others added 2 commits September 6, 2026 02:10
docker-entrypoint.sh translates BACKUP_DIRECTORY, SCHEDULED_USERS and
BACKUP_INTERVAL_MS into JVM system properties, but neither CI job executed
it: `build` runs `mvn clean verify`, which cannot run a shell script, and
`docker-build` only copies the script into the image without starting a
container. Entrypoint changes therefore landed on a fully green CI run with
the changed lines never having been run.

docker-entrypoint-test.sh puts a stub `java` on PATH that prints its
arguments wrapped in brackets, then asserts the argument list the entrypoint
builds for seven cases: no variables set, each variable set individually,
all three set together, all three set to the empty string (which must add no
arguments), and a value containing a space (which must stay a single
argument). The bracket delimiting is what makes the last case meaningful.

The test runs as a step in the docker-build job, so it gates the same pull
requests the image build already gates.

Closes #13

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The NAME=VALUE parsing used eval to export a dynamically-named variable,
which would mis-handle a value containing a quote or backtick and, more
importantly, silently accepted a misspelled variable name: a case written
against SCHEDULEDUSERS would export a variable the entrypoint never reads
and still assert the empty-variable argument list, looking like coverage
it did not provide.

A case statement over the three variables docker-entrypoint.sh actually
reads removes the eval and fails loudly on any other name.

The comment on the empty-value case also named GITHUB_TOKEN, which the
entrypoint does not read; it is trimmed to the two variables the case covers.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dmccoystephenson

Copy link
Copy Markdown
Member Author

Self-review rubric

Scored against the diff and command output rather than judgement. Anchor: CI run 34021267770 on head 24b846f, both jobs green.

  • Scope: PASS — five files: the test script, its CI wiring, and the three documentation files the docs check requires. git diff --stat origin/main reports 148 insertions and no deletions across those five, with no unrelated formatting or comment churn.
  • Tests-new: PASS (no production surface added) — no new public method or production code is introduced; the change is the test. Its execution is confirmed in the docker-build job log, which prints seven PASS: lines and All docker-entrypoint.sh tests passed.
  • Tests-fix: PASS — confirmed empirically by three mutation runs against docker-entrypoint.sh, each reverted afterwards: -Dbackup.scheduled.interval.ms= renamed → 2 cases fail, exit 1; the [ -n "$SCHEDULED_USERS" ] guard replaced with if true → 5 cases fail including the empty-value case, exit 1; -Dbackup.directory= renamed → 3 cases fail, exit 1. Restoration was verified by content comparison after each.
  • Sibling structure: PASS with one note — the new ### Entrypoint Script Test subsection in README.md mirrors the shape of the ### Unit Tests subsection above it (Linux/macOS block, Windows block, a "if you see X, the tests have passed" line). See the file-mode note below.
  • Sibling renames: no signal — nothing is renamed by this change.
  • Docs: PASS — README.md, CONTRIBUTING.md and CHANGELOG.md are updated. COMMANDS.md, CONFIG.md and USER_GUIDE.md are correctly left untouched: no CLI flag, JVM system property, REST endpoint, configuration key, or user-facing behaviour is changed by this pull request.
  • Issue resolution: PASS — docker-entrypoint.sh has no automated test, so entrypoint changes ship unverified by CI #13 asked for a test script that stubs java on PATH and asserts the constructed argument list across the named cases, plus a step in the docker-build job. Both are present, and all five cases the issue names are covered, with a sixth added for a value containing a space.
  • CI: PASS — build and docker-build both succeeded on the current head.
  • Config-doc parity: no signal — no application*.properties key, @Value or @ConfigurationProperties field is added or changed.
  • Command-doc parity: no signal — no CLI flag, system property or REST endpoint is added.
  • Package placement: no signal — no Java source is added or moved.
  • No credential leakage: PASS — GITHUB_TOKEN is neither read nor exported by the test, and the stub java echoes only the argument list docker-entrypoint.sh constructs, which contains no secret. The GITHUB_TOKEN reference in an earlier draft of a code comment was removed during this review.

Findings

  • docker-entrypoint-test.sh:43 — fixed during review. The NAME=VALUE parsing used eval "export $name=\"\$value\"". Beyond mishandling a value containing a quote or backtick, it silently accepted a misspelled variable name: a case written against SCHEDULEDUSERS=octocat would have exported a variable the entrypoint never reads and still asserted the empty-variable argument list — coverage that looks real and is not. Replaced with a case over the three variables docker-entrypoint.sh actually reads, which fails loudly on any other name.
  • docker-entrypoint-test.sh:101 — fixed during review. A comment stated the Dockerfile ships GITHUB_TOKEN among the empty defaults relevant to this case. That is true of the Dockerfile but irrelevant here, since the entrypoint never reads GITHUB_TOKEN; the comment now names only the two variables the case covers.
  • README.md:70 and README.md:76 — the Linux/macOS and Windows code blocks are byte-identical, since the test needs a POSIX shell and is therefore invoked the same way under Git Bash or WSL. This is left as-is deliberately: the ### Unit Tests subsection directly above uses the same two-block shape, and collapsing only the new subsection would break that parallel. Flagged rather than changed, as it is a judgement call.
  • docker-entrypoint-test.sh is committed with mode 100755 while docker-entrypoint.sh is 100644 (the Dockerfile chmod +xes the latter at build time). The inconsistency has no effect, because both the CI step and the documented invocation run sh <file> rather than executing it directly. Noted for the maintainer's preference.
  • Out of diff: CI run annotations report that actions/checkout@v4 and actions/setup-java@v4 are deprecated and being forced onto Node.js 24. This predates this pull request and is not addressed here; a separate issue is filed for it.

Verification not performed

The docker-build job's image build was not reproduced locally, as Docker is unavailable in this environment. The new step is plain sh on ubuntu-latest and requires no container, the script was executed directly under /bin/sh locally, and the green CI run on the exact head SHA is the anchor for the workflow wiring itself.

Merge disposition

.github/workflows/build.yml is on this loop's do-not-auto-merge list, so this pull request is left open for maintainer review rather than merged autonomously.

This review was posted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

@dmccoystephenson
dmccoystephenson merged commit 668e282 into main Sep 7, 2026
2 checks passed
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.

docker-entrypoint.sh has no automated test, so entrypoint changes ship unverified by CI

1 participant