mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-06 09:27:46 +08:00
feat: revamp analytics dashboards and harden database migrations
Add dashboard and overview analytics, health monitoring, provider expense tracking, and announcement updates across the gateway and frontend. Keep schema migrations free of historical backfills while preserving automatic backfill execution. Bound migration deadlines, run schema preparation before Compose replacement, and anonymize deleted dashboard users. Include the current documentation cleanup and regression coverage.
This commit is contained in:
@@ -19,6 +19,101 @@ make_fixture() {
|
||||
chmod 0755 "${fixture}/compose/update.sh"
|
||||
}
|
||||
|
||||
make_migration_docker_stub() {
|
||||
local fixture="$1"
|
||||
cat >"${fixture}/bin/docker" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf '%s\n' "$*" >>"${AETHER_TEST_CALLS}"
|
||||
case "$*" in
|
||||
"compose version"|"info") exit 0 ;;
|
||||
*"config --services") printf 'app\n' ;;
|
||||
*"pull app") exit 0 ;;
|
||||
*"run --rm --no-deps -T app --migrate") exit "${AETHER_TEST_MIGRATION_STATUS:-0}" ;;
|
||||
*"up --help") printf '%s\n' ' --wait Wait for services' ;;
|
||||
*"up -d --wait --wait-timeout 120 app"|*" ps") exit 0 ;;
|
||||
*) printf 'Unexpected docker arguments: %s\n' "$*" >&2; exit 99 ;;
|
||||
esac
|
||||
EOF
|
||||
chmod 0755 "${fixture}/bin/docker"
|
||||
}
|
||||
|
||||
test_migration_succeeds_before_recreate() {
|
||||
local fixture="${TEST_ROOT}/migration-before-recreate"
|
||||
make_fixture "${fixture}"
|
||||
make_migration_docker_stub "${fixture}"
|
||||
|
||||
PATH="${fixture}/bin:${PATH}" AETHER_TEST_CALLS="${fixture}/calls" \
|
||||
"${fixture}/compose/update.sh" --compose-dir "${fixture}/compose" \
|
||||
>"${fixture}/stdout" 2>"${fixture}/stderr"
|
||||
|
||||
local pull_line migration_line recreate_line
|
||||
pull_line="$(grep -nF 'pull app' "${fixture}/calls" | cut -d: -f1)"
|
||||
migration_line="$(grep -nF 'run --rm --no-deps -T app --migrate' "${fixture}/calls" | cut -d: -f1)"
|
||||
recreate_line="$(grep -nF 'up -d --wait --wait-timeout 120 app' "${fixture}/calls" | cut -d: -f1)"
|
||||
[[ "${pull_line}" -lt "${migration_line}" && "${migration_line}" -lt "${recreate_line}" ]] \
|
||||
|| fail_test "update did not pull, migrate, then recreate in order"
|
||||
[[ "$(grep -Fc ' --migrate' "${fixture}/calls")" -eq 1 ]] \
|
||||
|| fail_test "update did not run migrations exactly once"
|
||||
! grep -Eq 'db prepare|apply-backfills|--service-ports' "${fixture}/calls" \
|
||||
|| fail_test "migration preflight enabled backfills or published service ports"
|
||||
}
|
||||
|
||||
test_migration_failure_preserves_running_app() {
|
||||
local fixture="${TEST_ROOT}/migration-failure"
|
||||
make_fixture "${fixture}"
|
||||
make_migration_docker_stub "${fixture}"
|
||||
|
||||
if PATH="${fixture}/bin:${PATH}" AETHER_TEST_CALLS="${fixture}/calls" \
|
||||
AETHER_TEST_MIGRATION_STATUS=42 \
|
||||
"${fixture}/compose/update.sh" --compose-dir "${fixture}/compose" \
|
||||
>"${fixture}/stdout" 2>"${fixture}/stderr"; then
|
||||
fail_test "update succeeded after schema migration failed"
|
||||
fi
|
||||
|
||||
grep -Fq 'run --rm --no-deps -T app --migrate' "${fixture}/calls" \
|
||||
|| fail_test "update did not attempt schema migration"
|
||||
! grep -Eq ' (up|stop|down|restart|rm) ' "${fixture}/calls" \
|
||||
|| fail_test "failed migration changed the running service"
|
||||
grep -Fq 'app was not recreated' "${fixture}/stderr" \
|
||||
|| fail_test "migration failure did not explain that app was left running"
|
||||
! grep -Fq '>>> Done.' "${fixture}/stdout" \
|
||||
|| fail_test "failed migration was reported as successful"
|
||||
}
|
||||
|
||||
test_prepare_only_pulls_image() {
|
||||
local fixture="${TEST_ROOT}/prepare-only"
|
||||
make_fixture "${fixture}"
|
||||
make_migration_docker_stub "${fixture}"
|
||||
|
||||
PATH="${fixture}/bin:${PATH}" AETHER_TEST_CALLS="${fixture}/calls" \
|
||||
"${fixture}/compose/update.sh" --compose-dir "${fixture}/compose" --prepare \
|
||||
>"${fixture}/stdout" 2>"${fixture}/stderr"
|
||||
|
||||
grep -Fq 'pull app' "${fixture}/calls" \
|
||||
|| fail_test "--prepare did not pull the new app image"
|
||||
! grep -Eq ' (run|up|stop|down|restart) ' "${fixture}/calls" \
|
||||
|| fail_test "--prepare migrated or changed running services"
|
||||
}
|
||||
|
||||
test_no_pull_still_migrates_before_recreate() {
|
||||
local fixture="${TEST_ROOT}/migration-without-pull"
|
||||
make_fixture "${fixture}"
|
||||
make_migration_docker_stub "${fixture}"
|
||||
|
||||
PATH="${fixture}/bin:${PATH}" AETHER_TEST_CALLS="${fixture}/calls" \
|
||||
"${fixture}/compose/update.sh" --compose-dir "${fixture}/compose" --no-pull \
|
||||
>"${fixture}/stdout" 2>"${fixture}/stderr"
|
||||
|
||||
! grep -Fq 'pull app' "${fixture}/calls" \
|
||||
|| fail_test "--no-pull downloaded an app image"
|
||||
local migration_line recreate_line
|
||||
migration_line="$(grep -nF 'run --rm --no-deps -T app --migrate' "${fixture}/calls" | cut -d: -f1)"
|
||||
recreate_line="$(grep -nF 'up -d --wait --wait-timeout 120 app' "${fixture}/calls" | cut -d: -f1)"
|
||||
[[ "${migration_line}" -lt "${recreate_line}" ]] \
|
||||
|| fail_test "--no-pull skipped schema preparation before recreate"
|
||||
}
|
||||
|
||||
test_wait_failure_is_not_ignored() {
|
||||
local fixture="${TEST_ROOT}/wait-failure"
|
||||
make_fixture "${fixture}"
|
||||
@@ -126,9 +221,13 @@ test_option_like_service_name_is_rejected() {
|
||||
|| fail_test "unsafe service name was not rejected by the identifier guard"
|
||||
}
|
||||
|
||||
test_migration_succeeds_before_recreate
|
||||
test_migration_failure_preserves_running_app
|
||||
test_prepare_only_pulls_image
|
||||
test_no_pull_still_migrates_before_recreate
|
||||
test_wait_failure_is_not_ignored
|
||||
test_legacy_compose_uses_health_polling
|
||||
test_legacy_compose_health_failure_is_not_ignored
|
||||
test_option_like_service_name_is_rejected
|
||||
|
||||
echo "PASS: compose updater failure and argument safety fixtures"
|
||||
echo "PASS: compose updater migration preflight, failure, and argument safety fixtures"
|
||||
|
||||
Reference in New Issue
Block a user