diff --git a/pkg/config/operator.go b/pkg/config/operator.go index f962f96a..40316fa2 100644 --- a/pkg/config/operator.go +++ b/pkg/config/operator.go @@ -23,6 +23,7 @@ var ( ErrEmptyConfigItem = errors.New("empty config item") ErrConflictConfigItemType = errors.New("type of the config item conflicts between saved and registered") ErrEmptyConfigItemKey = errors.New("empty config item key") + ErrEmptyConfigItemValue = errors.New("empty config item value") ErrUnsupportedConfigItem = errors.New("unsupported config item") ErrEmptyBackendName = errors.New("backend name should not be empty") ErrInvalidBackendName = errors.New("backend name should not be current") @@ -246,9 +247,6 @@ func getConfigItemWithLaxType(config *v1.Config, key string) (any, error) { // the updated config. // ATTENTION! Cause the input config could be nil, change it or its value may both could result in assignment failure. func setItemInConfig(config *v1.Config, info *itemInfo, key string, value any) (*v1.Config, error) { - if err := validateConfig(config); err != nil { - return nil, err - } if err := validateConfigItem(config, info, key, value); err != nil { return nil, err } @@ -299,7 +297,7 @@ func tidyConfig(configAddr **v1.Config) { // validateConfigItem checks the config item value is valid or not. func validateConfigItem(config *v1.Config, info *itemInfo, key string, value any) error { if reflect.ValueOf(value).IsZero() { - return ErrEmptyConfigItem + return ErrEmptyConfigItemValue } if info.validateFunc != nil { return info.validateFunc(config, key, value) @@ -311,7 +309,7 @@ func validateConfigItem(config *v1.Config, info *itemInfo, key string, value any // its validation. func parseStructuredConfigItem(info *itemInfo, strValue string) (any, error) { if len(strValue) == 0 { - return nil, ErrEmptyConfigItem + return nil, ErrEmptyConfigItemValue } value := info.zeroValue diff --git a/pkg/config/operator_test.go b/pkg/config/operator_test.go index 310b245f..4162cc4c 100644 --- a/pkg/config/operator_test.go +++ b/pkg/config/operator_test.go @@ -11,14 +11,17 @@ import ( ) var ( - testDataPath = "testdata" - existValidConfigPath = filepath.Join(testDataPath, "config_for_read.yaml") - emptyValidConfigPath = filepath.Join(testDataPath, "config_for_write.yaml") - invalidConfigPath = filepath.Join(testDataPath, "config_invalid.yaml") + testDataPath = "testdata" + testExistValidConfigPath = filepath.Join(testDataPath, "config.yaml") + testEmptyValidConfigPath = filepath.Join(testDataPath, "config_empty.yaml") + testWriteValidConfigPath = filepath.Join(testDataPath, "config_write.yaml") + testInvalidConfigPath = filepath.Join(testDataPath, "config_invalid.yaml") - registeredItems = newRegisteredItems() + mockConfigPath = "" // used for get/set/delete operation which do not file operation +) - validConfig = &v1.Config{ +func mockValidConfig() *v1.Config { + return &v1.Config{ Backends: &v1.BackendConfigs{ Current: "dev", Backends: map[string]*v1.BackendConfig{ @@ -43,7 +46,10 @@ var ( }, }, } - validCfg = map[string]any{ +} + +func mockValidCfgMap() map[string]any { + return map[string]any{ v1.ConfigBackends: map[string]any{ v1.BackendCurrent: "dev", "dev": map[string]any{ @@ -66,12 +72,12 @@ var ( }, }, } -) +} func mockOperator(configFilePath string, config *v1.Config) *operator { return &operator{ configFilePath: configFilePath, - registeredItems: registeredItems, + registeredItems: newRegisteredItems(), config: config, } } @@ -86,19 +92,19 @@ func TestOperator_ReadConfig(t *testing.T) { { name: "read config successfully", success: true, - o: mockOperator(existValidConfigPath, nil), - expectedConfig: validConfig, + o: mockOperator(testExistValidConfigPath, nil), + expectedConfig: mockValidConfig(), }, { name: "read not exist config successfully", success: true, - o: mockOperator(emptyValidConfigPath, nil), + o: mockOperator(testEmptyValidConfigPath, nil), expectedConfig: nil, }, { name: "failed to read config invalid structure", success: false, - o: mockOperator(invalidConfigPath, nil), + o: mockOperator(testInvalidConfigPath, nil), expectedConfig: nil, }, } @@ -121,7 +127,7 @@ func TestOperator_WriteConfig(t *testing.T) { { name: "write config successfully", success: true, - o: mockOperator(emptyValidConfigPath, validConfig), + o: mockOperator(testWriteValidConfigPath, mockValidConfig()), }, } @@ -145,21 +151,21 @@ func TestOperator_GetConfigItem(t *testing.T) { { name: "get structured config item successfully type string", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre.configs.host", expectedVal: "127.0.0.1", }, { name: "get structured config item successfully type int", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre.configs.port", expectedVal: 3306, }, { name: "get structured config item successfully type pointer of struct", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre", expectedVal: &v1.BackendConfig{ Type: v1.BackendTypeMysql, @@ -174,7 +180,7 @@ func TestOperator_GetConfigItem(t *testing.T) { { name: "get structured config item successfully type map", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.prod.configs", expectedVal: map[string]any{ v1.BackendGenericOssBucket: "kusion", @@ -202,21 +208,21 @@ func TestOperator_GetEncodedConfigItem(t *testing.T) { { name: "get encoding config item successfully type string", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre.configs.host", expectedVal: "127.0.0.1", }, { name: "get encoding config item successfully type int", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre.configs.port", expectedVal: "3306", }, { name: "get encoding config item successfully type map", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre", expectedVal: `{"configs":{"dbName":"kusion","host":"127.0.0.1","port":3306,"user":"kk"},"type":"mysql"}`, }, @@ -243,7 +249,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "set config item successfully type string", success: true, - o: mockOperator(existValidConfigPath, nil), + o: mockOperator(mockConfigPath, nil), key: "backends.dev.type", val: v1.BackendTypeLocal, expectedConfig: &v1.Config{ @@ -257,7 +263,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "set config item successfully type int", success: true, - o: mockOperator(existValidConfigPath, &v1.Config{ + o: mockOperator(mockConfigPath, &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ "pre": {Type: v1.BackendTypeMysql}, @@ -282,7 +288,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "set config item successfully type struct", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre", val: &v1.BackendConfig{ Type: v1.BackendTypeMysql, @@ -322,7 +328,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "set config item successfully type map", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.prod.configs", val: map[string]any{ v1.BackendGenericOssBucket: "kk-so-tired", @@ -356,7 +362,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "failed to set config item invalid type", success: false, - o: mockOperator(existValidConfigPath, nil), + o: mockOperator(mockConfigPath, nil), key: "backends.dev.configs.path", val: 234, expectedConfig: nil, @@ -364,7 +370,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "failed to set config item empty value", success: false, - o: mockOperator(existValidConfigPath, nil), + o: mockOperator(mockConfigPath, nil), key: "backends.dev.configs.path", val: "", expectedConfig: nil, @@ -372,7 +378,7 @@ func TestOperator_SetConfigItem(t *testing.T) { { name: "failed to set config item validate func failed", success: false, - o: mockOperator(existValidConfigPath, nil), + o: mockOperator(mockConfigPath, nil), key: "backends.dev.configs.path", val: "/etc", expectedConfig: nil, @@ -402,7 +408,7 @@ func TestOperator_setEncodedConfigItem(t *testing.T) { { name: "set config item successfully type string", success: true, - o: mockOperator(existValidConfigPath, nil), + o: mockOperator(mockConfigPath, nil), key: "backends.dev.type", val: v1.BackendTypeLocal, expectedConfig: &v1.Config{ @@ -416,7 +422,7 @@ func TestOperator_setEncodedConfigItem(t *testing.T) { { name: "set config item successfully type int", success: true, - o: mockOperator(existValidConfigPath, &v1.Config{ + o: mockOperator(mockConfigPath, &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ "pre": {Type: v1.BackendTypeMysql}, @@ -441,7 +447,7 @@ func TestOperator_setEncodedConfigItem(t *testing.T) { { name: "set config item successfully type struct", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.pre", val: `{"configs":{"dbName":"kusion","host":"127.0.0.1","port":3306,"user":"kk-tired"},"type":"mysql"}`, expectedConfig: &v1.Config{ @@ -473,7 +479,7 @@ func TestOperator_setEncodedConfigItem(t *testing.T) { { name: "set config item successfully type map", success: true, - o: mockOperator(existValidConfigPath, validConfig), + o: mockOperator(mockConfigPath, mockValidConfig()), key: "backends.prod.configs", val: `{"bucket":"kusion","region":"us-east-1"}`, expectedConfig: &v1.Config{ @@ -527,7 +533,7 @@ func TestOperator_DeleteConfigItem(t *testing.T) { { name: "delete config item successfully", success: true, - o: mockOperator(existValidConfigPath, &v1.Config{ + o: mockOperator(mockConfigPath, &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ "dev": { @@ -543,7 +549,7 @@ func TestOperator_DeleteConfigItem(t *testing.T) { { name: "failed to delete config item validateUnsetFunc failed", success: false, - o: mockOperator(existValidConfigPath, &v1.Config{ + o: mockOperator(mockConfigPath, &v1.Config{ Backends: &v1.BackendConfigs{ Current: "dev", Backends: map[string]*v1.BackendConfig{ @@ -560,7 +566,7 @@ func TestOperator_DeleteConfigItem(t *testing.T) { { name: "failed to delete config item unsupported key", success: false, - o: mockOperator(existValidConfigPath, &v1.Config{ + o: mockOperator(mockConfigPath, &v1.Config{ Backends: &v1.BackendConfigs{ Current: "dev", Backends: map[string]*v1.BackendConfig{ @@ -654,8 +660,8 @@ func TestValidateConfigItem(t *testing.T) { { name: "invalid config item empty value", success: false, - config: validConfig, - info: registeredItems["backends.current"], + config: mockValidConfig(), + info: newRegisteredItems()["backends.current"], key: "backends.current", val: "", }, @@ -680,14 +686,14 @@ func TestParseStructuredConfigItem(t *testing.T) { { name: "parse structured config item successfully string", success: true, - info: registeredItems["backends.current"], + info: newRegisteredItems()["backends.current"], strVal: "dev", val: "dev", }, { name: "parse structured config item successfully int", success: true, - info: registeredItems["backends.*.configs.port"], + info: newRegisteredItems()["backends.*.configs.port"], strVal: "3306", val: 3306, }, @@ -701,7 +707,7 @@ func TestParseStructuredConfigItem(t *testing.T) { { name: "parse structured config item successfully struct ptr", success: true, - info: registeredItems["backends.*"], + info: newRegisteredItems()["backends.*"], strVal: `{"configs":{"dbName":"kusion","host":"127.0.0.1","port":3306,"user":"kk"},"type":"mysql"}`, val: &v1.BackendConfig{ Type: v1.BackendTypeMysql, @@ -731,7 +737,7 @@ func TestParseStructuredConfigItem(t *testing.T) { { name: "parse structured config item successfully map", success: true, - info: registeredItems["backends.*.configs"], + info: newRegisteredItems()["backends.*.configs"], strVal: `{"bucket":"kusion"}`, val: map[string]any{ v1.BackendGenericOssBucket: "kusion", @@ -740,7 +746,7 @@ func TestParseStructuredConfigItem(t *testing.T) { { name: "failed to parse structured config item int", success: false, - info: registeredItems["backends.*.configs.port"], + info: newRegisteredItems()["backends.*.configs.port"], strVal: "not_valid_int", val: nil, }, @@ -803,7 +809,7 @@ func TestConvertToRegisteredKey(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - registeredKey, err := convertToRegisteredKey(registeredItems, tc.key) + registeredKey, err := convertToRegisteredKey(newRegisteredItems(), tc.key) assert.Equal(t, tc.success, err == nil) assert.Equal(t, tc.registeredKey, registeredKey) }) @@ -820,8 +826,8 @@ func TestConvertCfgMap(t *testing.T) { { name: "convert config map successfully", success: true, - config: validConfig, - cfg: validCfg, + config: mockValidConfig(), + cfg: mockValidCfgMap(), }, } @@ -848,21 +854,21 @@ func TestGetItemFromCfgMap(t *testing.T) { { name: "get item from config map successfully type string", success: true, - cfg: validCfg, + cfg: mockValidCfgMap(), key: "backends.current", expectedVal: "dev", }, { name: "get item from config map successfully type int", success: true, - cfg: validCfg, + cfg: mockValidCfgMap(), key: "backends.pre.configs.port", expectedVal: 3306, }, { name: "get item from config map successfully type map", success: true, - cfg: validCfg, + cfg: mockValidCfgMap(), key: "backends.prod", expectedVal: map[string]any{ v1.BackendType: v1.BackendTypeS3, @@ -874,14 +880,14 @@ func TestGetItemFromCfgMap(t *testing.T) { { name: "failed to get item from config map not exist value", success: false, - cfg: validCfg, + cfg: mockValidCfgMap(), key: "backends.dev.configs.path", expectedVal: nil, }, { name: "failed to get item from config map wrong key", success: false, - cfg: validCfg, + cfg: mockValidCfgMap(), key: "backends.stage.configs", expectedVal: nil, }, diff --git a/pkg/config/testdata/config_for_read.yaml b/pkg/config/testdata/config.yaml similarity index 100% rename from pkg/config/testdata/config_for_read.yaml rename to pkg/config/testdata/config.yaml diff --git a/pkg/config/util_test.go b/pkg/config/util_test.go index 27ce6cbf..926e0fbd 100644 --- a/pkg/config/util_test.go +++ b/pkg/config/util_test.go @@ -1,7 +1,6 @@ package config import ( - "os" "testing" "github.com/bytedance/mockey" @@ -10,9 +9,9 @@ import ( v1 "kusionstack.io/kusion/pkg/apis/core/v1" ) -func mockNewOperator(configFilePath string, config *v1.Config) { +func mockNewOperator(config *v1.Config) { mockey.Mock(newOperator).Return(&operator{ - configFilePath: configFilePath, + configFilePath: mockConfigPath, registeredItems: newRegisteredItems(), config: config, }, nil).Build() @@ -22,25 +21,16 @@ func TestGetConfig(t *testing.T) { testcases := []struct { name string success bool - configFilePath string expectedConfig *v1.Config }{ { name: "get config successfully", success: true, - configFilePath: existValidConfigPath, - expectedConfig: validConfig, + expectedConfig: mockValidConfig(), }, { name: "failed to get config empty config", success: false, - configFilePath: emptyValidConfigPath, - expectedConfig: nil, - }, - { - name: "failed to get config invalid config", - success: false, - configFilePath: invalidConfigPath, expectedConfig: nil, }, } @@ -48,7 +38,8 @@ func TestGetConfig(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { mockey.PatchConvey("mock config operator", t, func() { - mockNewOperator(tc.configFilePath, nil) + mockNewOperator(tc.expectedConfig) + mockey.Mock((*operator).readConfig).Return(nil) config, err := GetConfig() assert.Equal(t, tc.success, err == nil) assert.Equal(t, tc.expectedConfig, config) @@ -61,42 +52,42 @@ func TestGetEncodedConfigItem(t *testing.T) { testcases := []struct { name string success bool - configFilePath string + config *v1.Config configItemKey string expectedConfigItem string }{ { name: "get encoded config item successfully type string", success: true, - configFilePath: existValidConfigPath, + config: mockValidConfig(), configItemKey: "backends.dev.type", expectedConfigItem: "local", }, { name: "get encoded config item successfully type int", success: true, - configFilePath: existValidConfigPath, + config: mockValidConfig(), configItemKey: "backends.pre.configs.port", expectedConfigItem: "3306", }, { name: "get encoded config item successfully type struct", success: true, - configFilePath: existValidConfigPath, + config: mockValidConfig(), configItemKey: "backends.prod", expectedConfigItem: `{"configs":{"bucket":"kusion"},"type":"s3"}`, }, { name: "failed to get encoded config item empty item", success: false, - configFilePath: emptyValidConfigPath, + config: nil, configItemKey: "backends.stage", expectedConfigItem: "", }, { name: "failed to get encoded config item not registered item", success: false, - configFilePath: emptyValidConfigPath, + config: nil, configItemKey: "backends.current.not.registered", expectedConfigItem: "", }, @@ -105,7 +96,8 @@ func TestGetEncodedConfigItem(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { mockey.PatchConvey("mock config operator", t, func() { - mockNewOperator(tc.configFilePath, nil) + mockNewOperator(tc.config) + mockey.Mock((*operator).readConfig).Return(nil).Build() item, err := GetEncodedConfigItem(tc.configItemKey) assert.Equal(t, tc.success, err == nil) assert.Equal(t, tc.expectedConfigItem, item) @@ -116,19 +108,18 @@ func TestGetEncodedConfigItem(t *testing.T) { func TestSetEncodedConfigItem(t *testing.T) { testcases := []struct { - name string - success bool - configFilePath string - configItemKey string - configItem string - expectedConfig *v1.Config + name string + success bool + configItemKey string + configItem string + config, expectedConfig *v1.Config }{ { - name: "set encoded config item successfully type string", - success: true, - configFilePath: emptyValidConfigPath, - configItemKey: "backends.dev.type", - configItem: "local", + name: "set encoded config item successfully type string", + success: true, + configItemKey: "backends.dev.type", + configItem: "local", + config: nil, expectedConfig: &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ @@ -138,11 +129,11 @@ func TestSetEncodedConfigItem(t *testing.T) { }, }, { - name: "set encoded config item successfully type struct", - success: true, - configFilePath: emptyValidConfigPath, - configItemKey: "backends.pre", - configItem: `{"configs":{"dbName":"kusion","host":"127.0.0.1","port":3306,"user":"kk"},"type":"mysql"}`, + name: "set encoded config item successfully type struct", + success: true, + configItemKey: "backends.pre", + configItem: `{"configs":{"dbName":"kusion","host":"127.0.0.1","port":3306,"user":"kk"},"type":"mysql"}`, + config: nil, expectedConfig: &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ @@ -162,25 +153,25 @@ func TestSetEncodedConfigItem(t *testing.T) { { name: "failed to set encoded config item empty key", success: false, - configFilePath: emptyValidConfigPath, configItemKey: "", configItem: "dev", + config: nil, expectedConfig: nil, }, { name: "failed to set encoded config item empty value", success: false, - configFilePath: emptyValidConfigPath, configItemKey: "backends.dev.type", configItem: "", + config: nil, expectedConfig: nil, }, { name: "failed to set encoded config item invalid value", success: false, - configFilePath: existValidConfigPath, configItemKey: "backends.dev.configs.port", configItem: "-1", + config: mockValidConfig(), expectedConfig: nil, }, } @@ -188,7 +179,8 @@ func TestSetEncodedConfigItem(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { mockey.PatchConvey("mock config operator", t, func() { - mockNewOperator(tc.configFilePath, nil) + mockNewOperator(tc.config) + mockey.Mock((*operator).writeConfig).Return(nil).Build() err := SetEncodedConfigItem(tc.configItemKey, tc.configItem) assert.Equal(t, tc.success, err == nil) if err == nil { @@ -197,9 +189,6 @@ func TestSetEncodedConfigItem(t *testing.T) { assert.NoError(t, err) assert.Equal(t, tc.expectedConfig, config) } - if tc.configFilePath == emptyValidConfigPath { - _ = os.Remove(emptyValidConfigPath) - } }) }) } @@ -209,15 +198,13 @@ func TestDeleteConfigItem(t *testing.T) { testcases := []struct { name string success bool - configFilePath string configItemKey string config, expectedConfig *v1.Config }{ { - name: "delete config item successfully", - success: true, - configFilePath: emptyValidConfigPath, - configItemKey: "backends.dev.type", + name: "delete config item successfully", + success: true, + configItemKey: "backends.dev.type", config: &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ @@ -228,10 +215,9 @@ func TestDeleteConfigItem(t *testing.T) { expectedConfig: nil, }, { - name: "failed to delete config item invalid unset", - success: false, - configFilePath: emptyValidConfigPath, - configItemKey: "backends.pre.type", + name: "failed to delete config item invalid unset", + success: false, + configItemKey: "backends.pre.type", config: &v1.Config{ Backends: &v1.BackendConfigs{ Backends: map[string]*v1.BackendConfig{ @@ -254,7 +240,8 @@ func TestDeleteConfigItem(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { mockey.PatchConvey("mock config operator", t, func() { - mockNewOperator(tc.configFilePath, tc.config) + mockNewOperator(tc.config) + mockey.Mock((*operator).writeConfig).Return(nil).Build() err := DeleteConfigItem(tc.configItemKey) assert.Equal(t, tc.success, err == nil) if err == nil { @@ -267,9 +254,6 @@ func TestDeleteConfigItem(t *testing.T) { assert.Equal(t, tc.expectedConfig, config) } } - if tc.configFilePath == emptyValidConfigPath { - _ = os.Remove(emptyValidConfigPath) - } }) }) } diff --git a/pkg/config/validation.go b/pkg/config/validation.go index 56f837e7..5ce51b52 100644 --- a/pkg/config/validation.go +++ b/pkg/config/validation.go @@ -15,7 +15,6 @@ type ( ) var ( - ErrUnexpectedInvalidConfig = errors.New("unexpected invalid config") ErrNotExistCurrentBackend = errors.New("cannot assign current to not exist backend") ErrInUseCurrentBackend = errors.New("unset in-use current backend") ErrUnsupportedBackendType = errors.New("unsupported backend type") @@ -25,38 +24,6 @@ var ( ErrInvalidBackendMysqlPort = errors.New("backend mysql port must be between 1 and 65535") ) -// validateConfig is used to check the config is valid or not, where the invalidation comes from the unexpected -// manual modification. -func validateConfig(config *v1.Config) error { - if config == nil { - return nil - } - - // validate backends configuration - backends := config.Backends - if backends == nil { - return nil - } - if backends.Current != "" && len(backends.Backends) == 0 { - return fmt.Errorf("%w, non-empty current backend name %s but empty backends", ErrUnexpectedInvalidConfig, backends.Current) - } - for name, bkConfig := range backends.Backends { - if name == "" || name == "current" { - return fmt.Errorf("%w, invalid backend name %s", ErrUnexpectedInvalidConfig, name) - } - if bkConfig == nil { - return fmt.Errorf("%w, empty backend config with name %s", ErrUnexpectedInvalidConfig, name) - } - if bkConfig.Type == "" && len(bkConfig.Configs) != 0 { - return fmt.Errorf("%w, empty backend config item but non-empty type with name %s", ErrUnexpectedInvalidConfig, name) - } - if err := checkBasalBackendConfig(bkConfig); err != nil { - return fmt.Errorf("%w, %v", ErrUnexpectedInvalidConfig, err) - } - } - return nil -} - // validateCurrentBackend is used to check that setting the current backend is valid or not. func validateCurrentBackend(config *v1.Config, _ string, val any) error { current, _ := val.(string) diff --git a/pkg/config/validation_test.go b/pkg/config/validation_test.go index ee9eac3a..076bf217 100644 --- a/pkg/config/validation_test.go +++ b/pkg/config/validation_test.go @@ -8,70 +8,6 @@ import ( v1 "kusionstack.io/kusion/pkg/apis/core/v1" ) -func TestValidateConfig(t *testing.T) { - testcases := []struct { - name string - success bool - config *v1.Config - }{ - { - name: "valid config", - success: true, - config: &v1.Config{ - Backends: &v1.BackendConfigs{ - Current: "dev", - Backends: map[string]*v1.BackendConfig{ - "dev": {Type: v1.BackendTypeLocal}, - }, - }, - }, - }, - { - name: "invalid config non-empty current but empty backends", - success: false, - config: &v1.Config{ - Backends: &v1.BackendConfigs{ - Current: "dev", - }, - }, - }, - { - name: "invalid config invalid backend name", - success: false, - config: &v1.Config{ - Backends: &v1.BackendConfigs{ - Backends: map[string]*v1.BackendConfig{ - "current": {Type: v1.BackendTypeLocal}, - }, - }, - }, - }, - { - name: "invalid config empty type but non-empty config", - success: false, - config: &v1.Config{ - Backends: &v1.BackendConfigs{ - Backends: map[string]*v1.BackendConfig{ - "dev": { - Type: "", - Configs: map[string]any{ - v1.BackendLocalPath: "/etc", - }, - }, - }, - }, - }, - }, - } - - for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - err := validateConfig(tc.config) - assert.Equal(t, tc.success, err == nil) - }) - } -} - func TestValidateCurrentBackend(t *testing.T) { testcases := []struct { name string