github.com/thanos-io/thanos@v0.32.5/pkg/metadata/prometheus_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package metadata 5 6 import ( 7 "context" 8 "fmt" 9 "net/http" 10 "net/url" 11 "testing" 12 "time" 13 14 "github.com/go-kit/log" 15 "github.com/pkg/errors" 16 "github.com/prometheus/prometheus/storage" 17 18 "github.com/efficientgo/core/testutil" 19 "github.com/thanos-io/thanos/pkg/metadata/metadatapb" 20 "github.com/thanos-io/thanos/pkg/promclient" 21 "github.com/thanos-io/thanos/pkg/runutil" 22 "github.com/thanos-io/thanos/pkg/testutil/custom" 23 "github.com/thanos-io/thanos/pkg/testutil/e2eutil" 24 ) 25 26 func TestMain(m *testing.M) { 27 custom.TolerantVerifyLeakMain(m) 28 } 29 30 func TestPrometheus_Metadata_e2e(t *testing.T) { 31 p, err := e2eutil.NewPrometheus() 32 testutil.Ok(t, err) 33 defer func() { testutil.Ok(t, p.Stop()) }() 34 35 p.SetConfig(fmt.Sprintf(` 36 global: 37 external_labels: 38 region: eu-west 39 scrape_configs: 40 - job_name: 'myself' 41 # Quick scrapes for test purposes. 42 scrape_interval: 1s 43 scrape_timeout: 1s 44 static_configs: 45 - targets: ['%s'] 46 `, e2eutil.PromAddrPlaceHolder)) 47 testutil.Ok(t, p.Start()) 48 49 ctx, cancel := context.WithCancel(context.Background()) 50 defer cancel() 51 52 upctx, upcancel := context.WithTimeout(ctx, 10*time.Second) 53 defer upcancel() 54 55 logger := log.NewNopLogger() 56 err = p.WaitPrometheusUp(upctx, logger) 57 testutil.Ok(t, err) 58 59 u, err := url.Parse("http://" + p.Addr()) 60 testutil.Ok(t, err) 61 62 c := promclient.NewClient(http.DefaultClient, logger, "") 63 64 // Wait metadata response to be ready as Prometheus gets metadata after scrape. 65 testutil.Ok(t, runutil.Retry(3*time.Second, ctx.Done(), func() error { 66 meta, err := c.MetricMetadataInGRPC(ctx, u, "", -1) 67 testutil.Ok(t, err) 68 if len(meta) > 0 { 69 return nil 70 } 71 return errors.New("empty metadata response from Prometheus") 72 })) 73 74 grpcClient := NewGRPCClient(NewPrometheus(u, c)) 75 for _, tcase := range []struct { 76 name string 77 metric string 78 limit int32 79 expectedFunc func(map[string][]metadatapb.Meta) bool 80 }{ 81 { 82 name: "all metadata return", 83 limit: -1, 84 // We just check two metrics here. 85 expectedFunc: func(m map[string][]metadatapb.Meta) bool { 86 return len(m["prometheus_build_info"]) > 0 && len(m["prometheus_engine_query_duration_seconds"]) > 0 87 }, 88 }, 89 { 90 name: "no metadata return", 91 limit: 0, 92 expectedFunc: func(m map[string][]metadatapb.Meta) bool { 93 return len(m) == 0 94 }, 95 }, 96 { 97 name: "only 1 metadata return", 98 limit: 1, 99 expectedFunc: func(m map[string][]metadatapb.Meta) bool { 100 return len(m) == 1 101 }, 102 }, 103 { 104 name: "only prometheus_build_info metadata return", 105 metric: "prometheus_build_info", 106 limit: 1, 107 expectedFunc: func(m map[string][]metadatapb.Meta) bool { 108 return len(m) == 1 && len(m["prometheus_build_info"]) > 0 109 }, 110 }, 111 } { 112 t.Run(tcase.name, func(t *testing.T) { 113 meta, w, err := grpcClient.MetricMetadata(ctx, &metadatapb.MetricMetadataRequest{ 114 Metric: tcase.metric, 115 Limit: tcase.limit, 116 }) 117 118 testutil.Equals(t, storage.Warnings(nil), w) 119 testutil.Ok(t, err) 120 testutil.Assert(t, tcase.expectedFunc(meta)) 121 }) 122 } 123 }