diff --git a/src/restic/backend/test/backend_test.go b/src/restic/backend/test/backend_test.go deleted file mode 100644 index b495ce663..000000000 --- a/src/restic/backend/test/backend_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// DO NOT EDIT, AUTOMATICALLY GENERATED -package test_test - -import ( - "testing" - - "restic/backend/test" -) - -var SkipMessage string - -func TestTestBackendCreate(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestCreate(t) -} - -func TestTestBackendOpen(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestOpen(t) -} - -func TestTestBackendCreateWithConfig(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestCreateWithConfig(t) -} - -func TestTestBackendLocation(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestLocation(t) -} - -func TestTestBackendConfig(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestConfig(t) -} - -func TestTestBackendLoad(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestLoad(t) -} - -func TestTestBackendSave(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestSave(t) -} - -func TestTestBackendSaveFilenames(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestSaveFilenames(t) -} - -func TestTestBackendBackend(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestBackend(t) -} - -func TestTestBackendDelete(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestDelete(t) -} - -func TestTestBackendCleanup(t *testing.T) { - if SkipMessage != "" { - t.Skip(SkipMessage) - } - test.TestCleanup(t) -} diff --git a/src/restic/backend/test/funcs.go b/src/restic/backend/test/funcs.go new file mode 100644 index 000000000..b790ca815 --- /dev/null +++ b/src/restic/backend/test/funcs.go @@ -0,0 +1,20 @@ +// DO NOT EDIT, AUTOMATICALLY GENERATED +package test + +import ( + "testing" +) + +var TestFunctions = []struct { + Name string + Fn func(t testing.TB, suite *Suite) +}{ + {"CreateWithConfig", TestCreateWithConfig}, + {"Location", TestLocation}, + {"Config", TestConfig}, + {"Load", TestLoad}, + {"Save", TestSave}, + {"SaveFilenames", TestSaveFilenames}, + {"Backend", TestBackend}, + {"Delete", TestDelete}, +} diff --git a/src/restic/backend/test/generate_backend_tests.go b/src/restic/backend/test/generate_test_list.go similarity index 75% rename from src/restic/backend/test/generate_backend_tests.go rename to src/restic/backend/test/generate_test_list.go index 4d1e9b478..73ce25672 100644 --- a/src/restic/backend/test/generate_backend_tests.go +++ b/src/restic/backend/test/generate_test_list.go @@ -18,9 +18,8 @@ import ( ) var data struct { - Package string - PackagePrefix string - Funcs []string + Package string + Funcs []string } var testTemplate = ` @@ -29,24 +28,20 @@ package {{ .Package }} import ( "testing" - - "restic/backend/test" ) -var SkipMessage string - -{{ $prefix := .PackagePrefix }} -{{ range $f := .Funcs }} -func Test{{ $prefix }}{{ $f }}(t *testing.T){ - if SkipMessage != "" { t.Skip(SkipMessage) } - test.Test{{ $f }}(t) -} - +var TestFunctions = []struct { + Name string + Fn func(t testing.TB, suite *Suite) +}{ +{{ range $f := .Funcs -}} + {"{{ $f }}", Test{{ $f }},}, {{ end }} +} ` -var testFile = flag.String("testfile", "../test/tests.go", "file to search test functions in") -var outputFile = flag.String("output", "backend_test.go", "output file to write generated code to") +var testFile = flag.String("testfile", "tests.go", "file to search test functions in") +var outputFile = flag.String("output", "funcs.go", "output file to write generated code to") var packageName = flag.String("package", "", "the package name to use") var prefix = flag.String("prefix", "", "test function prefix") var quiet = flag.Bool("quiet", false, "be quiet") @@ -123,12 +118,7 @@ func main() { f, err := os.Create(*outputFile) errx(err) - data.Package = pkg + "_test" - if *prefix != "" { - data.PackagePrefix = *prefix - } else { - data.PackagePrefix = packageTestFunctionPrefix(pkg) + "Backend" - } + data.Package = pkg data.Funcs = findTestFunctions() generateOutput(f, data) diff --git a/src/restic/backend/test/tests.go b/src/restic/backend/test/tests.go index fb51bf99d..69346db6d 100644 --- a/src/restic/backend/test/tests.go +++ b/src/restic/backend/test/tests.go @@ -19,115 +19,88 @@ import ( "restic/backend" ) -// CreateFn is a function that creates a temporary repository for the tests. -var CreateFn func() (restic.Backend, error) +// Suite implements a test suite for restic backends. +type Suite struct { + Config interface{} -// OpenFn is a function that opens a previously created temporary repository. -var OpenFn func() (restic.Backend, error) + // NewConfig returns a config for a new temporary backend that will be used in tests. + NewConfig func() (interface{}, error) -// CleanupFn removes temporary files and directories created during the tests. -var CleanupFn func() error + // CreateFn is a function that creates a temporary repository for the tests. + Create func(cfg interface{}) (restic.Backend, error) -// MinimalData instructs the tests to not use excessive data. -var MinimalData = false + // OpenFn is a function that opens a previously created temporary repository. + Open func(cfg interface{}) (restic.Backend, error) -var but restic.Backend // backendUnderTest -var butInitialized bool + // CleanupFn removes data created during the tests. + Cleanup func(cfg interface{}) error -func open(t testing.TB) restic.Backend { - if OpenFn == nil { - t.Fatal("OpenFn not set") - } - - if CreateFn == nil { - t.Fatalf("CreateFn not set") - } - - if !butInitialized { - be, err := CreateFn() - if err != nil { - t.Fatalf("Create returned unexpected error: %+v", err) - } - - but = be - butInitialized = true - } - - if but == nil { - var err error - but, err = OpenFn() - if err != nil { - t.Fatalf("Open returned unexpected error: %+v", err) - } - } - - return but + // MinimalData instructs the tests to not use excessive data. + MinimalData bool } -func close(t testing.TB) { - if but == nil { - t.Fatalf("trying to close non-existing backend") - } - - err := but.Close() +// RunTests executes all defined tests as subtests of t. +func (s *Suite) RunTests(t *testing.T) { + var err error + s.Config, err = s.NewConfig() if err != nil { - t.Fatalf("Close returned unexpected error: %+v", err) + t.Fatal(err) } - but = nil -} + // test create/open functions first + be := s.create(t) + s.close(t, be) -// TestCreate creates a backend. -func TestCreate(t testing.TB) { - if CreateFn == nil { - t.Fatalf("CreateFn not set!") + for _, test := range TestFunctions { + t.Run(test.Name, func(t *testing.T) { + test.Fn(t, s) + }) } - be, err := CreateFn() - if err != nil { - t.Fatalf("Create returned error: %+v", err) + if !test.TestCleanupTempDirs { + t.Logf("not cleaning up backend") + return } - butInitialized = true - - err = be.Close() - if err != nil { - t.Fatalf("Close returned error: %+v", err) + if err = s.Cleanup(s.Config); err != nil { + t.Fatal(err) } } -// TestOpen opens a previously created backend. -func TestOpen(t testing.TB) { - if OpenFn == nil { - t.Fatalf("OpenFn not set!") - } - - be, err := OpenFn() +func (s *Suite) create(t testing.TB) restic.Backend { + be, err := s.Create(s.Config) if err != nil { - t.Fatalf("Open returned error: %+v", err) + t.Fatal(err) } + return be +} - err = be.Close() +func (s *Suite) open(t testing.TB) restic.Backend { + be, err := s.Open(s.Config) if err != nil { - t.Fatalf("Close returned error: %+v", err) + t.Fatal(err) + } + return be +} + +func (s *Suite) close(t testing.TB, be restic.Backend) { + err := be.Close() + if err != nil { + t.Fatal(err) } } // TestCreateWithConfig tests that creating a backend in a location which already // has a config file fails. -func TestCreateWithConfig(t testing.TB) { - if CreateFn == nil { - t.Fatalf("CreateFn not set") - } - - b := open(t) - defer close(t) +func TestCreateWithConfig(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) // save a config store(t, b, restic.ConfigFile, []byte("test config")) // now create the backend again, this must fail - _, err := CreateFn() + _, err := s.Create(s.Config) if err == nil { t.Fatalf("expected error not found for creating a backend with an existing config file") } @@ -140,9 +113,9 @@ func TestCreateWithConfig(t testing.TB) { } // TestLocation tests that a location string is returned. -func TestLocation(t testing.TB) { - b := open(t) - defer close(t) +func TestLocation(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) l := b.Location() if l == "" { @@ -151,9 +124,9 @@ func TestLocation(t testing.TB) { } // TestConfig saves and loads a config from the backend. -func TestConfig(t testing.TB) { - b := open(t) - defer close(t) +func TestConfig(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) var testString = "Config" @@ -184,9 +157,9 @@ func TestConfig(t testing.TB) { } // TestLoad tests the backend's Load function. -func TestLoad(t testing.TB) { - b := open(t) - defer close(t) +func TestLoad(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) _, err := b.Load(restic.Handle{}, 0, 0) if err == nil { @@ -219,7 +192,7 @@ func TestLoad(t testing.TB) { } loadTests := 50 - if MinimalData { + if s.MinimalData { loadTests = 10 } @@ -312,13 +285,13 @@ func (ec errorCloser) Close() error { } // TestSave tests saving data in the backend. -func TestSave(t testing.TB) { - b := open(t) - defer close(t) +func TestSave(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) var id restic.ID saveTests := 10 - if MinimalData { + if s.MinimalData { saveTests = 2 } @@ -412,9 +385,9 @@ var filenameTests = []struct { } // TestSaveFilenames tests saving data with various file names in the backend. -func TestSaveFilenames(t testing.TB) { - b := open(t) - defer close(t) +func TestSaveFilenames(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) for i, test := range filenameTests { h := restic.Handle{Name: test.name, Type: restic.DataFile} @@ -461,9 +434,9 @@ func store(t testing.TB, b restic.Backend, tpe restic.FileType, data []byte) res } // TestBackend tests all functions of the backend. -func TestBackend(t testing.TB) { - b := open(t) - defer close(t) +func TestBackend(t testing.TB, s *Suite) { + b := s.open(t) + defer s.close(t, b) for _, tpe := range []restic.FileType{ restic.DataFile, restic.KeyFile, restic.LockFile, @@ -595,9 +568,13 @@ func TestBackend(t testing.TB) { } // TestDelete tests the Delete function. -func TestDelete(t testing.TB) { - b := open(t) - defer close(t) +func TestDelete(t testing.TB, s *Suite) { + if !test.TestCleanupTempDirs { + t.Skipf("not removing backend, TestCleanupTempDirs is false") + } + + b := s.open(t) + defer s.close(t, b) be, ok := b.(restic.Deleter) if !ok { @@ -609,21 +586,3 @@ func TestDelete(t testing.TB) { t.Fatalf("error deleting backend: %+v", err) } } - -// TestCleanup runs the cleanup function after all tests are run. -func TestCleanup(t testing.TB) { - if CleanupFn == nil { - t.Log("CleanupFn function not set") - return - } - - if !test.TestCleanupTempDirs { - t.Logf("not cleaning up backend") - return - } - - err := CleanupFn() - if err != nil { - t.Fatalf("Cleanup returned error: %+v", err) - } -} diff --git a/src/restic/backend/test/tests_test.go b/src/restic/backend/test/tests_test.go index 04e9936e0..514cd9ef9 100644 --- a/src/restic/backend/test/tests_test.go +++ b/src/restic/backend/test/tests_test.go @@ -2,38 +2,59 @@ package test_test import ( "restic" - "restic/errors" + "testing" "restic/backend/mem" "restic/backend/test" ) -var be restic.Backend +//go:generate go run generate_test_list.go -//go:generate go run ../test/generate_backend_tests.go - -func init() { - test.CreateFn = func() (restic.Backend, error) { - if be != nil { - return nil, errors.New("temporary memory backend dir already exists") - } - - be = mem.New() - - return be, nil - } - - test.OpenFn = func() (restic.Backend, error) { - if be == nil { - return nil, errors.New("repository not initialized") - } - - return be, nil - } - - test.CleanupFn = func() error { - be = nil - return nil - } +type memConfig struct { + be restic.Backend +} + +func TestSuiteBackendMem(t *testing.T) { + suite := test.Suite{ + // NewConfig returns a config for a new temporary backend that will be used in tests. + NewConfig: func() (interface{}, error) { + return &memConfig{}, nil + }, + + // CreateFn is a function that creates a temporary repository for the tests. + Create: func(cfg interface{}) (restic.Backend, error) { + c := cfg.(*memConfig) + if c.be != nil { + ok, err := c.be.Test(restic.Handle{Type: restic.ConfigFile}) + if err != nil { + return nil, err + } + + if ok { + return nil, errors.New("config already exists") + } + } + + c.be = mem.New() + return c.be, nil + }, + + // OpenFn is a function that opens a previously created temporary repository. + Open: func(cfg interface{}) (restic.Backend, error) { + c := cfg.(*memConfig) + if c.be == nil { + c.be = mem.New() + } + return c.be, nil + }, + + // CleanupFn removes data created during the tests. + Cleanup: func(cfg interface{}) error { + // no cleanup needed + return nil + }, + } + + suite.RunTests(t) }