Skip to content

Commit 1e1562b

Browse files
authored
Merge pull request #20 from ChrsMark/move_hints_to_utils
Move hints helpers under utils and add tests
2 parents c4745a4 + ac0cd3d commit 1e1562b

File tree

2 files changed

+319
-1
lines changed

2 files changed

+319
-1
lines changed

kubernetes/hints.go renamed to utils/hints.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
package kubernetes
18+
package utils
1919

2020
import (
2121
"encoding/json"

utils/hints_test.go

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package utils
19+
20+
import (
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
25+
"github.com/elastic/elastic-agent-libs/mapstr"
26+
)
27+
28+
func TestGetProcessors(t *testing.T) {
29+
hints := mapstr.M{
30+
"co": mapstr.M{
31+
"elastic": mapstr.M{
32+
"logs": mapstr.M{
33+
"processors": mapstr.M{
34+
"add_fields": `{"fields": {"foo": "bar"}}`,
35+
},
36+
},
37+
},
38+
},
39+
}
40+
procs := GetProcessors(hints, "co.elastic.logs")
41+
assert.Equal(t, []mapstr.M{
42+
mapstr.M{
43+
"add_fields": mapstr.M{
44+
"fields": map[string]interface{}{
45+
"foo": "bar",
46+
},
47+
},
48+
},
49+
}, procs)
50+
}
51+
52+
func TestGenerateHints(t *testing.T) {
53+
tests := []struct {
54+
annotations map[string]string
55+
result mapstr.M
56+
}{
57+
// Empty annotations should return empty hints
58+
{
59+
annotations: map[string]string{},
60+
result: mapstr.M{},
61+
},
62+
63+
// Scenarios being tested:
64+
// logs/multiline.pattern must be a nested mapstr.M under hints.logs
65+
// logs/processors.add_fields must be nested mapstr.M under hints.logs
66+
// logs/json.keys_under_root must be a nested mapstr.M under hints.logs
67+
// metrics/module must be found in hints.metrics
68+
// not.to.include must not be part of hints
69+
// period is annotated at both container and pod level. Container level value must be in hints
70+
{
71+
annotations: map[string]string{
72+
"co.elastic.logs/multiline.pattern": "^test",
73+
"co.elastic.logs/json.keys_under_root": "true",
74+
"co.elastic.metrics/module": "prometheus",
75+
"co.elastic.metrics/period": "10s",
76+
"co.elastic.metrics.foobar/period": "15s",
77+
"co.elastic.metrics.foobar1/period": "15s",
78+
"not.to.include": "true",
79+
},
80+
result: mapstr.M{
81+
"logs": mapstr.M{
82+
"multiline": mapstr.M{
83+
"pattern": "^test",
84+
},
85+
"json": mapstr.M{
86+
"keys_under_root": "true",
87+
},
88+
},
89+
"metrics": mapstr.M{
90+
"module": "prometheus",
91+
"period": "15s",
92+
},
93+
},
94+
},
95+
// Scenarios being tested:
96+
// logs/multiline.pattern must be a nested mapstr.M under hints.logs
97+
// metrics/module must be found in hints.metrics
98+
// not.to.include must not be part of hints
99+
// metrics/metrics_path must be found in hints.metrics
100+
{
101+
annotations: map[string]string{
102+
"co.elastic.logs/multiline.pattern": "^test",
103+
"co.elastic.metrics/module": "prometheus",
104+
"co.elastic.metrics/period": "10s",
105+
"co.elastic.metrics/metrics_path": "/metrics/prometheus",
106+
"co.elastic.metrics/username": "user",
107+
"co.elastic.metrics/password": "pass",
108+
"co.elastic.metrics.foobar/period": "15s",
109+
"co.elastic.metrics.foobar1/period": "15s",
110+
"not.to.include": "true",
111+
},
112+
result: mapstr.M{
113+
"logs": mapstr.M{
114+
"multiline": mapstr.M{
115+
"pattern": "^test",
116+
},
117+
},
118+
"metrics": mapstr.M{
119+
"module": "prometheus",
120+
"period": "15s",
121+
"metrics_path": "/metrics/prometheus",
122+
"username": "user",
123+
"password": "pass",
124+
},
125+
},
126+
},
127+
// Scenarios being tested:
128+
// have co.elastic.logs/disable set to false.
129+
// logs/multiline.pattern must be a nested mapstr.M under hints.logs
130+
// metrics/module must be found in hints.metrics
131+
// not.to.include must not be part of hints
132+
// period is annotated at both container and pod level. Container level value must be in hints
133+
{
134+
annotations: map[string]string{
135+
"co.elastic.logs/multiline.pattern": "^test",
136+
"co.elastic.metrics/module": "prometheus",
137+
"co.elastic.metrics/period": "10s",
138+
"co.elastic.metrics.foobar/period": "15s",
139+
"co.elastic.metrics.foobar1/period": "15s",
140+
"not.to.include": "true",
141+
},
142+
result: mapstr.M{
143+
"logs": mapstr.M{
144+
"multiline": mapstr.M{
145+
"pattern": "^test",
146+
},
147+
},
148+
"metrics": mapstr.M{
149+
"module": "prometheus",
150+
"period": "15s",
151+
},
152+
},
153+
},
154+
// Scenarios being tested:
155+
// have co.elastic.logs/disable set to false.
156+
// logs/multiline.pattern must be a nested mapstr.M under hints.logs
157+
// metrics/module must be found in hints.metrics
158+
// not.to.include must not be part of hints
159+
// period is annotated at both container and pod level. Container level value must be in hints
160+
{
161+
annotations: map[string]string{
162+
"co.elastic.logs/disable": "false",
163+
"co.elastic.logs/multiline.pattern": "^test",
164+
"co.elastic.metrics/module": "prometheus",
165+
"co.elastic.metrics/period": "10s",
166+
"co.elastic.metrics.foobar/period": "15s",
167+
"co.elastic.metrics.foobar1/period": "15s",
168+
"not.to.include": "true",
169+
},
170+
result: mapstr.M{
171+
"logs": mapstr.M{
172+
"multiline": mapstr.M{
173+
"pattern": "^test",
174+
},
175+
"disable": "false",
176+
},
177+
"metrics": mapstr.M{
178+
"module": "prometheus",
179+
"period": "15s",
180+
},
181+
},
182+
},
183+
// Scenarios being tested:
184+
// have co.elastic.logs/disable set to true.
185+
// logs/multiline.pattern must be a nested mapstr.M under hints.logs
186+
// metrics/module must be found in hints.metrics
187+
// not.to.include must not be part of hints
188+
// period is annotated at both container and pod level. Container level value must be in hints
189+
{
190+
annotations: map[string]string{
191+
"co.elastic.logs/disable": "true",
192+
"co.elastic.logs/multiline.pattern": "^test",
193+
"co.elastic.metrics/module": "prometheus",
194+
"co.elastic.metrics/period": "10s",
195+
"co.elastic.metrics.foobar/period": "15s",
196+
"co.elastic.metrics.foobar1/period": "15s",
197+
"not.to.include": "true",
198+
},
199+
result: mapstr.M{
200+
"logs": mapstr.M{
201+
"multiline": mapstr.M{
202+
"pattern": "^test",
203+
},
204+
"disable": "true",
205+
},
206+
"metrics": mapstr.M{
207+
"module": "prometheus",
208+
"period": "15s",
209+
},
210+
},
211+
},
212+
}
213+
214+
for _, test := range tests {
215+
annMap := mapstr.M{}
216+
for k, v := range test.annotations {
217+
_, err := annMap.Put(k, v)
218+
if err != nil {
219+
continue
220+
}
221+
}
222+
assert.Equal(t, test.result, GenerateHints(annMap, "foobar", "co.elastic"))
223+
}
224+
}
225+
func TestGetHintsAsList(t *testing.T) {
226+
tests := []struct {
227+
input mapstr.M
228+
output []mapstr.M
229+
message string
230+
}{
231+
{
232+
input: mapstr.M{
233+
"metrics": mapstr.M{
234+
"module": "prometheus",
235+
"period": "15s",
236+
},
237+
},
238+
output: []mapstr.M{
239+
{
240+
"module": "prometheus",
241+
"period": "15s",
242+
},
243+
},
244+
message: "Single hint should return a single set of configs",
245+
},
246+
{
247+
input: mapstr.M{
248+
"metrics": mapstr.M{
249+
"1": mapstr.M{
250+
"module": "prometheus",
251+
"period": "15s",
252+
},
253+
},
254+
},
255+
output: []mapstr.M{
256+
{
257+
"module": "prometheus",
258+
"period": "15s",
259+
},
260+
},
261+
message: "Single hint with numeric prefix should return a single set of configs",
262+
},
263+
{
264+
input: mapstr.M{
265+
"metrics": mapstr.M{
266+
"1": mapstr.M{
267+
"module": "prometheus",
268+
"period": "15s",
269+
},
270+
"2": mapstr.M{
271+
"module": "dropwizard",
272+
"period": "20s",
273+
},
274+
},
275+
},
276+
output: []mapstr.M{
277+
{
278+
"module": "prometheus",
279+
"period": "15s",
280+
},
281+
{
282+
"module": "dropwizard",
283+
"period": "20s",
284+
},
285+
},
286+
message: "Multiple hints with numeric prefix should return configs in numeric ordering",
287+
},
288+
{
289+
input: mapstr.M{
290+
"metrics": mapstr.M{
291+
"1": mapstr.M{
292+
"module": "prometheus",
293+
"period": "15s",
294+
},
295+
"module": "dropwizard",
296+
"period": "20s",
297+
},
298+
},
299+
output: []mapstr.M{
300+
{
301+
"module": "prometheus",
302+
"period": "15s",
303+
},
304+
{
305+
"module": "dropwizard",
306+
"period": "20s",
307+
},
308+
},
309+
message: "Multiple hints with numeric prefix and default should return configs with defaults at the last",
310+
},
311+
}
312+
313+
for _, test := range tests {
314+
t.Run(test.message, func(t *testing.T) {
315+
assert.Equal(t, test.output, GetHintsAsList(test.input, "metrics"))
316+
})
317+
}
318+
}

0 commit comments

Comments
 (0)