@@ -33,16 +33,17 @@ func TestOperatorControllerMetricsExportedEndpoint(t *testing.T) {
3333 client := utils .FindK8sClient (t )
3434 curlNamespace := createRandomNamespace (t , client )
3535 componentNamespace := getComponentNamespace (t , client , "control-plane=operator-controller-controller-manager" )
36- metricsURL := fmt .Sprintf ("https://operator-controller-service.%s.svc.cluster.local:8443/metrics" , componentNamespace )
3736
3837 config := NewMetricsTestConfig (
3938 client ,
4039 curlNamespace ,
40+ componentNamespace ,
4141 "operator-controller-metrics-reader" ,
4242 "operator-controller-metrics-binding" ,
4343 "operator-controller-metrics-reader" ,
4444 "oper-curl-metrics" ,
45- metricsURL ,
45+ "app.kubernetes.io/name=operator-controller" ,
46+ 8443 ,
4647 )
4748
4849 config .run (t )
@@ -53,42 +54,47 @@ func TestCatalogdMetricsExportedEndpoint(t *testing.T) {
5354 client := utils .FindK8sClient (t )
5455 curlNamespace := createRandomNamespace (t , client )
5556 componentNamespace := getComponentNamespace (t , client , "control-plane=catalogd-controller-manager" )
56- metricsURL := fmt .Sprintf ("https://catalogd-service.%s.svc.cluster.local:7443/metrics" , componentNamespace )
5757
5858 config := NewMetricsTestConfig (
5959 client ,
6060 curlNamespace ,
61+ componentNamespace ,
6162 "catalogd-metrics-reader" ,
6263 "catalogd-metrics-binding" ,
6364 "catalogd-metrics-reader" ,
6465 "catalogd-curl-metrics" ,
65- metricsURL ,
66+ "app.kubernetes.io/name=catalogd" ,
67+ 7443 ,
6668 )
6769
6870 config .run (t )
6971}
7072
7173// MetricsTestConfig holds the necessary configurations for testing metrics endpoints.
7274type MetricsTestConfig struct {
73- client string
74- namespace string
75- clusterRole string
76- clusterBinding string
77- serviceAccount string
78- curlPodName string
79- metricsURL string
75+ client string
76+ namespace string
77+ componentNamespace string
78+ clusterRole string
79+ clusterBinding string
80+ serviceAccount string
81+ curlPodName string
82+ componentSelector string
83+ metricsPort int
8084}
8185
8286// NewMetricsTestConfig initializes a new MetricsTestConfig.
83- func NewMetricsTestConfig (client , namespace , clusterRole , clusterBinding , serviceAccount , curlPodName , metricsURL string ) * MetricsTestConfig {
87+ func NewMetricsTestConfig (client , namespace , componentNamespace , clusterRole , clusterBinding , serviceAccount , curlPodName , componentSelector string , metricsPort int ) * MetricsTestConfig {
8488 return & MetricsTestConfig {
85- client : client ,
86- namespace : namespace ,
87- clusterRole : clusterRole ,
88- clusterBinding : clusterBinding ,
89- serviceAccount : serviceAccount ,
90- curlPodName : curlPodName ,
91- metricsURL : metricsURL ,
89+ client : client ,
90+ namespace : namespace ,
91+ componentNamespace : componentNamespace ,
92+ clusterRole : clusterRole ,
93+ clusterBinding : clusterBinding ,
94+ serviceAccount : serviceAccount ,
95+ curlPodName : curlPodName ,
96+ componentSelector : componentSelector ,
97+ metricsPort : metricsPort ,
9298 }
9399}
94100
@@ -154,19 +160,30 @@ func (c *MetricsTestConfig) createCurlMetricsPod(t *testing.T) {
154160 require .NoError (t , err , "Error creating curl pod: %s" , string (output ))
155161}
156162
157- // validate verifies if is possible to access the metrics
163+ // validate verifies if is possible to access the metrics from all pods
158164func (c * MetricsTestConfig ) validate (t * testing.T , token string ) {
159165 t .Log ("Waiting for the curl pod to be ready" )
160166 waitCmd := exec .Command (c .client , "wait" , "--for=condition=Ready" , "pod" , c .curlPodName , "--namespace" , c .namespace , "--timeout=60s" )
161167 waitOutput , waitErr := waitCmd .CombinedOutput ()
162168 require .NoError (t , waitErr , "Error waiting for curl pod to be ready: %s" , string (waitOutput ))
163169
164- t .Log ("Validating the metrics endpoint" )
165- curlCmd := exec .Command (c .client , "exec" , c .curlPodName , "--namespace" , c .namespace , "--" ,
166- "curl" , "-v" , "-k" , "-H" , "Authorization: Bearer " + token , c .metricsURL )
167- output , err := curlCmd .CombinedOutput ()
168- require .NoError (t , err , "Error calling metrics endpoint: %s" , string (output ))
169- require .Contains (t , string (output ), "200 OK" , "Metrics endpoint did not return 200 OK" )
170+ // Get all pod IPs for the component
171+ podIPs := c .getComponentPodIPs (t )
172+ require .NotEmpty (t , podIPs , "No pod IPs found for component" )
173+ t .Logf ("Found %d pod(s) to scrape metrics from" , len (podIPs ))
174+
175+ // Validate metrics endpoint for each pod
176+ for i , podIP := range podIPs {
177+ metricsURL := fmt .Sprintf ("https://%s:%d/metrics" , podIP , c .metricsPort )
178+ t .Logf ("Validating metrics endpoint for pod %d/%d: %s" , i + 1 , len (podIPs ), metricsURL )
179+
180+ curlCmd := exec .Command (c .client , "exec" , c .curlPodName , "--namespace" , c .namespace , "--" ,
181+ "curl" , "-v" , "-k" , "-H" , "Authorization: Bearer " + token , metricsURL )
182+ output , err := curlCmd .CombinedOutput ()
183+ require .NoError (t , err , "Error calling metrics endpoint %s: %s" , metricsURL , string (output ))
184+ require .Contains (t , string (output ), "200 OK" , "Metrics endpoint %s did not return 200 OK" , metricsURL )
185+ t .Logf ("Successfully scraped metrics from pod %d/%d" , i + 1 , len (podIPs ))
186+ }
170187}
171188
172189// cleanup removes the created resources. Uses a context with timeout to prevent hangs.
@@ -243,6 +260,29 @@ func getComponentNamespace(t *testing.T, client, selector string) string {
243260 return namespace
244261}
245262
263+ // getComponentPodIPs returns the IP addresses of all pods matching the component selector
264+ func (c * MetricsTestConfig ) getComponentPodIPs (t * testing.T ) []string {
265+ cmd := exec .Command (c .client , "get" , "pods" ,
266+ "--namespace=" + c .componentNamespace ,
267+ "--selector=" + c .componentSelector ,
268+ "--output=jsonpath={.items[*].status.podIP}" )
269+ output , err := cmd .CombinedOutput ()
270+ require .NoError (t , err , "Error getting pod IPs: %s" , string (output ))
271+
272+ podIPsStr := string (bytes .TrimSpace (output ))
273+ if podIPsStr == "" {
274+ return []string {}
275+ }
276+
277+ // Split space-separated IPs
278+ fields := bytes .Fields ([]byte (podIPsStr ))
279+ ips := make ([]string , len (fields ))
280+ for i , field := range fields {
281+ ips [i ] = string (field )
282+ }
283+ return ips
284+ }
285+
246286func stdoutAndCombined (cmd * exec.Cmd ) ([]byte , []byte , error ) {
247287 var outOnly , outAndErr bytes.Buffer
248288 allWriter := io .MultiWriter (& outOnly , & outAndErr )
0 commit comments