mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-03 10:37:21 +09:00
The layer below moved the unit suite to bats(1), which enforces `set -e` but not `set -u`. cozytest.sh ran every test body under `set -eu -x`, so without this a test that reads an unset variable silently sees an empty string and passes. There is no runner-level way to inject it, which is why this needs a per-file load rather than a Makefile flag. Two mechanisms were measured and rejected: a setup() defined in --setup-suite-file does not reach test files at all, and SHELLOPTS=nounset does reach them but is exported, so it also applies to the hack/*.sh scripts the tests exercise as subprocesses -- changing the behaviour of the code under test rather than the tests, and dropping two tests outright. `set -u` inside setup() is a shell option rather than an exported one, so it stays scoped to the test body. hack/test_helper.bash therefore defines the shared setup(), and all 32 unit files load it. The restoration is mutation-checked, not assumed: a canary test reading an unset variable aborts with "unbound variable" with the load in place and passes vacuously without it. Suite is 328/328 green either way, so nothing in the tree was relying on the laxer behaviour. The headers are the other half. 27 of the 32 files documented the cozytest contract in prose -- "there is no bats `run` or `$status`", "setup()/teardown() are not honored", "Run with: hack/cozytest.sh ...", title-sanitization rules from the awk parser, and instructions to keep `}` off column 0 so the parser would not truncate a test. Every one of those statements is now false or vacuous, and a false comment about the harness is worse than none: the next author reads "setup() is not honored" and hand-rolls per-test cleanup that the runner would have done. Where a constraint merely stopped binding rather than reversing, the comment says so instead of deleting the line -- the column-0 heredoc indentation and the manual status capture in migration-seaweedfs-db-adopt are both kept, now marked belt-and-braces. Claims that survived the move are left alone: `! cmd` really is still vacuous under `set -e`, since bash suppresses errexit for a negated command exactly as dash did. hack/seaweedfs-naming-audit.bats gains a note that its subject is POSIX sh executed by /bin/sh but sourced into bats' bash, so shellcheck's shell=sh directive is now the only thing guarding that gap. Refs: #3453 Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
175 lines
6.7 KiB
Bash
175 lines
6.7 KiB
Bash
#!/usr/bin/env bats
|
|
# -----------------------------------------------------------------------------
|
|
# Unit tests for hack/select-e2e.sh
|
|
#
|
|
# Runs under bats(1). Assertions are direct shell tests that exit non-zero on
|
|
# failure; `run` and `$status` are available but unused here. bats supplies
|
|
# `set -e`, and hack/test_helper.bash restores the `set -u` that cozytest.sh
|
|
# applied before #3453. Each test creates and cleans its own scratch dir
|
|
# rather than sharing a setup()/teardown() pair.
|
|
#
|
|
# Run with: bats hack/select-e2e_test.bats
|
|
# -----------------------------------------------------------------------------
|
|
|
|
load test_helper
|
|
|
|
@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 "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" ]
|
|
}
|