Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/metrics/instance/configstore/remote_test.go
5340 views
1
package configstore
2
3
import (
4
"context"
5
"fmt"
6
"sort"
7
"strings"
8
"testing"
9
"time"
10
11
"github.com/go-kit/log"
12
"github.com/grafana/agent/pkg/metrics/instance"
13
"github.com/grafana/agent/pkg/util"
14
"github.com/grafana/dskit/kv"
15
"github.com/prometheus/client_golang/prometheus"
16
"github.com/stretchr/testify/require"
17
)
18
19
func TestRemote_List(t *testing.T) {
20
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
21
Store: "inmemory",
22
Prefix: "configs/",
23
}, true)
24
require.NoError(t, err)
25
t.Cleanup(func() {
26
err := remote.Close()
27
require.NoError(t, err)
28
})
29
30
cfgs := []string{"a", "b", "c"}
31
for _, cfg := range cfgs {
32
err := remote.kv.CAS(context.Background(), cfg, func(in interface{}) (out interface{}, retry bool, err error) {
33
return fmt.Sprintf("name: %s", cfg), false, nil
34
})
35
require.NoError(t, err)
36
}
37
38
list, err := remote.List(context.Background())
39
require.NoError(t, err)
40
sort.Strings(list)
41
require.Equal(t, cfgs, list)
42
}
43
44
func TestRemote_Get(t *testing.T) {
45
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
46
Store: "inmemory",
47
Prefix: "configs/",
48
}, true)
49
require.NoError(t, err)
50
t.Cleanup(func() {
51
err := remote.Close()
52
require.NoError(t, err)
53
})
54
55
err = remote.kv.CAS(context.Background(), "someconfig", func(in interface{}) (out interface{}, retry bool, err error) {
56
return "name: someconfig", false, nil
57
})
58
require.NoError(t, err)
59
60
cfg, err := remote.Get(context.Background(), "someconfig")
61
require.NoError(t, err)
62
63
expect := instance.DefaultConfig
64
expect.Name = "someconfig"
65
require.Equal(t, expect, cfg)
66
}
67
68
func TestRemote_Put(t *testing.T) {
69
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
70
Store: "inmemory",
71
Prefix: "configs/",
72
}, true)
73
require.NoError(t, err)
74
t.Cleanup(func() {
75
err := remote.Close()
76
require.NoError(t, err)
77
})
78
79
cfg := instance.DefaultConfig
80
cfg.Name = "newconfig"
81
82
created, err := remote.Put(context.Background(), cfg)
83
require.NoError(t, err)
84
require.True(t, created)
85
86
actual, err := remote.Get(context.Background(), "newconfig")
87
require.NoError(t, err)
88
require.Equal(t, cfg, actual)
89
90
t.Run("Updating", func(t *testing.T) {
91
cfg := instance.DefaultConfig
92
cfg.Name = "newconfig"
93
cfg.HostFilter = true
94
95
created, err := remote.Put(context.Background(), cfg)
96
require.NoError(t, err)
97
require.False(t, created)
98
})
99
}
100
101
func TestRemote_Put_NonUnique(t *testing.T) {
102
var (
103
conflictingA = util.Untab(`
104
name: conflicting-a
105
scrape_configs:
106
- job_name: foobar
107
`)
108
conflictingB = util.Untab(`
109
name: conflicting-b
110
scrape_configs:
111
- job_name: fizzbuzz
112
- job_name: foobar
113
`)
114
)
115
116
conflictingACfg, err := instance.UnmarshalConfig(strings.NewReader(conflictingA))
117
require.NoError(t, err)
118
119
conflictingBCfg, err := instance.UnmarshalConfig(strings.NewReader(conflictingB))
120
require.NoError(t, err)
121
122
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
123
Store: "inmemory",
124
Prefix: "configs/",
125
}, true)
126
require.NoError(t, err)
127
t.Cleanup(func() {
128
err := remote.Close()
129
require.NoError(t, err)
130
})
131
132
created, err := remote.Put(context.Background(), *conflictingACfg)
133
require.NoError(t, err)
134
require.True(t, created)
135
136
_, err = remote.Put(context.Background(), *conflictingBCfg)
137
require.EqualError(t, err, fmt.Sprintf("failed to check uniqueness of config: found multiple scrape configs in config store with job name %q", "foobar"))
138
}
139
140
func TestRemote_Delete(t *testing.T) {
141
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
142
Store: "inmemory",
143
Prefix: "configs/",
144
}, true)
145
require.NoError(t, err)
146
t.Cleanup(func() {
147
err := remote.Close()
148
require.NoError(t, err)
149
})
150
151
var cfg instance.Config
152
cfg.Name = "deleteme"
153
154
created, err := remote.Put(context.Background(), cfg)
155
require.NoError(t, err)
156
require.True(t, created)
157
158
err = remote.Delete(context.Background(), "deleteme")
159
require.NoError(t, err)
160
161
_, err = remote.Get(context.Background(), "deleteme")
162
require.EqualError(t, err, "configuration deleteme does not exist")
163
164
err = remote.Delete(context.Background(), "deleteme")
165
require.EqualError(t, err, "configuration deleteme does not exist")
166
}
167
168
func TestRemote_All(t *testing.T) {
169
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
170
Store: "inmemory",
171
Prefix: "all-configs/",
172
}, true)
173
require.NoError(t, err)
174
t.Cleanup(func() {
175
err := remote.Close()
176
require.NoError(t, err)
177
})
178
179
cfgs := []string{"a", "b", "c"}
180
for _, cfg := range cfgs {
181
err := remote.kv.CAS(context.Background(), cfg, func(in interface{}) (out interface{}, retry bool, err error) {
182
return fmt.Sprintf("name: %s", cfg), false, nil
183
})
184
require.NoError(t, err)
185
}
186
187
configCh, err := remote.All(context.Background(), nil)
188
require.NoError(t, err)
189
190
var gotConfigs []string
191
for gotConfig := range configCh {
192
gotConfigs = append(gotConfigs, gotConfig.Name)
193
}
194
sort.Strings(gotConfigs)
195
196
require.Equal(t, cfgs, gotConfigs)
197
}
198
199
func TestRemote_Watch(t *testing.T) {
200
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
201
Store: "inmemory",
202
Prefix: "watch-configs/",
203
}, true)
204
require.NoError(t, err)
205
t.Cleanup(func() {
206
err := remote.Close()
207
require.NoError(t, err)
208
})
209
210
_, err = remote.Put(context.Background(), instance.Config{Name: "watch"})
211
require.NoError(t, err)
212
213
select {
214
case cfg := <-remote.Watch():
215
require.Equal(t, "watch", cfg.Key)
216
require.NotNil(t, cfg.Config)
217
require.Equal(t, "watch", cfg.Config.Name)
218
case <-time.After(3 * time.Second):
219
require.FailNow(t, "failed to watch for config")
220
}
221
222
// Make sure Watch gets other updates.
223
_, err = remote.Put(context.Background(), instance.Config{Name: "watch2"})
224
require.NoError(t, err)
225
226
select {
227
case cfg := <-remote.Watch():
228
require.Equal(t, "watch2", cfg.Key)
229
require.NotNil(t, cfg.Config)
230
require.Equal(t, "watch2", cfg.Config.Name)
231
case <-time.After(3 * time.Second):
232
require.FailNow(t, "failed to watch for config")
233
}
234
}
235
236
func TestRemote_ApplyConfig(t *testing.T) {
237
remote, err := NewRemote(log.NewNopLogger(), prometheus.NewRegistry(), kv.Config{
238
Store: "inmemory",
239
Prefix: "test-applyconfig/",
240
}, true)
241
require.NoError(t, err)
242
t.Cleanup(func() {
243
err := remote.Close()
244
require.NoError(t, err)
245
})
246
247
err = remote.ApplyConfig(kv.Config{
248
Store: "inmemory",
249
Prefix: "test-applyconfig2/",
250
}, true)
251
require.NoError(t, err, "failed to apply a new config")
252
253
err = remote.ApplyConfig(kv.Config{
254
Store: "inmemory",
255
Prefix: "test-applyconfig2/",
256
}, true)
257
require.NoError(t, err, "failed to re-apply the current config")
258
259
// Make sure watch still works
260
_, err = remote.Put(context.Background(), instance.Config{Name: "watch"})
261
require.NoError(t, err)
262
263
select {
264
case cfg := <-remote.Watch():
265
require.Equal(t, "watch", cfg.Key)
266
require.NotNil(t, cfg.Config)
267
require.Equal(t, "watch", cfg.Config.Name)
268
case <-time.After(3 * time.Second):
269
require.FailNow(t, "failed to watch for config")
270
}
271
}
272
273