Skip to content

Commit 6416ea5

Browse files
author
Moritz Clasmeier
committed
OLM Tests
1 parent b2a7239 commit 6416ea5

3 files changed

Lines changed: 320 additions & 2 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ test-e2e: build ## Run end-to-end tests (requires kubectl context and cluster ac
9090
echo "❌ skopeo not found. Please install skopeo for E2E tests."; \
9191
exit 1; \
9292
fi
93-
$(GOTEST) -v -tags=e2e -timeout=120m ./tests/e2e/...
93+
$(GOTEST) -v -tags=e2e -timeout=120m -parallel=1 ./tests/e2e/...
9494

9595
.PHONY: test-all
9696
test-all: test test-e2e ## Run all tests (unit + e2e)

tests/README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,43 @@ make test-e2e
4141

4242
Or directly with go:
4343
```bash
44-
go test -v -tags=e2e -timeout=30m ./tests/e2e/...
44+
# Note: -parallel=1 ensures tests run sequentially to avoid conflicts
45+
go test -v -tags=e2e -timeout=30m -parallel=1 ./tests/e2e/...
4546
```
4647

4748
### Environment Variables for E2E Tests
4849

4950
- `MAIN_IMAGE_TAG` - ACS image tag to use (default: "4.8.2")
5051
- `SKIP_OPERATOR_TESTS` - Skip operator-based tests if set
52+
- `SKIP_OLM_TESTS` - Skip OLM-specific tests if set (useful when OLM is not available)
5153
- `SKIP_IMAGE_VERIFICATION` - Skip image verification if set to "true"
5254

5355
Example:
5456
```bash
5557
MAIN_IMAGE_TAG=4.9.0 make test-e2e
5658
```
5759

60+
### Running OLM Switching Tests
61+
62+
The OLM switching tests verify that roxie can properly switch between OLM and non-OLM operator deployment modes. These tests:
63+
- Require OLM installed in the cluster
64+
- Require sufficient cluster resources
65+
- Test all switching scenarios: OLM↔non-OLM, version upgrades, multi-component deployments
66+
67+
Run OLM tests:
68+
```bash
69+
# Run all OLM tests (they run sequentially via -parallel=1)
70+
go test -v -tags=e2e -timeout=120m -parallel=1 ./tests/e2e/ -run TestOLM
71+
72+
# Run specific OLM test
73+
go test -v -tags=e2e -timeout=60m -parallel=1 ./tests/e2e/ -run TestOLMToNonOLMSwitch
74+
```
75+
76+
Skip OLM tests if OLM is not available:
77+
```bash
78+
SKIP_OLM_TESTS=1 go test -v -tags=e2e -timeout=30m -parallel=1 ./tests/e2e/
79+
```
80+
5881
## Test Organization
5982

6083
### Unit Tests
@@ -108,10 +131,14 @@ func TestMyFunction(t *testing.T) {
108131
package e2e
109132

110133
import (
134+
"os"
111135
"testing"
112136
"time"
113137
)
114138

139+
// Note: All e2e tests run sequentially via the -parallel=1 flag in the Makefile
140+
// to prevent conflicts when modifying shared cluster resources.
141+
115142
func TestDeployment(t *testing.T) {
116143
if os.Getenv("SKIP_OPERATOR_TESTS") != "" {
117144
t.Skip("Operator tests disabled")

tests/e2e/olm_switch_test.go

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
//go:build e2e
2+
// +build e2e
3+
4+
package e2e
5+
6+
import (
7+
"os"
8+
"os/exec"
9+
"strings"
10+
"testing"
11+
"time"
12+
)
13+
14+
// Note: All e2e tests run sequentially via the -parallel=1 flag in the Makefile.
15+
// This prevents conflicts when multiple tests modify shared cluster resources.
16+
17+
// verifyOperatorMode checks if the operator is deployed in the expected mode (OLM or non-OLM)
18+
func verifyOperatorMode(t *testing.T, expectOLM bool) {
19+
t.Helper()
20+
21+
operatorNamespace := "rhacs-operator-system"
22+
subscriptionName := "stackrox-operator-subscription"
23+
24+
// Check for OLM Subscription (OLM-specific resource)
25+
cmd := exec.Command("kubectl", "get", "subscription", subscriptionName, "-n", operatorNamespace)
26+
err := cmd.Run()
27+
olmExists := (err == nil)
28+
29+
if expectOLM && !olmExists {
30+
t.Fatalf("Expected OLM operator but Subscription not found")
31+
}
32+
if !expectOLM && olmExists {
33+
t.Fatalf("Expected non-OLM operator but Subscription found (indicates OLM deployment)")
34+
}
35+
36+
t.Logf("✓ Operator is deployed in expected mode (OLM: %v)", expectOLM)
37+
}
38+
39+
// verifyOperatorDeploymentExists checks if the operator deployment exists
40+
func verifyOperatorDeploymentExists(t *testing.T) {
41+
t.Helper()
42+
43+
operatorNamespace := "rhacs-operator-system"
44+
deploymentName := "rhacs-operator-controller-manager"
45+
46+
cmd := exec.Command("kubectl", "get", "deployment", deploymentName, "-n", operatorNamespace)
47+
if err := cmd.Run(); err != nil {
48+
t.Fatalf("Operator deployment not found: %v", err)
49+
}
50+
51+
// Also check if deployment is ready
52+
cmd = exec.Command("kubectl", "get", "deployment", deploymentName, "-n", operatorNamespace,
53+
"-o", "jsonpath={.status.readyReplicas}")
54+
output, err := cmd.Output()
55+
if err != nil {
56+
t.Fatalf("Failed to check operator deployment readiness: %v", err)
57+
}
58+
59+
readyReplicas := strings.TrimSpace(string(output))
60+
if readyReplicas == "" || readyReplicas == "0" {
61+
t.Fatalf("Operator deployment exists but has no ready replicas")
62+
}
63+
64+
t.Logf("✓ Operator deployment exists and is ready (%s replicas)", readyReplicas)
65+
}
66+
67+
// TestOLMToNonOLMSwitch tests switching from OLM operator to non-OLM operator
68+
func TestOLMToNonOLMSwitch(t *testing.T) {
69+
if os.Getenv("SKIP_OLM_TESTS") != "" {
70+
t.Skip("SKIP_OLM_TESTS is set")
71+
}
72+
73+
// Create temporary envrc file
74+
envrcFile, err := os.CreateTemp("", ".envrc.roxie-test-*")
75+
if err != nil {
76+
t.Fatalf("Failed to create temp envrc: %v", err)
77+
}
78+
envrcPath := envrcFile.Name()
79+
envrcFile.Close()
80+
defer os.Remove(envrcPath)
81+
82+
// Step 1: Deploy central with OLM operator
83+
t.Log("=== Step 1: Deploy central with OLM operator ===")
84+
args := append([]string{roxieBinary, "deploy", "central", "--olm", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
85+
runCommand(t, deployTimeout, nil, args...)
86+
87+
// Verify operator is in OLM mode
88+
t.Log("Verifying operator is in OLM mode")
89+
verifyOperatorMode(t, true)
90+
verifyOperatorDeploymentExists(t)
91+
92+
// Verify central namespace exists
93+
verifyNamespaceExists(t, "acs-central")
94+
95+
// Brief pause
96+
time.Sleep(10 * time.Second)
97+
98+
// Step 2: Deploy central again without OLM (should switch modes)
99+
t.Log("=== Step 2: Redeploy central without OLM (triggering mode switch) ===")
100+
args = append([]string{roxieBinary, "deploy", "central", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
101+
runCommand(t, deployTimeout, nil, args...)
102+
103+
// Verify operator switched to non-OLM mode
104+
t.Log("Verifying operator switched to non-OLM mode")
105+
verifyOperatorMode(t, false)
106+
verifyOperatorDeploymentExists(t)
107+
108+
// Verify central namespace still exists
109+
verifyNamespaceExists(t, "acs-central")
110+
111+
// Cleanup
112+
t.Log("=== Cleaning up ===")
113+
teardownArgs := []string{roxieBinary, "teardown", "central"}
114+
runCommand(t, teardownTimeout, nil, teardownArgs...)
115+
116+
verifyNamespaceAbsent(t, "acs-central")
117+
}
118+
119+
// TestNonOLMToOLMSwitch tests switching from non-OLM operator to OLM operator
120+
func TestNonOLMToOLMSwitch(t *testing.T) {
121+
if os.Getenv("SKIP_OLM_TESTS") != "" {
122+
t.Skip("SKIP_OLM_TESTS is set")
123+
}
124+
125+
// Create temporary envrc file
126+
envrcFile, err := os.CreateTemp("", ".envrc.roxie-test-*")
127+
if err != nil {
128+
t.Fatalf("Failed to create temp envrc: %v", err)
129+
}
130+
envrcPath := envrcFile.Name()
131+
envrcFile.Close()
132+
defer os.Remove(envrcPath)
133+
134+
// Step 1: Deploy central without OLM (non-OLM operator)
135+
t.Log("=== Step 1: Deploy central with non-OLM operator ===")
136+
args := append([]string{roxieBinary, "deploy", "central", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
137+
runCommand(t, deployTimeout, nil, args...)
138+
139+
// Verify operator is in non-OLM mode
140+
t.Log("Verifying operator is in non-OLM mode")
141+
verifyOperatorMode(t, false)
142+
verifyOperatorDeploymentExists(t)
143+
144+
// Verify central namespace exists
145+
verifyNamespaceExists(t, "acs-central")
146+
147+
// Brief pause
148+
time.Sleep(10 * time.Second)
149+
150+
// Step 2: Deploy central again with OLM (should switch modes)
151+
t.Log("=== Step 2: Redeploy central with OLM (triggering mode switch) ===")
152+
args = append([]string{roxieBinary, "deploy", "central", "--olm", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
153+
runCommand(t, deployTimeout, nil, args...)
154+
155+
// Verify operator switched to OLM mode
156+
t.Log("Verifying operator switched to OLM mode")
157+
verifyOperatorMode(t, true)
158+
verifyOperatorDeploymentExists(t)
159+
160+
// Verify central namespace still exists
161+
verifyNamespaceExists(t, "acs-central")
162+
163+
// Cleanup
164+
t.Log("=== Cleaning up ===")
165+
teardownArgs := []string{roxieBinary, "teardown", "central"}
166+
runCommand(t, teardownTimeout, nil, teardownArgs...)
167+
168+
verifyNamespaceAbsent(t, "acs-central")
169+
}
170+
171+
// TestOLMOperatorVersionUpgrade tests that OLM operator version mismatches trigger teardown and redeploy
172+
func TestOLMOperatorVersionUpgrade(t *testing.T) {
173+
if os.Getenv("SKIP_OLM_TESTS") != "" {
174+
t.Skip("SKIP_OLM_TESTS is set")
175+
}
176+
177+
// This test requires two different operator versions
178+
// We can simulate this by deploying twice with the same version,
179+
// but the logic should handle version changes by tearing down and redeploying
180+
181+
// Create temporary envrc file
182+
envrcFile, err := os.CreateTemp("", ".envrc.roxie-test-*")
183+
if err != nil {
184+
t.Fatalf("Failed to create temp envrc: %v", err)
185+
}
186+
envrcPath := envrcFile.Name()
187+
envrcFile.Close()
188+
defer os.Remove(envrcPath)
189+
190+
// Step 1: Deploy central with OLM operator
191+
t.Log("=== Step 1: Deploy central with OLM operator ===")
192+
args := append([]string{roxieBinary, "deploy", "central", "--olm", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
193+
runCommand(t, deployTimeout, nil, args...)
194+
195+
// Verify operator is in OLM mode
196+
t.Log("Verifying initial OLM operator deployment")
197+
verifyOperatorMode(t, true)
198+
verifyOperatorDeploymentExists(t)
199+
200+
// Get the current operator version
201+
operatorNamespace := "rhacs-operator-system"
202+
deploymentName := "rhacs-operator-controller-manager"
203+
cmd := exec.Command("kubectl", "get", "deployment", deploymentName, "-n", operatorNamespace,
204+
"-o", "jsonpath={.spec.template.spec.containers[0].image}")
205+
output, err := cmd.Output()
206+
if err != nil {
207+
t.Fatalf("Failed to get operator image: %v", err)
208+
}
209+
initialImage := strings.TrimSpace(string(output))
210+
t.Logf("Initial operator image: %s", initialImage)
211+
212+
// Brief pause
213+
time.Sleep(10 * time.Second)
214+
215+
// Step 2: Redeploy with same version (should skip if version matches)
216+
t.Log("=== Step 2: Redeploy with same version (should detect correct version) ===")
217+
args = append([]string{roxieBinary, "deploy", "central", "--olm", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
218+
runCommand(t, deployTimeout, nil, args...)
219+
220+
// Verify operator is still in OLM mode and deployment exists
221+
t.Log("Verifying operator is still deployed correctly")
222+
verifyOperatorMode(t, true)
223+
verifyOperatorDeploymentExists(t)
224+
225+
// Note: In a real version upgrade test, we would set a different MAIN_IMAGE_TAG
226+
// and verify that the operator was torn down and redeployed with the new version.
227+
// For now, this test validates the basic flow.
228+
229+
// Cleanup
230+
t.Log("=== Cleaning up ===")
231+
teardownArgs := []string{roxieBinary, "teardown", "central"}
232+
runCommand(t, teardownTimeout, nil, teardownArgs...)
233+
234+
verifyNamespaceAbsent(t, "acs-central")
235+
}
236+
237+
// TestSecuredClusterWithOLMSwitch tests that secured-cluster deployment also respects OLM mode switches
238+
func TestSecuredClusterWithOLMSwitch(t *testing.T) {
239+
if os.Getenv("SKIP_OLM_TESTS") != "" {
240+
t.Skip("SKIP_OLM_TESTS is set")
241+
}
242+
243+
// Create temporary envrc file
244+
envrcFile, err := os.CreateTemp("", ".envrc.roxie-test-*")
245+
if err != nil {
246+
t.Fatalf("Failed to create temp envrc: %v", err)
247+
}
248+
envrcPath := envrcFile.Name()
249+
envrcFile.Close()
250+
defer os.Remove(envrcPath)
251+
252+
// Step 1: Deploy central with OLM
253+
t.Log("=== Step 1: Deploy central with OLM ===")
254+
args := append([]string{roxieBinary, "deploy", "central", "--olm", "--envrc", envrcPath}, commonDeployArgsNoPortForward...)
255+
runCommand(t, deployTimeout, nil, args...)
256+
257+
verifyOperatorMode(t, true)
258+
verifyNamespaceExists(t, "acs-central")
259+
260+
// Load envrc for secured-cluster
261+
envrcEnv, err := loadEnvrcFile(envrcPath)
262+
if err != nil {
263+
t.Fatalf("Failed to load envrc file: %v", err)
264+
}
265+
266+
// Step 2: Deploy secured-cluster (should reuse OLM operator)
267+
t.Log("=== Step 2: Deploy secured-cluster (should reuse OLM operator) ===")
268+
args = append([]string{roxieBinary, "deploy", "secured-cluster", "--olm"}, commonDeployArgsNoPortForward...)
269+
runCommand(t, deployTimeout, envrcEnv, args...)
270+
271+
// Verify operator is still in OLM mode
272+
verifyOperatorMode(t, true)
273+
verifyNamespaceExists(t, "acs-sensor")
274+
275+
// Step 3: Switch to non-OLM by redeploying secured-cluster without --olm
276+
t.Log("=== Step 3: Redeploy secured-cluster without OLM (triggering mode switch) ===")
277+
args = append([]string{roxieBinary, "deploy", "secured-cluster"}, commonDeployArgsNoPortForward...)
278+
runCommand(t, deployTimeout, envrcEnv, args...)
279+
280+
// Verify operator switched to non-OLM mode
281+
verifyOperatorMode(t, false)
282+
verifyNamespaceExists(t, "acs-sensor")
283+
284+
// Cleanup
285+
t.Log("=== Cleaning up ===")
286+
teardownArgs := []string{roxieBinary, "teardown", "both"}
287+
runCommand(t, teardownTimeout, nil, teardownArgs...)
288+
289+
verifyNamespaceAbsent(t, "acs-central")
290+
verifyNamespaceAbsent(t, "acs-sensor")
291+
}

0 commit comments

Comments
 (0)