From 328a96b6af01712797a35a057bae1ef96d738bb2 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Sun, 3 May 2020 08:33:07 -0700 Subject: [PATCH 1/2] Allow config.Load to load partial config Signed-off-by: Bogdan Drutu --- config/config.go | 34 +++++++++------------------------- config/config_test.go | 8 ++++---- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/config/config.go b/config/config.go index 7d2c9a861e9..5e59df4e877 100644 --- a/config/config.go +++ b/config/config.go @@ -123,6 +123,7 @@ func NewViper() *viper.Viper { } // Load loads a Config from Viper. +// After loading the config, need to check if it is valid by calling `ValidateConfig`. func Load( v *viper.Viper, factories Factories, @@ -349,15 +350,6 @@ func loadReceivers(v *viper.Viper, factories map[configmodels.Type]component.Rec // Get the map of "receivers" sub-keys. keyMap := v.GetStringMap(receiversKeyName) - // Currently there is no default receiver enabled. The configuration must specify at least one receiver to enable - // functionality. - if len(keyMap) == 0 { - return nil, &configError{ - code: errMissingReceivers, - msg: "no receivers specified in config", - } - } - // Prepare resulting map receivers := make(configmodels.Receivers) @@ -408,14 +400,6 @@ func loadExporters(v *viper.Viper, factories map[configmodels.Type]component.Exp // Get the map of "exporters" sub-keys. keyMap := v.GetStringMap(exportersKeyName) - // There is no default exporter. The configuration must specify at least one exporter to enable functionality. - if len(keyMap) == 0 { - return nil, &configError{ - code: errMissingExporters, - msg: "no exporters specified in config", - } - } - // Prepare resulting map exporters := make(configmodels.Exporters) @@ -602,6 +586,7 @@ func ValidateConfig(cfg *configmodels.Config, logger *zap.Logger) error { if err := validateReceivers(cfg); err != nil { return err } + if err := validateExporters(cfg); err != nil { return err } @@ -610,25 +595,24 @@ func ValidateConfig(cfg *configmodels.Config, logger *zap.Logger) error { return err } - if err := validatePipelines(cfg); err != nil { - return err - } - return nil } func validateService(cfg *configmodels.Config) error { - // Currently only to validate extensions. - return validateServiceExtensions(cfg, &cfg.Service) + if err := validatePipelines(cfg); err != nil { + return err + } + + return validateServiceExtensions(cfg) } -func validateServiceExtensions(cfg *configmodels.Config, service *configmodels.Service) error { +func validateServiceExtensions(cfg *configmodels.Config) error { if len(cfg.Service.Extensions) == 0 { return nil } // Validate extensions. - for _, ref := range service.Extensions { + for _, ref := range cfg.Service.Extensions { // Check that the name referenced in the service extensions exists in the top-level extensions if cfg.Extensions[ref] == nil { return &configError{ diff --git a/config/config_test.go b/config/config_test.go index eb26c359ea0..9c8efcd89ad 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -26,7 +26,7 @@ import ( func TestDecodeConfig(t *testing.T) { factories, err := ExampleComponents() - assert.Nil(t, err) + assert.NoError(t, err) // Load the config config, err := LoadConfigFile(t, path.Join(".", "testdata", "valid-config.yaml"), factories) @@ -192,7 +192,7 @@ func TestSimpleConfig(t *testing.T) { for _, test := range testCases { t.Logf("TEST[%s]", test.name) factories, err := ExampleComponents() - assert.Nil(t, err) + assert.NoError(t, err) // Load the config config, err := LoadConfigFile(t, path.Join(".", "testdata", test.name+".yaml"), factories) @@ -287,7 +287,7 @@ func TestSimpleConfig(t *testing.T) { func TestDecodeConfig_MultiProto(t *testing.T) { factories, err := ExampleComponents() - assert.Nil(t, err) + assert.NoError(t, err) // Load the config config, err := LoadConfigFile(t, path.Join(".", "testdata", "multiproto-config.yaml"), factories) @@ -383,7 +383,7 @@ func TestDecodeConfig_Invalid(t *testing.T) { } factories, err := ExampleComponents() - assert.Nil(t, err) + assert.NoError(t, err) for _, test := range testCases { _, err := LoadConfigFile(t, path.Join(".", "testdata", test.name+".yaml"), factories) From f0d96e462e4f1f69bec0f23b4942b0df6bd7fafb Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 4 May 2020 17:01:09 -0700 Subject: [PATCH 2/2] Add test to load empty config. Signed-off-by: Bogdan Drutu --- config/config_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/config/config_test.go b/config/config_test.go index 9c8efcd89ad..b0b2a7a2b8d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/open-telemetry/opentelemetry-collector/config/configmodels" ) @@ -407,3 +408,25 @@ func TestDecodeConfig_Invalid(t *testing.T) { } } } + +func TestLoadEmptyConfig(t *testing.T) { + factories, err := ExampleComponents() + assert.NoError(t, err) + + // Open the file for reading. + file, err := os.Open(path.Join(".", "testdata", "empty-config.yaml")) + require.NoError(t, err) + + defer func() { + require.NoError(t, file.Close()) + }() + + // Read yaml config from file + v := NewViper() + v.SetConfigType("yaml") + require.NoError(t, v.ReadConfig(file)) + + // Load the config from viper using the given factories. + _, err = Load(v, factories) + assert.NoError(t, err) +}