mirror of
https://github.com/octoleo/restic.git
synced 2025-01-03 15:17:28 +00:00
Merge pull request #3973 from MichaelEischer/speedup-integration-tests
speed-up integration tests by reducing the RetryBackend timeout
This commit is contained in:
commit
8e2695be0b
@ -9,6 +9,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/backend"
|
||||||
"github.com/restic/restic/internal/options"
|
"github.com/restic/restic/internal/options"
|
||||||
"github.com/restic/restic/internal/repository"
|
"github.com/restic/restic/internal/repository"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
@ -171,6 +172,7 @@ func withTestEnvironment(t testing.TB) (env *testEnvironment, cleanup func()) {
|
|||||||
|
|
||||||
repository.TestUseLowSecurityKDFParameters(t)
|
repository.TestUseLowSecurityKDFParameters(t)
|
||||||
restic.TestDisableCheckPolynomial(t)
|
restic.TestDisableCheckPolynomial(t)
|
||||||
|
backend.TestFastRetries(t)
|
||||||
|
|
||||||
tempdir, err := ioutil.TempDir(rtest.TestTempDir, "restic-test-")
|
tempdir, err := ioutil.TempDir(rtest.TestTempDir, "restic-test-")
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
@ -55,6 +55,8 @@ func retryNotifyErrorWithSuccess(operation backoff.Operation, b backoff.BackOff,
|
|||||||
return backoff.RetryNotify(operationWrapper, b, notify)
|
return backoff.RetryNotify(operationWrapper, b, notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fastRetries = false
|
||||||
|
|
||||||
func (be *RetryBackend) retry(ctx context.Context, msg string, f func() error) error {
|
func (be *RetryBackend) retry(ctx context.Context, msg string, f func() error) error {
|
||||||
// Don't do anything when called with an already cancelled context. There would be
|
// Don't do anything when called with an already cancelled context. There would be
|
||||||
// no retries in that case either, so be consistent and abort always.
|
// no retries in that case either, so be consistent and abort always.
|
||||||
@ -66,8 +68,14 @@ func (be *RetryBackend) retry(ctx context.Context, msg string, f func() error) e
|
|||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bo := backoff.NewExponentialBackOff()
|
||||||
|
if fastRetries {
|
||||||
|
// speed up integration tests
|
||||||
|
bo.InitialInterval = 1 * time.Millisecond
|
||||||
|
}
|
||||||
|
|
||||||
err := retryNotifyErrorWithSuccess(f,
|
err := retryNotifyErrorWithSuccess(f,
|
||||||
backoff.WithContext(backoff.WithMaxRetries(backoff.NewExponentialBackOff(), uint64(be.MaxTries)), ctx),
|
backoff.WithContext(backoff.WithMaxRetries(bo, uint64(be.MaxTries)), ctx),
|
||||||
func(err error, d time.Duration) {
|
func(err error, d time.Duration) {
|
||||||
if be.Report != nil {
|
if be.Report != nil {
|
||||||
be.Report(msg, err, d)
|
be.Report(msg, err, d)
|
||||||
|
@ -35,6 +35,7 @@ func TestBackendSaveRetry(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
||||||
|
|
||||||
data := test.Random(23, 5*1024*1024+11241)
|
data := test.Random(23, 5*1024*1024+11241)
|
||||||
@ -70,6 +71,7 @@ func TestBackendSaveRetryAtomic(t *testing.T) {
|
|||||||
HasAtomicReplaceFn: func() bool { return true },
|
HasAtomicReplaceFn: func() bool { return true },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
||||||
|
|
||||||
data := test.Random(23, 5*1024*1024+11241)
|
data := test.Random(23, 5*1024*1024+11241)
|
||||||
@ -103,6 +105,7 @@ func TestBackendListRetry(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
||||||
|
|
||||||
var listed []string
|
var listed []string
|
||||||
@ -132,6 +135,7 @@ func TestBackendListRetryErrorFn(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
||||||
|
|
||||||
var ErrTest = errors.New("test error")
|
var ErrTest = errors.New("test error")
|
||||||
@ -187,6 +191,7 @@ func TestBackendListRetryErrorBackend(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
const maxRetries = 2
|
const maxRetries = 2
|
||||||
retryBackend := NewRetryBackend(be, maxRetries, nil, nil)
|
retryBackend := NewRetryBackend(be, maxRetries, nil, nil)
|
||||||
|
|
||||||
@ -257,6 +262,7 @@ func TestBackendLoadRetry(t *testing.T) {
|
|||||||
return failingReader{data: data, limit: limit}, nil
|
return failingReader{data: data, limit: limit}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestFastRetries(t)
|
||||||
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
retryBackend := NewRetryBackend(be, 10, nil, nil)
|
||||||
|
|
||||||
var buf []byte
|
var buf []byte
|
||||||
@ -276,6 +282,7 @@ func assertIsCanceled(t *testing.T, err error) {
|
|||||||
func TestBackendCanceledContext(t *testing.T) {
|
func TestBackendCanceledContext(t *testing.T) {
|
||||||
// unimplemented mock backend functions return an error by default
|
// unimplemented mock backend functions return an error by default
|
||||||
// check that we received the expected context canceled error instead
|
// check that we received the expected context canceled error instead
|
||||||
|
TestFastRetries(t)
|
||||||
retryBackend := NewRetryBackend(mock.NewBackend(), 2, nil, nil)
|
retryBackend := NewRetryBackend(mock.NewBackend(), 2, nil, nil)
|
||||||
h := restic.Handle{Type: restic.PackFile, Name: restic.NewRandomID().String()}
|
h := restic.Handle{Type: restic.PackFile, Name: restic.NewRandomID().String()}
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@ package mem
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/cespare/xxhash/v2"
|
||||||
"github.com/restic/restic/internal/backend"
|
"github.com/restic/restic/internal/backend"
|
||||||
"github.com/restic/restic/internal/backend/sema"
|
"github.com/restic/restic/internal/backend/sema"
|
||||||
"github.com/restic/restic/internal/debug"
|
"github.com/restic/restic/internal/debug"
|
||||||
@ -266,7 +266,7 @@ func (be *MemoryBackend) Location() string {
|
|||||||
|
|
||||||
// Hasher may return a hash function for calculating a content hash for the backend
|
// Hasher may return a hash function for calculating a content hash for the backend
|
||||||
func (be *MemoryBackend) Hasher() hash.Hash {
|
func (be *MemoryBackend) Hasher() hash.Hash {
|
||||||
return md5.New()
|
return xxhash.New()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasAtomicReplace returns whether Save() can atomically replace files
|
// HasAtomicReplace returns whether Save() can atomically replace files
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
package test_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/restic/restic/internal/errors"
|
|
||||||
"github.com/restic/restic/internal/restic"
|
|
||||||
|
|
||||||
"github.com/restic/restic/internal/backend/mem"
|
|
||||||
"github.com/restic/restic/internal/backend/test"
|
|
||||||
)
|
|
||||||
|
|
||||||
type memConfig struct {
|
|
||||||
be restic.Backend
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTestSuite(t testing.TB) *test.Suite {
|
|
||||||
return &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(context.TODO(), 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
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSuiteBackendMem(t *testing.T) {
|
|
||||||
newTestSuite(t).RunTests(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSuiteBackendMem(b *testing.B) {
|
|
||||||
newTestSuite(b).RunBenchmarks(b)
|
|
||||||
}
|
|
8
internal/backend/testing.go
Normal file
8
internal/backend/testing.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package backend
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// TestFastRetries reduces the initial retry delay to 1 millisecond
|
||||||
|
func TestFastRetries(t testing.TB) {
|
||||||
|
fastRetries = true
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user