2018-07-04 06:32:52 +08:00
|
|
|
package enum
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
2021-11-25 03:38:08 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
2018-07-04 06:32:52 +08:00
|
|
|
"github.com/influxdata/telegraf"
|
|
|
|
|
"github.com/influxdata/telegraf/metric"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func createTestMetric() telegraf.Metric {
|
2021-04-14 02:40:03 +08:00
|
|
|
m := metric.New("m1",
|
2020-12-19 05:41:39 +08:00
|
|
|
map[string]string{
|
|
|
|
|
"tag": "tag_value",
|
|
|
|
|
"duplicate_tag": "tag_value",
|
|
|
|
|
},
|
2018-07-04 06:32:52 +08:00
|
|
|
map[string]interface{}{
|
2020-12-19 05:41:39 +08:00
|
|
|
"string_value": "test",
|
|
|
|
|
"duplicate_string_value": "test",
|
2021-11-25 03:38:08 +08:00
|
|
|
"int_value": 200,
|
2020-12-19 05:41:39 +08:00
|
|
|
"uint_value": uint(500),
|
|
|
|
|
"float_value": float64(3.14),
|
|
|
|
|
"true_value": true,
|
2018-07-04 06:32:52 +08:00
|
|
|
},
|
|
|
|
|
time.Now(),
|
|
|
|
|
)
|
2021-04-14 02:40:03 +08:00
|
|
|
return m
|
2018-07-04 06:32:52 +08:00
|
|
|
}
|
|
|
|
|
|
2021-11-25 03:38:08 +08:00
|
|
|
func calculateProcessedValues(mapper EnumMapper, m telegraf.Metric) map[string]interface{} {
|
|
|
|
|
processed := mapper.Apply(m)
|
2018-07-04 06:32:52 +08:00
|
|
|
return processed[0].Fields()
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 03:38:08 +08:00
|
|
|
func calculateProcessedTags(mapper EnumMapper, m telegraf.Metric) map[string]string {
|
|
|
|
|
processed := mapper.Apply(m)
|
2019-05-17 06:59:19 +08:00
|
|
|
return processed[0].Tags()
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-04 06:32:52 +08:00
|
|
|
func assertFieldValue(t *testing.T, expected interface{}, field string, fields map[string]interface{}) {
|
|
|
|
|
value, present := fields[field]
|
2021-11-25 03:38:08 +08:00
|
|
|
require.True(t, present, "value of field '"+field+"' was not present")
|
|
|
|
|
require.EqualValues(t, expected, value)
|
2018-07-04 06:32:52 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-17 06:59:19 +08:00
|
|
|
func assertTagValue(t *testing.T, expected interface{}, tag string, tags map[string]string) {
|
|
|
|
|
value, present := tags[tag]
|
2021-11-25 03:38:08 +08:00
|
|
|
require.True(t, present, "value of tag '"+tag+"' was not present")
|
|
|
|
|
require.EqualValues(t, expected, value)
|
2019-05-17 06:59:19 +08:00
|
|
|
}
|
|
|
|
|
|
2018-07-04 06:32:52 +08:00
|
|
|
func TestRetainsMetric(t *testing.T) {
|
|
|
|
|
mapper := EnumMapper{}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2018-07-04 06:32:52 +08:00
|
|
|
source := createTestMetric()
|
|
|
|
|
|
|
|
|
|
target := mapper.Apply(source)[0]
|
|
|
|
|
fields := target.Fields()
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, "test", "string_value", fields)
|
2020-05-12 02:36:21 +08:00
|
|
|
assertFieldValue(t, 200, "int_value", fields)
|
|
|
|
|
assertFieldValue(t, 500, "uint_value", fields)
|
2021-04-14 05:31:07 +08:00
|
|
|
assertFieldValue(t, float64(3.14), "float_value", fields)
|
2018-07-04 06:32:52 +08:00
|
|
|
assertFieldValue(t, true, "true_value", fields)
|
2021-11-25 03:38:08 +08:00
|
|
|
require.Equal(t, "m1", target.Name())
|
|
|
|
|
require.Equal(t, source.Tags(), target.Tags())
|
|
|
|
|
require.Equal(t, source.Time(), target.Time())
|
2018-07-04 06:32:52 +08:00
|
|
|
}
|
|
|
|
|
|
2019-05-17 06:59:19 +08:00
|
|
|
func TestMapsSingleStringValueTag(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
2025-04-08 20:34:24 +08:00
|
|
|
Tags: []string{"tag"},
|
2025-03-26 22:02:56 +08:00
|
|
|
ValueMappings: map[string]interface{}{"tag_value": "valuable"},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2019-05-17 06:59:19 +08:00
|
|
|
tags := calculateProcessedTags(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertTagValue(t, "valuable", "tag", tags)
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-12 02:36:21 +08:00
|
|
|
func TestMappings(t *testing.T) {
|
|
|
|
|
mappings := []map[string][]interface{}{
|
|
|
|
|
{
|
|
|
|
|
"field_name": []interface{}{"string_value"},
|
|
|
|
|
"target_values": []interface{}{"test", "test", "test", "not_test", "50", "true"},
|
|
|
|
|
"mapped_values": []interface{}{"test_1", 5, true, "test_1", 10, false},
|
|
|
|
|
"expected_values": []interface{}{"test_1", 5, true, "test", "test", "test"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"field_name": []interface{}{"true_value"},
|
|
|
|
|
"target_value": []interface{}{"true", "true", "true", "false", "test", "5"},
|
|
|
|
|
"mapped_value": []interface{}{false, 1, "false", false, false, false},
|
|
|
|
|
"expected_value": []interface{}{false, 1, "false", true, true, true},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"field_name": []interface{}{"int_value"},
|
|
|
|
|
"target_value": []interface{}{"200", "200", "200", "200", "test", "5"},
|
|
|
|
|
"mapped_value": []interface{}{"http_ok", true, 1, float64(200.001), false, false},
|
|
|
|
|
"expected_value": []interface{}{"http_ok", true, 1, float64(200.001), 200, 200},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"field_name": []interface{}{"uint_value"},
|
|
|
|
|
"target_value": []interface{}{"500", "500", "500", "test", "false", "5"},
|
|
|
|
|
"mapped_value": []interface{}{"internal_error", 1, false, false, false, false},
|
|
|
|
|
"expected_value": []interface{}{"internal_error", 1, false, 500, 500, 500},
|
|
|
|
|
},
|
2021-04-14 05:31:07 +08:00
|
|
|
{
|
|
|
|
|
"field_name": []interface{}{"float_value"},
|
|
|
|
|
"target_value": []interface{}{"3.14", "3.14", "3.14", "3.14", "not_float", "5"},
|
|
|
|
|
"mapped_value": []interface{}{"pi", 1, false, float64(100.2), float64(3.14), "pi"},
|
|
|
|
|
"expected_value": []interface{}{"pi", 1, false, float64(100.2), float64(3.14), float64(3.14)},
|
|
|
|
|
},
|
2020-05-12 02:36:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, mapping := range mappings {
|
2021-03-02 05:04:35 +08:00
|
|
|
fieldName := mapping["field_name"][0].(string)
|
2020-05-12 02:36:21 +08:00
|
|
|
for index := range mapping["target_value"] {
|
2022-11-08 23:12:30 +08:00
|
|
|
mapper := EnumMapper{
|
2025-03-26 22:02:56 +08:00
|
|
|
Mappings: []*Mapping{
|
|
|
|
|
{
|
|
|
|
|
Fields: []string{fieldName},
|
|
|
|
|
ValueMappings: map[string]interface{}{
|
|
|
|
|
mapping["target_value"][index].(string): mapping["mapped_value"][index],
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-11-08 23:12:30 +08:00
|
|
|
},
|
|
|
|
|
}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2020-05-12 02:36:21 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
2021-03-02 05:04:35 +08:00
|
|
|
assertFieldValue(t, mapping["expected_value"][index], fieldName, fields)
|
2020-05-12 02:36:21 +08:00
|
|
|
}
|
|
|
|
|
}
|
2018-07-04 06:32:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestMapsToDefaultValueOnUnknownSourceValue(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"string_value"},
|
|
|
|
|
Default: int64(42),
|
|
|
|
|
ValueMappings: map[string]interface{}{"other": int64(1)},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2018-07-04 06:32:52 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, 42, "string_value", fields)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestDoNotMapToDefaultValueKnownSourceValue(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"string_value"},
|
|
|
|
|
Default: int64(42),
|
|
|
|
|
ValueMappings: map[string]interface{}{"test": int64(1)},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2018-07-04 06:32:52 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, 1, "string_value", fields)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestNoMappingWithoutDefaultOrDefinedMappingValue(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"string_value"},
|
|
|
|
|
ValueMappings: map[string]interface{}{"other": int64(1)},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2018-07-04 06:32:52 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, "test", "string_value", fields)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestWritesToDestination(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"string_value"},
|
|
|
|
|
Dest: "string_code",
|
|
|
|
|
ValueMappings: map[string]interface{}{"test": int64(1)},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2018-07-04 06:32:52 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, "test", "string_value", fields)
|
|
|
|
|
assertFieldValue(t, 1, "string_code", fields)
|
|
|
|
|
}
|
2019-10-08 09:08:35 +08:00
|
|
|
|
|
|
|
|
func TestDoNotWriteToDestinationWithoutDefaultOrDefinedMapping(t *testing.T) {
|
|
|
|
|
field := "string_code"
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"string_value"},
|
|
|
|
|
Dest: field,
|
|
|
|
|
ValueMappings: map[string]interface{}{"other": int64(1)},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2019-10-08 09:08:35 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, "test", "string_value", fields)
|
|
|
|
|
_, present := fields[field]
|
2021-11-25 03:38:08 +08:00
|
|
|
require.False(t, present, "value of field '"+field+"' was present")
|
2019-10-08 09:08:35 +08:00
|
|
|
}
|
2020-12-19 05:41:39 +08:00
|
|
|
|
2025-03-26 22:02:56 +08:00
|
|
|
func TestMultipleFields(t *testing.T) {
|
|
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"string_value", "duplicate_string_value"},
|
|
|
|
|
ValueMappings: map[string]interface{}{"test": "multiple"},
|
|
|
|
|
}}}
|
|
|
|
|
require.NoError(t, mapper.Init())
|
|
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, "multiple", "string_value", fields)
|
|
|
|
|
assertFieldValue(t, "multiple", "duplicate_string_value", fields)
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:41:39 +08:00
|
|
|
func TestFieldGlobMatching(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
|
|
|
|
Fields: []string{"*"},
|
|
|
|
|
ValueMappings: map[string]interface{}{"test": "glob"},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2020-12-19 05:41:39 +08:00
|
|
|
fields := calculateProcessedValues(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertFieldValue(t, "glob", "string_value", fields)
|
|
|
|
|
assertFieldValue(t, "glob", "duplicate_string_value", fields)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestTagGlobMatching(t *testing.T) {
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
2025-04-08 20:34:24 +08:00
|
|
|
Tags: []string{"*"},
|
2025-03-26 22:02:56 +08:00
|
|
|
ValueMappings: map[string]interface{}{"tag_value": "glob"},
|
|
|
|
|
}}}
|
2020-12-19 05:41:39 +08:00
|
|
|
err := mapper.Init()
|
2023-10-27 21:42:25 +08:00
|
|
|
require.NoError(t, err)
|
2020-12-19 05:41:39 +08:00
|
|
|
tags := calculateProcessedTags(mapper, createTestMetric())
|
|
|
|
|
|
|
|
|
|
assertTagValue(t, "glob", "tag", tags)
|
|
|
|
|
}
|
2024-02-10 03:08:09 +08:00
|
|
|
|
2025-03-26 22:02:56 +08:00
|
|
|
func TestCollidingValueMappings(t *testing.T) {
|
|
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{
|
|
|
|
|
{
|
|
|
|
|
Fields: []string{"status"},
|
|
|
|
|
ValueMappings: map[string]interface{}{"green": 1, "amber": 2, "red": 3},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Fields: []string{"status_reverse"},
|
|
|
|
|
ValueMappings: map[string]interface{}{"green": 3, "amber": 2, "red": 1},
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
require.NoError(t, mapper.Init())
|
|
|
|
|
|
|
|
|
|
input := metric.New("m1",
|
|
|
|
|
map[string]string{
|
|
|
|
|
"tag": "tag_value",
|
|
|
|
|
},
|
|
|
|
|
map[string]interface{}{
|
|
|
|
|
"status": "green",
|
|
|
|
|
"status_reverse": "green",
|
|
|
|
|
},
|
|
|
|
|
time.Now(),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
output := mapper.Apply(input)[0]
|
|
|
|
|
fields := output.Fields()
|
|
|
|
|
assertFieldValue(t, int64(1), "status", fields)
|
|
|
|
|
assertFieldValue(t, int64(3), "status_reverse", fields)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 03:08:09 +08:00
|
|
|
func TestTracking(t *testing.T) {
|
|
|
|
|
m := createTestMetric()
|
|
|
|
|
var delivered bool
|
2024-02-13 06:26:10 +08:00
|
|
|
notify := func(telegraf.DeliveryInfo) {
|
2024-02-10 03:08:09 +08:00
|
|
|
delivered = true
|
|
|
|
|
}
|
|
|
|
|
m, _ = metric.WithTracking(m, notify)
|
|
|
|
|
|
2025-03-26 22:02:56 +08:00
|
|
|
mapper := EnumMapper{Mappings: []*Mapping{{
|
2025-04-08 20:34:24 +08:00
|
|
|
Tags: []string{"*"},
|
2025-03-26 22:02:56 +08:00
|
|
|
ValueMappings: map[string]interface{}{"tag_value": "glob"},
|
|
|
|
|
}}}
|
2024-02-10 03:08:09 +08:00
|
|
|
err := mapper.Init()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
actual := mapper.Apply(m)[0]
|
|
|
|
|
assertTagValue(t, "glob", "tag", actual.Tags())
|
|
|
|
|
|
|
|
|
|
actual.Accept()
|
|
|
|
|
require.Eventually(t, func() bool {
|
|
|
|
|
return delivered
|
|
|
|
|
}, time.Second, 100*time.Millisecond, "no metrics delivered")
|
|
|
|
|
}
|