@@ -2,6 +2,8 @@ package sequential
22
33import (
44 "context"
5+ "os/exec"
6+ "strings"
57
68 argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1"
79 . "github.com/onsi/ginkgo/v2"
@@ -13,6 +15,7 @@ import (
1315 fixtureUtils "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils"
1416 appsv1 "k8s.io/api/apps/v1"
1517 corev1 "k8s.io/api/core/v1"
18+ "k8s.io/apimachinery/pkg/api/errors"
1619 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1720 "k8s.io/utils/ptr"
1821 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -45,8 +48,10 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
4548
4649 It ("validates monitoring setup, alert rule creation, and teardown" , func () {
4750 const (
48- invalidImage = "test-image"
49- prometheusRuleName = "gitops-operator-argocd-alerts"
51+ // picking a valid image that exists to avoid ImagePullBackOff
52+ // but should fail to run as an ApplicationSet controller
53+ invalidImage = "quay.io/libpod/alpine:latest"
54+ prometheusRuleName = "argocd-component-status-alert"
5055 clusterInstanceName = "openshift-gitops"
5156 )
5257
@@ -56,16 +61,29 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
5661 ruleNamespaced := & monitoringv1.PrometheusRule {
5762 ObjectMeta : metav1.ObjectMeta {Name : prometheusRuleName , Namespace : nsNamespaced .Name },
5863 }
59-
64+ appSetDeplCluster := & appsv1.Deployment {
65+ ObjectMeta : metav1.ObjectMeta {Name : clusterInstanceName + "-applicationset-controller" , Namespace : nsCluster .Name },
66+ }
6067 uwmConfigMap := & corev1.ConfigMap {
6168 ObjectMeta : metav1.ObjectMeta {Name : "cluster-monitoring-config" , Namespace : "openshift-monitoring" },
62- Data : map [string ]string {"config.yaml" : "enableUserWorkload: true" },
69+ Data : map [string ]string {"config.yaml" : "enableUserWorkload: true\n " },
70+ }
71+
72+ By ("labeling the namespace for monitoring" )
73+ // Prometheus will only scrape User Workload namespaces that have this label
74+ err := k8sClient .Get (ctx , client .ObjectKeyFromObject (nsNamespaced ), nsNamespaced )
75+ Expect (err ).NotTo (HaveOccurred ())
76+
77+ if nsNamespaced .Labels == nil {
78+ nsNamespaced .Labels = make (map [string ]string )
6379 }
64- cmKey := client.ObjectKey {Name : uwmConfigMap .Name , Namespace : uwmConfigMap .Namespace }
80+ nsNamespaced .Labels ["openshift.io/cluster-monitoring" ] = "true"
81+ err = k8sClient .Update (ctx , nsNamespaced )
82+ Expect (err ).NotTo (HaveOccurred ())
6583
6684 By ("enabling user workload monitoring in the cluster monitoring config map" )
6785 existingCM := & corev1.ConfigMap {}
68- err : = k8sClient .Get (ctx , cmKey , existingCM )
86+ err = k8sClient .Get (ctx , client . ObjectKeyFromObject ( uwmConfigMap ) , existingCM )
6987
7088 DeferCleanup (func () {
7189 _ = k8sClient .Delete (ctx , uwmConfigMap )
@@ -74,71 +92,98 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() {
7492 if err == nil {
7593 existingCM .Data = uwmConfigMap .Data
7694 Expect (k8sClient .Update (ctx , existingCM )).To (Succeed (), "Failed to update existing UWM ConfigMap" )
77- } else {
95+ } else if errors . IsNotFound ( err ) {
7896 Expect (k8sClient .Create (ctx , uwmConfigMap )).To (Succeed (), "Failed to create UWM ConfigMap" )
97+ } else {
98+ Expect (err ).NotTo (HaveOccurred (), "Failed to fetch UWM ConfigMap" )
7999 }
80100
81- By ("enabling monitoring on the cluster Argo CD instance and setting an invalid image to trigger alerts " )
101+ By ("modifying both ArgoCD instances to enable monitoring and break the AppSet image" )
82102 argoCDCluster := & argov1beta1api.ArgoCD {
83103 ObjectMeta : metav1.ObjectMeta {Name : clusterInstanceName , Namespace : nsCluster .Name },
84104 }
85105 Expect (k8sClient .Get (ctx , client .ObjectKeyFromObject (argoCDCluster ), argoCDCluster )).To (Succeed ())
86106
87- //restore the cluster instance even if the test fails halfway through it
107+ // Restore even if the test fails halfway through
88108 DeferCleanup (func () {
89109 By ("restoring the default image and disabling monitoring on cluster Argo CD instance (Cleanup)" )
90110 _ = k8sClient .Get (ctx , client .ObjectKeyFromObject (argoCDCluster ), argoCDCluster )
91111 argocdFixture .Update (argoCDCluster , func (ac * argov1beta1api.ArgoCD ) {
92112 ac .Spec .ApplicationSet .Image = ""
93113 ac .Spec .Monitoring .DisableMetrics = ptr .To (true )
114+ ac .Spec .Monitoring .Enabled = false
94115 })
95116 })
96117
97118 argocdFixture .Update (argoCDCluster , func (ac * argov1beta1api.ArgoCD ) {
98119 ac .Spec .ApplicationSet = & argov1beta1api.ArgoCDApplicationSet {Image : invalidImage }
99- ac .Spec .Monitoring = argov1beta1api.ArgoCDMonitoringSpec {DisableMetrics : ptr .To (false )}
120+ ac .Spec .Monitoring = argov1beta1api.ArgoCDMonitoringSpec {Enabled : true , DisableMetrics : ptr .To (false )}
100121 })
101122
102- By ("creating a namespaced Argo CD instance with monitoring enabled" )
103123 argoCDNamespaced := & argov1beta1api.ArgoCD {
104124 ObjectMeta : metav1.ObjectMeta {Name : "argocd" , Namespace : nsNamespaced .Name },
105125 Spec : argov1beta1api.ArgoCDSpec {
106126 ApplicationSet : & argov1beta1api.ArgoCDApplicationSet {Image : invalidImage },
107- Monitoring : argov1beta1api.ArgoCDMonitoringSpec {DisableMetrics : ptr .To (false )},
127+ Monitoring : argov1beta1api.ArgoCDMonitoringSpec {Enabled : true , DisableMetrics : ptr .To (false )},
108128 },
109129 }
110130 Expect (k8sClient .Create (ctx , argoCDNamespaced )).To (Succeed ())
111131
112- //the verification
113132 By ("waiting for the Argo CD instances to become available" )
114133 Eventually (argoCDCluster , "5m" ).Should (argocdFixture .BeAvailable ())
115134 Eventually (argoCDNamespaced , "5m" ).Should (argocdFixture .BeAvailable ())
116135
117- By ("verifying the operator created the expected PrometheusRules " )
118- Eventually (ruleCluster , "5m " ).Should (k8sFixture .ExistByName (), "PrometheusRule should be created in cluster namespace" )
119- Eventually (ruleNamespaced , "5m " ).Should (k8sFixture .ExistByName (), "PrometheusRule should be created in test namespace" )
136+ By ("verifying PrometheusRules are created with the correct alerts " )
137+ Eventually (ruleCluster , "3m" , "5s " ).Should (k8sFixture .ExistByName (), "PrometheusRule should be created in cluster namespace" )
138+ Eventually (ruleNamespaced , "3m" , "5s " ).Should (k8sFixture .ExistByName (), "PrometheusRule should be created in test namespace" )
120139
121- By ("verifying the ApplicationSet deployments are present (likely in a crash loop due to the invalid image)" )
122- appSetDeplCluster := & appsv1.Deployment {ObjectMeta : metav1.ObjectMeta {Name : clusterInstanceName + "-applicationset-controller" , Namespace : nsCluster .Name }}
140+ By ("verifying the ApplicationSet deployments are present" )
123141 Eventually (appSetDeplCluster ).Should (k8sFixture .ExistByName ())
124142
125- By ("disabling monitoring and restoring the default image on the cluster Argo CD instance" )
143+ By ("verifying the workload degradation alerts are actively firing in Prometheus" )
144+ Eventually (func () bool {
145+ cmd := exec .Command ("oc" , "exec" , "-n" , "openshift-monitoring" , "prometheus-k8s-0" , "-c" , "prometheus" , "--" , "curl" , "-s" , "http://localhost:9090/api/v1/alerts" )
146+ outBytes , err := cmd .Output ()
147+ if err != nil {
148+ GinkgoWriter .Printf ("Failed to query Prometheus: %v\n " , err )
149+ return false
150+ }
151+ out := string (outBytes )
152+
153+ // check both default and the custom instance alerts are firing
154+ hasDefaultAlert := strings .Contains (out , "openshift-gitops-applicationset-controller" ) &&
155+ strings .Contains (out , "ApplicationSetControllerNotReady" ) &&
156+ strings .Contains (out , "firing" )
157+
158+ hasCustomAlert := strings .Contains (out , "argocd-applicationset-controller" ) &&
159+ strings .Contains (out , nsNamespaced .Name ) &&
160+ strings .Contains (out , "ApplicationSetControllerNotReady" ) &&
161+ strings .Contains (out , "firing" )
162+
163+ return hasDefaultAlert && hasCustomAlert
164+ }, "15m" , "30s" ).Should (BeTrue (), "Expected ApplicationSetControllerNotReady alerts to reach 'firing' state for both instances" )
165+
166+ By ("disabling monitoring and restoring the default images" )
126167 Expect (k8sClient .Get (ctx , client .ObjectKeyFromObject (argoCDCluster ), argoCDCluster )).To (Succeed ())
127168 argocdFixture .Update (argoCDCluster , func (ac * argov1beta1api.ArgoCD ) {
128169 ac .Spec .ApplicationSet .Image = ""
170+ ac .Spec .Monitoring .Enabled = false
129171 ac .Spec .Monitoring .DisableMetrics = ptr .To (true )
130172 })
131173
132- By ("disabling monitoring on the namespaced Argo CD instance" )
133174 Expect (k8sClient .Get (ctx , client .ObjectKeyFromObject (argoCDNamespaced ), argoCDNamespaced )).To (Succeed ())
134175 argocdFixture .Update (argoCDNamespaced , func (ac * argov1beta1api.ArgoCD ) {
176+ ac .Spec .ApplicationSet .Image = ""
177+ ac .Spec .Monitoring .Enabled = false
135178 ac .Spec .Monitoring .DisableMetrics = ptr .To (true )
136179 })
137180
138- By ("verifying the PrometheusRules are removed" )
181+ By ("deleting cluster monitoring config" )
182+ Expect (k8sClient .Delete (ctx , uwmConfigMap )).To (Succeed ())
183+
184+ By ("verifying PrometheusRules are deleted" )
139185 Eventually (ruleCluster , "5m" ).Should (k8sFixture .NotExistByName (), "Cluster PrometheusRule should be deleted" )
140186 Eventually (ruleNamespaced , "5m" ).Should (k8sFixture .NotExistByName (), "Namespaced PrometheusRule should be deleted" )
141-
142187 })
143188 })
144189})
0 commit comments