Skip to content

Commit 68410d7

Browse files
committed
Add OLM Install & Delete Testing
Signed-off-by: Triona Doyle <[email protected]>
1 parent 15c5833 commit 68410d7

File tree

9 files changed

+638
-104
lines changed

9 files changed

+638
-104
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ kuttl-test.json
2222

2323
!vendor/**/zz_generated.*
2424

25-
# editor and IDE paraphernalia
25+
# editor and IDE paraphernalia (inc MacOs)
2626
.idea
2727
*.swp
2828
*.swo
2929
*~
30+
.DS_Store
31+
3032

3133
# ignore vendor
3234
vendor/

test/openshift/e2e/ginkgo/fixture/fixture.go

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/argocd"
3030
deploymentFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/deployment"
3131
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/k8s"
32-
osFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/os"
32+
osFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/os" // Corrected import path
3333
subscriptionFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/subscription"
3434
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils"
3535
appsv1 "k8s.io/api/apps/v1"
@@ -40,16 +40,18 @@ import (
4040
)
4141

4242
const (
43-
// E2ETestLabelsKey and E2ETestLabelsValue are added to cluster-scoped resources (e.g. Namespaces) created by E2E tests (where possible). On startup (and before each test for sequential tests), any resources with this label will be deleted.
44-
E2ETestLabelsKey = "app"
45-
E2ETestLabelsValue = "test-argo-app"
43+
E2ETestLabelsKey = "app"
44+
E2ETestLabelsValue = "test-argo-app"
45+
GitOpsOperatorNamespace = "openshift-gitops-operator"
46+
GitOpsOperatorDeploymentName = "openshift-gitops-operator-controller-manager"
47+
GitOpsOperatorSubscriptionName = "openshift-gitops-operator"
48+
HelloWorldPattern = "helloworld-operator"
4649
)
4750

4851
var NamespaceLabels = map[string]string{E2ETestLabelsKey: E2ETestLabelsValue}
4952

5053
func EnsureParallelCleanSlate() {
5154

52-
// Increase the maximum length of debug output, for when tests fail
5355
format.MaxLength = 64 * 1024
5456
SetDefaultEventuallyTimeout(time.Second * 60)
5557
SetDefaultEventuallyPollingInterval(time.Second * 3)
@@ -71,20 +73,12 @@ func EnsureParallelCleanSlate() {
7173
// Unlike sequential clean slate, parallel clean slate cannot assume that there are no other tests running. This limits our ability to clean up old test artifacts.
7274
}
7375

74-
// EnsureSequentialCleanSlate will clean up resources that were created during previous sequential tests
75-
// - Deletes namespaces that were created by previous tests
76-
// - Deletes other cluster-scoped resources that were created
77-
// - Reverts changes made to Subscription CR
78-
// - etc
7976
func EnsureSequentialCleanSlate() {
8077
Expect(EnsureSequentialCleanSlateWithError()).To(Succeed())
8178
}
8279

8380
func EnsureSequentialCleanSlateWithError() error {
8481

85-
// With sequential tests, we are always safe to assume that there is no other test running. That allows us to clean up old test artifacts before new test starts.
86-
87-
// Increase the maximum length of debug output, for when tests fail
8882
format.MaxLength = 64 * 1024
8983
SetDefaultEventuallyTimeout(time.Second * 60)
9084
SetDefaultEventuallyPollingInterval(time.Second * 3)
@@ -131,8 +125,8 @@ func EnsureSequentialCleanSlateWithError() error {
131125
Enabled: true,
132126
TLS: nil,
133127
// TLS: &routev1.TLSConfig{
134-
// Termination: routev1.TLSTerminationReencrypt,
135-
// InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
128+
// Termination: routev1.TLSTerminationReencrypt,
129+
// InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
136130
// },
137131
}
138132

@@ -206,13 +200,12 @@ func EnsureSequentialCleanSlateWithError() error {
206200
func RemoveDynamicPluginFromCSV(ctx context.Context, k8sClient client.Client) error {
207201

208202
if EnvNonOLM() || EnvLocalRun() {
209-
// Skipping as CSV does exist when not using OLM, nor does it exist when running locally
210203
return nil
211204
}
212205

213206
var csv *olmv1alpha1.ClusterServiceVersion
214207
var csvList olmv1alpha1.ClusterServiceVersionList
215-
Expect(k8sClient.List(ctx, &csvList, client.InNamespace("openshift-gitops-operator"))).To(Succeed())
208+
Expect(k8sClient.List(ctx, &csvList, client.InNamespace(GitOpsOperatorNamespace))).To(Succeed())
216209

217210
for idx := range csvList.Items {
218211
idxCSV := csvList.Items[idx]
@@ -221,7 +214,7 @@ func RemoveDynamicPluginFromCSV(ctx context.Context, k8sClient client.Client) er
221214
break
222215
}
223216
}
224-
Expect(csv).ToNot(BeNil(), "if you see this, it likely means, either: A) the operator is not installed via OLM (and you meant to install it), OR B) you are running the operator locally via 'make run', and thus should specify LOCAL_RUN=true env var when calling the test")
217+
Expect(csv).ToNot(BeNil(), "if you see this, it likely means, either: A) the operator is not installed via OLM (and you meant to install it), OR B) you are running the operator locally via 'make run', and thus should not specify LOCAL_RUN=true env var when calling the test")
225218

226219
if err := updateWithoutConflict(csv, func(obj client.Object) {
227220

@@ -374,7 +367,7 @@ func GetEnvInOperatorSubscriptionOrDeployment(key string) (*string, error) {
374367
}
375368

376369
if EnvNonOLM() {
377-
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator-controller-manager", Namespace: "openshift-gitops-operator"}}
370+
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorDeploymentName, Namespace: GitOpsOperatorNamespace}}
378371

379372
return deploymentFixture.GetEnv(depl, key)
380373

@@ -394,7 +387,7 @@ func GetEnvInOperatorSubscriptionOrDeployment(key string) (*string, error) {
394387

395388
} else {
396389

397-
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator", Namespace: "openshift-gitops-operator"}}
390+
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorSubscriptionName, Namespace: GitOpsOperatorNamespace}}
398391
if err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(sub), sub); err != nil {
399392
return nil, err
400393
}
@@ -411,11 +404,11 @@ func SetEnvInOperatorSubscriptionOrDeployment(key string, value string) {
411404
k8sClient, _ := utils.GetE2ETestKubeClient()
412405

413406
if EnvNonOLM() {
414-
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator-controller-manager", Namespace: "openshift-gitops-operator"}}
407+
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorDeploymentName, Namespace: GitOpsOperatorNamespace}}
415408

416409
deploymentFixture.SetEnv(depl, key, value)
417410

418-
WaitForAllDeploymentsInTheNamespaceToBeReady("openshift-gitops-operator", k8sClient)
411+
WaitForAllDeploymentsInTheNamespaceToBeReady(GitOpsOperatorNamespace, k8sClient)
419412

420413
} else if EnvCI() {
421414

@@ -429,7 +422,7 @@ func SetEnvInOperatorSubscriptionOrDeployment(key string, value string) {
429422

430423
} else {
431424

432-
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator", Namespace: "openshift-gitops-operator"}}
425+
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorSubscriptionName, Namespace: GitOpsOperatorNamespace}}
433426
Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(sub), sub)).To(Succeed())
434427

435428
subscriptionFixture.SetEnv(sub, key, value)
@@ -448,11 +441,11 @@ func RemoveEnvFromOperatorSubscriptionOrDeployment(key string) error {
448441
}
449442

450443
if EnvNonOLM() {
451-
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator-controller-manager", Namespace: "openshift-gitops-operator"}}
444+
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorDeploymentName, Namespace: GitOpsOperatorNamespace}}
452445

453446
deploymentFixture.RemoveEnv(depl, key)
454447

455-
WaitForAllDeploymentsInTheNamespaceToBeReady("openshift-gitops-operator", k8sClient)
448+
WaitForAllDeploymentsInTheNamespaceToBeReady(GitOpsOperatorNamespace, k8sClient)
456449

457450
} else if EnvCI() {
458451

@@ -470,7 +463,7 @@ func RemoveEnvFromOperatorSubscriptionOrDeployment(key string) error {
470463

471464
} else {
472465

473-
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator", Namespace: "openshift-gitops-operator"}}
466+
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorSubscriptionName, Namespace: GitOpsOperatorNamespace}}
474467
if err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(sub), sub); err != nil {
475468
return err
476469
}
@@ -485,9 +478,7 @@ func RemoveEnvFromOperatorSubscriptionOrDeployment(key string) error {
485478

486479
func GetSubscriptionInEnvCIEnvironment(k8sClient client.Client) (*olmv1alpha1.Subscription, error) {
487480
subscriptionList := olmv1alpha1.SubscriptionList{}
488-
if err := k8sClient.List(context.Background(), &subscriptionList, client.InNamespace("openshift-gitops-operator")); err != nil {
489-
return nil, err
490-
}
481+
Expect(k8sClient.List(context.Background(), &subscriptionList, client.InNamespace(GitOpsOperatorNamespace))).To(Succeed())
491482

492483
var sub *olmv1alpha1.Subscription
493484

@@ -516,7 +507,7 @@ func RestoreSubcriptionToDefault() error {
516507

517508
if EnvNonOLM() {
518509

519-
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator-controller-manager", Namespace: "openshift-gitops-operator"}}
510+
depl := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorDeploymentName, Namespace: GitOpsOperatorNamespace}}
520511

521512
for _, envKey := range optionalEnvVarsToRemove {
522513
deploymentFixture.RemoveEnv(depl, envKey)
@@ -539,30 +530,26 @@ func RestoreSubcriptionToDefault() error {
539530
subscriptionFixture.RemoveSpecConfig(sub)
540531
}
541532

542-
if err := waitForAllEnvVarsToBeRemovedFromDeployments("openshift-gitops-operator", optionalEnvVarsToRemove, k8sClient); err != nil {
533+
if err := waitForAllEnvVarsToBeRemovedFromDeployments(GitOpsOperatorNamespace, optionalEnvVarsToRemove, k8sClient); err != nil {
543534
return err
544535
}
545536

546-
WaitForAllDeploymentsInTheNamespaceToBeReady("openshift-gitops-operator", k8sClient)
547-
548-
} else if EnvLocalRun() {
549-
// When running locally, there are no cluster resources to clean up
550-
return nil
537+
WaitForAllDeploymentsInTheNamespaceToBeReady(GitOpsOperatorNamespace, k8sClient)
551538

552539
} else {
553540

554-
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: "openshift-gitops-operator", Namespace: "openshift-gitops-operator"}}
541+
sub := &olmv1alpha1.Subscription{ObjectMeta: metav1.ObjectMeta{Name: GitOpsOperatorSubscriptionName, Namespace: GitOpsOperatorNamespace}}
555542
if err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(sub), sub); err != nil {
556543
return err
557544
}
558545

559546
subscriptionFixture.RemoveSpecConfig(sub)
560547

561-
if err := waitForAllEnvVarsToBeRemovedFromDeployments("openshift-gitops-operator", optionalEnvVarsToRemove, k8sClient); err != nil {
548+
if err := waitForAllEnvVarsToBeRemovedFromDeployments(GitOpsOperatorNamespace, optionalEnvVarsToRemove, k8sClient); err != nil {
562549
return err
563550
}
564551

565-
WaitForAllDeploymentsInTheNamespaceToBeReady("openshift-gitops-operator", k8sClient)
552+
WaitForAllDeploymentsInTheNamespaceToBeReady(GitOpsOperatorNamespace, k8sClient)
566553
}
567554

568555
return nil
@@ -848,15 +835,14 @@ func OutputDebugOnFail(namespaceParams ...any) {
848835
debugOutput, exists := testReportMap[testName]
849836

850837
if exists && debugOutput.isOutputted {
851-
// Skip output if we have already outputted once for this test
852838
return
853839
}
854840

855841
testReportMap[testName] = testReportEntry{
856842
isOutputted: true,
857843
}
858844

859-
outputPodLog("openshift-gitops-operator-controller-manager")
845+
outputPodLog(GitOpsOperatorDeploymentName)
860846

861847
for _, namespace := range namespaces {
862848

@@ -911,7 +897,6 @@ func outputPodLog(podSubstring string) {
911897
}
912898

913899
if len(matchingPods) == 0 {
914-
// This can happen when the operator is not running on the cluster
915900
GinkgoWriter.Println("DebugOutputOperatorLogs was called, but no pods were found.")
916901
return
917902
}
@@ -922,7 +907,7 @@ func outputPodLog(podSubstring string) {
922907
}
923908

924909
// Extract operator logs
925-
kubectlLogOutput, err := osFixture.ExecCommandWithOutputParam(false, "kubectl", "logs", "pod/"+matchingPods[0].Name, "manager", "-n", matchingPods[0].Namespace)
910+
kubectlLogOutput, err := osFixture.ExecCommandWithOutputParam(false, "kubectl", "logs", "pod/"+matchingPods[0].Name, "manager", "-n", GitOpsOperatorNamespace)
926911
if err != nil {
927912
GinkgoWriter.Println("unable to extract operator logs", err)
928913
return
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package olm
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
. "github.com/onsi/ginkgo/v2"
9+
. "github.com/onsi/gomega"
10+
11+
olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
12+
apierr "k8s.io/apimachinery/pkg/api/errors"
13+
"k8s.io/apimachinery/pkg/types"
14+
"sigs.k8s.io/controller-runtime/pkg/client"
15+
16+
"github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils"
17+
)
18+
19+
// WaitForClusterServiceVersion waits for a specific ClusterServiceVersion to reach the 'Succeeded' phase.
20+
func WaitForClusterServiceVersion(ctx context.Context, namespace, csvName string, timeout, pollingInterval time.Duration) {
21+
k8sClient, _, err := utils.GetE2ETestKubeClientWithError() // Get client here
22+
Expect(err).ToNot(HaveOccurred())
23+
24+
GinkgoWriter.Printf("Waiting for ClusterServiceVersion '%s' in namespace '%s' to be Succeeded...\n", csvName, namespace)
25+
26+
csvKey := types.NamespacedName{
27+
Name: csvName,
28+
Namespace: namespace,
29+
}
30+
31+
var foundCSV olmv1alpha1.ClusterServiceVersion
32+
33+
Eventually(func() bool {
34+
getErr := k8sClient.Get(ctx, csvKey, &foundCSV)
35+
if getErr != nil {
36+
if apierr.IsNotFound(getErr) {
37+
GinkgoWriter.Printf("CSV '%s' not found yet. Listing all CSVs in '%s' for debug...\n", csvName, namespace)
38+
var csvList olmv1alpha1.ClusterServiceVersionList
39+
listErr := k8sClient.List(ctx, &csvList, client.InNamespace(namespace))
40+
if listErr != nil {
41+
GinkgoWriter.Printf("Error listing CSVs for debug: %v\n", listErr)
42+
} else {
43+
for _, csv := range csvList.Items {
44+
GinkgoWriter.Printf("- Found CSV: %s (Phase: %s, Reason: %s)\n", csv.Name, csv.Status.Phase, csv.Status.Reason)
45+
}
46+
}
47+
return false
48+
}
49+
GinkgoWriter.Printf("Error getting CSV '%s': %v. Retrying...\n", csvName, getErr)
50+
return false // retrying on errors
51+
}
52+
53+
// Check if the CSV phase is Succeeded
54+
if foundCSV.Status.Phase == olmv1alpha1.CSVPhaseSucceeded {
55+
GinkgoWriter.Printf("ClusterServiceVersion '%s' is Succeeded.\n", csvName)
56+
return true
57+
}
58+
59+
GinkgoWriter.Printf("CSV '%s' status is '%s' (Reason: %s). Waiting...\n", csvName, foundCSV.Status.Phase, foundCSV.Status.Reason)
60+
return false // Not succeeded yet
61+
}).WithTimeout(timeout).WithPolling(pollingInterval).Should(BeTrue(),
62+
fmt.Sprintf("Expected ClusterServiceVersion '%s' in namespace '%s' to be Succeeded within %s", csvName, namespace, timeout))
63+
64+
GinkgoWriter.Println("ClusterServiceVersion successfully installed and Succeeded.")
65+
}

0 commit comments

Comments
 (0)