From e78e22fb2a446efe41667c1425815257cd30ff93 Mon Sep 17 00:00:00 2001 From: Lucas Bremgartner Date: Mon, 22 Sep 2025 07:38:38 +0200 Subject: [PATCH] api: Handle pre initialized targed ConfigMap (default values) Signed-off-by: Lucas Bremgartner --- shared/api/config.go | 7 +- shared/api/config_test.go | 191 +++++++++++++++++++++++++++++++++++--- 2 files changed, 181 insertions(+), 17 deletions(-) diff --git a/shared/api/config.go b/shared/api/config.go index 85d022b5a..9dd0ae428 100644 --- a/shared/api/config.go +++ b/shared/api/config.go @@ -47,11 +47,14 @@ func (m *ConfigMap) UnmarshalYAML(unmarshal func(any) error) error { func (m *ConfigMap) fromMapStringAny(raw map[string]any) error { if raw == nil { - *m = nil return nil } - result := make(ConfigMap, len(raw)) + result := *m + if result == nil { + result = make(ConfigMap, len(raw)) + } + for k, v := range raw { switch val := v.(type) { case string: diff --git a/shared/api/config_test.go b/shared/api/config_test.go index 6920b0aa2..4f99ab328 100644 --- a/shared/api/config_test.go +++ b/shared/api/config_test.go @@ -13,8 +13,9 @@ import ( func TestConfigMap_UnmarshalJSON(t *testing.T) { tests := []struct { - name string - input map[string]any + name string + input map[string]any + target api.ConfigMap assertErr require.ErrorAssertionFunc want api.ConfigMap @@ -27,11 +28,28 @@ func TestConfigMap_UnmarshalJSON(t *testing.T) { want: nil, }, { - name: "empty", - input: map[string]any{}, + name: "nil with defaults", + input: nil, + target: api.ConfigMap{ + "default_string": "string", + }, assertErr: require.NoError, - want: api.ConfigMap{}, + want: api.ConfigMap{ + "default_string": "string", + }, + }, + { + name: "empty", + input: map[string]any{}, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.NoError, + want: api.ConfigMap{ + "default_string": "string", + }, }, { name: "only string", @@ -79,6 +97,35 @@ func TestConfigMap_UnmarshalJSON(t *testing.T) { "null": "", }, }, + { + name: "mixed with defaults", + input: map[string]any{ + "string": "string", + "int": 5, + "uint": uint64(math.MaxUint64), + "float64": 5.4, + "float64max": math.MaxFloat64, + "bool": true, + "empty": "", + "null": nil, + }, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.NoError, + want: api.ConfigMap{ + "string": "string", + "int": "5", + "uint": "1.8446744073709552e+19", + "float64": "5.4", + "float64max": "1.7976931348623157e+308", + "bool": "true", + "empty": "", + "null": "", + "default_string": "string", + }, + }, // errors { @@ -92,6 +139,22 @@ func TestConfigMap_UnmarshalJSON(t *testing.T) { assertErr: require.Error, want: nil, }, + { + name: "error - unsupported type object with defaults", + input: map[string]any{ + "invalid": map[string]any{ // invalid + "inner": "value", + }, + }, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.Error, + want: api.ConfigMap{ + "default_string": "string", + }, + }, { name: "error - unsupported type array", input: map[string]any{ @@ -103,6 +166,22 @@ func TestConfigMap_UnmarshalJSON(t *testing.T) { assertErr: require.Error, want: nil, }, + { + name: "error - unsupported type array with defaults", + input: map[string]any{ + "invalid": []string{ // invalid + "inner", "value", + }, + }, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.Error, + want: api.ConfigMap{ + "default_string": "string", + }, + }, } for _, tc := range tests { @@ -110,20 +189,19 @@ func TestConfigMap_UnmarshalJSON(t *testing.T) { in, err := json.Marshal(tc.input) require.NoError(t, err) - var got api.ConfigMap - - err = json.Unmarshal(in, &got) + err = json.Unmarshal(in, &tc.target) tc.assertErr(t, err) - require.Equal(t, tc.want, got) + require.Equal(t, tc.want, tc.target) }) } } func TestConfigMap_UnmarshalYAML(t *testing.T) { tests := []struct { - name string - input map[string]any + name string + input map[string]any + target api.ConfigMap assertErr require.ErrorAssertionFunc want api.ConfigMap @@ -135,6 +213,18 @@ func TestConfigMap_UnmarshalYAML(t *testing.T) { assertErr: require.NoError, want: api.ConfigMap{}, }, + { + name: "nil with defaults", + input: nil, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.NoError, + want: api.ConfigMap{ + "default_string": "string", + }, + }, { name: "empty", input: map[string]any{}, @@ -142,6 +232,18 @@ func TestConfigMap_UnmarshalYAML(t *testing.T) { assertErr: require.NoError, want: api.ConfigMap{}, }, + { + name: "empty with defaults", + input: map[string]any{}, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.NoError, + want: api.ConfigMap{ + "default_string": "string", + }, + }, { name: "only string", input: map[string]any{ @@ -188,6 +290,35 @@ func TestConfigMap_UnmarshalYAML(t *testing.T) { "null": "", }, }, + { + name: "mixed with defaults", + input: map[string]any{ + "string": "string", + "int": 5, + "uint": uint64(math.MaxUint64), + "float64": 5.4, + "float64max": math.MaxFloat64, + "bool": true, + "empty": "", + "null": nil, + }, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.NoError, + want: api.ConfigMap{ + "string": "string", + "int": "5", + "uint": "18446744073709551615", + "float64": "5.4", + "float64max": "1.7976931348623157e+308", + "bool": "true", + "empty": "", + "null": "", + "default_string": "string", + }, + }, // errors { @@ -201,6 +332,22 @@ func TestConfigMap_UnmarshalYAML(t *testing.T) { assertErr: require.Error, want: nil, }, + { + name: "error - unsupported type object with defaults", + input: map[string]any{ + "invalid": map[string]any{ // invalid + "inner": "value", + }, + }, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.Error, + want: api.ConfigMap{ + "default_string": "string", + }, + }, { name: "error - unsupported type array", input: map[string]any{ @@ -212,6 +359,22 @@ func TestConfigMap_UnmarshalYAML(t *testing.T) { assertErr: require.Error, want: nil, }, + { + name: "error - unsupported type array with defaults", + input: map[string]any{ + "invalid": []string{ // invalid + "inner", "value", + }, + }, + target: api.ConfigMap{ + "default_string": "string", + }, + + assertErr: require.Error, + want: api.ConfigMap{ + "default_string": "string", + }, + }, } for _, tc := range tests { @@ -219,12 +382,10 @@ func TestConfigMap_UnmarshalYAML(t *testing.T) { in, err := yaml.Marshal(tc.input) require.NoError(t, err) - var got api.ConfigMap - - err = yaml.Unmarshal(in, &got) + err = yaml.Unmarshal(in, &tc.target) tc.assertErr(t, err) - require.Equal(t, tc.want, got) + require.Equal(t, tc.want, tc.target) }) } }