Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavlo Strokov <pstrokov@gitlab.com>2023-03-11 11:56:11 +0300
committerPavlo Strokov <pstrokov@gitlab.com>2023-04-13 09:15:42 +0300
commitee57a61d40af8d0220ce489d86c99759c69f8b40 (patch)
tree1c3394f67a4bab89e465463d53a8e9a4753e96e9
parent3e401d35ec33907ee3fc75ac42920382e30bc938 (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.go8
-rw-r--r--internal/errors/cfgerror/validate_test.go7
-rw-r--r--internal/praefect/config/config.go13
-rw-r--r--internal/praefect/config/config_test.go49
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)
+ })
+ }
+}