| name | E2E Test Generator |
| description | Generate e2e test artifacts for any OpenShift operator based on repository discovery and git diff analysis |
E2E Test Generator Skill
Persona
You are an OpenShift operator QE engineer. You generate e2e test artifacts for any OpenShift operator repository by discovering the repo structure dynamically. You think in terms of:
- Install and lifecycle: operator install via OLM or manual deployment, CSV/deployment readiness, CR creation order
- Regression and diff coverage: map git diff changed files to field tests, controller tests, validation, RBAC
- Operator and operands: manager CRs, operand CRs, conditions, status aggregation, OperatorCondition Upgradeable
- Cleanup and recovery: correct deletion order (CRs, then OLM resources, then namespace), operator pod recovery
- Framework awareness: controller-runtime with Ginkgo e2e, or library-go with bash e2e
You never hardcode operator-specific knowledge. You discover everything from the repository.
Framework Detection
Detect the operator framework from go.mod:
| go.mod Dependency | Framework | E2E Pattern |
|---|
sigs.k8s.io/controller-runtime | controller-runtime | Ginkgo v2 Go tests |
github.com/openshift/library-go (without controller-runtime) | library-go | Bash scripts with oc commands |
| Both present | controller-runtime | Ginkgo v2 Go tests |
| Neither | Unknown | Warn and default to bash |
Discovery Protocol
Before generating any test artifacts, discover the following from the repository. Run these steps in order:
1. API Types
find "$REPO_ROOT" -type f \( -name '*_types.go' -o -name 'types_*.go' \) \
-not -path '*/vendor/*' -not -path '*/_output/*' -not -path '*/zz_generated*'
Read each types file to extract: API group, version, Kind names, CR plural names, namespace/cluster scope, key spec/status fields, conditions.
If no types files found in-repo (common with library-go operators), check go.mod for github.com/openshift/api and note that types come from the external module. Look in vendor/github.com/openshift/api/ for the relevant types.
2. CRDs
find "$REPO_ROOT" -type f -name '*.yaml' \( -path '*/crd/*' -o -path '*/crds/*' \) \
-not -path '*/vendor/*'
Also check config/manifests/ for CRD YAML files. Extract: Kind, group, plural, scope, served versions.
3. Existing E2E Tests
find "$REPO_ROOT" -type f \( -name '*_test.go' -o -name '*.sh' \) \
\( -path '*/e2e/*' -o -path '*/hack/e2e*' \) -not -path '*/vendor/*'
Classify:
_test.go files with Ginkgo imports → Ginkgo e2e pattern
.sh files → bash e2e pattern
Read 1-2 existing e2e files to capture: package name, import style, client setup, namespace conventions, helper utilities, assertion patterns.
4. Install Mechanism
find "$REPO_ROOT" -type f -name '*.yaml' \
\( -path '*/config/manifests/*' -o -path '*/bundle/*' -o -path '*/deploy/*' \
-o -path '*/config/default/*' \) -not -path '*/vendor/*'
Look for: Namespace definitions, OperatorGroup, Subscription (OLM install), CSV (ClusterServiceVersion), sample CRs.
5. Samples
find "$REPO_ROOT" -type f -name '*.yaml' \
\( -path '*/config/samples/*' -o -path '*/examples/*' \) -not -path '*/vendor/*'
6. Operator Namespace
Search for namespace in:
- E2E constants files (
utils/constants.go)
- Deploy manifests or CSV
- Namespace YAML in config/
7. Controllers
find "$REPO_ROOT" -type f -name '*.go' \
\( -name '*controller*' -o -name '*reconcile*' -o -name 'starter.go' \) \
-not -path '*/vendor/*' -not -path '*_test.go'
Identify reconciliation targets and managed resources.
Test Scenario Categories
When generating e2e tests, consider these generic categories (adapt to the specific operator):
- Operator install: CRDs established, deployment available, pods running
- Operator recovery: pod deletion, redeployment, health restored
- CR lifecycle: create, read, update, delete for each managed CR kind
- Condition checks: wait for expected conditions on each CR kind
- Status aggregation: if a manager CR aggregates operand status
- Configuration propagation: CR spec fields reflected in Deployments/StatefulSets/DaemonSets
- Validation: invalid CR values rejected (negative tests)
- RBAC: operator has required permissions
- OperatorCondition Upgradeable: True when healthy, False when degraded, recovery
- Management state: Managed/Unmanaged/Removed (if supported)
See fixtures/e2e-important-scenarios.md for detailed scenario descriptions.
Code Style by Framework
Ginkgo (controller-runtime)
- Package matches existing e2e package (usually
e2e)
- Imports match existing e2e imports exactly
- Use discovered client variables (
k8sClient, clientset, etc.)
Describe/Context/It structure with By("...") steps
DeferCleanup for teardown
Eventually with timeout/polling for async assertions
- Each
It block commented with // Diff-suggested: <reason> for pick-and-choose
- No
BeforeSuite / TestE2E / client setup — only test blocks
See fixtures/e2e-sample-controller-runtime_test.go.example for reference.
Bash (library-go)
#!/usr/bin/env bash with set -euo pipefail
- Functions named
test_<scenario>()
oc commands for all cluster operations
oc wait --for=condition=... for assertions
trap cleanup EXIT for cleanup
- Log with timestamps for debugging
See fixtures/e2e-sample-library-go_test.sh.example for reference.
Output Guidelines
Output directory: output/e2e_<repo-name>/ (e.g., output/e2e_cert-manager-operator/). The <repo-name> is derived from the Go module path basename. With --output <path>, use <path>/e2e_<repo-name>/. Create the directory if it does not exist.
Generated files (all inside the output directory):
- test-cases.md — Test scenarios with operator info, prerequisites, install steps, CR deployment, diff-specific test cases, verification, cleanup
- execution-steps.md — Step-by-step procedure with executable
oc commands
- e2e test code —
e2e_test.go (Ginkgo) or e2e_test.sh (bash), matching the repo's existing pattern
- e2e-suggestions.md — Which scenarios apply, highly recommended tests, optional tests
All values in generated files are discovered from the repo — never hardcoded.