mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-13 08:05:19 +09:00
Review findings on the previous two commits. 1. TIA no longer selected the suite that runs the harness. select-e2e.sh maps examples/backups/<app>/** to suite <app>, so with the round-trip living in a separate clickhouse-backup/ dir an edit to the harness selected `clickhouse` — which did not execute those scripts — while the suite that does was left out. Fixed the way postgres/mariadb/etcd already do it: both Tests move into hack/e2e-chainsaw/clickhouse/ as clickhouse-1-backup-contracts and clickhouse-2-backup-roundtrip. That also deletes every special case the earlier commits added (src_to_suites, suite_to_source, and the bats case that guarded them — both scripts are now byte-identical to main), and the suite list in hack/e2e-chainsaw/README.md stays correct because no dir is added. The bats case is replaced by one asserting the invariant that actually matters: an examples/backups/clickhouse edit selects the suite that runs it. 2. The docs claimed a fail-fast the harness did not have, and the budget was sized as if it did. wait_for_field polled to the full timeout with no terminal-value escape, and the HelmRelease/StatefulSet waits were bare `kubectl wait` with no existence backstop and no Stalled fail-fast. Ported wait_for_field's fail_value parameter and wait_hr_ready from the postgres helpers, added wait_sts_ready, and routed all eight waits through them. Verified against a fake kubectl: a Failed BackupJob now bails in 3s instead of 600s, a Stalled HelmRelease immediately. The inner budgets sum to 3900s, which the old 30m op timeout did not cover — a hang would have been SIGKILLed with no diagnostics, the failure mode .chainsaw.yaml calls strictly worse — so the timeout is now 65m with the arithmetic written out. 3. The strategy Pod ran `apk add --no-cache curl jq` on every backup and restore. Harmless while nothing in CI ran it; a per-PR dependency on the Alpine CDN once it does, and broken outright air-gapped — which is exactly why the shipped strategy bakes curl+jq into its image. Step 01 now reads that image off cozy-default-altinity and drops the apk add, falling back to alpine only when the platform strategy is absent. Also bounded the two polling curls with --max-time; a hung connection previously stalled the loop until the outer timeout. 4. 91-scenario-user-backup.md still documented the old tenant-test default. 5. .chainsaw.yaml claimed all app tests run in tenant-test, which the postgres and mariadb round-trips already contradicted before this branch. The round-trip header now also states its scope plainly: it exercises the example's strategy, not the shipped cozy-default-altinity. Assisted-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Andrey Kolkov <androndo@gmail.com>
188 lines
7.5 KiB
Bash
188 lines
7.5 KiB
Bash
#!/usr/bin/env bats
|
|
# -----------------------------------------------------------------------------
|
|
# Unit tests for hack/select-e2e.sh
|
|
#
|
|
# cozytest.sh's awk parser recognizes only @test blocks and a bare `}` on its
|
|
# own line; there is no bats `run` or `$status`. Each test runs as a shell
|
|
# function under `set -eu -x`, so assertions are direct shell tests that exit
|
|
# non-zero on failure. setup()/teardown() are not honored — each test creates
|
|
# and cleans its own scratch dir.
|
|
#
|
|
# Run with: hack/cozytest.sh hack/select-e2e_test.bats
|
|
# -----------------------------------------------------------------------------
|
|
|
|
@test "single app diff selects only that suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "packages/apps/postgres/values.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$output" = "postgres" ]
|
|
}
|
|
|
|
@test "operator diff selects all dependent app suites" {
|
|
# postgres-operator is depended on by postgres-application, harbor-application
|
|
# (Harbor uses postgres as its backing DB), and monitoring-application (Grafana
|
|
# DB). monitoring has no chainsaw suite so it's filtered out by the selector.
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "packages/system/postgres-operator/values.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
echo "$output" | grep -wq postgres
|
|
echo "$output" | grep -wq harbor
|
|
if echo "$output" | grep -wq kafka; then
|
|
echo "operator diff must not trigger full suite; got: $output" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
@test "engine-dependency change does not fan out via the ordering edge" {
|
|
# cert-manager is a dependency of cozystack-engine, and every app declares
|
|
# dependsOn cozystack-engine purely as an INSTALL-ORDERING edge (the app's
|
|
# *-rd HelmRelease waits for the ApplicationDefinition CRD). That edge must
|
|
# not propagate test selection: a cert-manager change selects only its
|
|
# genuine direct dependents (postgres, harbor, ...), never unrelated apps
|
|
# like kafka that reach cert-manager solely through the engine.
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "packages/system/cert-manager/values.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
echo "$output" | grep -wq postgres
|
|
echo "$output" | grep -wq harbor
|
|
if echo "$output" | grep -wq kafka; then
|
|
echo "cert-manager change must not fan out via engine; got: $output" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
@test "networking change triggers full suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "packages/system/cilium/values.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
# Full suite means more than 5 suites
|
|
[ "$(echo "$output" | wc -w)" -gt 5 ]
|
|
}
|
|
|
|
@test "library change triggers full suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "packages/library/cozy-lib/templates/_helpers.tpl" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$(echo "$output" | wc -w)" -gt 5 ]
|
|
}
|
|
|
|
@test "docs-only diff selects nothing" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "docs/README.md" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ -z "$output" ]
|
|
}
|
|
|
|
@test "kubernetes-application maps to the four kubernetes suites" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "packages/apps/kubernetes/values.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
echo "$output" | grep -q "kubernetes-latest"
|
|
echo "$output" | grep -q "kubernetes-previous"
|
|
# The OIDC render-side suites exercise the same kubernetes app chart, so a
|
|
# chart-only change must select them too.
|
|
echo "$output" | grep -q "kubernetes-oidc-system"
|
|
echo "$output" | grep -q "kubernetes-oidc-customconfig"
|
|
}
|
|
|
|
@test "clickhouse backup harness edit selects the suite that runs it" {
|
|
# The clickhouse suite dir holds the backup round-trip Test that executes
|
|
# examples/backups/clickhouse/run-all.sh, so an edit to that harness has to
|
|
# select `clickhouse` — the suite is what runs the scripts. Keeping the
|
|
# round-trip in the app's own suite dir (rather than a clickhouse-backup one)
|
|
# is what makes the examples/backups/<app> -> <app> mapping line up; this
|
|
# locks that alignment for clickhouse specifically.
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "examples/backups/clickhouse/run-all.sh" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$output" = "clickhouse" ]
|
|
}
|
|
|
|
@test "dashboards-only diff selects nothing (path is plural)" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "dashboards/gpu/gpu-fleet.json" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ -z "$output" ]
|
|
}
|
|
|
|
@test "shared E2E helper script triggers full suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "hack/e2e-chainsaw/_lib/run-kubernetes.sh" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$(echo "$output" | wc -w)" -gt 5 ]
|
|
}
|
|
|
|
@test "chainsaw config change triggers full suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "hack/e2e-chainsaw/.chainsaw.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$(echo "$output" | wc -w)" -gt 5 ]
|
|
}
|
|
|
|
@test "install bats triggers full suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "hack/e2e-install-cozystack.bats" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$(echo "$output" | wc -w)" -gt 5 ]
|
|
}
|
|
|
|
@test "per-suite edit selects only that suite, never escalates" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "hack/e2e-chainsaw/redis/chainsaw-test.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$output" = "redis" ]
|
|
}
|
|
|
|
@test "pull-requests workflow change triggers full suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo ".github/workflows/pull-requests.yaml" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$(echo "$output" | wc -w)" -gt 5 ]
|
|
}
|
|
|
|
@test "backup example harness edit selects its app suite" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "examples/backups/postgres/run-all.sh" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources")
|
|
[ "$output" = "postgres" ]
|
|
}
|
|
|
|
@test "backup example without a matching suite selects nothing" {
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
cp -r packages/core/platform/sources "$tmp/sources"
|
|
echo "examples/backups/no-such-app/run.sh" > "$tmp/diff"
|
|
output=$(hack/select-e2e.sh "$tmp/diff" "$tmp/sources") || true
|
|
[ -z "$output" ]
|
|
}
|