End-to-End Testing
Use the KUTTL framework to execute KubeElasti end-to-end tests in a real Kubernetes environment:
For detailed information about the E2E test framework, see tests/e2e/README.md.
Testing Flow
The E2E testing pipeline follows these detailed steps:
-
Registry Setup
- A Docker registry is started on
port 5002
- This registry will store the locally built operator and resolver images
- A Docker registry is started on
-
Kind Cluster Creation
- A Kind cluster is created using the configuration in
kind-config.yaml
- The registry is connected to the Kind network to allow image pulling
- A Kind cluster is created using the configuration in
-
Image Building and Publishing
- Elasti operator and resolver images are built from source
- Images are tagged and pushed to the local registry
-
Dependency Installation
- Istio Ingress: Sets up the ingress gateway for routing external traffic
- Prometheus: Installed for metrics collection (without Grafana to reduce overhead)
- KEDA: Installed for event-driven autoscaling capabilities
- KubeElasti: The operator and CRDs are installed using Helm
-
Test Initialization
- Persistent, lightweight resources are applied via the
kuttl-test.yaml
config - These resources are shared across all test cases
- Persistent, lightweight resources are applied via the
-
Test Execution
- Tests are executed in order based on their numerical prefix
- Each folder in the
tests/
directory represents an independent test - Each file within a test folder represents steps of that test
- Tests can run in parallel if enabled, with no cross-dependencies between test folders
-
Test Cleanup
- Resources are cleaned up after each test completes
graph TD
A[Start Registry:5002] --> B[Create Kind Cluster]
B --> C[Build & Publish Images to Registry]
C --> D[Install Dependencies]
subgraph "Dependencies Setup"
D --> D1[Install Istio Ingress]
D --> D2[Install Prometheus]
D --> D3[Install KEDA]
D --> D4[Install Elasti]
end
D1 & D2 & D3 & D4 --> E[Apply KUTTL Config Resources]
E --> F[Run KUTTL Tests]
F --> G1[Test 00-Scenario-x]
F --> Ga1[Test 01-Scenario-y]
F --> Gb1[Test 02-Scenario-z]
subgraph "Parallel 0 Test Execution"
G1 --> G2[01-Step]
G2 --> G3[02-Step]
G3 --> G4[03-Step]
end
subgraph "Parallel 1 Test Execution"
Ga1 --> Ga2[01-Step]
Ga2 --> Ga3[02-Step]
Ga3 --> Ga4[03-Step]
end
subgraph "Parallel 2 Test Execution"
Gb1 --> Gb2[01-Step]
Gb2 --> Gb3[02-Step]
Gb3 --> Gb4[03-Step]
end
G4 --> H[Cleanup Resources]
Ga4 --> H
Gb4 --> H
Test configuration
The test configuration is defined in the kuttl-test.yaml
file.
There is a timeout
field in the kuttl-test.yaml
file, which is set to 30s by default. This is the timeout for each test step.
Testing Environment
The testing environment consists of:
flowchart TB
subgraph "Kind Cluster"
subgraph "elasti namespace"
OP[Elasti Operator]
CRD[Elasti CRDs]
end
subgraph "monitoring namespace"
PROM[Prometheus Server]
end
subgraph "default namespace"
D[Test Deployment]
ES[ElastiService CR]
TF[Traffic Generator]
end
PROM -- metrics --> OP
OP -- monitors --> ES
ES -- controls --> D
TF -- generates traffic --> D
end
Adding New Tests
To add a new test scenario:
- Create a new directory in the
tests/e2e/tests/
directory following the KUTTL format,<number>-<test-name>
. - Define test steps with commands and assertions, in the directory using
<number>-<step-name>.yaml
format. - Add any supporting files or manifests needed
- To run the test individually, use:
KUTTL Test Files Structure
KUTTL tests follow a specific structure:
tests/
└── 00-elasti-setup/ # Test case (folder named with numbered prefix)
├── 00-apply.yaml # First step - apply resources, created the required scenario.
├── 01-wait.yaml # Second step - wait for resources to be ready.
└── 02-assert.yaml # Third step - assertion
- Each directory represents an individual test (This number doesn't determine order, that works only for steps inside the directory)
- Each file within a test directory represents a step in that test
- Steps follow naming convention with prefix 00-, 01-, etc. for execution ordering
- For example,
00-assert.yaml
is the first step in the test,01-apply.yaml
is the second step, and so on. - Same doesn't apply for folders in
tests/e2e/tests/
directory. We still follow the same naming for them just to keep it consistent.
- For example,
Run Single Test
Example Test Structure
# Test step to assert elasti operator, resolver and target deployment are running, and if elasti service is in serve mode.
apiVersion: apps/v1
kind: Deployment
metadata:
name: elasti-operator-controller-manager
namespace: elasti
status:
readyReplicas: 1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: elasti-resolver
namespace: elasti
status:
readyReplicas: 1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: target-deployment
namespace: default
status:
readyReplicas: 1
---
apiVersion: elasti.truefoundry.com/v1alpha1
kind: ElastiService
metadata:
name: target-elastiservice
namespace: default
status:
mode: serve
Tip
Refer to KUTTL Docs for more information.
Tips for Writing KUTTL Tests
- Naming Convention: Use numerical prefixes within test folders to know the sequence of test cases and files to control execution of the steps.
- Avoid Cross-Dependencies: Each test folder should be independent of others
- Use Timeouts Wisely: Set appropriate timeouts for operations that may take time
- Resource Sharing: Put shared resources in
kuttl-test.yaml
commands section - Debugging: Use
kubectl kuttl test --debug
for verbose output during test development