diff --git a/test/e2e/testdata/prometheus.yaml b/test/e2e/testdata/prometheus.yaml new file mode 100644 index 00000000000..d33db1d2dea --- /dev/null +++ b/test/e2e/testdata/prometheus.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: envoy-gateway-metrics-lb + namespace: envoy-gateway-system + labels: + control-plane: envoy-gateway +spec: + selector: + control-plane: envoy-gateway + app.kubernetes.io/instance: eg + ports: + - name: http-metrics + port: 19001 + protocol: TCP + targetPort: 19001 + type: LoadBalancer diff --git a/test/e2e/tests/controlplane.go b/test/e2e/tests/controlplane.go new file mode 100644 index 00000000000..7149c2546b6 --- /dev/null +++ b/test/e2e/tests/controlplane.go @@ -0,0 +1,76 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +//go:build e2e +// +build e2e + +package tests + +import ( + "context" + "testing" + "time" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/gateway-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, ControlPlaneMetricTest) +} + +var ControlPlaneMetricTest = suite.ConformanceTest{ + ShortName: "ControlPlane", + Description: "Make sure control plane prometheus endpoint is working", + Manifests: []string{"testdata/prometheus.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + t.Run("Prometheus", func(t *testing.T) { + nn := types.NamespacedName{Name: "envoy-gateway-metrics-lb", Namespace: "envoy-gateway-system"} + if err := wait.PollUntilContextTimeout(context.TODO(), time.Second, time.Minute, true, + func(_ context.Context) (done bool, err error) { + svc := corev1.Service{} + if err := suite.Client.Get(context.Background(), nn, &svc); err != nil { + return false, nil + } + + host := "" + switch svc.Spec.Type { + case corev1.ServiceTypeLoadBalancer: + for _, ing := range svc.Status.LoadBalancer.Ingress { + if ing.IP != "" { + host = ing.IP + break + } + } + default: + // do nothing + } + + if host == "" { + return false, nil + } + + return true, nil + }); err != nil { + t.Errorf("failed to get service %s : %v", nn.String(), err) + } + + // too much flakes in the test if timeout is 1 minute + // this should not take so long, but we give it a long timeout to be safe, and poll every second + if err := wait.PollUntilContextTimeout(context.TODO(), time.Second, 2*time.Minute, true, + func(_ context.Context) (done bool, err error) { + if err := ScrapeMetrics(t, suite.Client, nn, 19001, "/metrics"); err != nil { + t.Logf("failed to get metric: %v", err) + return false, nil + } + return true, nil + }); err != nil { + t.Errorf("failed to scrape metrics: %v", err) + } + }) + }, +} diff --git a/test/e2e/tests/metric.go b/test/e2e/tests/metric.go index 0f312dc07b5..2c9a8c296c3 100644 --- a/test/e2e/tests/metric.go +++ b/test/e2e/tests/metric.go @@ -59,7 +59,7 @@ var MetricTest = suite.ConformanceTest{ if err := ScrapeMetrics(t, suite.Client, types.NamespacedName{ Namespace: "envoy-gateway-system", Name: "same-namespace-gw-metrics", - }, "/stats/prometheus"); err != nil { + }, 19001, "/stats/prometheus"); err != nil { t.Logf("failed to get metric: %v", err) return false, nil } @@ -93,7 +93,7 @@ var MetricTest = suite.ConformanceTest{ if err := ScrapeMetrics(t, suite.Client, types.NamespacedName{ Namespace: "monitoring", Name: "otel-collecot-prometheus", - }, "/metrics"); err != nil { + }, 19001, "/metrics"); err != nil { t.Logf("failed to get metric: %v", err) return false, nil } @@ -105,19 +105,25 @@ var MetricTest = suite.ConformanceTest{ }, } -func ScrapeMetrics(t *testing.T, c client.Client, nn types.NamespacedName, path string) error { +func ScrapeMetrics(t *testing.T, c client.Client, nn types.NamespacedName, port int32, path string) error { svc := corev1.Service{} if err := c.Get(context.Background(), nn, &svc); err != nil { return err } host := "" - for _, ing := range svc.Status.LoadBalancer.Ingress { - if ing.IP != "" { - host = ing.IP - break + switch svc.Spec.Type { + case corev1.ServiceTypeLoadBalancer: + for _, ing := range svc.Status.LoadBalancer.Ingress { + if ing.IP != "" { + host = ing.IP + break + } } + default: + host = fmt.Sprintf("%s.%s.svc", nn.Name, nn.Namespace) } - url := fmt.Sprintf("http://%s:19001%s", host, path) + + url := fmt.Sprintf("http://%s:%d%s", host, port, path) t.Logf("try to request: %s", url) httpClient := http.Client{