Consistently use withTermstatus in tests

This commit is contained in:
Michael Eischer 2025-09-15 22:24:33 +02:00
parent 6b5c8ce14e
commit 364271c6c3
6 changed files with 225 additions and 186 deletions

View file

@ -43,9 +43,10 @@ func testRunKeyAddNewKey(t testing.TB, newPassword string, gopts GlobalOptions)
testKeyNewPassword = ""
}()
term, cancel := setupTermstatus()
defer cancel()
rtest.OK(t, runKeyAdd(context.TODO(), gopts, KeyAddOptions{}, []string{}, term))
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, gopts, KeyAddOptions{}, []string{}, term)
})
rtest.OK(t, err)
}
func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
@ -55,12 +56,13 @@ func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
}()
t.Log("adding key for john@example.com")
term, cancel := setupTermstatus()
defer cancel()
rtest.OK(t, runKeyAdd(context.TODO(), gopts, KeyAddOptions{
Username: "john",
Hostname: "example.com",
}, []string{}, term))
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, gopts, KeyAddOptions{
Username: "john",
Hostname: "example.com",
}, []string{}, term)
})
rtest.OK(t, err)
repo, err := OpenRepository(context.TODO(), gopts, &progress.NoopPrinter{})
rtest.OK(t, err)
@ -77,17 +79,19 @@ func testRunKeyPasswd(t testing.TB, newPassword string, gopts GlobalOptions) {
testKeyNewPassword = ""
}()
term, cancel := setupTermstatus()
defer cancel()
rtest.OK(t, runKeyPasswd(context.TODO(), gopts, KeyPasswdOptions{}, []string{}, term))
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyPasswd(ctx, gopts, KeyPasswdOptions{}, []string{}, term)
})
rtest.OK(t, err)
}
func testRunKeyRemove(t testing.TB, gopts GlobalOptions, IDs []string) {
t.Logf("remove %d keys: %q\n", len(IDs), IDs)
term, cancel := setupTermstatus()
defer cancel()
for _, id := range IDs {
rtest.OK(t, runKeyRemove(context.TODO(), gopts, []string{id}, term))
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyRemove(ctx, gopts, []string{id}, term)
})
rtest.OK(t, err)
}
}
@ -117,9 +121,10 @@ func TestKeyAddRemove(t *testing.T) {
env.gopts.password = passwordList[len(passwordList)-1]
t.Logf("testing access with last password %q\n", env.gopts.password)
term, cancel := setupTermstatus()
defer cancel()
rtest.OK(t, runKeyList(context.TODO(), env.gopts, []string{}, term))
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyList(ctx, env.gopts, []string{}, term)
})
rtest.OK(t, err)
testRunCheck(t, env.gopts)
testRunKeyAddNewKeyUserHost(t, env.gopts)
@ -130,20 +135,22 @@ func TestKeyAddInvalid(t *testing.T) {
defer cleanup()
testRunInit(t, env.gopts)
term, cancel := setupTermstatus()
defer cancel()
err := runKeyAdd(context.TODO(), env.gopts, KeyAddOptions{
NewPasswordFile: "some-file",
InsecureNoPassword: true,
}, []string{}, term)
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, env.gopts, KeyAddOptions{
NewPasswordFile: "some-file",
InsecureNoPassword: true,
}, []string{}, term)
})
rtest.Assert(t, strings.Contains(err.Error(), "only either"), "unexpected error message, got %q", err)
pwfile := filepath.Join(t.TempDir(), "pwfile")
rtest.OK(t, os.WriteFile(pwfile, []byte{}, 0o666))
err = runKeyAdd(context.TODO(), env.gopts, KeyAddOptions{
NewPasswordFile: pwfile,
}, []string{}, term)
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, env.gopts, KeyAddOptions{
NewPasswordFile: pwfile,
}, []string{}, term)
})
rtest.Assert(t, strings.Contains(err.Error(), "an empty password is not allowed by default"), "unexpected error message, got %q", err)
}
@ -154,11 +161,12 @@ func TestKeyAddEmpty(t *testing.T) {
defer cleanup()
testRunInit(t, env.gopts)
term, cancel := setupTermstatus()
defer cancel()
rtest.OK(t, runKeyAdd(context.TODO(), env.gopts, KeyAddOptions{
InsecureNoPassword: true,
}, []string{}, term))
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, env.gopts, KeyAddOptions{
InsecureNoPassword: true,
}, []string{}, term)
})
rtest.OK(t, err)
env.gopts.password = ""
env.gopts.InsecureNoPassword = true
@ -188,20 +196,23 @@ func TestKeyProblems(t *testing.T) {
testKeyNewPassword = ""
}()
term, cancel := setupTermstatus()
defer cancel()
err := runKeyPasswd(context.TODO(), env.gopts, KeyPasswdOptions{}, []string{}, term)
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyPasswd(ctx, env.gopts, KeyPasswdOptions{}, []string{}, term)
})
t.Log(err)
rtest.Assert(t, err != nil, "expected passwd change to fail")
err = runKeyAdd(context.TODO(), env.gopts, KeyAddOptions{}, []string{}, term)
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, env.gopts, KeyAddOptions{}, []string{}, term)
})
t.Log(err)
rtest.Assert(t, err != nil, "expected key adding to fail")
t.Logf("testing access with initial password %q\n", env.gopts.password)
term2, cancel2 := setupTermstatus()
defer cancel2()
rtest.OK(t, runKeyList(context.TODO(), env.gopts, []string{}, term2))
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyList(ctx, env.gopts, []string{}, term)
})
rtest.OK(t, err)
testRunCheck(t, env.gopts)
}
@ -214,27 +225,33 @@ func TestKeyCommandInvalidArguments(t *testing.T) {
return &emptySaveBackend{r}, nil
}
term, cancel := setupTermstatus()
defer cancel()
err := runKeyAdd(context.TODO(), env.gopts, KeyAddOptions{}, []string{"johndoe"}, term)
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyAdd(ctx, env.gopts, KeyAddOptions{}, []string{"johndoe"}, term)
})
t.Log(err)
rtest.Assert(t, err != nil && strings.Contains(err.Error(), "no arguments"), "unexpected error for key add: %v", err)
err = runKeyPasswd(context.TODO(), env.gopts, KeyPasswdOptions{}, []string{"johndoe"}, term)
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyPasswd(ctx, env.gopts, KeyPasswdOptions{}, []string{"johndoe"}, term)
})
t.Log(err)
rtest.Assert(t, err != nil && strings.Contains(err.Error(), "no arguments"), "unexpected error for key passwd: %v", err)
term3, cancel3 := setupTermstatus()
defer cancel3()
err = runKeyList(context.TODO(), env.gopts, []string{"johndoe"}, term3)
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyList(ctx, env.gopts, []string{"johndoe"}, term)
})
t.Log(err)
rtest.Assert(t, err != nil && strings.Contains(err.Error(), "no arguments"), "unexpected error for key list: %v", err)
err = runKeyRemove(context.TODO(), env.gopts, []string{}, term)
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyRemove(ctx, env.gopts, []string{}, term)
})
t.Log(err)
rtest.Assert(t, err != nil && strings.Contains(err.Error(), "one argument"), "unexpected error for key remove: %v", err)
err = runKeyRemove(context.TODO(), env.gopts, []string{"john", "doe"}, term)
err = withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
return runKeyRemove(ctx, env.gopts, []string{"john", "doe"}, term)
})
t.Log(err)
rtest.Assert(t, err != nil && strings.Contains(err.Error(), "one argument"), "unexpected error for key remove: %v", err)
}

View file

@ -128,37 +128,41 @@ func checkSnapshots(t testing.TB, gopts GlobalOptions, mountpoint string, snapsh
}
}
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
_, repo, unlock, err := openWithReadLock(context.TODO(), gopts, false, printer)
rtest.OK(t, err)
defer unlock()
for _, id := range snapshotIDs {
snapshot, err := restic.LoadSnapshot(context.TODO(), repo, id)
rtest.OK(t, err)
ts := snapshot.Time.Format(time.RFC3339)
present, ok := namesMap[ts]
if !ok {
t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts)
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
_, repo, unlock, err := openWithReadLock(ctx, gopts, false, printer)
if err != nil {
return err
}
defer unlock()
for i := 1; present; i++ {
ts = fmt.Sprintf("%s-%d", snapshot.Time.Format(time.RFC3339), i)
present, ok = namesMap[ts]
for _, id := range snapshotIDs {
snapshot, err := restic.LoadSnapshot(ctx, repo, id)
rtest.OK(t, err)
ts := snapshot.Time.Format(time.RFC3339)
present, ok := namesMap[ts]
if !ok {
t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts)
}
if !present {
break
}
}
for i := 1; present; i++ {
ts = fmt.Sprintf("%s-%d", snapshot.Time.Format(time.RFC3339), i)
present, ok = namesMap[ts]
if !ok {
t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts)
}
namesMap[ts] = true
}
if !present {
break
}
}
namesMap[ts] = true
}
return nil
})
rtest.OK(t, err)
for name, present := range namesMap {
rtest.Assert(t, present, "Directory %s is present in fuse dir but is not a snapshot", name)

View file

@ -40,14 +40,16 @@ func createBasicRewriteRepo(t testing.TB, env *testEnvironment) restic.ID {
func getSnapshot(t testing.TB, snapshotID restic.ID, env *testEnvironment) *restic.Snapshot {
t.Helper()
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
ctx, repo, unlock, err := openWithReadLock(context.TODO(), env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
var snapshots []*restic.Snapshot
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
ctx, repo, unlock, err := openWithReadLock(ctx, env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
snapshots, err := restic.TestLoadAllSnapshots(ctx, repo, nil)
snapshots, err = restic.TestLoadAllSnapshots(ctx, repo, nil)
return err
})
rtest.OK(t, err)
for _, s := range snapshots {
@ -114,14 +116,16 @@ func testRewriteMetadata(t *testing.T, metadata snapshotMetadataArgs) {
createBasicRewriteRepo(t, env)
testRunRewriteExclude(t, env.gopts, []string{}, true, metadata)
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
ctx, repo, unlock, err := openWithReadLock(context.TODO(), env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
var snapshots []*restic.Snapshot
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
ctx, repo, unlock, err := openWithReadLock(ctx, env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
snapshots, err := restic.TestLoadAllSnapshots(ctx, repo, nil)
snapshots, err = restic.TestLoadAllSnapshots(ctx, repo, nil)
return err
})
rtest.OK(t, err)
rtest.Assert(t, len(snapshots) == 1, "expected one snapshot, got %v", len(snapshots))
newSnapshot := snapshots[0]
@ -160,19 +164,22 @@ func TestRewriteSnaphotSummary(t *testing.T) {
snapshots := testListSnapshots(t, env.gopts, 1)
// replace snapshot by one without a summary
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
_, repo, unlock, err := openWithExclusiveLock(context.TODO(), env.gopts, false, printer)
var oldSummary *restic.SnapshotSummary
err := withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
_, repo, unlock, err := openWithExclusiveLock(ctx, env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
sn, err := restic.LoadSnapshot(ctx, repo, snapshots[0])
rtest.OK(t, err)
oldSummary = sn.Summary
sn.Summary = nil
rtest.OK(t, repo.RemoveUnpacked(ctx, restic.WriteableSnapshotFile, snapshots[0]))
snapshots[0], err = restic.SaveSnapshot(ctx, repo, sn)
return err
})
rtest.OK(t, err)
sn, err := restic.LoadSnapshot(context.TODO(), repo, snapshots[0])
rtest.OK(t, err)
oldSummary := sn.Summary
sn.Summary = nil
rtest.OK(t, repo.RemoveUnpacked(context.TODO(), restic.WriteableSnapshotFile, snapshots[0]))
snapshots[0], err = restic.SaveSnapshot(context.TODO(), repo, sn)
rtest.OK(t, err)
unlock()
// rewrite snapshot and lookup ID of new snapshot
rtest.OK(t, withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
@ -181,9 +188,8 @@ func TestRewriteSnaphotSummary(t *testing.T) {
newSnapshots := testListSnapshots(t, env.gopts, 2)
newSnapshot := restic.NewIDSet(newSnapshots...).Sub(restic.NewIDSet(snapshots...)).List()[0]
sn, err = restic.LoadSnapshot(context.TODO(), repo, newSnapshot)
rtest.OK(t, err)
rtest.Assert(t, sn.Summary != nil, "snapshot should have summary attached")
rtest.Equals(t, oldSummary.TotalBytesProcessed, sn.Summary.TotalBytesProcessed, "unexpected TotalBytesProcessed value")
rtest.Equals(t, oldSummary.TotalFilesProcessed, sn.Summary.TotalFilesProcessed, "unexpected TotalFilesProcessed value")
newSn := testLoadSnapshot(t, env.gopts, newSnapshot)
rtest.Assert(t, newSn.Summary != nil, "snapshot should have summary attached")
rtest.Equals(t, oldSummary.TotalBytesProcessed, newSn.Summary.TotalBytesProcessed, "unexpected TotalBytesProcessed value")
rtest.Equals(t, oldSummary.TotalFilesProcessed, newSn.Summary.TotalFilesProcessed, "unexpected TotalFilesProcessed value")
}

View file

@ -7,6 +7,7 @@ import (
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui"
)
func testRunSnapshots(t testing.TB, gopts GlobalOptions) (newest *Snapshot, snapmap map[restic.ID]Snapshot) {
@ -14,9 +15,9 @@ func testRunSnapshots(t testing.TB, gopts GlobalOptions) (newest *Snapshot, snap
gopts.JSON = true
opts := SnapshotOptions{}
term, cancel := setupTermstatus()
defer cancel()
return runSnapshots(context.TODO(), opts, gopts, []string{}, term)
return withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
return runSnapshots(ctx, opts, gopts, []string{}, term)
})
})
rtest.OK(t, err)

View file

@ -247,38 +247,41 @@ func testSetupBackupData(t testing.TB, env *testEnvironment) string {
}
func listPacks(gopts GlobalOptions, t *testing.T) restic.IDSet {
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, r, unlock, err := openWithReadLock(context.TODO(), gopts, false, printer)
var packs restic.IDSet
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, r, unlock, err := openWithReadLock(ctx, gopts, false, printer)
rtest.OK(t, err)
defer unlock()
packs = restic.NewIDSet()
return r.List(ctx, restic.PackFile, func(id restic.ID, size int64) error {
packs.Insert(id)
return nil
})
})
rtest.OK(t, err)
defer unlock()
packs := restic.NewIDSet()
rtest.OK(t, r.List(ctx, restic.PackFile, func(id restic.ID, size int64) error {
packs.Insert(id)
return nil
}))
return packs
}
func listTreePacks(gopts GlobalOptions, t *testing.T) restic.IDSet {
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, r, unlock, err := openWithReadLock(context.TODO(), gopts, false, printer)
var treePacks restic.IDSet
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, r, unlock, err := openWithReadLock(ctx, gopts, false, printer)
rtest.OK(t, err)
defer unlock()
rtest.OK(t, r.LoadIndex(ctx, nil))
treePacks = restic.NewIDSet()
return r.ListBlobs(ctx, func(pb restic.PackedBlob) {
if pb.Type == restic.TreeBlob {
treePacks.Insert(pb.PackID)
}
})
})
rtest.OK(t, err)
defer unlock()
rtest.OK(t, r.LoadIndex(ctx, nil))
treePacks := restic.NewIDSet()
rtest.OK(t, r.ListBlobs(ctx, func(pb restic.PackedBlob) {
if pb.Type == restic.TreeBlob {
treePacks.Insert(pb.PackID)
}
}))
return treePacks
}
@ -295,44 +298,47 @@ func captureBackend(gopts *GlobalOptions) func() backend.Backend {
func removePacks(gopts GlobalOptions, t testing.TB, remove restic.IDSet) {
be := captureBackend(&gopts)
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, _, unlock, err := openWithExclusiveLock(context.TODO(), gopts, false, printer)
rtest.OK(t, err)
defer unlock()
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, _, unlock, err := openWithExclusiveLock(ctx, gopts, false, printer)
rtest.OK(t, err)
defer unlock()
for id := range remove {
rtest.OK(t, be().Remove(ctx, backend.Handle{Type: restic.PackFile, Name: id.String()}))
}
for id := range remove {
rtest.OK(t, be().Remove(ctx, backend.Handle{Type: restic.PackFile, Name: id.String()}))
}
return nil
})
rtest.OK(t, err)
}
func removePacksExcept(gopts GlobalOptions, t testing.TB, keep restic.IDSet, removeTreePacks bool) {
be := captureBackend(&gopts)
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, r, unlock, err := openWithExclusiveLock(context.TODO(), gopts, false, printer)
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
ctx, r, unlock, err := openWithExclusiveLock(ctx, gopts, false, printer)
rtest.OK(t, err)
defer unlock()
// Get all tree packs
rtest.OK(t, r.LoadIndex(ctx, nil))
treePacks := restic.NewIDSet()
rtest.OK(t, r.ListBlobs(ctx, func(pb restic.PackedBlob) {
if pb.Type == restic.TreeBlob {
treePacks.Insert(pb.PackID)
}
}))
// remove all packs containing data blobs
return r.List(ctx, restic.PackFile, func(id restic.ID, size int64) error {
if treePacks.Has(id) != removeTreePacks || keep.Has(id) {
return nil
}
return be().Remove(ctx, backend.Handle{Type: restic.PackFile, Name: id.String()})
})
})
rtest.OK(t, err)
defer unlock()
// Get all tree packs
rtest.OK(t, r.LoadIndex(ctx, nil))
treePacks := restic.NewIDSet()
rtest.OK(t, r.ListBlobs(ctx, func(pb restic.PackedBlob) {
if pb.Type == restic.TreeBlob {
treePacks.Insert(pb.PackID)
}
}))
// remove all packs containing data blobs
rtest.OK(t, r.List(ctx, restic.PackFile, func(id restic.ID, size int64) error {
if treePacks.Has(id) != removeTreePacks || keep.Has(id) {
return nil
}
return be().Remove(ctx, backend.Handle{Type: restic.PackFile, Name: id.String()})
}))
}
func includes(haystack []string, needle string) bool {
@ -368,13 +374,16 @@ func lastSnapshot(old, new map[string]struct{}) (map[string]struct{}, string) {
}
func testLoadSnapshot(t testing.TB, gopts GlobalOptions, id restic.ID) *restic.Snapshot {
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
_, repo, unlock, err := openWithReadLock(context.TODO(), gopts, false, printer)
defer unlock()
rtest.OK(t, err)
snapshot, err := restic.LoadSnapshot(context.TODO(), repo, id)
var snapshot *restic.Snapshot
err := withTermStatus(gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(gopts.JSON, gopts.verbosity, term)
_, repo, unlock, err := openWithReadLock(ctx, gopts, false, printer)
rtest.OK(t, err)
defer unlock()
snapshot, err = restic.LoadSnapshot(ctx, repo, id)
return err
})
rtest.OK(t, err)
return snapshot
}

View file

@ -161,22 +161,24 @@ func TestFindListOnce(t *testing.T) {
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
thirdSnapshot := restic.NewIDSet(testListSnapshots(t, env.gopts, 3)...)
term, cancel := setupTermstatus()
defer cancel()
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
ctx, repo, unlock, err := openWithReadLock(context.TODO(), env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
var snapshotIDs restic.IDSet
rtest.OK(t, withTermStatus(env.gopts, func(ctx context.Context, term ui.Terminal) error {
printer := newTerminalProgressPrinter(env.gopts.JSON, env.gopts.verbosity, term)
ctx, repo, unlock, err := openWithReadLock(ctx, env.gopts, false, printer)
rtest.OK(t, err)
defer unlock()
snapshotIDs := restic.NewIDSet()
// specify the two oldest snapshots explicitly and use "latest" to reference the newest one
for sn := range FindFilteredSnapshots(ctx, repo, repo, &restic.SnapshotFilter{}, []string{
secondSnapshot[0].String(),
secondSnapshot[1].String()[:8],
"latest",
}, printer) {
snapshotIDs.Insert(*sn.ID())
}
snapshotIDs = restic.NewIDSet()
// specify the two oldest snapshots explicitly and use "latest" to reference the newest one
for sn := range FindFilteredSnapshots(ctx, repo, repo, &restic.SnapshotFilter{}, []string{
secondSnapshot[0].String(),
secondSnapshot[1].String()[:8],
"latest",
}, printer) {
snapshotIDs.Insert(*sn.ID())
}
return nil
}))
// the snapshots can only be listed once, if both lists match then the there has been only a single List() call
rtest.Equals(t, thirdSnapshot, snapshotIDs)