diff options
author | Pavlo Strokov <pstrokov@gitlab.com> | 2023-03-14 12:22:37 +0300 |
---|---|---|
committer | Pavlo Strokov <pstrokov@gitlab.com> | 2023-03-21 00:38:57 +0300 |
commit | 3af1e6b677f2c66edbf1fd32df3df2146d83465b (patch) | |
tree | e7d26b6a27c2b4339a351ce0813293bb68c961d1 /internal/errors/cfgerror | |
parent | e0b945da70367b68e9b1eb78386a1d2b6bfe9c95 (diff) |
gitaly: Validation of Storage configuration
The 'cfgerror' package extended with two validation functions. They
should reduce code duplication and also standardize text of the
errors. All frequently used basic errors are defined in the package
as well and now ErrNoUnique add to them as well.
The 'Storage' type fields now have toml tags and a 'Validate()'
method. As in all other cases it returns all found validation
errors.
The validation logic for 'Storage' field placed into
'validateStorages()' and will replace 'validateStorages()' method
of the 'Cfg' afterwards.
Diffstat (limited to 'internal/errors/cfgerror')
-rw-r--r-- | internal/errors/cfgerror/testhelper_test.go | 11 | ||||
-rw-r--r-- | internal/errors/cfgerror/validate.go | 48 | ||||
-rw-r--r-- | internal/errors/cfgerror/validate_test.go | 35 |
3 files changed, 92 insertions, 2 deletions
diff --git a/internal/errors/cfgerror/testhelper_test.go b/internal/errors/cfgerror/testhelper_test.go new file mode 100644 index 000000000..be6675514 --- /dev/null +++ b/internal/errors/cfgerror/testhelper_test.go @@ -0,0 +1,11 @@ +package cfgerror + +import ( + "testing" + + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestMain(m *testing.M) { + testhelper.Run(m) +} diff --git a/internal/errors/cfgerror/validate.go b/internal/errors/cfgerror/validate.go index 54a31123b..935caf905 100644 --- a/internal/errors/cfgerror/validate.go +++ b/internal/errors/cfgerror/validate.go @@ -3,11 +3,22 @@ package cfgerror import ( "errors" "fmt" + "os" "strings" ) -// ErrNotSet should be used when the value is not set, but it is required. -var ErrNotSet = errors.New("not set") +var ( + // ErrNotSet should be used when the value is not set, but it is required. + ErrNotSet = errors.New("not set") + // ErrBlankOrEmpty should be used when non-blank/non-empty string is expected. + ErrBlankOrEmpty = errors.New("blank or empty") + // ErrDoesntExist should be used when resource doesn't exist. + ErrDoesntExist = errors.New("doesn't exist") + // ErrNotDir should be used when path on the file system exists, but it is not a directory. + ErrNotDir = errors.New("not a dir") + // ErrNotUnique should be used when the value must be unique, but there are duplicates. + ErrNotUnique = errors.New("not unique") +) // ValidationError represents an issue with provided configuration. type ValidationError struct { @@ -96,3 +107,36 @@ func (vs ValidationErrors) Error() string { func New() ValidationErrors { return nil } + +// NotEmpty checks if value is empty. +func NotEmpty(val string) error { + if val == "" { + return NewValidationError(ErrNotSet) + } + return nil +} + +// NotBlank checks the value is not empty or blank. +func NotBlank(val string) error { + if strings.TrimSpace(val) == "" { + return NewValidationError(ErrBlankOrEmpty) + } + return nil +} + +// DirExists checks the value points to an existing directory on the disk. +func DirExists(path string) error { + fs, err := os.Stat(path) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return NewValidationError(fmt.Errorf("%w: %q", ErrDoesntExist, path)) + } + return err + } + + if !fs.IsDir() { + return NewValidationError(fmt.Errorf("%w: %q", ErrNotDir, path)) + } + + return nil +} diff --git a/internal/errors/cfgerror/validate_test.go b/internal/errors/cfgerror/validate_test.go index 847a62cc6..c129a17d7 100644 --- a/internal/errors/cfgerror/validate_test.go +++ b/internal/errors/cfgerror/validate_test.go @@ -2,10 +2,15 @@ package cfgerror import ( "errors" + "fmt" + "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/perm" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" ) func TestValidationError_Error(t *testing.T) { @@ -99,3 +104,33 @@ func TestNewValidationError(t *testing.T) { err = NewValidationError(assert.AnError, "outer", "inner") require.Equal(t, ValidationError{Cause: assert.AnError, Key: []string{"outer", "inner"}}, err) } + +func TestNotEmpty(t *testing.T) { + t.Parallel() + require.NoError(t, NotEmpty("value")) + require.Equal(t, NewValidationError(ErrNotSet), NotEmpty("")) +} + +func TestNotBlank(t *testing.T) { + t.Parallel() + require.NoError(t, NotBlank("value")) + require.Equal(t, NewValidationError(ErrBlankOrEmpty), NotBlank("")) + require.Equal(t, NewValidationError(ErrBlankOrEmpty), NotBlank(" \t \n ")) +} + +func TestDirExists(t *testing.T) { + t.Parallel() + + filePath := filepath.Join(testhelper.TempDir(t), "tmp-file") + require.NoError(t, os.WriteFile(filePath, []byte{}, perm.PublicFile)) + existing := testhelper.TempDir(t) + notExisting := filepath.Join(existing, "bad") + + require.NoError(t, DirExists(existing)) + + expectedNotExisting := NewValidationError(fmt.Errorf("%w: %q", ErrDoesntExist, notExisting)) + require.Equal(t, expectedNotExisting, DirExists(notExisting)) + + expectedNotDir := NewValidationError(fmt.Errorf("%w: %q", ErrNotDir, filePath)) + require.Equal(t, expectedNotDir, DirExists(filePath)) +} |