github.com/argoproj/argo-cd/v3@v3.2.1/test/e2e/metrics_test.go (about) 1 package e2e 2 3 import ( 4 "io" 5 "net/http" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "k8s.io/apimachinery/pkg/types" 12 13 . "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 14 "github.com/argoproj/argo-cd/v3/test/e2e/fixture" 15 . "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app" 16 "github.com/argoproj/argo-cd/v3/util/argo" 17 "github.com/argoproj/argo-cd/v3/util/errors" 18 ) 19 20 func TestKubectlMetrics(t *testing.T) { 21 // Sync an app so that there are metrics to scrape. 22 ctx := Given(t) 23 ctx. 24 Path(guestbookPath). 25 When(). 26 CreateApp(). 27 Then(). 28 Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). 29 And(func(app *Application) { 30 assert.Equal(t, fixture.Name(), app.Name) 31 assert.Equal(t, fixture.RepoURL(fixture.RepoURLTypeFile), app.Spec.GetSource().RepoURL) 32 assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) 33 assert.Equal(t, fixture.DeploymentNamespace(), app.Spec.Destination.Namespace) 34 assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) 35 }). 36 Expect(Event(argo.EventReasonResourceCreated, "create")). 37 And(func(_ *Application) { 38 // app should be listed 39 output, err := fixture.RunCli("app", "list") 40 require.NoError(t, err) 41 assert.Contains(t, output, fixture.Name()) 42 }). 43 When(). 44 // ensure that create is idempotent 45 CreateApp(). 46 Then(). 47 Given(). 48 Revision("master"). 49 When(). 50 // ensure that update replaces spec and merge labels and annotations 51 And(func() { 52 errors.NewHandler(t).FailOnErr(fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Patch(t.Context(), 53 ctx.GetName(), types.MergePatchType, []byte(`{"metadata": {"labels": { "test": "label" }, "annotations": { "test": "annotation" }}}`), metav1.PatchOptions{})) 54 }). 55 CreateApp("--upsert"). 56 Then(). 57 And(func(app *Application) { 58 assert.Equal(t, "label", app.Labels["test"]) 59 assert.Equal(t, "annotation", app.Annotations["test"]) 60 assert.Equal(t, "master", app.Spec.GetSource().TargetRevision) 61 }) 62 63 // Make a request to the app controller metrics endpoint and ensure the response contains kubectl metrics. 64 resp, err := http.Get("http://127.0.0.1:8082/metrics") 65 require.NoError(t, err) 66 defer func() { 67 err = resp.Body.Close() 68 require.NoError(t, err) 69 }() 70 body, err := io.ReadAll(resp.Body) 71 require.NoError(t, err) 72 assert.Equal(t, http.StatusOK, resp.StatusCode) 73 74 assert.Contains(t, string(body), "argocd_kubectl_request_duration_seconds", "metrics should have contained argocd_kubectl_request_duration_seconds") 75 assert.Contains(t, string(body), "argocd_kubectl_request_size_bytes", "metrics should have contained argocd_kubectl_request_size_bytes") 76 assert.Contains(t, string(body), "argocd_kubectl_response_size_bytes", "metrics should have contained argocd_kubectl_response_size_bytes") 77 assert.Contains(t, string(body), "argocd_kubectl_rate_limiter_duration_seconds", "metrics should have contained argocd_kubectl_rate_limiter_duration_seconds") 78 assert.Contains(t, string(body), "argocd_kubectl_requests_total", "metrics should have contained argocd_kubectl_requests_total") 79 80 /* 81 The following metrics are not being tested: 82 - argocd_kubectl_client_cert_rotation_age_seconds: The test doesn't use a client certificate, so this metric doesn't get populated. 83 - argocd_kubectl_dns_resolution_duration_seconds: It's unclear why this metric isn't populated. Possibly because DNS resolution is short-circuited by the test environment. 84 - argocd_kubectl_exec_plugin_call_total: The test doesn't use an exec plugin, so this metric doesn't get populated. TODO: add a test using an exec plugin to populate this metric. 85 - argocd_kubectl_request_retries_total: The test is unlikely to encounter a need to retry requests, so this metric is likely unpopulated. 86 - argocd_kubectl_transport_cache_entries: The transport cache is only used under certain conditions, which this test doesn't encounter. 87 - argocd_kubectl_transport_create_calls_total: The transport cache is only used under certain conditions, which this test doesn't encounter. 88 */ 89 90 // Repeat the test for port 8083, i.e. the API server. 91 resp, err = http.Get("http://127.0.0.1:8083/metrics") 92 require.NoError(t, err) 93 defer func() { 94 err = resp.Body.Close() 95 require.NoError(t, err) 96 }() 97 body, err = io.ReadAll(resp.Body) 98 require.NoError(t, err) 99 assert.Equal(t, http.StatusOK, resp.StatusCode) 100 101 assert.Contains(t, string(body), "argocd_kubectl_request_duration_seconds", "metrics should have contained argocd_kubectl_request_duration_seconds") 102 assert.Contains(t, string(body), "argocd_kubectl_request_size_bytes", "metrics should have contained argocd_kubectl_request_size_bytes") 103 assert.Contains(t, string(body), "argocd_kubectl_response_size_bytes", "metrics should have contained argocd_kubectl_response_size_bytes") 104 assert.Contains(t, string(body), "argocd_kubectl_rate_limiter_duration_seconds", "metrics should have contained argocd_kubectl_rate_limiter_duration_seconds") 105 assert.Contains(t, string(body), "argocd_kubectl_requests_total", "metrics should have contained argocd_kubectl_requests_total") 106 assert.Contains(t, string(body), "grpc_server_handled_total", "metrics should have contained grpc_server_handled_total for all the reflected methods") 107 assert.Contains(t, string(body), "grpc_server_msg_received_total", "metrics should have contained grpc_server_msg_received_total for all the reflected methods") 108 }