[xconfmap] Create module and add validation facilities (#12226)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Builds on https://github.com/open-telemetry/opentelemetry-collector/pull/12224 and starts the move of config validation from component to confmap. We can keep this in `xconfmap` while we determine whether to add the ability to validate using struct field tags. I think this has the following advantages: 1. Everything configuration-related is now in confmap instead of split between confmap and component. 2. We can share things like the mapstructure tag and config key separator as constants between unmarshaling and validation without creating dependencies between confmap and component. ~The one uncertainty this creates is what to do with `component.Config`, which would now be used as a thin alias for `any` without any meaningful usage in component.~ <!-- Issue number if applicable --> #### Link to tracking issue Fixes https://github.com/open-telemetry/opentelemetry-collector/issues/11524
This commit is contained in:
parent
677b87e3ab
commit
0ac887e6b7
|
|
@ -0,0 +1,25 @@
|
|||
# Use this changelog template to create an entry for release notes.
|
||||
|
||||
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
|
||||
change_type: new_component
|
||||
|
||||
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
|
||||
component: xconfmap
|
||||
|
||||
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
|
||||
note: Create the xconfmap module and add the `Validator` interface and `Validate` function to facilitate config validation
|
||||
|
||||
# One or more tracking issues or pull requests related to the change
|
||||
issues: [11524]
|
||||
|
||||
# (Optional) One or more lines of additional information to render under the primary note.
|
||||
# These lines will be padded with 2 spaces and then inserted directly into the document.
|
||||
# Use pipe (|) for multiline entries.
|
||||
subtext:
|
||||
|
||||
# Optional: The change log or logs in which this entry should be included.
|
||||
# e.g. '[user]' or '[user, api]'
|
||||
# Include 'user' if the change is relevant to end users.
|
||||
# Include 'api' if there is a change to a library API.
|
||||
# Default: '[user]'
|
||||
change_logs: [api]
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Use this changelog template to create an entry for release notes.
|
||||
|
||||
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
|
||||
change_type: deprecation
|
||||
|
||||
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
|
||||
component: component
|
||||
|
||||
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
|
||||
note: Deprecate `ConfigValidator` and `ValidateConfig`
|
||||
|
||||
# One or more tracking issues or pull requests related to the change
|
||||
issues: [11524]
|
||||
|
||||
# (Optional) One or more lines of additional information to render under the primary note.
|
||||
# These lines will be padded with 2 spaces and then inserted directly into the document.
|
||||
# Use pipe (|) for multiline entries.
|
||||
subtext: Please use `Validator` and `Validate` respectively from `xconfmap`.
|
||||
|
||||
# Optional: The change log or logs in which this entry should be included.
|
||||
# e.g. '[user]' or '[user, api]'
|
||||
# Include 'user' if the change is relevant to end users.
|
||||
# Include 'api' if there is a change to a library API.
|
||||
# Default: '[user]'
|
||||
change_logs: [api]
|
||||
|
|
@ -53,6 +53,7 @@ var replaceModules = []string{
|
|||
"/config/configtelemetry",
|
||||
"/config/configtls",
|
||||
"/confmap",
|
||||
"/confmap/xconfmap",
|
||||
"/confmap/provider/envprovider",
|
||||
"/confmap/provider/fileprovider",
|
||||
"/confmap/provider/httpprovider",
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ replaces:
|
|||
- go.opentelemetry.io/collector/config/configtelemetry => ../../config/configtelemetry
|
||||
- go.opentelemetry.io/collector/config/configtls => ../../config/configtls
|
||||
- go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
- go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
- go.opentelemetry.io/collector/confmap/provider/envprovider => ../../confmap/provider/envprovider
|
||||
- go.opentelemetry.io/collector/confmap/provider/fileprovider => ../../confmap/provider/fileprovider
|
||||
- go.opentelemetry.io/collector/confmap/provider/httpprovider => ../../confmap/provider/httpprovider
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ require (
|
|||
go.opentelemetry.io/collector/config/configretry v1.25.0 // indirect
|
||||
go.opentelemetry.io/collector/config/configtelemetry v0.119.0 // indirect
|
||||
go.opentelemetry.io/collector/config/configtls v1.25.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000 // indirect
|
||||
go.opentelemetry.io/collector/connector/connectortest v0.119.0 // indirect
|
||||
go.opentelemetry.io/collector/connector/xconnector v0.119.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer v1.25.0 // indirect
|
||||
|
|
@ -190,6 +191,8 @@ replace go.opentelemetry.io/collector/config/configtls => ../../config/configtls
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/provider/envprovider => ../../confmap/provider/envprovider
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/provider/fileprovider => ../../confmap/provider/fileprovider
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
// Config defines the configuration for a component.Component.
|
||||
//
|
||||
// Implementations and/or any sub-configs (other types embedded or included in the Config implementation)
|
||||
// MUST implement the ConfigValidator if any validation is required for that part of the configuration
|
||||
// MUST implement xconfmap.Validator if any validation is required for that part of the configuration
|
||||
// (e.g. check if a required field is present).
|
||||
//
|
||||
// A valid implementation MUST pass the check componenttest.CheckConfigStruct (return nil error).
|
||||
|
|
@ -25,6 +25,8 @@ type Config any
|
|||
var configValidatorType = reflect.TypeOf((*ConfigValidator)(nil)).Elem()
|
||||
|
||||
// ConfigValidator defines an optional interface for configurations to implement to do validation.
|
||||
//
|
||||
// Deprecated: [v0.120.0] use xconfmap.Validator.
|
||||
type ConfigValidator interface {
|
||||
// Validate the configuration and returns an error if invalid.
|
||||
Validate() error
|
||||
|
|
@ -32,6 +34,8 @@ type ConfigValidator interface {
|
|||
|
||||
// ValidateConfig validates a config, by doing this:
|
||||
// - Call Validate on the config itself if the config implements ConfigValidator.
|
||||
//
|
||||
// Deprecated: [v0.120.0] use xconfmap.Validate.
|
||||
func ValidateConfig(cfg Config) error {
|
||||
var err error
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@ const (
|
|||
KeyDelimiter = "::"
|
||||
)
|
||||
|
||||
const (
|
||||
// MapstructureTag is the struct field tag used to record marshaling/unmarshaling settings.
|
||||
// See https://pkg.go.dev/github.com/go-viper/mapstructure/v2 for supported values.
|
||||
MapstructureTag = "mapstructure"
|
||||
)
|
||||
|
||||
// New creates a new empty confmap.Conf instance.
|
||||
func New() *Conf {
|
||||
return &Conf{k: koanf.New(KeyDelimiter)}
|
||||
|
|
@ -205,7 +211,7 @@ func decodeConfig(m *Conf, result any, errorUnused bool, skipTopLevelUnmarshaler
|
|||
dc := &mapstructure.DecoderConfig{
|
||||
ErrorUnused: errorUnused,
|
||||
Result: result,
|
||||
TagName: "mapstructure",
|
||||
TagName: MapstructureTag,
|
||||
WeaklyTypedInput: false,
|
||||
MatchName: caseSensitiveMatchName,
|
||||
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||
|
|
@ -407,7 +413,7 @@ func unmarshalerEmbeddedStructsHookFunc() mapstructure.DecodeHookFuncValue {
|
|||
for i := 0; i < to.Type().NumField(); i++ {
|
||||
// embedded structs passed in via `squash` cannot be pointers. We just check if they are structs:
|
||||
f := to.Type().Field(i)
|
||||
if f.IsExported() && slices.Contains(strings.Split(f.Tag.Get("mapstructure"), ","), "squash") {
|
||||
if f.IsExported() && slices.Contains(strings.Split(f.Tag.Get(MapstructureTag), ","), "squash") {
|
||||
if unmarshaler, ok := to.Field(i).Addr().Interface().(Unmarshaler); ok {
|
||||
c := NewFromStringMap(fromAsMap)
|
||||
c.skipTopLevelUnmarshaler = true
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
include ../../Makefile.Common
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package xconfmap // import "go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/collector/confmap"
|
||||
)
|
||||
|
||||
// As interface types are only used for static typing, a common idiom to find the reflection Type
|
||||
// for an interface type Foo is to use a *Foo value.
|
||||
var configValidatorType = reflect.TypeOf((*Validator)(nil)).Elem()
|
||||
|
||||
// Validator defines an optional interface for configurations to implement to do validation.
|
||||
type Validator interface {
|
||||
// Validate the configuration and returns an error if invalid.
|
||||
Validate() error
|
||||
}
|
||||
|
||||
// Validate validates a config, by doing this:
|
||||
// - Call Validate on the config itself if the config implements ConfigValidator.
|
||||
func Validate(cfg any) error {
|
||||
var err error
|
||||
|
||||
for _, validationErr := range validate(reflect.ValueOf(cfg)) {
|
||||
err = errors.Join(err, validationErr)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
type pathError struct {
|
||||
err error
|
||||
path []string
|
||||
}
|
||||
|
||||
func (pe pathError) Error() string {
|
||||
if len(pe.path) > 0 {
|
||||
var path string
|
||||
sb := strings.Builder{}
|
||||
|
||||
_, _ = sb.WriteString(pe.path[len(pe.path)-1])
|
||||
for i := len(pe.path) - 2; i >= 0; i-- {
|
||||
_, _ = sb.WriteString(confmap.KeyDelimiter)
|
||||
_, _ = sb.WriteString(pe.path[i])
|
||||
}
|
||||
path = sb.String()
|
||||
|
||||
return fmt.Sprintf("%s: %s", path, pe.err)
|
||||
}
|
||||
|
||||
return pe.err.Error()
|
||||
}
|
||||
|
||||
func (pe pathError) Unwrap() error {
|
||||
return pe.err
|
||||
}
|
||||
|
||||
func validate(v reflect.Value) []pathError {
|
||||
errs := []pathError{}
|
||||
// Validate the value itself.
|
||||
switch v.Kind() {
|
||||
case reflect.Invalid:
|
||||
return nil
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
return validate(v.Elem())
|
||||
case reflect.Struct:
|
||||
err := callValidateIfPossible(v)
|
||||
if err != nil {
|
||||
errs = append(errs, pathError{err: err})
|
||||
}
|
||||
|
||||
// Reflect on the pointed data and check each of its fields.
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if !v.Type().Field(i).IsExported() {
|
||||
continue
|
||||
}
|
||||
field := v.Type().Field(i)
|
||||
path := fieldName(field)
|
||||
|
||||
subpathErrs := validate(v.Field(i))
|
||||
for _, err := range subpathErrs {
|
||||
errs = append(errs, pathError{
|
||||
err: err.err,
|
||||
path: append(err.path, path),
|
||||
})
|
||||
}
|
||||
}
|
||||
return errs
|
||||
case reflect.Slice, reflect.Array:
|
||||
err := callValidateIfPossible(v)
|
||||
if err != nil {
|
||||
errs = append(errs, pathError{err: err})
|
||||
}
|
||||
|
||||
// Reflect on the pointed data and check each of its fields.
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
subPathErrs := validate(v.Index(i))
|
||||
|
||||
for _, err := range subPathErrs {
|
||||
errs = append(errs, pathError{
|
||||
err: err.err,
|
||||
path: append(err.path, strconv.Itoa(i)),
|
||||
})
|
||||
}
|
||||
}
|
||||
return errs
|
||||
case reflect.Map:
|
||||
err := callValidateIfPossible(v)
|
||||
if err != nil {
|
||||
errs = append(errs, pathError{err: err})
|
||||
}
|
||||
|
||||
iter := v.MapRange()
|
||||
for iter.Next() {
|
||||
keyErrs := validate(iter.Key())
|
||||
valueErrs := validate(iter.Value())
|
||||
key := stringifyMapKey(iter.Key())
|
||||
|
||||
for _, err := range keyErrs {
|
||||
errs = append(errs, pathError{err: err.err, path: append(err.path, key)})
|
||||
}
|
||||
|
||||
for _, err := range valueErrs {
|
||||
errs = append(errs, pathError{err: err.err, path: append(err.path, key)})
|
||||
}
|
||||
}
|
||||
return errs
|
||||
default:
|
||||
err := callValidateIfPossible(v)
|
||||
if err != nil {
|
||||
return []pathError{{err: err}}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func callValidateIfPossible(v reflect.Value) error {
|
||||
// If the value type implements ConfigValidator just call Validate
|
||||
if v.Type().Implements(configValidatorType) {
|
||||
return v.Interface().(Validator).Validate()
|
||||
}
|
||||
|
||||
// If the pointer type implements ConfigValidator call Validate on the pointer to the current value.
|
||||
if reflect.PointerTo(v.Type()).Implements(configValidatorType) {
|
||||
// If not addressable, then create a new *V pointer and set the value to current v.
|
||||
if !v.CanAddr() {
|
||||
pv := reflect.New(reflect.PointerTo(v.Type()).Elem())
|
||||
pv.Elem().Set(v)
|
||||
v = pv.Elem()
|
||||
}
|
||||
return v.Addr().Interface().(Validator).Validate()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fieldName(field reflect.StructField) string {
|
||||
var fieldName string
|
||||
if tag, ok := field.Tag.Lookup(confmap.MapstructureTag); ok {
|
||||
tags := strings.Split(tag, ",")
|
||||
if len(tags) > 0 {
|
||||
fieldName = tags[0]
|
||||
}
|
||||
}
|
||||
// Even if the mapstructure tag exists, the field name may not
|
||||
// be available, so set it if it is still blank.
|
||||
if len(fieldName) == 0 {
|
||||
fieldName = strings.ToLower(field.Name)
|
||||
}
|
||||
|
||||
return fieldName
|
||||
}
|
||||
|
||||
func stringifyMapKey(val reflect.Value) string {
|
||||
var key string
|
||||
|
||||
if str, ok := val.Interface().(string); ok {
|
||||
key = str
|
||||
} else if stringer, ok := val.Interface().(fmt.Stringer); ok {
|
||||
key = stringer.String()
|
||||
} else {
|
||||
switch val.Kind() {
|
||||
case reflect.Ptr, reflect.Interface, reflect.Struct, reflect.Slice, reflect.Array, reflect.Map:
|
||||
key = fmt.Sprintf("[%T key]", val.Interface())
|
||||
default:
|
||||
key = fmt.Sprintf("%v", val.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
// Copyright The OpenTelemetry Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package xconfmap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type configChildStruct struct {
|
||||
Child errValidateConfig
|
||||
ChildPtr *errValidateConfig
|
||||
}
|
||||
|
||||
type configChildSlice struct {
|
||||
Child []errValidateConfig
|
||||
ChildPtr []*errValidateConfig
|
||||
}
|
||||
|
||||
type configChildMapValue struct {
|
||||
Child map[string]errValidateConfig
|
||||
ChildPtr map[string]*errValidateConfig
|
||||
}
|
||||
|
||||
type configChildMapKey struct {
|
||||
Child map[errType]string
|
||||
ChildPtr map[*errType]string
|
||||
}
|
||||
|
||||
type configChildTypeDef struct {
|
||||
Child errType
|
||||
ChildPtr *errType
|
||||
}
|
||||
|
||||
type config any
|
||||
|
||||
type configChildInterface struct {
|
||||
Child config
|
||||
}
|
||||
|
||||
type errValidateConfig struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e *errValidateConfig) Validate() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
type errType string
|
||||
|
||||
func (e errType) Validate() error {
|
||||
if e == "" {
|
||||
return nil
|
||||
}
|
||||
return errors.New(string(e))
|
||||
}
|
||||
|
||||
func newErrType(etStr string) *errType {
|
||||
et := errType(etStr)
|
||||
return &et
|
||||
}
|
||||
|
||||
type errMapType map[string]string
|
||||
|
||||
func (e errMapType) Validate() error {
|
||||
return errors.New(e["err"])
|
||||
}
|
||||
|
||||
type structKey struct {
|
||||
k string
|
||||
e error
|
||||
}
|
||||
|
||||
func (s structKey) String() string {
|
||||
return s.k
|
||||
}
|
||||
|
||||
func (s structKey) Validate() error {
|
||||
return s.e
|
||||
}
|
||||
|
||||
type configChildMapCustomKey struct {
|
||||
Child map[structKey]errValidateConfig
|
||||
}
|
||||
|
||||
func newErrMapType() *errMapType {
|
||||
et := errMapType(nil)
|
||||
return &et
|
||||
}
|
||||
|
||||
type configMapstructure struct {
|
||||
Valid *errValidateConfig `mapstructure:"validtag,omitempty"`
|
||||
NoData *errValidateConfig `mapstructure:""`
|
||||
NoName *errValidateConfig `mapstructure:",remain"`
|
||||
}
|
||||
|
||||
type configDeeplyNested struct {
|
||||
MapKeyChild map[configChildStruct]string
|
||||
MapValueChild map[string]configChildStruct
|
||||
SliceChild []configChildSlice
|
||||
MapIntKey map[int]errValidateConfig
|
||||
MapFloatKey map[float64]errValidateConfig
|
||||
}
|
||||
|
||||
type sliceTypeAlias []configChildSlice
|
||||
|
||||
func (sliceTypeAlias) Validate() error {
|
||||
return errors.New("sliceTypeAlias error")
|
||||
}
|
||||
|
||||
func TestValidateConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cfg any
|
||||
expected error
|
||||
}{
|
||||
{
|
||||
name: "struct",
|
||||
cfg: errValidateConfig{err: errors.New("struct")},
|
||||
expected: errors.New("struct"),
|
||||
},
|
||||
{
|
||||
name: "pointer struct",
|
||||
cfg: &errValidateConfig{err: errors.New("pointer struct")},
|
||||
expected: errors.New("pointer struct"),
|
||||
},
|
||||
{
|
||||
name: "type",
|
||||
cfg: errType("type"),
|
||||
expected: errors.New("type"),
|
||||
},
|
||||
{
|
||||
name: "pointer child",
|
||||
cfg: newErrType("pointer type"),
|
||||
expected: errors.New("pointer type"),
|
||||
},
|
||||
{
|
||||
name: "child interface with nil",
|
||||
cfg: configChildInterface{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "pointer to child interface with nil",
|
||||
cfg: &configChildInterface{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "nil",
|
||||
cfg: nil,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "nil map type",
|
||||
cfg: errMapType(nil),
|
||||
expected: errors.New(""),
|
||||
},
|
||||
{
|
||||
name: "nil pointer map type",
|
||||
cfg: newErrMapType(),
|
||||
expected: errors.New(""),
|
||||
},
|
||||
{
|
||||
name: "child struct",
|
||||
cfg: configChildStruct{Child: errValidateConfig{err: errors.New("child struct")}},
|
||||
expected: errors.New("child: child struct"),
|
||||
},
|
||||
{
|
||||
name: "pointer child struct",
|
||||
cfg: &configChildStruct{Child: errValidateConfig{err: errors.New("pointer child struct")}},
|
||||
expected: errors.New("child: pointer child struct"),
|
||||
},
|
||||
{
|
||||
name: "child struct pointer",
|
||||
cfg: &configChildStruct{ChildPtr: &errValidateConfig{err: errors.New("child struct pointer")}},
|
||||
expected: errors.New("childptr: child struct pointer"),
|
||||
},
|
||||
{
|
||||
name: "child interface",
|
||||
cfg: configChildInterface{Child: errValidateConfig{err: errors.New("child interface")}},
|
||||
expected: errors.New("child: child interface"),
|
||||
},
|
||||
{
|
||||
name: "pointer to child interface",
|
||||
cfg: &configChildInterface{Child: errValidateConfig{err: errors.New("pointer to child interface")}},
|
||||
expected: errors.New("child: pointer to child interface"),
|
||||
},
|
||||
{
|
||||
name: "child interface with pointer",
|
||||
cfg: configChildInterface{Child: &errValidateConfig{err: errors.New("child interface with pointer")}},
|
||||
expected: errors.New("child: child interface with pointer"),
|
||||
},
|
||||
{
|
||||
name: "pointer to child interface with pointer",
|
||||
cfg: &configChildInterface{Child: &errValidateConfig{err: errors.New("pointer to child interface with pointer")}},
|
||||
expected: errors.New("child: pointer to child interface with pointer"),
|
||||
},
|
||||
{
|
||||
name: "child slice",
|
||||
cfg: configChildSlice{Child: []errValidateConfig{{}, {err: errors.New("child slice")}}},
|
||||
expected: errors.New("child::1: child slice"),
|
||||
},
|
||||
{
|
||||
name: "pointer child slice",
|
||||
cfg: &configChildSlice{Child: []errValidateConfig{{}, {err: errors.New("pointer child slice")}}},
|
||||
expected: errors.New("child::1: pointer child slice"),
|
||||
},
|
||||
{
|
||||
name: "child slice pointer",
|
||||
cfg: &configChildSlice{ChildPtr: []*errValidateConfig{{}, {err: errors.New("child slice pointer")}}},
|
||||
expected: errors.New("childptr::1: child slice pointer"),
|
||||
},
|
||||
{
|
||||
name: "child map value",
|
||||
cfg: configChildMapValue{Child: map[string]errValidateConfig{"test": {err: errors.New("child map")}}},
|
||||
expected: errors.New("child::test: child map"),
|
||||
},
|
||||
{
|
||||
name: "pointer child map value",
|
||||
cfg: &configChildMapValue{Child: map[string]errValidateConfig{"test": {err: errors.New("pointer child map")}}},
|
||||
expected: errors.New("child::test: pointer child map"),
|
||||
},
|
||||
{
|
||||
name: "child map value pointer",
|
||||
cfg: &configChildMapValue{ChildPtr: map[string]*errValidateConfig{"test": {err: errors.New("child map pointer")}}},
|
||||
expected: errors.New("childptr::test: child map pointer"),
|
||||
},
|
||||
{
|
||||
name: "child map key",
|
||||
cfg: configChildMapKey{Child: map[errType]string{"child_map_key": ""}},
|
||||
expected: errors.New("child::child_map_key: child_map_key"),
|
||||
},
|
||||
{
|
||||
name: "pointer child map key",
|
||||
cfg: &configChildMapKey{Child: map[errType]string{"pointer_child_map_key": ""}},
|
||||
expected: errors.New("child::pointer_child_map_key: pointer_child_map_key"),
|
||||
},
|
||||
{
|
||||
name: "child map key pointer",
|
||||
cfg: &configChildMapKey{ChildPtr: map[*errType]string{newErrType("child map key pointer"): ""}},
|
||||
expected: errors.New("childptr::[*xconfmap.errType key]: child map key pointer"),
|
||||
},
|
||||
{
|
||||
name: "map with stringified non-string key type",
|
||||
cfg: &configChildMapCustomKey{Child: map[structKey]errValidateConfig{{k: "struct_key", e: errors.New("custom key error")}: {err: errors.New("value error")}}},
|
||||
expected: errors.New("child::struct_key: custom key error\nchild::struct_key: value error"),
|
||||
},
|
||||
{
|
||||
name: "child type",
|
||||
cfg: configChildTypeDef{Child: "child type"},
|
||||
expected: errors.New("child: child type"),
|
||||
},
|
||||
{
|
||||
name: "pointer child type",
|
||||
cfg: &configChildTypeDef{Child: "pointer child type"},
|
||||
expected: errors.New("child: pointer child type"),
|
||||
},
|
||||
{
|
||||
name: "child type pointer",
|
||||
cfg: &configChildTypeDef{ChildPtr: newErrType("child type pointer")},
|
||||
expected: errors.New("childptr: child type pointer"),
|
||||
},
|
||||
{
|
||||
name: "valid mapstructure tag",
|
||||
cfg: configMapstructure{Valid: &errValidateConfig{errors.New("test")}},
|
||||
expected: errors.New("validtag: test"),
|
||||
},
|
||||
{
|
||||
name: "zero-length mapstructure tag",
|
||||
cfg: configMapstructure{NoData: &errValidateConfig{errors.New("test")}},
|
||||
expected: errors.New("nodata: test"),
|
||||
},
|
||||
{
|
||||
name: "no field name in mapstructure tag",
|
||||
cfg: configMapstructure{NoName: &errValidateConfig{errors.New("test")}},
|
||||
expected: errors.New("noname: test"),
|
||||
},
|
||||
{
|
||||
name: "nested map key error",
|
||||
cfg: configDeeplyNested{MapKeyChild: map[configChildStruct]string{{Child: errValidateConfig{err: errors.New("child key error")}}: "val"}},
|
||||
expected: errors.New("mapkeychild::[xconfmap.configChildStruct key]::child: child key error"),
|
||||
},
|
||||
{
|
||||
name: "nested map value error",
|
||||
cfg: configDeeplyNested{MapValueChild: map[string]configChildStruct{"key": {Child: errValidateConfig{err: errors.New("child key error")}}}},
|
||||
expected: errors.New("mapvaluechild::key::child: child key error"),
|
||||
},
|
||||
{
|
||||
name: "nested slice value error",
|
||||
cfg: configDeeplyNested{SliceChild: []configChildSlice{{Child: []errValidateConfig{{err: errors.New("child key error")}}}}},
|
||||
expected: errors.New("slicechild::0::child::0: child key error"),
|
||||
},
|
||||
{
|
||||
name: "nested map with int key",
|
||||
cfg: configDeeplyNested{MapIntKey: map[int]errValidateConfig{1: {err: errors.New("int key error")}}},
|
||||
expected: errors.New("mapintkey::1: int key error"),
|
||||
},
|
||||
{
|
||||
name: "nested map with float key",
|
||||
cfg: configDeeplyNested{MapFloatKey: map[float64]errValidateConfig{1.2: {err: errors.New("float key error")}}},
|
||||
expected: errors.New("mapfloatkey::1.2: float key error"),
|
||||
},
|
||||
{
|
||||
name: "slice type alias",
|
||||
cfg: sliceTypeAlias{},
|
||||
expected: errors.New("sliceTypeAlias error"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := Validate(tt.cfg)
|
||||
|
||||
if tt.expected != nil {
|
||||
assert.EqualError(t, err, tt.expected.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
module go.opentelemetry.io/collector/confmap/xconfmap
|
||||
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.10.0
|
||||
go.opentelemetry.io/collector/confmap v1.25.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // 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.2 // 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 => ../
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
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.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/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.2 h1:I2rtLRqXRy1p01m/utEtpZSSA6dcJbgGVuE27kW2PzQ=
|
||||
github.com/knadh/koanf/v2 v2.1.2/go.mod h1:Gphfaen0q1Fc1HTgJgSTC4oRX9R2R5ErYMZJy8fLJBo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
@ -19,6 +19,7 @@ import (
|
|||
"go.opentelemetry.io/collector/config/configtls"
|
||||
"go.opentelemetry.io/collector/confmap"
|
||||
"go.opentelemetry.io/collector/confmap/confmaptest"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/exporter/exporterbatcher"
|
||||
"go.opentelemetry.io/collector/exporter/exporterhelper"
|
||||
)
|
||||
|
|
@ -136,7 +137,7 @@ func TestUnmarshalInvalidConfig(t *testing.T) {
|
|||
sub, err := cm.Sub(tt.name)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, sub.Unmarshal(&cfg))
|
||||
assert.ErrorContains(t, component.ValidateConfig(cfg), tt.errorMsg)
|
||||
assert.ErrorContains(t, xconfmap.Validate(cfg), tt.errorMsg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ require (
|
|||
go.opentelemetry.io/collector/config/configretry v1.25.0
|
||||
go.opentelemetry.io/collector/config/configtls v1.25.0
|
||||
go.opentelemetry.io/collector/confmap v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000
|
||||
go.opentelemetry.io/collector/consumer v1.25.0
|
||||
go.opentelemetry.io/collector/consumer/consumererror v0.119.0
|
||||
go.opentelemetry.io/collector/exporter v0.119.0
|
||||
|
|
@ -98,6 +99,8 @@ replace go.opentelemetry.io/collector/config/configtls => ../../config/configtls
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/exporter => ../
|
||||
|
||||
replace go.opentelemetry.io/collector/extension => ../../extension
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/collector/component"
|
||||
"go.opentelemetry.io/collector/config/confighttp"
|
||||
"go.opentelemetry.io/collector/config/configopaque"
|
||||
"go.opentelemetry.io/collector/config/configretry"
|
||||
"go.opentelemetry.io/collector/config/configtls"
|
||||
"go.opentelemetry.io/collector/confmap"
|
||||
"go.opentelemetry.io/collector/confmap/confmaptest"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/exporter/exporterhelper"
|
||||
)
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ func TestUnmarshalDefaultConfig(t *testing.T) {
|
|||
require.NoError(t, confmap.New().Unmarshal(&cfg))
|
||||
assert.Equal(t, factory.CreateDefaultConfig(), cfg)
|
||||
// Default/Empty config is invalid.
|
||||
assert.Error(t, component.ValidateConfig(cfg))
|
||||
assert.Error(t, xconfmap.Validate(cfg))
|
||||
}
|
||||
|
||||
func TestUnmarshalConfig(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ require (
|
|||
go.opentelemetry.io/collector/config/configretry v1.25.0
|
||||
go.opentelemetry.io/collector/config/configtls v1.25.0
|
||||
go.opentelemetry.io/collector/confmap v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000
|
||||
go.opentelemetry.io/collector/consumer v1.25.0
|
||||
go.opentelemetry.io/collector/consumer/consumererror v0.119.0
|
||||
go.opentelemetry.io/collector/exporter v0.119.0
|
||||
|
|
@ -98,6 +99,8 @@ replace go.opentelemetry.io/collector/config/configtls => ../../config/configtls
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/exporter => ../
|
||||
|
||||
replace go.opentelemetry.io/collector/extension => ../../extension
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ replace go.opentelemetry.io/collector/extension => ../../extension
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/component => ../../component
|
||||
|
||||
replace go.opentelemetry.io/collector/component/componenttest => ../../component/componenttest
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"go.opentelemetry.io/collector/component"
|
||||
"go.opentelemetry.io/collector/confmap"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/extension"
|
||||
"go.opentelemetry.io/collector/otelcol/internal/grpclog"
|
||||
"go.opentelemetry.io/collector/service"
|
||||
|
|
@ -171,7 +172,7 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error {
|
|||
return fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
if err = component.ValidateConfig(cfg); err != nil {
|
||||
if err = xconfmap.Validate(cfg); err != nil {
|
||||
return fmt.Errorf("invalid configuration: %w", err)
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +262,7 @@ func (col *Collector) DryRun(ctx context.Context) error {
|
|||
return fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
return component.ValidateConfig(cfg)
|
||||
return xconfmap.Validate(cfg)
|
||||
}
|
||||
|
||||
func newFallbackLogger(options []zap.Option) (*zap.Logger, error) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
"go.opentelemetry.io/collector/component"
|
||||
"go.opentelemetry.io/collector/config/configtelemetry"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/pipeline"
|
||||
"go.opentelemetry.io/collector/service"
|
||||
"go.opentelemetry.io/collector/service/pipelines"
|
||||
|
|
@ -241,7 +242,7 @@ func TestConfigValidate(t *testing.T) {
|
|||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := tt.cfgFn()
|
||||
err := component.ValidateConfig(cfg)
|
||||
err := xconfmap.Validate(cfg)
|
||||
if tt.expected != nil {
|
||||
assert.EqualError(t, err, tt.expected.Error())
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ require (
|
|||
go.opentelemetry.io/collector/component/componentstatus v0.119.0
|
||||
go.opentelemetry.io/collector/config/configtelemetry v0.119.0
|
||||
go.opentelemetry.io/collector/confmap v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000
|
||||
go.opentelemetry.io/collector/connector v0.119.0
|
||||
go.opentelemetry.io/collector/connector/connectortest v0.119.0
|
||||
go.opentelemetry.io/collector/exporter v0.119.0
|
||||
|
|
@ -141,6 +142,8 @@ replace go.opentelemetry.io/collector/exporter => ../exporter
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/config/configtelemetry => ../config/configtelemetry
|
||||
|
||||
replace go.opentelemetry.io/collector/processor => ../processor
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ package otelcoltest // import "go.opentelemetry.io/collector/otelcol/otelcoltest
|
|||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/collector/component"
|
||||
"go.opentelemetry.io/collector/confmap"
|
||||
"go.opentelemetry.io/collector/confmap/provider/envprovider"
|
||||
"go.opentelemetry.io/collector/confmap/provider/fileprovider"
|
||||
"go.opentelemetry.io/collector/confmap/provider/httpprovider"
|
||||
"go.opentelemetry.io/collector/confmap/provider/yamlprovider"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/otelcol"
|
||||
)
|
||||
|
||||
|
|
@ -41,5 +41,5 @@ func LoadConfigAndValidate(fileName string, factories otelcol.Factories) (*otelc
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg, component.ValidateConfig(cfg)
|
||||
return cfg, xconfmap.Validate(cfg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ require (
|
|||
go.opentelemetry.io/collector/confmap/provider/fileprovider v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/provider/httpprovider v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000
|
||||
go.opentelemetry.io/collector/connector v0.119.0
|
||||
go.opentelemetry.io/collector/connector/connectortest v0.119.0
|
||||
go.opentelemetry.io/collector/exporter v0.119.0
|
||||
|
|
@ -216,6 +217,8 @@ replace go.opentelemetry.io/collector/extension/xextension => ../../extension/xe
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/processor/processortest => ../../processor/processortest
|
||||
|
||||
replace go.opentelemetry.io/collector/pdata/testdata => ../../pdata/testdata
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
"go.opentelemetry.io/collector/config/configtls"
|
||||
"go.opentelemetry.io/collector/confmap"
|
||||
"go.opentelemetry.io/collector/confmap/confmaptest"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
)
|
||||
|
||||
func TestUnmarshalDefaultConfig(t *testing.T) {
|
||||
|
|
@ -193,7 +194,7 @@ func TestUnmarshalConfigEmptyProtocols(t *testing.T) {
|
|||
factory := NewFactory()
|
||||
cfg := factory.CreateDefaultConfig()
|
||||
require.NoError(t, cm.Unmarshal(&cfg))
|
||||
assert.EqualError(t, component.ValidateConfig(cfg), "must specify at least one protocol when using the OTLP receiver")
|
||||
assert.EqualError(t, xconfmap.Validate(cfg), "must specify at least one protocol when using the OTLP receiver")
|
||||
}
|
||||
|
||||
func TestUnmarshalConfigInvalidSignalPath(t *testing.T) {
|
||||
|
|
@ -230,5 +231,5 @@ func TestUnmarshalConfigEmpty(t *testing.T) {
|
|||
factory := NewFactory()
|
||||
cfg := factory.CreateDefaultConfig()
|
||||
require.NoError(t, confmap.New().Unmarshal(&cfg))
|
||||
assert.EqualError(t, component.ValidateConfig(cfg), "must specify at least one protocol when using the OTLP receiver")
|
||||
assert.EqualError(t, xconfmap.Validate(cfg), "must specify at least one protocol when using the OTLP receiver")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ require (
|
|||
go.opentelemetry.io/collector/config/confignet v1.25.0
|
||||
go.opentelemetry.io/collector/config/configtls v1.25.0
|
||||
go.opentelemetry.io/collector/confmap v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000
|
||||
go.opentelemetry.io/collector/consumer v1.25.0
|
||||
go.opentelemetry.io/collector/consumer/consumererror v0.119.0
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.119.0
|
||||
|
|
@ -98,6 +99,8 @@ replace go.opentelemetry.io/collector/config/configtls => ../../config/configtls
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/extension => ../../extension
|
||||
|
||||
replace go.opentelemetry.io/collector/extension/auth => ../../extension/auth
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
"go.opentelemetry.io/collector/component"
|
||||
"go.opentelemetry.io/collector/config/configtelemetry"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/pipeline"
|
||||
"go.opentelemetry.io/collector/service/extensions"
|
||||
"go.opentelemetry.io/collector/service/pipelines"
|
||||
|
|
@ -77,7 +78,7 @@ func TestConfigValidate(t *testing.T) {
|
|||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := tt.cfgFn()
|
||||
err := component.ValidateConfig(cfg)
|
||||
err := xconfmap.Validate(cfg)
|
||||
if tt.expected != nil {
|
||||
assert.ErrorContains(t, err, tt.expected.Error())
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ require (
|
|||
go.opentelemetry.io/collector/config/confighttp v0.119.0
|
||||
go.opentelemetry.io/collector/config/configtelemetry v0.119.0
|
||||
go.opentelemetry.io/collector/confmap v1.25.0
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.0.0-00010101000000-000000000000
|
||||
go.opentelemetry.io/collector/connector v0.119.0
|
||||
go.opentelemetry.io/collector/connector/connectortest v0.119.0
|
||||
go.opentelemetry.io/collector/connector/xconnector v0.119.0
|
||||
|
|
@ -150,6 +151,8 @@ replace go.opentelemetry.io/collector/exporter => ../exporter
|
|||
|
||||
replace go.opentelemetry.io/collector/confmap => ../confmap
|
||||
|
||||
replace go.opentelemetry.io/collector/confmap/xconfmap => ../confmap/xconfmap
|
||||
|
||||
replace go.opentelemetry.io/collector/config/configtelemetry => ../config/configtelemetry
|
||||
|
||||
replace go.opentelemetry.io/collector/pipeline => ../pipeline
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/collector/component"
|
||||
"go.opentelemetry.io/collector/confmap/xconfmap"
|
||||
"go.opentelemetry.io/collector/featuregate"
|
||||
"go.opentelemetry.io/collector/pipeline"
|
||||
"go.opentelemetry.io/collector/pipeline/xpipeline"
|
||||
|
|
@ -108,9 +109,9 @@ func TestConfigValidate(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := tt.cfgFn(t)
|
||||
if tt.expected != nil {
|
||||
require.ErrorContains(t, component.ValidateConfig(cfg), tt.expected.Error())
|
||||
require.ErrorContains(t, xconfmap.Validate(cfg), tt.expected.Error())
|
||||
} else {
|
||||
require.NoError(t, component.ValidateConfig(cfg))
|
||||
require.NoError(t, xconfmap.Validate(cfg))
|
||||
}
|
||||
|
||||
// Clean up the profiles support gate, which may have been enabled in `cfgFn`.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ module-sets:
|
|||
- go.opentelemetry.io/collector/component
|
||||
- go.opentelemetry.io/collector/component/componenttest
|
||||
- go.opentelemetry.io/collector/component/componentstatus
|
||||
- go.opentelemetry.io/collector/confmap/xconfmap
|
||||
- go.opentelemetry.io/collector/config/configauth
|
||||
- go.opentelemetry.io/collector/config/configgrpc
|
||||
- go.opentelemetry.io/collector/config/confighttp
|
||||
|
|
|
|||
Loading…
Reference in New Issue