prometheus

Форк
0
/
http_test.go 
456 строк · 11.7 Кб
1
// Copyright 2021 The Prometheus Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13

14
package http
15

16
import (
17
	"context"
18
	"fmt"
19
	"net/http"
20
	"net/http/httptest"
21
	"testing"
22
	"time"
23

24
	"github.com/go-kit/log"
25
	"github.com/prometheus/client_golang/prometheus"
26
	dto "github.com/prometheus/client_model/go"
27
	"github.com/prometheus/common/config"
28
	"github.com/prometheus/common/model"
29
	"github.com/stretchr/testify/require"
30

31
	"github.com/prometheus/prometheus/discovery"
32
	"github.com/prometheus/prometheus/discovery/targetgroup"
33
)
34

35
func TestHTTPValidRefresh(t *testing.T) {
36
	ts := httptest.NewServer(http.FileServer(http.Dir("./fixtures")))
37
	t.Cleanup(ts.Close)
38

39
	cfg := SDConfig{
40
		HTTPClientConfig: config.DefaultHTTPClientConfig,
41
		URL:              ts.URL + "/http_sd.good.json",
42
		RefreshInterval:  model.Duration(30 * time.Second),
43
	}
44

45
	reg := prometheus.NewRegistry()
46
	refreshMetrics := discovery.NewRefreshMetrics(reg)
47
	defer refreshMetrics.Unregister()
48
	metrics := cfg.NewDiscovererMetrics(reg, refreshMetrics)
49
	require.NoError(t, metrics.Register())
50
	defer metrics.Unregister()
51

52
	d, err := NewDiscovery(&cfg, log.NewNopLogger(), nil, metrics)
53
	require.NoError(t, err)
54

55
	ctx := context.Background()
56
	tgs, err := d.Refresh(ctx)
57
	require.NoError(t, err)
58

59
	expectedTargets := []*targetgroup.Group{
60
		{
61
			Targets: []model.LabelSet{
62
				{
63
					model.AddressLabel: model.LabelValue("127.0.0.1:9090"),
64
				},
65
			},
66
			Labels: model.LabelSet{
67
				model.LabelName("__meta_datacenter"): model.LabelValue("bru1"),
68
				model.LabelName("__meta_url"):        model.LabelValue(ts.URL + "/http_sd.good.json"),
69
			},
70
			Source: urlSource(ts.URL+"/http_sd.good.json", 0),
71
		},
72
	}
73
	require.Equal(t, expectedTargets, tgs)
74
	require.Equal(t, 0.0, getFailureCount(d.metrics.failuresCount))
75
}
76

77
func TestHTTPInvalidCode(t *testing.T) {
78
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
79
		w.WriteHeader(http.StatusBadRequest)
80
	}))
81

82
	t.Cleanup(ts.Close)
83

84
	cfg := SDConfig{
85
		HTTPClientConfig: config.DefaultHTTPClientConfig,
86
		URL:              ts.URL,
87
		RefreshInterval:  model.Duration(30 * time.Second),
88
	}
89

90
	reg := prometheus.NewRegistry()
91
	refreshMetrics := discovery.NewRefreshMetrics(reg)
92
	defer refreshMetrics.Unregister()
93
	metrics := cfg.NewDiscovererMetrics(reg, refreshMetrics)
94
	require.NoError(t, metrics.Register())
95
	defer metrics.Unregister()
96

97
	d, err := NewDiscovery(&cfg, log.NewNopLogger(), nil, metrics)
98
	require.NoError(t, err)
99

100
	ctx := context.Background()
101
	_, err = d.Refresh(ctx)
102
	require.EqualError(t, err, "server returned HTTP status 400 Bad Request")
103
	require.Equal(t, 1.0, getFailureCount(d.metrics.failuresCount))
104
}
105

106
func TestHTTPInvalidFormat(t *testing.T) {
107
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
108
		fmt.Fprintln(w, "{}")
109
	}))
110

111
	t.Cleanup(ts.Close)
112

113
	cfg := SDConfig{
114
		HTTPClientConfig: config.DefaultHTTPClientConfig,
115
		URL:              ts.URL,
116
		RefreshInterval:  model.Duration(30 * time.Second),
117
	}
118

119
	reg := prometheus.NewRegistry()
120
	refreshMetrics := discovery.NewRefreshMetrics(reg)
121
	defer refreshMetrics.Unregister()
122
	metrics := cfg.NewDiscovererMetrics(reg, refreshMetrics)
123
	require.NoError(t, metrics.Register())
124
	defer metrics.Unregister()
125

126
	d, err := NewDiscovery(&cfg, log.NewNopLogger(), nil, metrics)
127
	require.NoError(t, err)
128

129
	ctx := context.Background()
130
	_, err = d.Refresh(ctx)
131
	require.EqualError(t, err, `unsupported content type "text/plain; charset=utf-8"`)
132
	require.Equal(t, 1.0, getFailureCount(d.metrics.failuresCount))
133
}
134

135
func getFailureCount(failuresCount prometheus.Counter) float64 {
136
	failureChan := make(chan prometheus.Metric)
137

138
	go func() {
139
		failuresCount.Collect(failureChan)
140
		close(failureChan)
141
	}()
142

143
	var counter dto.Metric
144
	for {
145
		metric, ok := <-failureChan
146
		if ok == false {
147
			break
148
		}
149
		metric.Write(&counter)
150
	}
151

152
	return *counter.Counter.Value
153
}
154

155
func TestContentTypeRegex(t *testing.T) {
156
	cases := []struct {
157
		header string
158
		match  bool
159
	}{
160
		{
161
			header: "application/json;charset=utf-8",
162
			match:  true,
163
		},
164
		{
165
			header: "application/json;charset=UTF-8",
166
			match:  true,
167
		},
168
		{
169
			header: "Application/JSON;Charset=\"utf-8\"",
170
			match:  true,
171
		},
172
		{
173
			header: "application/json; charset=\"utf-8\"",
174
			match:  true,
175
		},
176
		{
177
			header: "application/json",
178
			match:  true,
179
		},
180
		{
181
			header: "application/jsonl; charset=\"utf-8\"",
182
			match:  false,
183
		},
184
		{
185
			header: "application/json;charset=UTF-9",
186
			match:  false,
187
		},
188
		{
189
			header: "application /json;charset=UTF-8",
190
			match:  false,
191
		},
192
		{
193
			header: "application/ json;charset=UTF-8",
194
			match:  false,
195
		},
196
		{
197
			header: "application/json;",
198
			match:  false,
199
		},
200
		{
201
			header: "charset=UTF-8",
202
			match:  false,
203
		},
204
	}
205

206
	for _, test := range cases {
207
		t.Run(test.header, func(t *testing.T) {
208
			require.Equal(t, test.match, matchContentType.MatchString(test.header))
209
		})
210
	}
211
}
212

213
func TestSourceDisappeared(t *testing.T) {
214
	var stubResponse string
215
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
216
		w.Header().Set("Content-Type", "application/json")
217
		fmt.Fprintln(w, stubResponse)
218
	}))
219
	t.Cleanup(ts.Close)
220

221
	cases := []struct {
222
		responses       []string
223
		expectedTargets [][]*targetgroup.Group
224
	}{
225
		{
226
			responses: []string{
227
				`[]`,
228
				`[]`,
229
			},
230
			expectedTargets: [][]*targetgroup.Group{{}, {}},
231
		},
232
		{
233
			responses: []string{
234
				`[{"labels": {"k": "1"}, "targets": ["127.0.0.1"]}]`,
235
				`[{"labels": {"k": "1"}, "targets": ["127.0.0.1"]}, {"labels": {"k": "2"}, "targets": ["127.0.0.1"]}]`,
236
			},
237
			expectedTargets: [][]*targetgroup.Group{
238
				{
239
					{
240
						Targets: []model.LabelSet{
241
							{
242
								model.AddressLabel: model.LabelValue("127.0.0.1"),
243
							},
244
						},
245
						Labels: model.LabelSet{
246
							model.LabelName("k"):          model.LabelValue("1"),
247
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
248
						},
249
						Source: urlSource(ts.URL, 0),
250
					},
251
				},
252
				{
253
					{
254
						Targets: []model.LabelSet{
255
							{
256
								model.AddressLabel: model.LabelValue("127.0.0.1"),
257
							},
258
						},
259
						Labels: model.LabelSet{
260
							model.LabelName("k"):          model.LabelValue("1"),
261
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
262
						},
263
						Source: urlSource(ts.URL, 0),
264
					},
265
					{
266
						Targets: []model.LabelSet{
267
							{
268
								model.AddressLabel: model.LabelValue("127.0.0.1"),
269
							},
270
						},
271
						Labels: model.LabelSet{
272
							model.LabelName("k"):          model.LabelValue("2"),
273
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
274
						},
275
						Source: urlSource(ts.URL, 1),
276
					},
277
				},
278
			},
279
		},
280
		{
281
			responses: []string{
282
				`[{"labels": {"k": "1"}, "targets": ["127.0.0.1"]}, {"labels": {"k": "2"}, "targets": ["127.0.0.1"]}]`,
283
				`[{"labels": {"k": "1"}, "targets": ["127.0.0.1"]}]`,
284
			},
285
			expectedTargets: [][]*targetgroup.Group{
286
				{
287
					{
288
						Targets: []model.LabelSet{
289
							{
290
								model.AddressLabel: model.LabelValue("127.0.0.1"),
291
							},
292
						},
293
						Labels: model.LabelSet{
294
							model.LabelName("k"):          model.LabelValue("1"),
295
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
296
						},
297
						Source: urlSource(ts.URL, 0),
298
					},
299
					{
300
						Targets: []model.LabelSet{
301
							{
302
								model.AddressLabel: model.LabelValue("127.0.0.1"),
303
							},
304
						},
305
						Labels: model.LabelSet{
306
							model.LabelName("k"):          model.LabelValue("2"),
307
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
308
						},
309
						Source: urlSource(ts.URL, 1),
310
					},
311
				},
312
				{
313
					{
314
						Targets: []model.LabelSet{
315
							{
316
								model.AddressLabel: model.LabelValue("127.0.0.1"),
317
							},
318
						},
319
						Labels: model.LabelSet{
320
							model.LabelName("k"):          model.LabelValue("1"),
321
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
322
						},
323
						Source: urlSource(ts.URL, 0),
324
					},
325
					{
326
						Targets: nil,
327
						Labels:  nil,
328
						Source:  urlSource(ts.URL, 1),
329
					},
330
				},
331
			},
332
		},
333
		{
334
			responses: []string{
335
				`[{"labels": {"k": "1"}, "targets": ["127.0.0.1"]}, {"labels": {"k": "2"}, "targets": ["127.0.0.1"]}, {"labels": {"k": "3"}, "targets": ["127.0.0.1"]}]`,
336
				`[{"labels": {"k": "1"}, "targets": ["127.0.0.1"]}]`,
337
				`[{"labels": {"k": "v"}, "targets": ["127.0.0.2"]}, {"labels": {"k": "vv"}, "targets": ["127.0.0.3"]}]`,
338
			},
339
			expectedTargets: [][]*targetgroup.Group{
340
				{
341
					{
342
						Targets: []model.LabelSet{
343
							{
344
								model.AddressLabel: model.LabelValue("127.0.0.1"),
345
							},
346
						},
347
						Labels: model.LabelSet{
348
							model.LabelName("k"):          model.LabelValue("1"),
349
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
350
						},
351
						Source: urlSource(ts.URL, 0),
352
					},
353
					{
354
						Targets: []model.LabelSet{
355
							{
356
								model.AddressLabel: model.LabelValue("127.0.0.1"),
357
							},
358
						},
359
						Labels: model.LabelSet{
360
							model.LabelName("k"):          model.LabelValue("2"),
361
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
362
						},
363
						Source: urlSource(ts.URL, 1),
364
					},
365
					{
366
						Targets: []model.LabelSet{
367
							{
368
								model.AddressLabel: model.LabelValue("127.0.0.1"),
369
							},
370
						},
371
						Labels: model.LabelSet{
372
							model.LabelName("k"):          model.LabelValue("3"),
373
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
374
						},
375
						Source: urlSource(ts.URL, 2),
376
					},
377
				},
378
				{
379
					{
380
						Targets: []model.LabelSet{
381
							{
382
								model.AddressLabel: model.LabelValue("127.0.0.1"),
383
							},
384
						},
385
						Labels: model.LabelSet{
386
							model.LabelName("k"):          model.LabelValue("1"),
387
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
388
						},
389
						Source: urlSource(ts.URL, 0),
390
					},
391
					{
392
						Targets: nil,
393
						Labels:  nil,
394
						Source:  urlSource(ts.URL, 1),
395
					},
396
					{
397
						Targets: nil,
398
						Labels:  nil,
399
						Source:  urlSource(ts.URL, 2),
400
					},
401
				},
402
				{
403
					{
404
						Targets: []model.LabelSet{
405
							{
406
								model.AddressLabel: model.LabelValue("127.0.0.2"),
407
							},
408
						},
409
						Labels: model.LabelSet{
410
							model.LabelName("k"):          model.LabelValue("v"),
411
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
412
						},
413
						Source: urlSource(ts.URL, 0),
414
					},
415
					{
416
						Targets: []model.LabelSet{
417
							{
418
								model.AddressLabel: model.LabelValue("127.0.0.3"),
419
							},
420
						},
421
						Labels: model.LabelSet{
422
							model.LabelName("k"):          model.LabelValue("vv"),
423
							model.LabelName("__meta_url"): model.LabelValue(ts.URL),
424
						},
425
						Source: urlSource(ts.URL, 1),
426
					},
427
				},
428
			},
429
		},
430
	}
431

432
	cfg := SDConfig{
433
		HTTPClientConfig: config.DefaultHTTPClientConfig,
434
		URL:              ts.URL,
435
		RefreshInterval:  model.Duration(1 * time.Second),
436
	}
437

438
	reg := prometheus.NewRegistry()
439
	refreshMetrics := discovery.NewRefreshMetrics(reg)
440
	defer refreshMetrics.Unregister()
441
	metrics := cfg.NewDiscovererMetrics(reg, refreshMetrics)
442
	require.NoError(t, metrics.Register())
443
	defer metrics.Unregister()
444

445
	d, err := NewDiscovery(&cfg, log.NewNopLogger(), nil, metrics)
446
	require.NoError(t, err)
447
	for _, test := range cases {
448
		ctx := context.Background()
449
		for i, res := range test.responses {
450
			stubResponse = res
451
			tgs, err := d.Refresh(ctx)
452
			require.NoError(t, err)
453
			require.Equal(t, test.expectedTargets[i], tgs)
454
		}
455
	}
456
}
457

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.