diff --git a/flytestdlib/config/tests/accessor_test.go b/flytestdlib/config/tests/accessor_test.go index e53e4f6..64d9f55 100644 --- a/flytestdlib/config/tests/accessor_test.go +++ b/flytestdlib/config/tests/accessor_test.go @@ -299,6 +299,38 @@ func TestAccessor_UpdateConfig(t *testing.T) { assert.Equal(t, 4, (*topLevel)[1].IntValue) }) + t.Run(fmt.Sprintf("[%v] Override default array config", provider(config.Options{}).ID()), func(t *testing.T) { + root := config.NewRootSection() + _, err := root.RegisterSection(MyComponentSectionKey, &ItemArray{ + Items: []Item{ + { + ID: "default_1", + Name: "default_Name", + }, + { + ID: "default_2", + Name: "default_2_Name", + }, + }, + OtherItem: Item{ + ID: "default_3", + Name: "default_3_name", + }, + }) + assert.NoError(t, err) + + v := provider(config.Options{ + SearchPaths: []string{filepath.Join("testdata", "array_config_2.yaml")}, + RootSection: root, + }) + + assert.NoError(t, v.UpdateConfig(context.TODO())) + r := root.GetSection(MyComponentSectionKey).GetConfig().(*ItemArray) + assert.Len(t, r.Items, 1) + assert.Equal(t, "abc", r.Items[0].ID) + assert.Equal(t, "default_3", r.OtherItem.ID) + }) + t.Run(fmt.Sprintf("[%v] Override in Env Var", provider(config.Options{}).ID()), func(t *testing.T) { reg := config.NewRootSection() _, err := reg.RegisterSection(MyComponentSectionKey, &MyComponentConfig{}) diff --git a/flytestdlib/config/tests/testdata/array_config_2.yaml b/flytestdlib/config/tests/testdata/array_config_2.yaml new file mode 100644 index 0000000..05aa2bb --- /dev/null +++ b/flytestdlib/config/tests/testdata/array_config_2.yaml @@ -0,0 +1,4 @@ +my-component: + items: + - id: abc + name: "A b c" \ No newline at end of file diff --git a/flytestdlib/config/tests/types_test.go b/flytestdlib/config/tests/types_test.go index 0be368f..03c442b 100644 --- a/flytestdlib/config/tests/types_test.go +++ b/flytestdlib/config/tests/types_test.go @@ -27,6 +27,16 @@ type OtherComponentConfig struct { StringArrayWithDefaults []string `json:"strings-def"` } +type Item struct { + ID string `json:"id"` + Name string `json:"name"` +} + +type ItemArray struct { + Items []Item `json:"items"` + OtherItem Item `json:"otherItem"` +} + func (MyComponentConfig) GetPFlagSet(prefix string) *pflag.FlagSet { cmdFlags := pflag.NewFlagSet("MyComponentConfig", pflag.ExitOnError) cmdFlags.String(fmt.Sprintf("%v%v", prefix, "str"), "hello world", "life is short") diff --git a/flytestdlib/config/viper/viper.go b/flytestdlib/config/viper/viper.go index 6f472fe..d91bc63 100644 --- a/flytestdlib/config/viper/viper.go +++ b/flytestdlib/config/viper/viper.go @@ -270,6 +270,8 @@ func defaultDecoderConfig(output interface{}, opts ...viperLib.DecoderConfigOpti mapstructure.StringToTimeDurationHookFunc(), mapstructure.StringToSliceHookFunc(","), ), + // Empty/zero fields before applying provided values. This avoids potentially undesired/unexpected merging logic. + ZeroFields: true, } for _, opt := range opts {