mirror of
https://github.com/lukaszraczylo/kubemirror.git
synced 2026-06-26 04:43:12 +00:00
CRD discovery, log noise reduction, e2e tests
This commit is contained in:
Executable
+557
@@ -0,0 +1,557 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Comprehensive E2E Test Suite for KubeMirror
|
||||
# Tests all scenarios systematically using the test framework
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/common.sh"
|
||||
source "$SCRIPT_DIR/test-framework.sh"
|
||||
|
||||
TEST_NAME="Comprehensive E2E Tests"
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up all test resources"
|
||||
|
||||
# Delete all test secrets, configmaps, and CRDs
|
||||
kubectl delete secret,configmap -n default -l test-resource=e2e --ignore-not-found=true 2>/dev/null || true
|
||||
kubectl delete middleware.traefik.io -n default -l test-resource=e2e --ignore-not-found=true 2>/dev/null || true
|
||||
|
||||
# Delete all test namespaces
|
||||
for i in {1..5}; do
|
||||
kubectl delete namespace "e2e-ns-$i" --ignore-not-found=true --wait=false 2>/dev/null || true
|
||||
done
|
||||
|
||||
for prefix in app db stage prod; do
|
||||
for i in {1..3}; do
|
||||
kubectl delete namespace "e2e-${prefix}-${i}" --ignore-not-found=true --wait=false 2>/dev/null || true
|
||||
done
|
||||
done
|
||||
|
||||
kubectl delete namespace e2e-labeled e2e-unlabeled e2e-test-ns --ignore-not-found=true --wait=false 2>/dev/null || true
|
||||
|
||||
sleep 5
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
log_info "Starting $TEST_NAME"
|
||||
|
||||
# Clean up before starting
|
||||
cleanup
|
||||
sleep 3
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 1: Source without labels/annotations
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "1: Source created without labels or annotations"
|
||||
|
||||
create_test_namespace e2e-ns-1
|
||||
create_test_namespace e2e-ns-2
|
||||
|
||||
create_source secret test-no-labels-1 default false false "" "data-v1"
|
||||
|
||||
sleep 3
|
||||
|
||||
# Should NOT create mirrors (no enabled label or sync annotation)
|
||||
verify_mirrors_not_exist secret test-no-labels-1 e2e-ns-1 e2e-ns-2
|
||||
|
||||
complete_test_scenario "1" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 2: Labels added to source
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "2: Add enabled label to source (no sync annotation yet)"
|
||||
|
||||
update_source_labels secret test-no-labels-1 default true
|
||||
|
||||
sleep 3
|
||||
|
||||
# Still no mirrors (sync annotation required)
|
||||
verify_mirrors_not_exist secret test-no-labels-1 e2e-ns-1 e2e-ns-2
|
||||
|
||||
complete_test_scenario "2" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 3: Sync annotation added to labeled source
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "3: Add sync annotation with target namespaces"
|
||||
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-ns-1,e2e-ns-2"
|
||||
|
||||
# Now mirrors should be created
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-ns-1 e2e-ns-2
|
||||
verify_mirror_data secret test-no-labels-1 default e2e-ns-1 "data-v1"
|
||||
|
||||
complete_test_scenario "3" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 4: Source content modified
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "4: Modify source data content"
|
||||
|
||||
update_source_data secret test-no-labels-1 default "data-v2-updated"
|
||||
|
||||
sleep 20
|
||||
|
||||
# Mirrors should be updated
|
||||
verify_mirror_data secret test-no-labels-1 default e2e-ns-1 "data-v2-updated"
|
||||
verify_mirror_data secret test-no-labels-1 default e2e-ns-2 "data-v2-updated"
|
||||
|
||||
complete_test_scenario "4" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 5: Add namespace to target list
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "5: Add namespace to target-namespaces list"
|
||||
|
||||
create_test_namespace e2e-ns-3
|
||||
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-ns-1,e2e-ns-2,e2e-ns-3"
|
||||
|
||||
# New namespace should receive mirror
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-ns-1 e2e-ns-2 e2e-ns-3
|
||||
verify_mirror_data secret test-no-labels-1 default e2e-ns-3 "data-v2-updated"
|
||||
|
||||
complete_test_scenario "5" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 6: Remove namespace from target list
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "6: Remove namespace from target-namespaces list"
|
||||
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-ns-1,e2e-ns-2"
|
||||
|
||||
# Orphaned mirror in e2e-ns-3 should be deleted
|
||||
verify_orphan_cleanup secret test-no-labels-1 e2e-ns-3
|
||||
|
||||
# Others still exist
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-ns-1 e2e-ns-2
|
||||
|
||||
complete_test_scenario "6" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 7: Change target-namespaces from explicit list to pattern
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "7: Change from explicit list to pattern"
|
||||
|
||||
create_test_namespace e2e-app-1
|
||||
create_test_namespace e2e-app-2
|
||||
create_test_namespace e2e-db-1
|
||||
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-app-*"
|
||||
|
||||
# Should remove mirrors from e2e-ns-1, e2e-ns-2
|
||||
verify_orphan_cleanup secret test-no-labels-1 e2e-ns-1 e2e-ns-2
|
||||
|
||||
# Should create mirrors in e2e-app-*
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-app-1 e2e-app-2
|
||||
|
||||
# Should NOT create in e2e-db-1
|
||||
verify_mirrors_not_exist secret test-no-labels-1 e2e-db-1
|
||||
|
||||
complete_test_scenario "7" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 8: Multiple patterns
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "8: Multiple patterns in target-namespaces"
|
||||
|
||||
create_test_namespace e2e-db-2
|
||||
create_test_namespace e2e-stage-1
|
||||
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-app-*,e2e-db-*"
|
||||
|
||||
# Should add mirrors to e2e-db-*
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-db-1 e2e-db-2
|
||||
|
||||
# Should still have e2e-app-*
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-app-1 e2e-app-2
|
||||
|
||||
# Should NOT have e2e-stage-*
|
||||
verify_mirrors_not_exist secret test-no-labels-1 e2e-stage-1
|
||||
|
||||
complete_test_scenario "8" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 9: Sync annotation set to false
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "9: Set sync annotation to false"
|
||||
|
||||
update_source_annotations secret test-no-labels-1 default false ""
|
||||
|
||||
# All mirrors should be deleted
|
||||
verify_orphan_cleanup secret test-no-labels-1 e2e-app-1 e2e-app-2 e2e-db-1 e2e-db-2
|
||||
|
||||
complete_test_scenario "9" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 10: Enabled label set to false
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "10: Set enabled label to false"
|
||||
|
||||
# Re-enable sync first
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-app-1"
|
||||
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-app-1
|
||||
|
||||
# Now disable via label
|
||||
update_source_labels secret test-no-labels-1 default false
|
||||
|
||||
sleep 3
|
||||
|
||||
# Mirror should be removed (label filtering)
|
||||
verify_orphan_cleanup secret test-no-labels-1 e2e-app-1
|
||||
|
||||
complete_test_scenario "10" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 11: Pattern with new namespace created
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "11: Create new namespace matching existing pattern"
|
||||
|
||||
# Re-enable the source
|
||||
update_source_labels secret test-no-labels-1 default true
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-prod-*"
|
||||
|
||||
create_test_namespace e2e-prod-1
|
||||
|
||||
# Should automatically create mirror in new namespace
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-prod-1
|
||||
|
||||
# Create another matching namespace
|
||||
create_test_namespace e2e-prod-2
|
||||
|
||||
# Should also get the mirror
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-prod-2
|
||||
|
||||
complete_test_scenario "11" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 12: 'all' keyword without namespace label (opt-OUT model)
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "12: Source with 'all' keyword, namespace without allow-mirrors label"
|
||||
|
||||
create_source configmap test-all-no-label default true true "all" "all-data-v1"
|
||||
|
||||
create_test_namespace e2e-unlabeled
|
||||
|
||||
sleep 5
|
||||
|
||||
# SHOULD create mirror (opt-OUT model: namespaces without label get mirrors by default)
|
||||
verify_mirrors_exist configmap test-all-no-label e2e-unlabeled
|
||||
verify_mirror_data configmap test-all-no-label default e2e-unlabeled "all-data-v1"
|
||||
|
||||
complete_test_scenario "12" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 13: Set allow-mirrors=false to opt-out
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "13: Set allow-mirrors=false on namespace (explicit opt-OUT)"
|
||||
|
||||
update_namespace_labels e2e-unlabeled false
|
||||
|
||||
sleep 5
|
||||
|
||||
# Mirror should be deleted (explicit opt-OUT)
|
||||
verify_orphan_cleanup configmap test-all-no-label e2e-unlabeled
|
||||
|
||||
complete_test_scenario "13" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 14: Change allow-mirrors from false to true
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "14: Change allow-mirrors label from false to true"
|
||||
|
||||
update_namespace_labels e2e-unlabeled true
|
||||
|
||||
sleep 5
|
||||
|
||||
# Mirror should be recreated
|
||||
verify_mirrors_exist configmap test-all-no-label e2e-unlabeled
|
||||
verify_mirror_data configmap test-all-no-label default e2e-unlabeled "all-data-v1"
|
||||
|
||||
complete_test_scenario "14" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 15: Remove allow-mirrors label (back to default opt-IN)
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "15: Remove allow-mirrors label from namespace"
|
||||
|
||||
update_namespace_labels e2e-unlabeled ""
|
||||
|
||||
sleep 5
|
||||
|
||||
# Mirror should STILL exist (default is opt-IN, not opt-OUT)
|
||||
verify_mirrors_exist configmap test-all-no-label e2e-unlabeled
|
||||
verify_mirror_data configmap test-all-no-label default e2e-unlabeled "all-data-v1"
|
||||
|
||||
complete_test_scenario "15" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 16: Target namespace deleted
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "16: Delete target namespace"
|
||||
|
||||
create_test_namespace e2e-ns-4
|
||||
update_source_annotations secret test-no-labels-1 default true "e2e-ns-4,e2e-prod-1"
|
||||
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-ns-4 e2e-prod-1
|
||||
|
||||
# Delete one of the target namespaces
|
||||
delete_namespace e2e-ns-4
|
||||
|
||||
sleep 3
|
||||
|
||||
# Other mirror should still exist
|
||||
verify_mirrors_exist secret test-no-labels-1 e2e-prod-1
|
||||
|
||||
complete_test_scenario "16" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 17: Recreate deleted target namespace
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "17: Recreate deleted target namespace"
|
||||
|
||||
# Wait for namespace to be fully deleted
|
||||
sleep 5
|
||||
|
||||
create_test_namespace e2e-ns-4
|
||||
|
||||
# Mirror should be recreated automatically (namespace reconciler + pattern matching)
|
||||
# Note: This requires namespace reconciler to be working
|
||||
wait_for_resource secret test-no-labels-1 e2e-ns-4 30 || log_warn "Mirror not auto-created (may require source update)"
|
||||
|
||||
complete_test_scenario "17" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 18: Source deleted
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "18: Delete source resource"
|
||||
|
||||
create_test_namespace e2e-ns-5
|
||||
create_source secret test-delete-source default true true "e2e-ns-5" "delete-test"
|
||||
|
||||
verify_mirrors_exist secret test-delete-source e2e-ns-5
|
||||
|
||||
# Delete source
|
||||
kubectl delete secret test-delete-source -n default
|
||||
|
||||
# Mirror should be cascade deleted
|
||||
verify_orphan_cleanup secret test-delete-source e2e-ns-5
|
||||
|
||||
complete_test_scenario "18" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 19: Target manually deleted (should be recreated)
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "19: Manually delete target mirror (should recreate)"
|
||||
|
||||
create_source secret test-recreate default true true "e2e-prod-1" "recreate-data"
|
||||
|
||||
verify_mirrors_exist secret test-recreate e2e-prod-1
|
||||
|
||||
# Manually delete the mirror
|
||||
kubectl delete secret test-recreate -n e2e-prod-1
|
||||
|
||||
# Should be automatically recreated
|
||||
wait_for_resource secret test-recreate e2e-prod-1 15
|
||||
|
||||
assert_resource_exists secret test-recreate e2e-prod-1
|
||||
|
||||
complete_test_scenario "19" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 20: ConfigMap with same test patterns
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "20: ConfigMap with pattern matching"
|
||||
|
||||
create_source configmap test-cm-pattern default true true "e2e-app-*" "cm-data-v1"
|
||||
|
||||
verify_mirrors_exist configmap test-cm-pattern e2e-app-1 e2e-app-2
|
||||
|
||||
# Update content
|
||||
update_source_data configmap test-cm-pattern default "cm-data-v2"
|
||||
|
||||
sleep 20
|
||||
|
||||
verify_mirror_data configmap test-cm-pattern default e2e-app-1 "cm-data-v2"
|
||||
|
||||
# Change pattern
|
||||
update_source_annotations configmap test-cm-pattern default true "e2e-db-*"
|
||||
|
||||
verify_orphan_cleanup configmap test-cm-pattern e2e-app-1 e2e-app-2
|
||||
verify_mirrors_exist configmap test-cm-pattern e2e-db-1 e2e-db-2
|
||||
|
||||
complete_test_scenario "20" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 21: Mix of explicit and pattern
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "21: Mix of explicit namespaces and patterns"
|
||||
|
||||
create_test_namespace e2e-test-ns
|
||||
|
||||
create_source secret test-mixed default true true "e2e-test-ns,e2e-stage-*" "mixed-data"
|
||||
|
||||
create_test_namespace e2e-stage-2
|
||||
|
||||
verify_mirrors_exist secret test-mixed e2e-test-ns e2e-stage-1 e2e-stage-2
|
||||
|
||||
# Remove explicit, keep pattern
|
||||
update_source_annotations secret test-mixed default true "e2e-stage-*"
|
||||
|
||||
verify_orphan_cleanup secret test-mixed e2e-test-ns
|
||||
verify_mirrors_exist secret test-mixed e2e-stage-1 e2e-stage-2
|
||||
|
||||
complete_test_scenario "21" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 22: Sync annotation removed completely
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "22: Remove sync annotation completely"
|
||||
|
||||
verify_mirrors_exist secret test-mixed e2e-stage-1 e2e-stage-2
|
||||
|
||||
update_source_annotations secret test-mixed default "" ""
|
||||
|
||||
verify_orphan_cleanup secret test-mixed e2e-stage-1 e2e-stage-2
|
||||
|
||||
complete_test_scenario "22" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# SCENARIO 23: Traefik Middleware CRD (test generic CRD support)
|
||||
#===============================================================================
|
||||
|
||||
run_test_scenario "23: Traefik Middleware CRD with spec updates"
|
||||
|
||||
# Create Traefik Middleware CRD manually (CRDs aren't supported by create_source helper)
|
||||
cat <<EOF | kubectl apply -f - >/dev/null 2>&1
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-middleware
|
||||
namespace: default
|
||||
labels:
|
||||
kubemirror.raczylo.com/enabled: "true"
|
||||
test-resource: e2e
|
||||
annotations:
|
||||
kubemirror.raczylo.com/sync: "true"
|
||||
kubemirror.raczylo.com/target-namespaces: "e2e-app-1,e2e-app-2"
|
||||
spec:
|
||||
basicAuth:
|
||||
secret: auth-secret-v1
|
||||
removeHeader: false
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Test-Header: "test-value-v1"
|
||||
EOF
|
||||
|
||||
sleep 5
|
||||
|
||||
# Verify mirrors created with correct spec
|
||||
verify_mirrors_exist middleware.traefik.io test-middleware e2e-app-1 e2e-app-2
|
||||
|
||||
# Verify mirror spec content (check one of the spec fields)
|
||||
app1_secret=$(kubectl get middleware test-middleware -n e2e-app-1 -o jsonpath='{.spec.basicAuth.secret}' 2>/dev/null || echo "")
|
||||
if [ "$app1_secret" = "auth-secret-v1" ]; then
|
||||
log_success "Mirror spec in e2e-app-1 matches expected: auth-secret-v1"
|
||||
((PASS_COUNT++))
|
||||
else
|
||||
log_fail "Mirror spec in e2e-app-1 does not match. Expected: auth-secret-v1, Got: $app1_secret"
|
||||
((FAIL_COUNT++))
|
||||
fi
|
||||
|
||||
# Update the Middleware spec
|
||||
cat <<EOF | kubectl apply -f - >/dev/null 2>&1
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-middleware
|
||||
namespace: default
|
||||
labels:
|
||||
kubemirror.raczylo.com/enabled: "true"
|
||||
test-resource: e2e
|
||||
annotations:
|
||||
kubemirror.raczylo.com/sync: "true"
|
||||
kubemirror.raczylo.com/target-namespaces: "e2e-app-1,e2e-app-2"
|
||||
spec:
|
||||
basicAuth:
|
||||
secret: auth-secret-v2-updated
|
||||
removeHeader: true
|
||||
headers:
|
||||
customRequestHeaders:
|
||||
X-Test-Header: "test-value-v2-updated"
|
||||
X-New-Header: "new-value"
|
||||
EOF
|
||||
|
||||
sleep 20
|
||||
|
||||
# Verify mirror spec was updated
|
||||
app1_secret_updated=$(kubectl get middleware test-middleware -n e2e-app-1 -o jsonpath='{.spec.basicAuth.secret}' 2>/dev/null || echo "")
|
||||
if [ "$app1_secret_updated" = "auth-secret-v2-updated" ]; then
|
||||
log_success "Mirror spec in e2e-app-1 updated correctly: auth-secret-v2-updated"
|
||||
((PASS_COUNT++))
|
||||
else
|
||||
log_fail "Mirror spec in e2e-app-1 not updated. Expected: auth-secret-v2-updated, Got: $app1_secret_updated"
|
||||
((FAIL_COUNT++))
|
||||
fi
|
||||
|
||||
app1_header=$(kubectl get middleware test-middleware -n e2e-app-1 -o jsonpath='{.spec.headers.customRequestHeaders.X-New-Header}' 2>/dev/null || echo "")
|
||||
if [ "$app1_header" = "new-value" ]; then
|
||||
log_success "Mirror spec headers in e2e-app-1 updated correctly: new-value"
|
||||
((PASS_COUNT++))
|
||||
else
|
||||
log_fail "Mirror spec headers in e2e-app-1 not updated. Expected: new-value, Got: $app1_header"
|
||||
((FAIL_COUNT++))
|
||||
fi
|
||||
|
||||
# Change target namespaces pattern
|
||||
kubectl annotate middleware test-middleware -n default \
|
||||
kubemirror.raczylo.com/target-namespaces="e2e-db-*" --overwrite >/dev/null 2>&1
|
||||
|
||||
sleep 10
|
||||
|
||||
# Verify old mirrors cleaned up
|
||||
verify_orphan_cleanup middleware.traefik.io test-middleware e2e-app-1 e2e-app-2
|
||||
|
||||
# Verify new mirrors created
|
||||
verify_mirrors_exist middleware.traefik.io test-middleware e2e-db-1 e2e-db-2
|
||||
|
||||
# Clean up CRD
|
||||
kubectl delete middleware test-middleware -n default --ignore-not-found=true >/dev/null 2>&1
|
||||
|
||||
complete_test_scenario "23" "pass"
|
||||
|
||||
#===============================================================================
|
||||
# Final Summary
|
||||
#===============================================================================
|
||||
|
||||
echo ""
|
||||
echo "======================================"
|
||||
echo "Comprehensive E2E Test Complete"
|
||||
echo "======================================"
|
||||
|
||||
print_summary
|
||||
Reference in New Issue
Block a user