From eb8041b9438755f74e512062173373757eb36d1e Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 18 Jun 2017 17:36:57 +0200 Subject: [PATCH] backend tests: Add configurable delay for delayed remove --- src/restic/backend/b2/b2_test.go | 3 +++ src/restic/backend/swift/swift_test.go | 3 +++ src/restic/backend/test/suite.go | 7 ++++++ src/restic/backend/test/tests.go | 30 +++++++++++++++----------- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/restic/backend/b2/b2_test.go b/src/restic/backend/b2/b2_test.go index 6cf5c1bc6..d9828fa78 100644 --- a/src/restic/backend/b2/b2_test.go +++ b/src/restic/backend/b2/b2_test.go @@ -19,6 +19,9 @@ func newB2TestSuite(t testing.TB) *test.Suite { // do not use excessive data MinimalData: true, + // wait for at most 10 seconds for removed files to disappear + WaitForDelayedRemoval: 10 * time.Second, + // NewConfig returns a config for a new temporary backend that will be used in tests. NewConfig: func() (interface{}, error) { b2cfg, err := b2.ParseConfig(os.Getenv("RESTIC_TEST_B2_REPOSITORY")) diff --git a/src/restic/backend/swift/swift_test.go b/src/restic/backend/swift/swift_test.go index 843efdcd4..904d1a30a 100644 --- a/src/restic/backend/swift/swift_test.go +++ b/src/restic/backend/swift/swift_test.go @@ -20,6 +20,9 @@ func newSwiftTestSuite(t testing.TB) *test.Suite { // do not use excessive data MinimalData: true, + // wait for removals for at least 10s + WaitForDelayedRemoval: 10 * time.Second, + // NewConfig returns a config for a new temporary backend that will be used in tests. NewConfig: func() (interface{}, error) { swiftcfg, err := swift.ParseConfig(os.Getenv("RESTIC_TEST_SWIFT")) diff --git a/src/restic/backend/test/suite.go b/src/restic/backend/test/suite.go index 0b9b78a88..5fecc73f4 100644 --- a/src/restic/backend/test/suite.go +++ b/src/restic/backend/test/suite.go @@ -6,10 +6,12 @@ import ( "restic/test" "strings" "testing" + "time" ) // Suite implements a test suite for restic backends. type Suite struct { + // Config should be used to configure the backend. Config interface{} // NewConfig returns a config for a new temporary backend that will be used in tests. @@ -26,6 +28,11 @@ type Suite struct { // MinimalData instructs the tests to not use excessive data. MinimalData bool + + // WaitForDelayedRemoval is set to a non-zero value to instruct the test + // suite to wait for this amount of time until a file that was removed + // really disappeared. + WaitForDelayedRemoval time.Duration } // RunTests executes all defined tests as subtests of t. diff --git a/src/restic/backend/test/tests.go b/src/restic/backend/test/tests.go index d6971a9e7..67d7a6c3b 100644 --- a/src/restic/backend/test/tests.go +++ b/src/restic/backend/test/tests.go @@ -435,17 +435,18 @@ func testLoad(b restic.Backend, h restic.Handle, length int, offset int64) error return err } -func delayedRemove(b restic.Backend, h restic.Handle) error { +func delayedRemove(t testing.TB, be restic.Backend, h restic.Handle, maxwait time.Duration) error { // Some backend (swift, I'm looking at you) may implement delayed // removal of data. Let's wait a bit if this happens. - err := b.Remove(context.TODO(), h) + err := be.Remove(context.TODO(), h) if err != nil { return err } - found, err := b.Test(context.TODO(), h) - for i := 0; found && i < 20; i++ { - found, err = b.Test(context.TODO(), h) + start := time.Now() + attempt := 0 + for time.Since(start) <= maxwait { + found, err := be.Test(context.TODO(), h) if err != nil { return err } @@ -454,20 +455,23 @@ func delayedRemove(b restic.Backend, h restic.Handle) error { break } - time.Sleep(100 * time.Millisecond) + time.Sleep(500 * time.Millisecond) + attempt++ } - return err + + return nil } -func delayedList(t testing.TB, b restic.Backend, tpe restic.FileType, max int) restic.IDs { +func delayedList(t testing.TB, b restic.Backend, tpe restic.FileType, max int, maxwait time.Duration) restic.IDs { list := restic.NewIDSet() + start := time.Now() for i := 0; i < max; i++ { for s := range b.List(context.TODO(), tpe) { id := restic.TestParseID(s) list.Insert(id) } - if len(list) < max { - time.Sleep(100 * time.Millisecond) + if len(list) < max && time.Since(start) < maxwait { + time.Sleep(500 * time.Millisecond) } } @@ -548,7 +552,7 @@ func (s *Suite) TestBackend(t *testing.T) { test.Assert(t, err != nil, "expected error for %v, got %v", h, err) // remove and recreate - err = delayedRemove(b, h) + err = delayedRemove(t, b, h, s.WaitForDelayedRemoval) test.OK(t, err) // test that the blob is gone @@ -569,7 +573,7 @@ func (s *Suite) TestBackend(t *testing.T) { IDs = append(IDs, id) } - list := delayedList(t, b, tpe, len(IDs)) + list := delayedList(t, b, tpe, len(IDs), s.WaitForDelayedRemoval) if len(IDs) != len(list) { t.Fatalf("wrong number of IDs returned: want %d, got %d", len(IDs), len(list)) } @@ -593,7 +597,7 @@ func (s *Suite) TestBackend(t *testing.T) { test.OK(t, err) test.Assert(t, found, fmt.Sprintf("id %q not found", id)) - test.OK(t, delayedRemove(b, h)) + test.OK(t, delayedRemove(t, b, h, s.WaitForDelayedRemoval)) found, err = b.Test(context.TODO(), h) test.OK(t, err)