From 36bd464e8c503b9171ed824ddee99b88dbc2370c Mon Sep 17 00:00:00 2001 From: Lorenz Bausch Date: Sat, 7 May 2022 20:55:15 +0200 Subject: [PATCH] Add tests for validating exclude patterns --- cmd/restic/integration_filter_pattern_test.go | 69 +++++++++++++++++++ internal/filter/filter_patterns_test.go | 57 +++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 cmd/restic/integration_filter_pattern_test.go create mode 100644 internal/filter/filter_patterns_test.go diff --git a/cmd/restic/integration_filter_pattern_test.go b/cmd/restic/integration_filter_pattern_test.go new file mode 100644 index 000000000..e1534d841 --- /dev/null +++ b/cmd/restic/integration_filter_pattern_test.go @@ -0,0 +1,69 @@ +//go:build go1.16 +// +build go1.16 + +// Before Go 1.16 filepath.Match returned early on a failed match, +// and thus did not report any later syntax error in the pattern. +// https://go.dev/doc/go1.16#path/filepath + +package main + +import ( + "io/ioutil" + "path/filepath" + "testing" + + rtest "github.com/restic/restic/internal/test" +) + +func TestBackupFailsWhenUsingInvalidPatterns(t *testing.T) { + env, cleanup := withTestEnvironment(t) + defer cleanup() + + testRunInit(t, env.gopts) + + var err error + + // Test --exclude + err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"testdata"}, BackupOptions{Excludes: []string{"*[._]log[.-][0-9]", "!*[._]log[.-][0-9]"}}, env.gopts) + + rtest.Equals(t, `Fatal: --exclude: invalid pattern(s) provided: +*[._]log[.-][0-9] +!*[._]log[.-][0-9]`, err.Error()) + + // Test --iexclude + err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"testdata"}, BackupOptions{InsensitiveExcludes: []string{"*[._]log[.-][0-9]", "!*[._]log[.-][0-9]"}}, env.gopts) + + rtest.Equals(t, `Fatal: --iexclude: invalid pattern(s) provided: +*[._]log[.-][0-9] +!*[._]log[.-][0-9]`, err.Error()) +} + +func TestBackupFailsWhenUsingInvalidPatternsFromFile(t *testing.T) { + env, cleanup := withTestEnvironment(t) + defer cleanup() + + testRunInit(t, env.gopts) + + // Create an exclude file with some invalid patterns + excludeFile := env.base + "/excludefile" + fileErr := ioutil.WriteFile(excludeFile, []byte("*.go\n*[._]log[.-][0-9]\n!*[._]log[.-][0-9]"), 0644) + if fileErr != nil { + t.Fatalf("Could not write exclude file: %v", fileErr) + } + + var err error + + // Test --exclude-file: + err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"testdata"}, BackupOptions{ExcludeFiles: []string{excludeFile}}, env.gopts) + + rtest.Equals(t, `Fatal: --exclude-file: invalid pattern(s) provided: +*[._]log[.-][0-9] +!*[._]log[.-][0-9]`, err.Error()) + + // Test --iexclude-file + err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"testdata"}, BackupOptions{InsensitiveExcludeFiles: []string{excludeFile}}, env.gopts) + + rtest.Equals(t, `Fatal: --iexclude-file: invalid pattern(s) provided: +*[._]log[.-][0-9] +!*[._]log[.-][0-9]`, err.Error()) +} diff --git a/internal/filter/filter_patterns_test.go b/internal/filter/filter_patterns_test.go new file mode 100644 index 000000000..215471500 --- /dev/null +++ b/internal/filter/filter_patterns_test.go @@ -0,0 +1,57 @@ +//go:build go1.16 +// +build go1.16 + +// Before Go 1.16 filepath.Match returned early on a failed match, +// and thus did not report any later syntax error in the pattern. +// https://go.dev/doc/go1.16#path/filepath + +package filter_test + +import ( + "strings" + "testing" + + "github.com/restic/restic/internal/filter" + rtest "github.com/restic/restic/internal/test" +) + +func TestValidPatterns(t *testing.T) { + // Test invalid patterns are detected and returned + t.Run("detect-invalid-patterns", func(t *testing.T) { + allValid, invalidPatterns := filter.ValidatePatterns([]string{"*.foo", "*[._]log[.-][0-9]", "!*[._]log[.-][0-9]"}) + + rtest.Assert(t, allValid == false, "Expected invalid patterns to be detected") + + rtest.Equals(t, invalidPatterns, []string{"*[._]log[.-][0-9]", "!*[._]log[.-][0-9]"}) + }) + + // Test all patterns defined in matchTests are valid + patterns := make([]string, 0) + + for _, data := range matchTests { + patterns = append(patterns, data.pattern) + } + + t.Run("validate-patterns", func(t *testing.T) { + allValid, invalidPatterns := filter.ValidatePatterns(patterns) + + if !allValid { + t.Errorf("Found invalid pattern(s):\n%s", strings.Join(invalidPatterns, "\n")) + } + }) + + // Test all patterns defined in childMatchTests are valid + childPatterns := make([]string, 0) + + for _, data := range childMatchTests { + childPatterns = append(childPatterns, data.pattern) + } + + t.Run("validate-child-patterns", func(t *testing.T) { + allValid, invalidPatterns := filter.ValidatePatterns(childPatterns) + + if !allValid { + t.Errorf("Found invalid child pattern(s):\n%s", strings.Join(invalidPatterns, "\n")) + } + }) +}