From 05a0d086fc2ba40bd19ca0faf8be44585b68d413 Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Thu, 14 Mar 2024 13:25:06 -0700 Subject: [PATCH] bring back test in config as well --- component/config.go | 2 +- component/config_test.go | 26 ++++++++++++++++++++++++++ confmap/confmap.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/component/config.go b/component/config.go index de7006b6a07..f305b253ae6 100644 --- a/component/config.go +++ b/component/config.go @@ -27,7 +27,7 @@ type Config any var configValidatorType = reflect.TypeOf((*ConfigValidator)(nil)).Elem() // UnmarshalConfig helper function to UnmarshalConfig a Config. -// Deprecated: [v0.97.0] Use conf.Unmarshal(&intoCfg) +// Deprecated: [v0.99.0] Use conf.Unmarshal(&intoCfg) func UnmarshalConfig(conf *confmap.Conf, intoCfg Config) error { return conf.Unmarshal(intoCfg) } diff --git a/component/config_test.go b/component/config_test.go index f47a9edc87c..f85511cbe3a 100644 --- a/component/config_test.go +++ b/component/config_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/confmap" ) var _ fmt.Stringer = Type{} @@ -420,3 +422,27 @@ func TestNewType(t *testing.T) { }) } } + +type configWithEmbeddedStruct struct { + String string `mapstructure:"string"` + Num int `mapstructure:"num"` + EmbeddedUnmarshallingConfig `mapstructure:",squash"` +} + +type EmbeddedUnmarshallingConfig struct { +} + +func (euc *EmbeddedUnmarshallingConfig) Unmarshal(_ *confmap.Conf) error { + return nil // do nothing. +} +func TestStructWithEmbeddedUnmarshaling(t *testing.T) { + cfgMap := confmap.NewFromStringMap(map[string]any{ + "string": "foo", + "num": 123, + }) + tc := &configWithEmbeddedStruct{} + err := UnmarshalConfig(cfgMap, tc) + require.NoError(t, err) + assert.Equal(t, "foo", tc.String) + assert.Equal(t, 123, tc.Num) +} diff --git a/confmap/confmap.go b/confmap/confmap.go index 4680af673be..a900b421f87 100644 --- a/confmap/confmap.go +++ b/confmap/confmap.go @@ -422,3 +422,36 @@ func zeroSliceHookFunc() mapstructure.DecodeHookFuncValue { return from.Interface(), nil } } + +// This hook is used to solve the issue: https://github.com/open-telemetry/opentelemetry-collector/issues/9060 +// Decoding should fail when converting a negative integer to any type of unsigned integer. This prevents +// negative values being decoded as large uint values. +// TODO: This should be removed as a part of https://github.com/open-telemetry/opentelemetry-collector/issues/9532 +func negativeUintHookFunc() mapstructure.DecodeHookFuncValue { + return func(from reflect.Value, to reflect.Value) (interface{}, error) { + if from.CanInt() && from.Int() < 0 && to.CanUint() { + return nil, fmt.Errorf("cannot convert negative value %v to an unsigned integer", from.Int()) + } + return from.Interface(), nil + } +} + +type moduleFactory[T any, S any] interface { + Create(s S) T +} + +type createConfmapFunc[T any, S any] func(s S) T + +type confmapModuleFactory[T any, S any] struct { + f createConfmapFunc[T, S] +} + +func (c confmapModuleFactory[T, S]) Create(s S) T { + return c.f(s) +} + +func newConfmapModuleFactory[T any, S any](f createConfmapFunc[T, S]) moduleFactory[T, S] { + return confmapModuleFactory[T, S]{ + f: f, + } +}