#!/usr/bin/env bats # Tests for scripts/orca-aggregate.sh + orca-watchdog.sh (P09, C-11, # REQ-107). Hermetic: exercises the aggregator against a fake peers.env # + state dir in a temp dir; the SSH path is exercised only when a # fake ssh shim is on PATH. The watchdog is exercised with a stale # cluster.json to confirm starvation detection. load test_helper @test "orca-aggregate.sh exists and is executable" { [ -f "$SCRIPTS_DIR/orca-aggregate.sh" ] [ -x "$SCRIPTS_DIR/orca-aggregate.sh" ] } @test "orca-watchdog.sh exists and is executable" { [ -f "$SCRIPTS_DIR/orca-watchdog.sh" ] [ -x "$SCRIPTS_DIR/orca-watchdog.sh" ] } @test "orca-aggregate.sh handles missing peers.env gracefully" { tmp="$(mktemp -d)" run env \ ORCA_PEERS_ENV="$tmp/nonexistent.env" \ ORCA_STATE_DIR="$tmp/state" \ ORCA_REMOTE_STATE_DIR="$tmp/remote-state" \ ORCA_REMOTE_DRIFT_DIR="$tmp/remote-drift" \ ORCA_APPLIED_DIR="$tmp/applied" \ bash "$SCRIPTS_DIR/orca-aggregate.sh" assert_status 0 "$status" # cluster.json written atomically with an empty peers array. [ -f "$tmp/state/cluster.json" ] assert_contains "$(cat "$tmp/state/cluster.json")" '"peers":[]' } @test "orca-aggregate.sh skips drift section when drift-events absent" { tmp="$(mktemp -d)" # No applied dir and no remote drift dir on lead → drift section # must skip (no drift-events-aggregated.json written). run env \ ORCA_PEERS_ENV="$tmp/nonexistent.env" \ ORCA_STATE_DIR="$tmp/state" \ ORCA_REMOTE_STATE_DIR="$tmp/remote-state" \ ORCA_REMOTE_DRIFT_DIR="$tmp/absent-drift" \ ORCA_APPLIED_DIR="$tmp/absent-applied" \ bash "$SCRIPTS_DIR/orca-aggregate.sh" assert_status 0 "$status" [ -f "$tmp/state/cluster.json" ] # Drift aggregation skipped → aggregated file must NOT exist. [ ! -f "$tmp/state/drift-events-aggregated.json" ] } @test "orca-watchdog.sh detects starvation with old cluster.json" { tmp="$(mktemp -d)" mkdir -p "$tmp/state" cluster="$tmp/state/cluster.json" echo '{}' >"$cluster" # Set mtime to 120s ago so age (120) >= threshold (default 30). old_ts="$(date -d '120 seconds ago' +%Y%m%d%H%M.%S)" touch -t "$old_ts" "$cluster" # logger is available in CI; capture the alert by overriding PATH # with a fake logger that records to a file. fake_bin="$tmp/bin" mkdir -p "$fake_bin" cat >"$fake_bin/logger" <<'LOGGER_EOF' #!/usr/bin/env bash echo "logger: $*" >>"$LOGGER_OUT" LOGGER_EOF chmod +x "$fake_bin/logger" env \ ORCA_STATE_DIR="$tmp/state" \ ORCA_WATCHDOG_THRESHOLD=30 \ LOGGER_OUT="$tmp/logger.out" \ PATH="$fake_bin:$PATH" \ bash "$SCRIPTS_DIR/orca-watchdog.sh" [ -f "$tmp/logger.out" ] out="$(cat "$tmp/logger.out")" assert_contains "$out" "aggregator starvation detected" } @test "orca-watchdog.sh passes when cluster.json is fresh" { tmp="$(mktemp -d)" mkdir -p "$tmp/state" echo '{}' >"$tmp/state/cluster.json" # Fresh mtime (now); age 0 < threshold. fake_bin="$tmp/bin" mkdir -p "$fake_bin" cat >"$fake_bin/logger" <<'LOGGER_EOF' #!/usr/bin/env bash echo "logger: $*" >>"$LOGGER_OUT" LOGGER_EOF chmod +x "$fake_bin/logger" env \ ORCA_STATE_DIR="$tmp/state" \ ORCA_WATCHDOG_THRESHOLD=30 \ LOGGER_OUT="$tmp/logger.out" \ PATH="$fake_bin:$PATH" \ bash "$SCRIPTS_DIR/orca-watchdog.sh" if [ -f "$tmp/logger.out" ]; then out="$(cat "$tmp/logger.out")" ! assert_contains "$out" "aggregator starvation detected" || { echo "unexpected starvation alert for fresh cluster.json" >&2 return 1 } fi } @test "orca-watchdog.sh alerts when cluster.json absent" { tmp="$(mktemp -d)" fake_bin="$tmp/bin" mkdir -p "$fake_bin" cat >"$fake_bin/logger" <<'LOGGER_EOF' #!/usr/bin/env bash echo "logger: $*" >>"$LOGGER_OUT" LOGGER_EOF chmod +x "$fake_bin/logger" env \ ORCA_STATE_DIR="$tmp/state" \ ORCA_WATCHDOG_THRESHOLD=30 \ LOGGER_OUT="$tmp/logger.out" \ PATH="$fake_bin:$PATH" \ bash "$SCRIPTS_DIR/orca-watchdog.sh" [ -f "$tmp/logger.out" ] out="$(cat "$tmp/logger.out")" assert_contains "$out" "aggregator starvation detected" assert_contains "$out" "cluster.json absent" }