Moritz Johner 62ad1ff507 feat: gate v2 providers behind explicit opt-in 3 месяцев назад
..
README.md ea19156e72 feat: provider v2 3 месяцев назад
fake_cluster_provider_test.go ea19156e72 feat: provider v2 3 месяцев назад
fake_test.go ea19156e72 feat: provider v2 3 месяцев назад
helpers.go 62ad1ff507 feat: gate v2 providers behind explicit opt-in 3 месяцев назад
kubernetes_capabilities_test.go ea19156e72 feat: provider v2 3 месяцев назад
kubernetes_cluster_provider_test.go ea19156e72 feat: provider v2 3 месяцев назад
kubernetes_delete_test.go ea19156e72 feat: provider v2 3 месяцев назад
kubernetes_find_test.go ea19156e72 feat: provider v2 3 месяцев назад
kubernetes_get_test.go ea19156e72 feat: provider v2 3 месяцев назад
kubernetes_push_test.go ea19156e72 feat: provider v2 3 месяцев назад
metrics_helpers.go ea19156e72 feat: provider v2 3 месяцев назад
metrics_test.go ea19156e72 feat: provider v2 3 месяцев назад
suite_test.go ea19156e72 feat: provider v2 3 месяцев назад

README.md

External Secrets Operator V2 E2E Test Suite

This directory contains End-to-End tests for ESO V2.

Test Coverage

✅ Implemented Tests

Test Case Description Status
Basic Secret Sync Cross-namespace secret synchronization
Key Extraction Extract specific keys with data[]
DataFrom Full secret extraction with dataFrom[]
Secret Updates Automatic refresh when source changes
Deletion Cleanup Owner policy cleanup on deletion
Error Handling Error conditions for missing secrets

🚧 Future Test Coverage

Test Case Priority Notes
ClusterSecretStore P1 Cross-namespace store
Multiple providers P1 AWS, GCP, Azure providers
Secret templates P2 Template transformations
Generators P2 Generator integration
PushSecret P2 Reverse sync
Concurrency P2 Multiple ExternalSecrets
TLS/mTLS P3 Provider authentication
Metrics P3 Prometheus metrics validation
Performance P3 Latency and throughput

Running Tests

All V2 Tests

make test.e2e.v2

Specific Tests

cd e2e

# Run single test
ginkgo -v --focus="should sync secrets across namespaces" ./suites/v2/

# Run with labels
ginkgo -v --label-filter="v2 && !slow" ./suites/v2/

# Verbose output
ginkgo -vv ./suites/v2/

Test Architecture

Framework Components

┌─────────────────────────────────────┐
│       Ginkgo Test Suite             │
│   (suite_test.go, v2_test.go)       │
└─────────────────┬───────────────────┘
                  │
                  ▼
┌─────────────────────────────────────┐
│      E2E Framework                  │
│   (framework/framework.go)          │
│   - Kubernetes client               │
│   - Test utilities                  │
└─────────────────┬───────────────────┘
                  │
                  ▼
┌─────────────────────────────────────┐
│      ESO V2 Addon                   │
│   (framework/addon/eso_v2.go)       │
│   - Controller installation         │
│   - Provider installation           │
│   - RBAC setup                      │
└─────────────────────────────────────┘

Test Flow

1. BeforeSuite
   ├── Initialize framework
   ├── Install ESO V2 controller
   ├── Install Kubernetes provider
   └── Wait for ready

2. BeforeEach (per test)
   ├── Create test namespace
   └── Create source secret

3. Test Execution
   ├── Create SecretStore
   ├── Create ExternalSecret
   ├── Wait for sync (Eventually)
   └── Assert results (Gomega)

4. AfterEach (per test)
   └── Delete test namespace

5. AfterSuite
   └── Uninstall ESO V2

Test Patterns

Creating Resources

secretStore := &ssv2alpha1.SecretStore{
    ObjectMeta: metav1.ObjectMeta{
        Name:      "test-store",
        Namespace: namespace,
    },
    Spec: ssv2alpha1.SecretStoreSpec{
        Provider: ssv2alpha1.ProviderConfig{
            Address: "kubernetes-provider:5000",
        },
    },
}
Expect(f.CRClient.Create(ctx, secretStore)).To(Succeed())

Waiting for Conditions

Eventually(func() bool {
    var ss ssv2alpha1.SecretStore
    err := f.CRClient.Get(ctx, client.ObjectKeyFromObject(secretStore), &ss)
    if err != nil {
        return false
    }
    
    for _, cond := range ss.Status.Conditions {
        if cond.Type == "Ready" && cond.Status == metav1.ConditionTrue {
            return true
        }
    }
    return false
}, 30*time.Second, 1*time.Second).Should(BeTrue())

Validating Data

var targetSecret corev1.Secret
Expect(f.CRClient.Get(ctx, targetKey, &targetSecret)).To(Succeed())
Expect(targetSecret.Data).To(HaveKeyWithValue("username", []byte("admin")))

Debugging

Enable Verbose Logging

# Ginkgo verbose
ginkgo -v ./suites/v2/

# Very verbose (includes test internals)
ginkgo -vv ./suites/v2/

# Trace level (framework logs)
ginkgo -v -trace ./suites/v2/

View Controller Logs

kubectl logs -n external-secrets-system \
  -l app.kubernetes.io/name=external-secrets-v2 \
  --tail=100 -f

View Provider Logs

kubectl logs -n external-secrets-system \
  -l app.kubernetes.io/name=kubernetes-provider \
  --tail=100 -f

Inspect Resources

# List all test namespaces
kubectl get ns | grep v2-test

# Check SecretStores
kubectl get secretstore --all-namespaces

# Check ExternalSecrets
kubectl get externalsecret --all-namespaces

# Describe for details
kubectl describe externalsecret <name> -n <namespace>

Keep Environment After Failure

# Run without cleanup
ginkgo -v ./suites/v2/ || true

# Inspect manually
kubectl get all --all-namespaces | grep v2-test

# Manual cleanup when done
kubectl delete ns external-secrets-system

Adding New Tests

Test Template

It("should <test description>", Label("v2", "feature-name"), func() {
    By("step 1: setup")
    // Create resources
    
    By("step 2: action")
    // Trigger behavior
    
    By("step 3: verification")
    Eventually(func() bool {
        // Check condition
        return true
    }, timeout, interval).Should(BeTrue())
    
    By("step 4: assert")
    // Final assertions
    Expect(actual).To(Equal(expected))
})

Checklist

  • Descriptive test name
  • Appropriate labels
  • Clear By() steps
  • Use Eventually() for async
  • Proper cleanup in AfterEach()
  • Meaningful assertions
  • Error messages for failures

CI Integration

Tests run automatically on:

  • Pull requests touching V2 code
  • Nightly builds
  • Release branches

GitHub Actions

- name: Run V2 E2E
  run: make test.e2e.v2

Required Checks

  • All tests pass
  • No resource leaks
  • Controller logs clean
  • No memory/CPU spikes

Metrics

Current Stats

  • Test Files: 2
  • Test Cases: 6
  • Coverage: Core functionality
  • Duration: ~2-3 minutes

Performance Benchmarks

Operation P50 P95 P99
SecretStore ready 2s 5s 10s
ExternalSecret sync 3s 8s 15s
Secret update 5s 12s 20s

Troubleshooting

Test Fails: "SecretStore not ready"

Cause: Provider not reachable
Fix: Check provider pod status

kubectl get pods -n external-secrets-system
kubectl logs -n external-secrets-system -l app.kubernetes.io/name=kubernetes-provider

Test Fails: "Secret not synced"

Cause: Source secret missing or permissions
Fix: Verify source secret exists

kubectl get secret -n <source-namespace>
kubectl get sa -n external-secrets-system

Test Timeout

Cause: Slow cluster or image pull
Fix: Increase timeout or pre-pull images

Eventually(..., 60*time.Second, ...).Should(...)

Resources