Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/metrics/http_test.go
4093 views
1
package metrics
2
3
import (
4
"fmt"
5
"net/http"
6
"net/http/httptest"
7
"testing"
8
"time"
9
10
"github.com/cortexproject/cortex/pkg/util/test"
11
"github.com/go-kit/log"
12
"github.com/grafana/agent/pkg/metrics/instance"
13
"github.com/prometheus/client_golang/prometheus"
14
"github.com/prometheus/common/model"
15
"github.com/prometheus/prometheus/model/labels"
16
"github.com/prometheus/prometheus/scrape"
17
"github.com/stretchr/testify/require"
18
)
19
20
func TestAgent_ListInstancesHandler(t *testing.T) {
21
fact := newFakeInstanceFactory()
22
a, err := newAgent(prometheus.NewRegistry(), Config{
23
WALDir: "/tmp/agent",
24
}, log.NewNopLogger(), fact.factory)
25
require.NoError(t, err)
26
defer a.Stop()
27
28
r := httptest.NewRequest("GET", "/agent/api/v1/metrics/instances", nil)
29
30
t.Run("no instances", func(t *testing.T) {
31
rr := httptest.NewRecorder()
32
a.ListInstancesHandler(rr, r)
33
expect := `{"status":"success","data":[]}`
34
require.Equal(t, expect, rr.Body.String())
35
})
36
37
t.Run("non-empty", func(t *testing.T) {
38
require.NoError(t, a.mm.ApplyConfig(makeInstanceConfig("foo")))
39
require.NoError(t, a.mm.ApplyConfig(makeInstanceConfig("bar")))
40
41
expect := `{"status":"success","data":["bar","foo"]}`
42
test.Poll(t, time.Second, true, func() interface{} {
43
rr := httptest.NewRecorder()
44
a.ListInstancesHandler(rr, r)
45
return expect == rr.Body.String()
46
})
47
})
48
}
49
50
func TestAgent_ListTargetsHandler(t *testing.T) {
51
fact := newFakeInstanceFactory()
52
a, err := newAgent(prometheus.NewRegistry(), Config{
53
WALDir: "/tmp/agent",
54
}, log.NewNopLogger(), fact.factory)
55
require.NoError(t, err)
56
57
mockManager := &instance.MockManager{
58
ListInstancesFunc: func() map[string]instance.ManagedInstance { return nil },
59
ListConfigsFunc: func() map[string]instance.Config { return nil },
60
ApplyConfigFunc: func(_ instance.Config) error { return nil },
61
DeleteConfigFunc: func(name string) error { return nil },
62
StopFunc: func() {},
63
}
64
a.mm, err = instance.NewModalManager(prometheus.NewRegistry(), a.logger, mockManager, instance.ModeDistinct)
65
require.NoError(t, err)
66
67
r := httptest.NewRequest("GET", "/agent/api/v1/metrics/targets", nil)
68
69
t.Run("scrape manager not ready", func(t *testing.T) {
70
mockManager.ListInstancesFunc = func() map[string]instance.ManagedInstance {
71
return map[string]instance.ManagedInstance{
72
"test_instance": &mockInstanceScrape{},
73
}
74
}
75
76
rr := httptest.NewRecorder()
77
a.ListTargetsHandler(rr, r)
78
expect := `{"status": "success", "data": []}`
79
require.JSONEq(t, expect, rr.Body.String())
80
require.Equal(t, http.StatusOK, rr.Result().StatusCode)
81
})
82
83
t.Run("scrape manager targets", func(t *testing.T) {
84
tgt := scrape.NewTarget(labels.FromMap(map[string]string{
85
model.JobLabel: "job",
86
model.InstanceLabel: "instance",
87
"foo": "bar",
88
model.SchemeLabel: "http",
89
model.AddressLabel: "localhost:12345",
90
model.MetricsPathLabel: "/metrics",
91
}), labels.FromMap(map[string]string{
92
"__discovered__": "yes",
93
}), nil)
94
95
startTime := time.Date(1994, time.January, 12, 0, 0, 0, 0, time.UTC)
96
tgt.Report(startTime, time.Minute, fmt.Errorf("something went wrong"))
97
98
mockManager.ListInstancesFunc = func() map[string]instance.ManagedInstance {
99
return map[string]instance.ManagedInstance{
100
"test_instance": &mockInstanceScrape{
101
tgts: map[string][]*scrape.Target{
102
"group_a": {tgt},
103
},
104
},
105
}
106
}
107
108
rr := httptest.NewRecorder()
109
a.ListTargetsHandler(rr, r)
110
expect := `{
111
"status": "success",
112
"data": [{
113
"instance": "test_instance",
114
"target_group": "group_a",
115
"endpoint": "http://localhost:12345/metrics",
116
"state": "down",
117
"labels": {
118
"foo": "bar",
119
"instance": "instance",
120
"job": "job"
121
},
122
"discovered_labels": {
123
"__discovered__": "yes"
124
},
125
"last_scrape": "1994-01-12T00:00:00Z",
126
"scrape_duration_ms": 60000,
127
"scrape_error":"something went wrong"
128
}]
129
}`
130
require.JSONEq(t, expect, rr.Body.String())
131
require.Equal(t, http.StatusOK, rr.Result().StatusCode)
132
})
133
}
134
135
type mockInstanceScrape struct {
136
instance.NoOpInstance
137
tgts map[string][]*scrape.Target
138
}
139
140
func (i *mockInstanceScrape) TargetsActive() map[string][]*scrape.Target {
141
return i.tgts
142
}
143
144