Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f6ead4ffc | |||
| 66f6eeb4e4 | |||
| 835d796781 | |||
| 51490707f5 | |||
| ba6e49ffb7 | |||
| e0ab86b8f8 | |||
| 82c944728e | |||
| ad74c8a39e | |||
| 0e35d8d978 | |||
| 3da86dbf8a | |||
| f5dd1de57a | |||
| 3b66b2b6a6 | |||
| cef655acc6 | |||
| 9a0ea96d22 | |||
| ec0502f829 | |||
| 7d04aef94d | |||
| 172c100dec | |||
| 94bd45c3b5 |
@@ -1,53 +1,20 @@
|
||||
# Task 06G4VF5HZW7Q4JBM3TTY7W1Y64
|
||||
# Task 06G4M6HF1Z3EREX1X3NEKSHP24
|
||||
|
||||
Add ten named checks to the healthcheck, in five phases
|
||||
Name the healthcheck success message once
|
||||
|
||||
- Project: test-e2e
|
||||
- Source: burnin/run18-implement-successor
|
||||
- Source: burnin/run14-a
|
||||
- Priority: 0
|
||||
|
||||
## Instructions
|
||||
|
||||
scripts/orchestra_e2e_healthcheck.sh currently runs a single check. Grow it to ten named checks, each implemented as its own shell function, each reported by name.
|
||||
scripts/orchestra_e2e_healthcheck.sh spells its success message inline. Give it a single named constant beside the existing VERSION constant and use that constant everywhere the message is printed.
|
||||
|
||||
The ten checks, all read-only and all satisfiable inside this repository:
|
||||
|
||||
1. repo_root_readable, 2. scripts_dir_present, 3. healthcheck_executable_bit, 4. selftest_present, 5. test_healthcheck_present, 6. readme_present, 7. no_crlf_line_endings, 8. no_tabs_in_scripts, 9. shebang_is_bash, 10. usage_text_mentions_every_flag.
|
||||
|
||||
Each check is a function named check_<name> that returns 0 for pass and 1 for fail, prints nothing on its own, and records its name and outcome in the existing results state.
|
||||
|
||||
Plan this as FIVE phases:
|
||||
|
||||
1. Checks 1 to 3, with the dispatch loop that runs a list of check functions and records each outcome.
|
||||
2. Checks 4 to 6.
|
||||
3. Checks 7 to 8.
|
||||
4. Checks 9 to 10.
|
||||
5. Update the usage text in --help to list every check name, and extend scripts/test_healthcheck.sh with one assertion per check plus an assertion that all ten names appear in the output.
|
||||
|
||||
## Work one phase at a time
|
||||
|
||||
This is a hard requirement. Implement phase N, request its verification, and only then begin phase N+1. Do not write the whole change first and verify the phases afterwards.
|
||||
|
||||
## Behaviour that must not change
|
||||
|
||||
The existing success line, the --quiet, --json and --help flags, and the exit status all keep their current behaviour when every check passes.
|
||||
|
||||
## Verification policy for this project
|
||||
|
||||
Only two commands may appear on a run: line, exactly:
|
||||
|
||||
- ["bash", "-n", "<path>"]
|
||||
- ["bash", "scripts/orchestra_e2e_healthcheck.sh"]
|
||||
|
||||
Anything else is refused when you seal the plan. Give every phase at least one automated check from that list, and add a manual check where a human should confirm the printed text.
|
||||
Behaviour must not change. The plain run, --quiet and --help keep their current output and exit statuses, and scripts/test_healthcheck.sh keeps passing.
|
||||
|
||||
## Research first
|
||||
|
||||
Establish at least three findings with distinct confidence: at least one fact, one inference, one assumption.
|
||||
|
||||
## Handoff behaviour
|
||||
|
||||
Behave normally throughout this task. If Orchestra asks you to write a handoff report, write it and stop.
|
||||
Establish at least three findings with distinct confidence: at least one `fact`, one `inference`, one `assumption`.
|
||||
|
||||
|
||||
## Quality gate
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
readonly VERSION=1.0.0
|
||||
readonly SUCCESS_MESSAGE='OK - all healthchecks passed'
|
||||
readonly ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||
|
||||
# Space-separated check names; each has a check_<name> function.
|
||||
@@ -57,6 +58,12 @@ check_usage_text_mentions_every_flag() {
|
||||
done
|
||||
}
|
||||
|
||||
# now_us: current time in microseconds. Strips any locale decimal separator.
|
||||
now_us() { printf '%s' "${EPOCHREALTIME//[!0-9]/}"; }
|
||||
|
||||
# elapsed_ms <start-us>: whole milliseconds since <start-us>.
|
||||
elapsed_ms() { printf '%s' "$(( ($(now_us) - $1) / 1000 ))"; }
|
||||
|
||||
# emit <format> <template> [args...]: the single output path.
|
||||
# format: text or json print; none suppresses (--quiet). Explicit argument,
|
||||
# never read from an enclosing variable.
|
||||
@@ -69,12 +76,16 @@ emit() {
|
||||
# usage <format>: the --help body. Also the source check_usage_text_mentions_every_flag
|
||||
# reads, so the flag list has exactly one home.
|
||||
usage() {
|
||||
emit "$1" 'Usage: %s [--quiet]\n\n' "${0##*/}"
|
||||
emit "$1" 'Usage: %s [--quiet] [--json] [--summary] [--timing] [--strict] [--list-checks]\n\n' "${0##*/}"
|
||||
emit "$1" 'Healthcheck script for Orchestra E2E tests.\n'
|
||||
emit "$1" 'Exits 0 with a success message if all checks pass.\n'
|
||||
emit "$1" ' --quiet Suppress the success message; still exits 0.\n'
|
||||
emit "$1" ' --json Print a single-line JSON result; still exits 0.\n'
|
||||
emit "$1" ' --help Print this usage text and exit 0.\n'
|
||||
emit "$1" ' --summary Print one line per check before the success message.\n'
|
||||
emit "$1" ' --timing Print elapsed milliseconds for the run.\n'
|
||||
emit "$1" ' --strict Reject an unrecognised flag: exits 2.\n'
|
||||
emit "$1" ' --list-checks Print the name of each check; exits 0.\n'
|
||||
emit "$1" '\nChecks:\n'
|
||||
local name
|
||||
for name in $CHECKS; do
|
||||
@@ -84,19 +95,44 @@ usage() {
|
||||
}
|
||||
|
||||
main() {
|
||||
local start_us
|
||||
start_us=$(now_us)
|
||||
local quiet=
|
||||
local json=
|
||||
local summary=
|
||||
local timing=
|
||||
local strict=
|
||||
local unknown=
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = --help ]; then
|
||||
usage text
|
||||
exit 0
|
||||
elif [ "$arg" = --list-checks ]; then
|
||||
local listed
|
||||
for listed in $CHECKS; do
|
||||
emit text '%s\n' "$listed"
|
||||
done
|
||||
exit 0
|
||||
elif [ "$arg" = --quiet ]; then
|
||||
quiet=1
|
||||
elif [ "$arg" = --json ]; then
|
||||
json=1
|
||||
elif [ "$arg" = --summary ]; then
|
||||
summary=1
|
||||
elif [ "$arg" = --timing ]; then
|
||||
timing=1
|
||||
elif [ "$arg" = --strict ]; then
|
||||
strict=1
|
||||
else
|
||||
[ -n "$unknown" ] || unknown=$arg
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$strict" ] && [ -n "$unknown" ]; then
|
||||
printf 'unknown flag: %s\n' "$unknown" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
local name
|
||||
for name in $CHECKS; do
|
||||
if "check_$name"; then
|
||||
@@ -118,12 +154,28 @@ main() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local elapsed
|
||||
elapsed=$(elapsed_ms "$start_us")
|
||||
|
||||
if [ "$format" = json ]; then
|
||||
emit "$format" '{"status":"ok","checks":%d}\n' "$TOTAL"
|
||||
local timings=
|
||||
[ -n "$timing" ] && timings=",\"timings\":{\"healthchecks\":$elapsed}"
|
||||
emit "$format" '{"status":"ok","checks":%d%s}\n' "$TOTAL" "$timings"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
emit "$format" 'OK - all healthchecks passed\n'
|
||||
if [ -n "$summary" ]; then
|
||||
local entry
|
||||
for entry in $RESULTS; do
|
||||
emit "$format" '%s: %s\n' "${entry%=*}" "${entry#*=}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "$timing" ]; then
|
||||
emit "$format" 'healthchecks: %sms\n' "$elapsed"
|
||||
fi
|
||||
|
||||
emit "$format" '%s\n' "$SUCCESS_MESSAGE"
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
@@ -34,4 +34,16 @@ case "$jout" in
|
||||
*) fail '--json run stdout prefix: want {"status":' "$jout" ;;
|
||||
esac
|
||||
|
||||
# --strict rejects an unknown flag
|
||||
sout=$(bash "$healthcheck" --strict --nonsense 2>&1)
|
||||
sstatus=$?
|
||||
|
||||
[ "$sstatus" -eq 2 ] || fail "--strict --nonsense exit status: want 2, got $sstatus" "$sout"
|
||||
|
||||
# --strict alone is accepted
|
||||
gout=$(bash "$healthcheck" --strict)
|
||||
gstatus=$?
|
||||
|
||||
[ "$gstatus" -eq 0 ] || fail "--strict run exit status: want 0, got $gstatus" "$gout"
|
||||
|
||||
printf 'selftest: ok\n'
|
||||
|
||||
@@ -7,7 +7,7 @@ NAMES='repo_root_readable scripts_dir_present healthcheck_executable_bit
|
||||
selftest_present test_healthcheck_present readme_present
|
||||
no_crlf_line_endings no_tabs_in_scripts
|
||||
shebang_is_bash usage_text_mentions_every_flag'
|
||||
USAGE="$(printf 'Usage: orchestra_e2e_healthcheck.sh [--quiet]\n\nHealthcheck script for Orchestra E2E tests.\nExits 0 with a success message if all checks pass.\n --quiet Suppress the success message; still exits 0.\n --json Print a single-line JSON result; still exits 0.\n --help Print this usage text and exit 0.\n\nChecks:\n repo_root_readable\n scripts_dir_present\n healthcheck_executable_bit\n selftest_present\n test_healthcheck_present\n readme_present\n no_crlf_line_endings\n no_tabs_in_scripts\n shebang_is_bash\n usage_text_mentions_every_flag\n\nVersion: 1.0.0')"
|
||||
USAGE="$(printf 'Usage: orchestra_e2e_healthcheck.sh [--quiet] [--json] [--summary] [--timing] [--strict] [--list-checks]\n\nHealthcheck script for Orchestra E2E tests.\nExits 0 with a success message if all checks pass.\n --quiet Suppress the success message; still exits 0.\n --json Print a single-line JSON result; still exits 0.\n --help Print this usage text and exit 0.\n --summary Print one line per check before the success message.\n --timing Print elapsed milliseconds for the run.\n --strict Reject an unrecognised flag: exits 2.\n --list-checks Print the name of each check; exits 0.\n\nChecks:\n repo_root_readable\n scripts_dir_present\n healthcheck_executable_bit\n selftest_present\n test_healthcheck_present\n readme_present\n no_crlf_line_endings\n no_tabs_in_scripts\n shebang_is_bash\n usage_text_mentions_every_flag\n\nVersion: 1.0.0')"
|
||||
fails=0
|
||||
|
||||
check() { # check <expected-stdout> <label> [args...]
|
||||
@@ -55,5 +55,40 @@ if [ -n "$missing" ]; then
|
||||
fails=$((fails + 1))
|
||||
fi
|
||||
|
||||
# --list-checks prints one name per line and nothing else.
|
||||
listed=$(bash "$HC" --list-checks 2>/dev/null)
|
||||
want_listed=$(printf '%s\n' $NAMES)
|
||||
if [ "$listed" != "$want_listed" ]; then
|
||||
printf 'FAIL: --list-checks\n---got---\n%s\n---want---\n%s\n' "$listed" "$want_listed"
|
||||
fails=$((fails + 1))
|
||||
fi
|
||||
|
||||
# --summary prints one name: outcome line per check, then the success line.
|
||||
summary_out=$(bash "$HC" --summary 2>/dev/null)
|
||||
for name in $NAMES; do
|
||||
case "$summary_out" in
|
||||
*"$name: ok"*) ;;
|
||||
*) printf 'FAIL: --summary omits %s\n' "$name"; fails=$((fails + 1)) ;;
|
||||
esac
|
||||
done
|
||||
case "$summary_out" in
|
||||
*"$OK") ;;
|
||||
*) printf 'FAIL: --summary does not end with the success line\n'; fails=$((fails + 1)) ;;
|
||||
esac
|
||||
|
||||
# --timing prints an elapsed line, and composes with --json and --quiet.
|
||||
contains 'healthchecks:' '--timing' --timing
|
||||
contains '"timings":{"healthchecks":' '--timing --json' --timing --json
|
||||
check '' '--timing --quiet' --timing --quiet
|
||||
|
||||
# --strict rejects an unrecognised flag; on its own it changes nothing.
|
||||
strict_out=$(bash "$HC" --strict --nonsense 2>&1)
|
||||
strict_status=$?
|
||||
if [ "$strict_status" -ne 2 ] || [ "${strict_out#*unknown flag}" = "$strict_out" ]; then
|
||||
printf 'FAIL: --strict --nonsense (exit=%s)\n---got---\n%s\n' "$strict_status" "$strict_out"
|
||||
fails=$((fails + 1))
|
||||
fi
|
||||
check "$OK" '--strict alone' --strict
|
||||
|
||||
[ "$fails" -eq 0 ] || exit 1
|
||||
printf 'all checks passed\n'
|
||||
|
||||
Reference in New Issue
Block a user