cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.83.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/promapi/buildinfo_test.go

136lines · modecode

1package promapi_test
2
3import (
4 "net/http"
5 "testing"
6 "time"
7
8 "github.com/prometheus/client_golang/prometheus"
9 "github.com/stretchr/testify/require"
10 "go.nhat.io/httpmock"
11
12 "github.com/cloudflare/pint/internal/promapi"
13)
14
15func TestBuildInfo(t *testing.T) {
16 type testCaseT struct {
17 mock httpmock.Mocker
18 assertErr func(t *testing.T, err error)
19 name string
20 version string
21 timeout time.Duration
22 }
23
24 testCases := []testCaseT{
25 // Verifies that a valid buildinfo response is parsed correctly.
26 {
27 name: "success",
28 timeout: time.Second,
29 version: "2.49.0",
30 assertErr: func(t *testing.T, err error) {
31 require.NoError(t, err)
32 },
33 mock: httpmock.New(func(s *httpmock.Server) {
34 s.ExpectGet(promapi.APIPathBuildInfo).
35 ReturnHeader("Content-Type", "application/json").
36 Return(`{"status":"success","data":{"version":"2.49.0","revision":"abc","branch":"HEAD","buildUser":"","buildDate":"","goVersion":"go1.21"}}`).
37 UnlimitedTimes()
38 }),
39 },
40 // Verifies that a request timeout produces a connection timeout error.
41 {
42 name: "slow",
43 timeout: time.Millisecond * 10,
44 assertErr: func(t *testing.T, err error) {
45 require.EqualError(t, err, "connection timeout")
46 },
47 mock: httpmock.New(func(s *httpmock.Server) {
48 s.ExpectGet(promapi.APIPathBuildInfo).
49 Run(func(_ *http.Request) ([]byte, error) {
50 time.Sleep(time.Second * 2)
51 return []byte(`{"status":"success","data":{"version":"2.49.0","revision":"abc","branch":"HEAD","buildUser":"","buildDate":"","goVersion":"go1.21"}}`), nil
52 }).
53 UnlimitedTimes()
54 }),
55 },
56 // Verifies that a non-2xx HTTP status produces a server error.
57 {
58 name: "error",
59 timeout: time.Second,
60 assertErr: func(t *testing.T, err error) {
61 require.EqualError(t, err, "server_error: 500 Internal Server Error")
62 },
63 mock: httpmock.New(func(s *httpmock.Server) {
64 s.ExpectGet(promapi.APIPathBuildInfo).
65 ReturnCode(http.StatusInternalServerError).
66 Return("fake error\n").
67 UnlimitedTimes()
68 }),
69 },
70 // Verifies that invalid JSON produces a bad_response error.
71 {
72 name: "badJson",
73 timeout: time.Second,
74 assertErr: func(t *testing.T, err error) {
75 require.EqualError(
76 t, err,
77 `bad_response: JSON parse error: invalid character '}' after object key`,
78 )
79 },
80 mock: httpmock.New(func(s *httpmock.Server) {
81 s.ExpectGet(promapi.APIPathBuildInfo).
82 ReturnHeader("Content-Type", "application/json").
83 Return(`{"status":"success","data":{"xxx"}}`).
84 UnlimitedTimes()
85 }),
86 },
87 // Verifies that an API-level error with a custom message is forwarded.
88 {
89 name: "apiError",
90 timeout: time.Second,
91 assertErr: func(t *testing.T, err error) {
92 require.EqualError(t, err, "bad_data: custom error message")
93 },
94 mock: httpmock.New(func(s *httpmock.Server) {
95 s.ExpectGet(promapi.APIPathBuildInfo).
96 ReturnHeader("Content-Type", "application/json").
97 Return(`{"status":"error","errorType":"bad_data","error":"custom error message"}`).
98 UnlimitedTimes()
99 }),
100 },
101 // Verifies that an API-level error without a message uses the fallback.
102 {
103 name: "emptyError",
104 timeout: time.Second,
105 assertErr: func(t *testing.T, err error) {
106 require.EqualError(t, err, "bad_data: empty response object")
107 },
108 mock: httpmock.New(func(s *httpmock.Server) {
109 s.ExpectGet(promapi.APIPathBuildInfo).
110 ReturnHeader("Content-Type", "application/json").
111 Return(`{"status":"error","errorType":"bad_data"}`).
112 UnlimitedTimes()
113 }),
114 },
115 }
116
117 for _, tc := range testCases {
118 t.Run(tc.name, func(t *testing.T) {
119 srv := tc.mock(t)
120
121 fg := promapi.NewFailoverGroup("test", srv.URL(), []*promapi.Prometheus{
122 promapi.NewPrometheus("test", srv.URL(), "", nil, tc.timeout, 1, 100, nil),
123 }, true, "up", nil, nil, nil)
124
125 reg := prometheus.NewRegistry()
126 fg.StartWorkers(reg)
127 defer fg.Close(reg)
128
129 bi, err := fg.BuildInfo(t.Context())
130 tc.assertErr(t, err)
131 if bi != nil {
132 require.Equal(t, tc.version, bi.Version)
133 }
134 })
135 }
136}
137