From b892b1a1503b665d45d2f7dfb26440906607d21f Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sun, 7 Jun 2026 13:06:02 +0200 Subject: [PATCH] repository: move lock file handling from restic package --- cmd/restic/cmd_cat.go | 2 +- cmd/restic/cmd_init_integration_test.go | 2 +- cmd/restic/main.go | 5 +- internal/repository/lock.go | 20 ++--- .../lock.go => repository/lock_file.go} | 46 +++++------ .../lock_file_test.go} | 81 +++++++++---------- .../lock_file_unix.go} | 2 +- .../lock_file_windows.go} | 2 +- internal/repository/lock_test.go | 8 +- internal/repository/testing.go | 5 -- 10 files changed, 83 insertions(+), 90 deletions(-) rename internal/{restic/lock.go => repository/lock_file.go} (87%) rename internal/{restic/lock_test.go => repository/lock_file_test.go} (69%) rename internal/{restic/lock_unix.go => repository/lock_file_unix.go} (97%) rename internal/{restic/lock_windows.go => repository/lock_file_windows.go} (96%) diff --git a/cmd/restic/cmd_cat.go b/cmd/restic/cmd_cat.go index 437c4437b..f54a5ce44 100644 --- a/cmd/restic/cmd_cat.go +++ b/cmd/restic/cmd_cat.go @@ -142,7 +142,7 @@ func runCat(ctx context.Context, gopts global.Options, args []string, term ui.Te printer.S(string(buf)) return nil case "lock": - lock, err := restic.LoadLock(ctx, repo, id) + lock, err := repository.LoadLock(ctx, repo, id) if err != nil { return err } diff --git a/cmd/restic/cmd_init_integration_test.go b/cmd/restic/cmd_init_integration_test.go index 5d8a8c64c..d30a7c078 100644 --- a/cmd/restic/cmd_init_integration_test.go +++ b/cmd/restic/cmd_init_integration_test.go @@ -16,7 +16,7 @@ import ( func testRunInit(t testing.TB, gopts global.Options) { repository.TestUseLowSecurityKDFParameters(t) restic.TestDisableCheckPolynomial(t) - restic.TestSetLockTimeout(t, 0) + repository.TestSetLockTimeout(t, 0) err := withTermStatus(t, gopts, func(ctx context.Context, gopts global.Options) error { return runInit(ctx, InitOptions{}, gopts, nil, gopts.Term) diff --git a/cmd/restic/main.go b/cmd/restic/main.go index 619eee642..09a64e8db 100644 --- a/cmd/restic/main.go +++ b/cmd/restic/main.go @@ -20,7 +20,6 @@ import ( "github.com/restic/restic/internal/feature" "github.com/restic/restic/internal/global" "github.com/restic/restic/internal/repository" - "github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/ui/termstatus" ) @@ -198,7 +197,7 @@ func main() { var exitMessage string switch { - case restic.IsAlreadyLocked(err): + case repository.IsAlreadyLocked(err): exitMessage = fmt.Sprintf("%v\nthe `unlock` command can be used to remove stale locks", err) case err == ErrInvalidSourceData: exitMessage = fmt.Sprintf("Warning: %v", err) @@ -228,7 +227,7 @@ func main() { exitCode = 3 case errors.Is(err, global.ErrNoRepository): exitCode = 10 - case restic.IsAlreadyLocked(err): + case repository.IsAlreadyLocked(err): exitCode = 11 case errors.Is(err, repository.ErrNoKeyFound): exitCode = 12 diff --git a/internal/repository/lock.go b/internal/repository/lock.go index 3267e933f..488aca022 100644 --- a/internal/repository/lock.go +++ b/internal/repository/lock.go @@ -14,7 +14,7 @@ import ( ) type lockContext struct { - lock *restic.Lock + lock *Lock cancel context.CancelFunc refreshWG sync.WaitGroup } @@ -34,7 +34,7 @@ var lockerInst = &locker{ refreshInterval: defaultRefreshInterval, // consider a lock refresh failed a bit before the lock actually becomes stale // the difference allows to compensate for a small time drift between clients. - refreshabilityTimeout: restic.StaleLockTimeout - defaultRefreshInterval*3/2, + refreshabilityTimeout: StaleLockTimeout - defaultRefreshInterval*3/2, } func LockRepo(ctx context.Context, repo *Repository, exclusive bool, retryLock time.Duration, printRetry func(msg string), logger func(format string, args ...interface{})) (Unlocker, context.Context, error) { @@ -43,8 +43,8 @@ func LockRepo(ctx context.Context, repo *Repository, exclusive bool, retryLock t // Lock wraps the ctx such that it is cancelled when the repository is unlocked // cancelling the original context also stops the lock refresh -func (l *locker) Lock(ctx context.Context, r *Repository, exclusive bool, retryLock time.Duration, printRetry func(msg string), logger func(format string, args ...interface{})) (Unlocker, context.Context, error) { - var lock *restic.Lock +func (l *locker) Lock(ctx context.Context, r *Repository, exclusive bool, retryLock time.Duration, printRetry func(msg string), logger func(format string, args ...interface{})) (*unlocker, context.Context, error) { + var lock *Lock var err error retrySleep := minDuration(l.retrySleepStart, retryLock) @@ -55,8 +55,8 @@ func (l *locker) Lock(ctx context.Context, r *Repository, exclusive bool, retryL retryLoop: for { - lock, err = restic.NewLock(ctx, repo, exclusive) - if err != nil && restic.IsAlreadyLocked(err) { + lock, err = NewLock(ctx, repo, exclusive) + if err != nil && IsAlreadyLocked(err) { if !retryMessagePrinted { printRetry(fmt.Sprintf("repo already locked, waiting up to %s for the lock\n", retryLock)) @@ -72,7 +72,7 @@ retryLoop: case <-retryTimeout: debug.Log("repo already locked, timeout expired") // Last lock attempt - lock, err = restic.NewLock(ctx, repo, exclusive) + lock, err = NewLock(ctx, repo, exclusive) break retryLoop case <-retrySleepCh: retrySleep = minDuration(retrySleep*2, l.retrySleepMax) @@ -82,7 +82,7 @@ retryLoop: break retryLoop } } - if restic.IsInvalidLock(err) { + if IsInvalidLock(err) { return nil, ctx, errors.Fatalf("%v\n\nthe `unlock --remove-all` command can be used to remove invalid locks. Make sure that no other restic process is accessing the repository when running the command", err) } if err != nil { @@ -242,7 +242,7 @@ func (l *locker) monitorLockRefresh(ctx context.Context, lockInfo *lockContext, } } -func tryRefreshStaleLock(ctx context.Context, be backend.Backend, lock *restic.Lock, cancel context.CancelFunc, logger func(format string, args ...interface{})) bool { +func tryRefreshStaleLock(ctx context.Context, be backend.Backend, lock *Lock, cancel context.CancelFunc, logger func(format string, args ...interface{})) bool { freeze := backend.AsBackend[backend.FreezeBackend](be) if freeze != nil { debug.Log("freezing backend") @@ -277,7 +277,7 @@ func (l *unlocker) Unlock() { // RemoveStaleLocks deletes all locks detected as stale from the repository. func RemoveStaleLocks(ctx context.Context, repo *Repository) (uint, error) { var processed uint - err := restic.ForAllLocks(ctx, repo, nil, func(id restic.ID, lock *restic.Lock, err error) error { + err := ForAllLocks(ctx, repo, nil, func(id restic.ID, lock *Lock, err error) error { if err != nil { // ignore locks that cannot be loaded debug.Log("ignore lock %v: %v", id, err) diff --git a/internal/restic/lock.go b/internal/repository/lock_file.go similarity index 87% rename from internal/restic/lock.go rename to internal/repository/lock_file.go index 7b7f04af8..b0a0b3ede 100644 --- a/internal/restic/lock.go +++ b/internal/repository/lock_file.go @@ -1,4 +1,4 @@ -package restic +package repository import ( "context" @@ -11,9 +11,9 @@ import ( "testing" "time" - "github.com/restic/restic/internal/errors" - "github.com/restic/restic/internal/debug" + "github.com/restic/restic/internal/errors" + "github.com/restic/restic/internal/restic" ) // UnlockCancelDelay bounds the duration how long lock cleanup operations will wait @@ -38,8 +38,8 @@ type Lock struct { UID uint32 `json:"uid,omitempty"` GID uint32 `json:"gid,omitempty"` - repo Unpacked[FileType] - lockID *ID + repo restic.Unpacked[restic.FileType] + lockID *restic.ID } // alreadyLockedError is returned when NewLock or NewExclusiveLock are unable to @@ -102,7 +102,7 @@ func TestSetLockTimeout(t testing.TB, d time.Duration) { // exclusive lock is already held by another process, it returns an error // that satisfies IsAlreadyLocked. If the new lock is exclude, then other // non-exclusive locks also result in an IsAlreadyLocked error. -func NewLock(ctx context.Context, repo Unpacked[FileType], exclusive bool) (*Lock, error) { +func NewLock(ctx context.Context, repo restic.Unpacked[restic.FileType], exclusive bool) (*Lock, error) { lock := &Lock{ Time: time.Now(), PID: os.Getpid(), @@ -147,7 +147,7 @@ func (l *Lock) fillUserInfo() error { } l.Username = usr.Username - l.UID, l.GID, err = UidGidInt(usr) + l.UID, l.GID, err = restic.UidGidInt(usr) return err } @@ -159,7 +159,7 @@ func (l *Lock) fillUserInfo() error { // exclusive lock is found. func (l *Lock) checkForOtherLocks(ctx context.Context) error { var err error - checkedIDs := NewIDSet() + checkedIDs := restic.NewIDSet() if l.lockID != nil { checkedIDs.Insert(*l.lockID) } @@ -177,7 +177,7 @@ func (l *Lock) checkForOtherLocks(ctx context.Context) error { // Store updates in new IDSet to prevent data races var m sync.Mutex newCheckedIDs := checkedIDs.Clone() - err = ForAllLocks(ctx, l.repo, checkedIDs, func(id ID, lock *Lock, err error) error { + err = ForAllLocks(ctx, l.repo, checkedIDs, func(id restic.ID, lock *Lock, err error) error { if err != nil { // if we cannot load a lock then it is unclear whether it can be ignored // it could either be invalid or just unreadable due to network/permission problems @@ -209,7 +209,7 @@ func (l *Lock) checkForOtherLocks(ctx context.Context) error { return err } } - if errors.Is(err, ErrInvalidData) { + if errors.Is(err, restic.ErrInvalidData) { return &invalidLockError{err} } return err @@ -228,10 +228,10 @@ func cancelableDelay(ctx context.Context, delay time.Duration) error { } // createLock acquires the lock by creating a file in the repository. -func (l *Lock) createLock(ctx context.Context) (ID, error) { - id, err := SaveJSONUnpacked(ctx, l.repo, LockFile, l) +func (l *Lock) createLock(ctx context.Context) (restic.ID, error) { + id, err := restic.SaveJSONUnpacked(ctx, l.repo, restic.LockFile, l) if err != nil { - return ID{}, err + return restic.ID{}, err } return id, nil @@ -246,7 +246,7 @@ func (l *Lock) Unlock(ctx context.Context) error { ctx, cancel := delayedCancelContext(ctx, UnlockCancelDelay) defer cancel() - return l.repo.RemoveUnpacked(ctx, LockFile, *l.lockID) + return l.repo.RemoveUnpacked(ctx, restic.LockFile, *l.lockID) } var StaleLockTimeout = 30 * time.Minute @@ -326,7 +326,7 @@ func (l *Lock) Refresh(ctx context.Context) error { ctx, cancel := delayedCancelContext(ctx, UnlockCancelDelay) defer cancel() - return l.repo.RemoveUnpacked(ctx, LockFile, *oldLockID) + return l.repo.RemoveUnpacked(ctx, restic.LockFile, *oldLockID) } // RefreshStaleLock is an extended variant of Refresh that can also refresh stale lock files. @@ -359,13 +359,13 @@ func (l *Lock) RefreshStaleLock(ctx context.Context) error { if err != nil { // cleanup replacement lock - _ = l.repo.RemoveUnpacked(ctx, LockFile, id) + _ = l.repo.RemoveUnpacked(ctx, restic.LockFile, id) return err } if !exists { // cleanup replacement lock - _ = l.repo.RemoveUnpacked(ctx, LockFile, id) + _ = l.repo.RemoveUnpacked(ctx, restic.LockFile, id) return ErrRemovedLock } @@ -376,7 +376,7 @@ func (l *Lock) RefreshStaleLock(ctx context.Context) error { oldLockID := l.lockID l.lockID = &id - return l.repo.RemoveUnpacked(ctx, LockFile, *oldLockID) + return l.repo.RemoveUnpacked(ctx, restic.LockFile, *oldLockID) } func (l *Lock) checkExistence(ctx context.Context) (bool, error) { @@ -385,7 +385,7 @@ func (l *Lock) checkExistence(ctx context.Context) (bool, error) { exists := false - err := l.repo.List(ctx, LockFile, func(id ID, _ int64) error { + err := l.repo.List(ctx, restic.LockFile, func(id restic.ID, _ int64) error { if id.Equal(*l.lockID) { exists = true } @@ -423,9 +423,9 @@ func init() { } // LoadLock loads and unserializes a lock from a repository. -func LoadLock(ctx context.Context, repo LoaderUnpacked, id ID) (*Lock, error) { +func LoadLock(ctx context.Context, repo restic.LoaderUnpacked, id restic.ID) (*Lock, error) { lock := &Lock{} - if err := LoadJSONUnpacked(ctx, repo, LockFile, id, lock); err != nil { + if err := restic.LoadJSONUnpacked(ctx, repo, restic.LockFile, id, lock); err != nil { return nil, err } lock.lockID = &id @@ -437,11 +437,11 @@ func LoadLock(ctx context.Context, repo LoaderUnpacked, id ID) (*Lock, error) { // It is guaranteed that the function is not run concurrently. If the // callback returns an error, this function is cancelled and also returns that error. // If a lock ID is passed via excludeID, it will be ignored. -func ForAllLocks(ctx context.Context, repo ListerLoaderUnpacked, excludeIDs IDSet, fn func(ID, *Lock, error) error) error { +func ForAllLocks(ctx context.Context, repo restic.ListerLoaderUnpacked, excludeIDs restic.IDSet, fn func(restic.ID, *Lock, error) error) error { var m sync.Mutex // For locks decoding is nearly for free, thus just assume were only limited by IO - return ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, size int64) error { + return restic.ParallelList(ctx, repo, restic.LockFile, repo.Connections(), func(ctx context.Context, id restic.ID, size int64) error { if excludeIDs.Has(id) { return nil } diff --git a/internal/restic/lock_test.go b/internal/repository/lock_file_test.go similarity index 69% rename from internal/restic/lock_test.go rename to internal/repository/lock_file_test.go index 67d2b9a46..5443c3ca7 100644 --- a/internal/restic/lock_test.go +++ b/internal/repository/lock_file_test.go @@ -1,4 +1,4 @@ -package restic_test +package repository import ( "context" @@ -10,26 +10,25 @@ import ( "github.com/restic/restic/internal/backend" "github.com/restic/restic/internal/backend/mem" - "github.com/restic/restic/internal/repository" "github.com/restic/restic/internal/restic" rtest "github.com/restic/restic/internal/test" ) -func TestLock(t *testing.T) { - repo := repository.TestRepository(t) - restic.TestSetLockTimeout(t, 5*time.Millisecond) +func TestLockFile(t *testing.T) { + repo := TestRepository(t) + TestSetLockTimeout(t, 5*time.Millisecond) - lock, err := repository.TestNewLock(t, repo, false) + lock, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) rtest.OK(t, lock.Unlock(context.TODO())) } func TestDoubleUnlock(t *testing.T) { - repo := repository.TestRepository(t) - restic.TestSetLockTimeout(t, 5*time.Millisecond) + repo := TestRepository(t) + TestSetLockTimeout(t, 5*time.Millisecond) - lock, err := repository.TestNewLock(t, repo, false) + lock, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) rtest.OK(t, lock.Unlock(context.TODO())) @@ -40,13 +39,13 @@ func TestDoubleUnlock(t *testing.T) { } func TestMultipleLock(t *testing.T) { - repo := repository.TestRepository(t) - restic.TestSetLockTimeout(t, 5*time.Millisecond) + repo := TestRepository(t) + TestSetLockTimeout(t, 5*time.Millisecond) - lock1, err := repository.TestNewLock(t, repo, false) + lock1, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) - lock2, err := repository.TestNewLock(t, repo, false) + lock2, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) rtest.OK(t, lock1.Unlock(context.TODO())) @@ -66,37 +65,37 @@ func (be *failLockLoadingBackend) Load(ctx context.Context, h backend.Handle, le func TestMultipleLockFailure(t *testing.T) { be := &failLockLoadingBackend{Backend: mem.New()} - repo, _ := repository.TestRepositoryWithBackend(t, be, 0, repository.Options{}) - restic.TestSetLockTimeout(t, 5*time.Millisecond) + repo, _ := TestRepositoryWithBackend(t, be, 0, Options{}) + TestSetLockTimeout(t, 5*time.Millisecond) - lock1, err := repository.TestNewLock(t, repo, false) + lock1, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) - _, err = repository.TestNewLock(t, repo, false) + _, err = NewLock(context.TODO(), &internalRepository{repo}, false) rtest.Assert(t, err != nil, "unreadable lock file did not result in an error") rtest.OK(t, lock1.Unlock(context.TODO())) } func TestLockExclusive(t *testing.T) { - repo := repository.TestRepository(t) + repo := TestRepository(t) - elock, err := repository.TestNewLock(t, repo, true) + elock, err := NewLock(context.TODO(), &internalRepository{repo}, true) rtest.OK(t, err) rtest.OK(t, elock.Unlock(context.TODO())) } func TestLockOnExclusiveLockedRepo(t *testing.T) { - repo := repository.TestRepository(t) - restic.TestSetLockTimeout(t, 5*time.Millisecond) + repo := TestRepository(t) + TestSetLockTimeout(t, 5*time.Millisecond) - elock, err := repository.TestNewLock(t, repo, true) + elock, err := NewLock(context.TODO(), &internalRepository{repo}, true) rtest.OK(t, err) - lock, err := repository.TestNewLock(t, repo, false) + lock, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.Assert(t, err != nil, "create normal lock with exclusively locked repo didn't return an error") - rtest.Assert(t, restic.IsAlreadyLocked(err), + rtest.Assert(t, IsAlreadyLocked(err), "create normal lock with exclusively locked repo didn't return the correct error") rtest.OK(t, lock.Unlock(context.TODO())) @@ -104,16 +103,16 @@ func TestLockOnExclusiveLockedRepo(t *testing.T) { } func TestExclusiveLockOnLockedRepo(t *testing.T) { - repo := repository.TestRepository(t) - restic.TestSetLockTimeout(t, 5*time.Millisecond) + repo := TestRepository(t) + TestSetLockTimeout(t, 5*time.Millisecond) - elock, err := repository.TestNewLock(t, repo, false) + elock, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) - lock, err := repository.TestNewLock(t, repo, true) + lock, err := NewLock(context.TODO(), &internalRepository{repo}, true) rtest.Assert(t, err != nil, "create normal lock with exclusively locked repo didn't return an error") - rtest.Assert(t, restic.IsAlreadyLocked(err), + rtest.Assert(t, IsAlreadyLocked(err), "create normal lock with exclusively locked repo didn't return the correct error") rtest.OK(t, lock.Unlock(context.TODO())) @@ -159,7 +158,7 @@ func TestLockStale(t *testing.T) { otherHostname := "other-" + hostname for i, test := range staleLockTests { - lock := restic.Lock{ + lock := Lock{ Time: test.timestamp, PID: test.pid, Hostname: hostname, @@ -195,11 +194,11 @@ func checkSingleLock(t *testing.T, repo restic.Lister) restic.ID { return *lockID } -func testLockRefresh(t *testing.T, refresh func(lock *restic.Lock) error) { - repo := repository.TestRepository(t) - restic.TestSetLockTimeout(t, 5*time.Millisecond) +func testLockRefresh(t *testing.T, refresh func(lock *Lock) error) { + repo := TestRepository(t) + TestSetLockTimeout(t, 5*time.Millisecond) - lock, err := repository.TestNewLock(t, repo, false) + lock, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) time0 := lock.Time @@ -212,7 +211,7 @@ func testLockRefresh(t *testing.T, refresh func(lock *restic.Lock) error) { rtest.Assert(t, !lockID.Equal(lockID2), "expected a new ID after lock refresh, got the same") - lock2, err := restic.LoadLock(context.TODO(), repo, lockID2) + lock2, err := LoadLock(context.TODO(), repo, lockID2) rtest.OK(t, err) rtest.Assert(t, lock2.Time.After(time0), "expected a later timestamp after lock refresh") @@ -220,22 +219,22 @@ func testLockRefresh(t *testing.T, refresh func(lock *restic.Lock) error) { } func TestLockRefresh(t *testing.T) { - testLockRefresh(t, func(lock *restic.Lock) error { + testLockRefresh(t, func(lock *Lock) error { return lock.Refresh(context.TODO()) }) } func TestLockRefreshStale(t *testing.T) { - testLockRefresh(t, func(lock *restic.Lock) error { + testLockRefresh(t, func(lock *Lock) error { return lock.RefreshStaleLock(context.TODO()) }) } func TestLockRefreshStaleMissing(t *testing.T) { - repo, _, be := repository.TestRepositoryWithVersion(t, 0) - restic.TestSetLockTimeout(t, 5*time.Millisecond) + repo, _, be := TestRepositoryWithVersion(t, 0) + TestSetLockTimeout(t, 5*time.Millisecond) - lock, err := repository.TestNewLock(t, repo, false) + lock, err := NewLock(context.TODO(), &internalRepository{repo}, false) rtest.OK(t, err) lockID := checkSingleLock(t, repo) @@ -243,5 +242,5 @@ func TestLockRefreshStaleMissing(t *testing.T) { rtest.OK(t, be.Remove(context.TODO(), backend.Handle{Type: restic.LockFile, Name: lockID.String()})) time.Sleep(time.Millisecond) err = lock.RefreshStaleLock(context.TODO()) - rtest.Assert(t, err == restic.ErrRemovedLock, "unexpected error, expected %v, got %v", restic.ErrRemovedLock, err) + rtest.Assert(t, err == ErrRemovedLock, "unexpected error, expected %v, got %v", ErrRemovedLock, err) } diff --git a/internal/restic/lock_unix.go b/internal/repository/lock_file_unix.go similarity index 97% rename from internal/restic/lock_unix.go rename to internal/repository/lock_file_unix.go index 71f43fd36..5a9d0f33d 100644 --- a/internal/restic/lock_unix.go +++ b/internal/repository/lock_file_unix.go @@ -1,6 +1,6 @@ //go:build !windows -package restic +package repository import ( "os" diff --git a/internal/restic/lock_windows.go b/internal/repository/lock_file_windows.go similarity index 96% rename from internal/restic/lock_windows.go rename to internal/repository/lock_file_windows.go index 442b08397..298d59e37 100644 --- a/internal/restic/lock_windows.go +++ b/internal/repository/lock_file_windows.go @@ -1,4 +1,4 @@ -package restic +package repository import ( "os" diff --git a/internal/repository/lock_test.go b/internal/repository/lock_test.go index 5a2813e75..a9c269738 100644 --- a/internal/repository/lock_test.go +++ b/internal/repository/lock_test.go @@ -38,7 +38,7 @@ func checkedLockRepo(ctx context.Context, t *testing.T, repo *Repository, locker lock, wrappedCtx, err := lockerInst.Lock(ctx, repo, false, retryLock, func(msg string) {}, func(format string, args ...interface{}) {}) rtest.OK(t, err) rtest.OK(t, wrappedCtx.Err()) - if lock.(*unlocker).info.lock.Stale() { + if lock.info.lock.Stale() { t.Fatal("lock returned stale lock") } return lock, wrappedCtx @@ -83,7 +83,7 @@ func TestLockConflict(t *testing.T) { if err == nil { t.Fatal("second lock should have failed") } - rtest.Assert(t, restic.IsAlreadyLocked(err), "unexpected error %v", err) + rtest.Assert(t, IsAlreadyLocked(err), "unexpected error %v", err) } type writeOnceBackend struct { @@ -309,8 +309,8 @@ func createFakeLock(repo *Repository, t time.Time, pid int) (restic.ID, error) { return restic.ID{}, err } - newLock := &restic.Lock{Time: t, PID: pid, Hostname: hostname} - return restic.SaveJSONUnpacked(context.TODO(), &internalRepository{repo}, restic.LockFile, &newLock) + newLock := &Lock{Time: t, PID: pid, Hostname: hostname} + return restic.SaveJSONUnpacked(context.TODO(), &internalRepository{repo}, restic.LockFile, newLock) } func lockExists(repo restic.Lister, t testing.TB, lockID restic.ID) bool { diff --git a/internal/repository/testing.go b/internal/repository/testing.go index 67b4b30ab..8ca2819f4 100644 --- a/internal/repository/testing.go +++ b/internal/repository/testing.go @@ -158,11 +158,6 @@ func BenchmarkAllVersions(b *testing.B, bench VersionedBenchmark) { } } -func TestNewLock(_ *testing.T, repo *Repository, exclusive bool) (*restic.Lock, error) { - // TODO get rid of this test helper - return restic.NewLock(context.TODO(), &internalRepository{repo}, exclusive) -} - // TestCheckRepo runs the checker on repo. func TestCheckRepo(t testing.TB, repo *Repository) { chkr := newChecker(repo)