diff options
author | Pavlo Strokov <pstrokov@gitlab.com> | 2023-03-11 11:56:11 +0300 |
---|---|---|
committer | Pavlo Strokov <pstrokov@gitlab.com> | 2023-04-13 09:15:42 +0300 |
commit | ee57a61d40af8d0220ce489d86c99759c69f8b40 (patch) | |
tree | 1c3394f67a4bab89e465463d53a8e9a4753e96e9 | |
parent | 3e401d35ec33907ee3fc75ac42920382e30bc938 (diff) |
Praefect: VirtualStorage.Validate method
The new 'Validate' method validates values of the
'VirtualStorage' type. It will be used in the later changes.
Package 'cfgerror' extended with new 'NotEmptySlice()' function
to check the slice is not empty.
-rw-r--r-- | internal/errors/cfgerror/validate.go | 8 | ||||
-rw-r--r-- | internal/errors/cfgerror/validate_test.go | 7 | ||||
-rw-r--r-- | internal/praefect/config/config.go | 13 | ||||
-rw-r--r-- | internal/praefect/config/config_test.go | 49 |
4 files changed, 77 insertions, 0 deletions
diff --git a/internal/errors/cfgerror/validate.go b/internal/errors/cfgerror/validate.go index 736e58ac9..b152f2c4c 100644 --- a/internal/errors/cfgerror/validate.go +++ b/internal/errors/cfgerror/validate.go @@ -313,3 +313,11 @@ func (c numeric[T]) GreaterOrEqual(val T) error { func (c numeric[T]) InRange(min, max T, opts ...InRangeOpt) error { return InRange(min, max, c.value, opts...) } + +// NotEmptySlice returns an error if provided slice has no elements. +func NotEmptySlice[T any](slice []T) error { + if len(slice) == 0 { + return NewValidationError(ErrNotSet) + } + return nil +} diff --git a/internal/errors/cfgerror/validate_test.go b/internal/errors/cfgerror/validate_test.go index 9e8e35c8e..6dd2f2e25 100644 --- a/internal/errors/cfgerror/validate_test.go +++ b/internal/errors/cfgerror/validate_test.go @@ -340,3 +340,10 @@ func TestIsSupportedValue(t *testing.T) { require.Equal(t, NewValidationError(fmt.Errorf("%w: 1", ErrUnsupportedValue)), IsSupportedValue(1, 0, 10)) require.Equal(t, NewValidationError(fmt.Errorf(`%w: "c"`, ErrUnsupportedValue)), IsSupportedValue("c", "a", "b")) } + +func TestNotEmptySlice(t *testing.T) { + t.Parallel() + require.NoError(t, NotEmptySlice([]int{1})) + require.Equal(t, NewValidationError(ErrNotSet), NotEmptySlice([]string{})) + require.Equal(t, NewValidationError(ErrNotSet), NotEmptySlice[any](nil)) +} diff --git a/internal/praefect/config/config.go b/internal/praefect/config/config.go index 35f8487a8..54d505cca 100644 --- a/internal/praefect/config/config.go +++ b/internal/praefect/config/config.go @@ -272,6 +272,19 @@ type VirtualStorage struct { DefaultReplicationFactor int `toml:"default_replication_factor,omitempty"` } +// Validate runs validation on all fields and compose all found errors. +func (vs VirtualStorage) Validate() error { + errs := cfgerror.New(). + Append(cfgerror.NotBlank(vs.Name), "name"). + Append(cfgerror.NotEmptySlice(vs.Nodes), "node") + + for i, node := range vs.Nodes { + errs = errs.Append(node.Validate(), "node", fmt.Sprintf("[%d]", i)) + } + + return errs.AsError() +} + // FromFile loads the config for the passed file path func FromFile(filePath string) (Config, error) { b, err := os.ReadFile(filePath) diff --git a/internal/praefect/config/config_test.go b/internal/praefect/config/config_test.go index f9afab8ef..dec2de721 100644 --- a/internal/praefect/config/config_test.go +++ b/internal/praefect/config/config_test.go @@ -759,3 +759,52 @@ func TestReplication_Validate(t *testing.T) { }) } } + +func TestVirtualStorage_Validate(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + name string + vs VirtualStorage + expectedErr error + }{ + { + name: "ok", + vs: VirtualStorage{ + Name: "vs", + Nodes: []*Node{{Storage: "st", Address: "addr"}}, + }, + }, + { + name: "invalid node", + vs: VirtualStorage{ + Name: "vs", + Nodes: []*Node{{Storage: "", Address: "addr"}}, + }, + expectedErr: cfgerror.ValidationErrors{ + { + Key: []string{"node", "[0]", "storage"}, + Cause: cfgerror.ErrBlankOrEmpty, + }, + }, + }, + { + name: "invalid", + vs: VirtualStorage{}, + expectedErr: cfgerror.ValidationErrors{ + { + Key: []string{"name"}, + Cause: cfgerror.ErrBlankOrEmpty, + }, + { + Key: []string{"node"}, + Cause: cfgerror.ErrNotSet, + }, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + err := tc.vs.Validate() + require.Equal(t, tc.expectedErr, err) + }) + } +} |