Files
cozystack/hack/e2e-apps/etcd.bats
Myasnikov DaniilandClaude Opus 4.8 763b85eb28 test(e2e): wait for EtcdBackupSchedule instead of a bare get in etcd.bats
Reconfiguring the Etcd CR triggers a HelmRelease upgrade that renders the EtcdBackupSchedule; hr/etcd and etcdcluster can report ready on the prior revision before the new resource materializes, so the immediate get raced to NotFound. Poll for it (timeout 120s), mirroring the CronJob wait already used later in the same test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-06-18 14:08:48 +05:00

118 lines
4.8 KiB
Bash

#!/usr/bin/env bats
# The etcd chart pins the Helm release name to 'etcd' via
# packages/extra/etcd/templates/check-release-name.yaml, so every test
# must apply its Etcd with metadata.name: etcd. setup() clears any
# prior run so tests remain independent despite the singleton name.
setup() {
kubectl -n tenant-test delete etcd.apps.cozystack.io --all --ignore-not-found --timeout=2m
# HelmRelease teardown is async relative to the CR deletion above; wait for
# downstream resources so the next test starts from a clean state.
kubectl -n tenant-test wait hr/etcd --for=delete --timeout=2m --ignore-not-found
kubectl -n tenant-test wait secret/etcd-s3-creds --for=delete --timeout=1m --ignore-not-found
kubectl -n tenant-test wait etcdbackupschedule.etcd.aenix.io/etcd --for=delete --timeout=1m --ignore-not-found
}
dump_diagnostics() {
echo "# --- diagnostics ---" >&3
kubectl -n tenant-test get etcdcluster,etcdbackupschedule,cronjob -o wide >&3 2>&1 || true
kubectl -n tenant-test describe etcdbackupschedule etcd >&3 2>&1 || true
kubectl -n cozy-etcd-operator logs -l app.kubernetes.io/name=etcd-operator --tail=100 >&3 2>&1 || true
}
# Wait until the etcd HelmRelease is reconciled by Flux and its
# condition=ready is set. kubectl wait fails immediately on a missing
# resource, so poll for existence first.
wait_etcd_hr_ready() {
timeout 60 sh -ec 'until kubectl -n tenant-test get hr/etcd >/dev/null 2>&1; do sleep 2; done'
kubectl -n tenant-test wait hr/etcd --timeout=5m --for=condition=ready
}
@test "Create Etcd" {
kubectl apply -f- <<EOF
apiVersion: apps.cozystack.io/v1alpha1
kind: Etcd
metadata:
name: etcd
namespace: tenant-test
spec:
size: 1Gi
replicas: 3
storageClass: ""
resources:
cpu: 100m
memory: 128Mi
EOF
wait_etcd_hr_ready || { dump_diagnostics; false; }
kubectl -n tenant-test wait etcdcluster.etcd.aenix.io etcd --timeout=180s --for=jsonpath='{.status.conditions[?(@.type=="Ready")].status}'=True || { dump_diagnostics; false; }
}
@test "Create Etcd with empty backup block (disabled by default)" {
kubectl apply -f- <<EOF
apiVersion: apps.cozystack.io/v1alpha1
kind: Etcd
metadata:
name: etcd
namespace: tenant-test
spec:
size: 1Gi
replicas: 3
storageClass: ""
resources:
cpu: 100m
memory: 128Mi
backup: {}
EOF
wait_etcd_hr_ready || { dump_diagnostics; false; }
# With backup disabled, neither the schedule nor the secret should be created.
! kubectl -n tenant-test get etcdbackupschedule.etcd.aenix.io etcd 2>/dev/null
! kubectl -n tenant-test get secret etcd-s3-creds 2>/dev/null
}
@test "Create Etcd with backup schedule" {
kubectl apply -f- <<EOF
apiVersion: apps.cozystack.io/v1alpha1
kind: Etcd
metadata:
name: etcd
namespace: tenant-test
spec:
size: 1Gi
replicas: 3
storageClass: ""
resources:
cpu: 100m
memory: 128Mi
backup:
enabled: true
# Schedule is chosen far in the future so no Jobs fire during the
# ~6-minute test window; this test only checks that the chart renders
# EtcdBackupSchedule/Secret and that the etcd-operator materializes a
# CronJob — it does NOT verify that backups reach S3. The endpoint
# below intentionally resolves nowhere to keep the test self-contained.
schedule: "0 0 1 1 *"
destinationPath: "s3://test-bucket/etcd-backups/"
endpointURL: "http://no-such-endpoint.invalid:9000"
region: "us-east-1"
forcePathStyle: true
s3AccessKey: "e2e-access-key"
s3SecretKey: "e2e-secret-key"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
EOF
wait_etcd_hr_ready || { dump_diagnostics; false; }
kubectl -n tenant-test wait etcdcluster.etcd.aenix.io etcd --timeout=180s --for=jsonpath='{.status.conditions[?(@.type=="Ready")].status}'=True || { dump_diagnostics; false; }
# Reconfiguring the Etcd CR triggers a HelmRelease upgrade that renders the
# EtcdBackupSchedule; hr/etcdcluster readiness can report ready on the prior
# revision before that resource materializes, so poll for it instead of a
# bare get (same pattern this test already uses for the CronJob below).
timeout 120 sh -ec "until kubectl -n tenant-test get etcdbackupschedule.etcd.aenix.io etcd >/dev/null 2>&1; do sleep 2; done" || { dump_diagnostics; false; }
# Verify the region field propagated to the EtcdBackupSchedule.
REGION=$(kubectl -n tenant-test get etcdbackupschedule.etcd.aenix.io etcd -o jsonpath='{.spec.destination.s3.region}')
[ "$REGION" = "us-east-1" ]
kubectl -n tenant-test get secret etcd-s3-creds -o jsonpath='{.data.AWS_ACCESS_KEY_ID}' | base64 -d | grep -q '^e2e-access-key$'
# The etcd-operator generates a CronJob from the EtcdBackupSchedule. Wait for it.
timeout 120 sh -ec "until [ \"\$(kubectl -n tenant-test get cronjob -l etcd.aenix.io/etcdbackupschedule-name=etcd -o jsonpath='{.items[*].metadata.name}' 2>/dev/null)\" != '' ]; do sleep 5; done" || { dump_diagnostics; false; }
}