diff --git a/confmap/internal/e2e/Makefile b/confmap/internal/e2e/Makefile new file mode 100644 index 00000000000..bdd863a203b --- /dev/null +++ b/confmap/internal/e2e/Makefile @@ -0,0 +1 @@ +include ../../../Makefile.Common diff --git a/confmap/internal/e2e/go.mod b/confmap/internal/e2e/go.mod new file mode 100644 index 00000000000..7cf6804715a --- /dev/null +++ b/confmap/internal/e2e/go.mod @@ -0,0 +1,30 @@ +module go.opentelemetry.io/collector/confmap/internal/e2e + +go 1.21.0 + +require ( + github.com/stretchr/testify v1.9.0 + go.opentelemetry.io/collector/confmap v0.102.1 + go.opentelemetry.io/collector/confmap/provider/envprovider v0.102.1 + go.opentelemetry.io/collector/confmap/provider/fileprovider v0.102.1 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0 // indirect + github.com/knadh/koanf/maps v0.1.1 // indirect + github.com/knadh/koanf/providers/confmap v0.1.0 // indirect + github.com/knadh/koanf/v2 v2.1.1 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace go.opentelemetry.io/collector/confmap => ../../ + +replace go.opentelemetry.io/collector/confmap/provider/fileprovider => ../../provider/fileprovider + +replace go.opentelemetry.io/collector/confmap/provider/envprovider => ../../provider/envprovider diff --git a/confmap/internal/e2e/go.sum b/confmap/internal/e2e/go.sum new file mode 100644 index 00000000000..f64ffe49188 --- /dev/null +++ b/confmap/internal/e2e/go.sum @@ -0,0 +1,28 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= +github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs= +github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= +github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= +github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= +github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM= +github.com/knadh/koanf/v2 v2.1.1/go.mod h1:4mnTRbZCK+ALuBXHZMjDfG9y714L7TykVnZkXbMU3Es= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/confmap/internal/e2e/testdata/types_expand.yaml b/confmap/internal/e2e/testdata/types_expand.yaml new file mode 100644 index 00000000000..2ffe5ca4628 --- /dev/null +++ b/confmap/internal/e2e/testdata/types_expand.yaml @@ -0,0 +1 @@ +field: ${env:ENV} diff --git a/confmap/internal/e2e/testdata/types_expand_inline.yaml b/confmap/internal/e2e/testdata/types_expand_inline.yaml new file mode 100644 index 00000000000..7235c4b32e9 --- /dev/null +++ b/confmap/internal/e2e/testdata/types_expand_inline.yaml @@ -0,0 +1 @@ +field: "inline field with ${env:ENV} expansion" diff --git a/confmap/internal/e2e/types_test.go b/confmap/internal/e2e/types_test.go new file mode 100644 index 00000000000..2c48b73535b --- /dev/null +++ b/confmap/internal/e2e/types_test.go @@ -0,0 +1,168 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package e2etest + +import ( + "context" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/provider/envprovider" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" +) + +type TargetField string + +const ( + TargetFieldInt TargetField = "int_field" + TargetFieldString TargetField = "string_field" + TargetFieldBool TargetField = "bool_field" + TargetFieldInlineString TargetField = "inline_string_field" +) + +type Test struct { + value string + targetField TargetField + expected any + expectedErr string +} + +type TargetConfig[T any] struct { + Field T `mapstructure:"field"` +} + +func AssertExpectedMatch[T any](t *testing.T, tt Test, conf *confmap.Conf, cfg *TargetConfig[T]) { + err := conf.Unmarshal(cfg) + if tt.expectedErr != "" { + require.ErrorContains(t, err, tt.expectedErr) + return + } + require.NoError(t, err) + require.Equal(t, tt.expected, cfg.Field) +} + +func TestTypeCasting(t *testing.T) { + values := []Test{ + { + value: "123", + targetField: TargetFieldInt, + expected: 123, + }, + { + value: "123", + targetField: TargetFieldString, + expected: "123", + }, + { + value: "123", + targetField: TargetFieldInlineString, + expected: "inline field with 123 expansion", + }, + { + value: "0123", + targetField: TargetFieldInt, + expected: 83, + }, + { + value: "0123", + targetField: TargetFieldString, + expected: "83", + }, + { + value: "0123", + targetField: TargetFieldInlineString, + expected: "inline field with 83 expansion", + }, + { + value: "0xdeadbeef", + targetField: TargetFieldInt, + expected: 3735928559, + }, + { + value: "0xdeadbeef", + targetField: TargetFieldString, + expected: "3735928559", + }, + { + value: "0xdeadbeef", + targetField: TargetFieldInlineString, + expected: "inline field with 3735928559 expansion", + }, + { + value: "\"0123\"", + targetField: TargetFieldString, + expected: "0123", + }, + { + value: "\"0123\"", + targetField: TargetFieldInt, + expected: 83, + }, + { + value: "\"0123\"", + targetField: TargetFieldInlineString, + expected: "inline field with 0123 expansion", + }, + { + value: "!!str 0123", + targetField: TargetFieldString, + expected: "0123", + }, + { + value: "!!str 0123", + targetField: TargetFieldInlineString, + expected: "inline field with 0123 expansion", + }, + { + value: "t", + targetField: TargetFieldBool, + expected: true, + }, + { + value: "23", + targetField: TargetFieldBool, + expected: true, + }, + } + + for _, tt := range values { + t.Run(tt.value+"/"+string(tt.targetField), func(t *testing.T) { + testFile := "types_expand.yaml" + if tt.targetField == TargetFieldInlineString { + testFile = "types_expand_inline.yaml" + } + + resolver, err := confmap.NewResolver(confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", testFile)}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + envprovider.NewFactory(), + }, + }) + require.NoError(t, err) + t.Setenv("ENV", tt.value) + + conf, err := resolver.Resolve(context.Background()) + require.NoError(t, err) + + switch tt.targetField { + case TargetFieldInt: + var cfg TargetConfig[int] + AssertExpectedMatch(t, tt, conf, &cfg) + case TargetFieldString, TargetFieldInlineString: + var cfg TargetConfig[string] + AssertExpectedMatch(t, tt, conf, &cfg) + case TargetFieldBool: + var cfg TargetConfig[bool] + AssertExpectedMatch(t, tt, conf, &cfg) + default: + t.Fatalf("unexpected target field %q", tt.targetField) + } + + }) + } +} diff --git a/versions.yaml b/versions.yaml index 49c6b625c58..71140f2d0a9 100644 --- a/versions.yaml +++ b/versions.yaml @@ -62,3 +62,4 @@ excluded-modules: - go.opentelemetry.io/collector/cmd/otelcorecol - go.opentelemetry.io/collector/internal/e2e - go.opentelemetry.io/collector/internal/tools + - go.opentelemetry.io/collector/confmap/internal/e2e