cloudflare/pint
Publicmirrored from https://github.com/cloudflare/pintAvailable
internal/promapi/metadata_test.go
148lines · modecode
| 1 | package promapi_test |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "fmt" |
| 6 | "net/http" |
| 7 | "net/http/httptest" |
| 8 | "sync" |
| 9 | "testing" |
| 10 | "time" |
| 11 | |
| 12 | v1 "github.com/prometheus/client_golang/api/prometheus/v1" |
| 13 | "github.com/stretchr/testify/assert" |
| 14 | |
| 15 | "github.com/cloudflare/pint/internal/promapi" |
| 16 | ) |
| 17 | |
| 18 | func TestMedatata(t *testing.T) { |
| 19 | done := sync.Map{} |
| 20 | srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 21 | err := r.ParseForm() |
| 22 | if err != nil { |
| 23 | t.Fatal(err) |
| 24 | } |
| 25 | metric := r.Form.Get("metric") |
| 26 | |
| 27 | switch metric { |
| 28 | case "gauge": |
| 29 | w.WriteHeader(200) |
| 30 | w.Header().Set("Content-Type", "application/json") |
| 31 | _, _ = w.Write([]byte(`{"status":"success","data":{"gauge":[{"type":"gauge","help":"Text","unit":""}]}}`)) |
| 32 | case "counter": |
| 33 | w.WriteHeader(200) |
| 34 | w.Header().Set("Content-Type", "application/json") |
| 35 | _, _ = w.Write([]byte(`{"status":"success","data":{"counter":[{"type":"counter","help":"Text","unit":""}]}}`)) |
| 36 | case "notfound": |
| 37 | w.WriteHeader(200) |
| 38 | w.Header().Set("Content-Type", "application/json") |
| 39 | _, _ = w.Write([]byte(`{"status":"success","data":{}}`)) |
| 40 | case "once": |
| 41 | if _, wasDone := done.Load(r.URL.Path); wasDone { |
| 42 | w.WriteHeader(500) |
| 43 | _, _ = w.Write([]byte("path already requested\n")) |
| 44 | return |
| 45 | } |
| 46 | w.WriteHeader(200) |
| 47 | w.Header().Set("Content-Type", "application/json") |
| 48 | _, _ = w.Write([]byte(`{"status":"success","data":{"once":[{"type":"gauge","help":"Text","unit":""}]}}`)) |
| 49 | done.Store(r.URL.Path, true) |
| 50 | case "slow": |
| 51 | w.WriteHeader(200) |
| 52 | w.Header().Set("Content-Type", "application/json") |
| 53 | time.Sleep(time.Second) |
| 54 | _, _ = w.Write([]byte(`{"status":"success","data":{"once":[{"type":"gauge","help":"Text","unit":""}]}}`)) |
| 55 | case "error": |
| 56 | w.WriteHeader(500) |
| 57 | _, _ = w.Write([]byte("fake error\n")) |
| 58 | default: |
| 59 | w.WriteHeader(400) |
| 60 | w.Header().Set("Content-Type", "application/json") |
| 61 | _, _ = w.Write([]byte(`{"status":"error","errorType":"bad_data","error":"unhandled metric"}`)) |
| 62 | } |
| 63 | })) |
| 64 | defer srv.Close() |
| 65 | |
| 66 | type testCaseT struct { |
| 67 | metric string |
| 68 | timeout time.Duration |
| 69 | metadata promapi.MetadataResult |
| 70 | err string |
| 71 | runs int |
| 72 | } |
| 73 | |
| 74 | testCases := []testCaseT{ |
| 75 | { |
| 76 | metric: "gauge", |
| 77 | timeout: time.Second, |
| 78 | metadata: promapi.MetadataResult{ |
| 79 | URI: srv.URL, |
| 80 | Metadata: []v1.Metadata{{Type: "gauge", Help: "Text", Unit: ""}}, |
| 81 | }, |
| 82 | runs: 5, |
| 83 | }, |
| 84 | { |
| 85 | metric: "counter", |
| 86 | timeout: time.Second, |
| 87 | metadata: promapi.MetadataResult{ |
| 88 | URI: srv.URL, |
| 89 | Metadata: []v1.Metadata{{Type: "counter", Help: "Text", Unit: ""}}, |
| 90 | }, |
| 91 | runs: 5, |
| 92 | }, |
| 93 | { |
| 94 | metric: "slow", |
| 95 | timeout: time.Millisecond * 10, |
| 96 | err: fmt.Sprintf(`failed to query Prometheus metric metadata: Get "%s/api/v1/metadata?limit=&metric=slow": context deadline exceeded`, srv.URL), |
| 97 | runs: 5, |
| 98 | }, |
| 99 | { |
| 100 | metric: "error", |
| 101 | timeout: time.Second, |
| 102 | err: "failed to query Prometheus metric metadata: server_error: server error: 500", |
| 103 | runs: 5, |
| 104 | }, |
| 105 | { |
| 106 | metric: "once", |
| 107 | timeout: time.Second, |
| 108 | metadata: promapi.MetadataResult{ |
| 109 | URI: srv.URL, |
| 110 | Metadata: []v1.Metadata{{Type: "gauge", Help: "Text", Unit: ""}}, |
| 111 | }, |
| 112 | runs: 10, |
| 113 | }, |
| 114 | // make sure /once fails on second query |
| 115 | { |
| 116 | metric: "once", |
| 117 | timeout: time.Second, |
| 118 | runs: 2, |
| 119 | err: "failed to query Prometheus metric metadata: server_error: server error: 500", |
| 120 | }, |
| 121 | } |
| 122 | |
| 123 | for _, tc := range testCases { |
| 124 | t.Run(tc.metric, func(t *testing.T) { |
| 125 | assert := assert.New(t) |
| 126 | |
| 127 | prom := promapi.NewPrometheus("test", srv.URL, tc.timeout) |
| 128 | |
| 129 | wg := sync.WaitGroup{} |
| 130 | wg.Add(tc.runs) |
| 131 | for i := 1; i <= tc.runs; i++ { |
| 132 | go func() { |
| 133 | metadata, err := prom.Metadata(context.Background(), tc.metric) |
| 134 | if tc.err != "" { |
| 135 | assert.EqualError(err, tc.err, tc) |
| 136 | } else { |
| 137 | assert.NoError(err) |
| 138 | } |
| 139 | if metadata != nil { |
| 140 | assert.Equal(*metadata, tc.metadata) |
| 141 | } |
| 142 | wg.Done() |
| 143 | }() |
| 144 | } |
| 145 | wg.Wait() |
| 146 | }) |
| 147 | } |
| 148 | } |
| 149 | |