2023-05-06 10:37:17 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"context"
|
|
|
|
"io"
|
2025-10-04 13:18:32 +01:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2023-05-06 10:37:17 +02:00
|
|
|
"testing"
|
|
|
|
|
2025-09-28 22:04:48 +02:00
|
|
|
"github.com/restic/restic/internal/global"
|
2023-05-06 10:37:17 +02:00
|
|
|
"github.com/restic/restic/internal/restic"
|
|
|
|
rtest "github.com/restic/restic/internal/test"
|
2025-10-04 13:18:32 +01:00
|
|
|
"github.com/restic/restic/internal/ui"
|
2023-05-06 10:37:17 +02:00
|
|
|
)
|
|
|
|
|
2025-09-28 22:04:48 +02:00
|
|
|
func testRunList(t testing.TB, gopts global.Options, tpe string) restic.IDs {
|
|
|
|
buf, err := withCaptureStdout(t, gopts, func(ctx context.Context, gopts global.Options) error {
|
2025-09-28 21:44:40 +02:00
|
|
|
return runList(ctx, gopts, []string{tpe}, gopts.Term)
|
2023-05-07 22:06:39 +02:00
|
|
|
})
|
|
|
|
rtest.OK(t, err)
|
2023-05-06 10:37:17 +02:00
|
|
|
return parseIDsFromReader(t, buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseIDsFromReader(t testing.TB, rd io.Reader) restic.IDs {
|
|
|
|
t.Helper()
|
|
|
|
IDs := restic.IDs{}
|
|
|
|
sc := bufio.NewScanner(rd)
|
|
|
|
|
|
|
|
for sc.Scan() {
|
2025-10-04 13:18:32 +01:00
|
|
|
if len(sc.Text()) == 64 {
|
|
|
|
id, err := restic.ParseID(sc.Text())
|
|
|
|
if err != nil {
|
|
|
|
t.Logf("parse id %v: %v", sc.Text(), err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
IDs = append(IDs, id)
|
|
|
|
} else {
|
|
|
|
// 'list blobs' is different because it lists the blobs together with the blob type
|
|
|
|
// e.g. "tree ac08ce34ba4f8123618661bef2425f7028ffb9ac740578a3ee88684d2523fee8"
|
|
|
|
parts := strings.Split(sc.Text(), " ")
|
|
|
|
id, err := restic.ParseID(parts[len(parts)-1])
|
|
|
|
if err != nil {
|
|
|
|
t.Logf("parse id %v: %v", sc.Text(), err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
IDs = append(IDs, id)
|
2023-05-06 10:37:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return IDs
|
|
|
|
}
|
|
|
|
|
2025-09-28 22:04:48 +02:00
|
|
|
func testListSnapshots(t testing.TB, gopts global.Options, expected int) restic.IDs {
|
2023-05-06 10:37:17 +02:00
|
|
|
t.Helper()
|
2025-09-18 22:19:38 +02:00
|
|
|
snapshotIDs := testRunList(t, gopts, "snapshots")
|
2023-05-06 10:37:17 +02:00
|
|
|
rtest.Assert(t, len(snapshotIDs) == expected, "expected %v snapshot, got %v", expected, snapshotIDs)
|
|
|
|
return snapshotIDs
|
|
|
|
}
|
2025-10-04 13:18:32 +01:00
|
|
|
|
|
|
|
// extract blob set from repository index
|
2025-09-28 22:04:48 +02:00
|
|
|
func testListBlobs(t testing.TB, gopts global.Options) (blobSetFromIndex restic.IDSet) {
|
|
|
|
err := withTermStatus(t, gopts, func(ctx context.Context, gopts global.Options) error {
|
2025-09-28 21:44:40 +02:00
|
|
|
printer := ui.NewProgressPrinter(gopts.JSON, gopts.Verbosity, gopts.Term)
|
2025-10-04 13:18:32 +01:00
|
|
|
_, repo, unlock, err := openWithReadLock(ctx, gopts, false, printer)
|
|
|
|
rtest.OK(t, err)
|
|
|
|
defer unlock()
|
|
|
|
|
|
|
|
// make sure the index is loaded
|
|
|
|
rtest.OK(t, repo.LoadIndex(ctx, nil))
|
|
|
|
|
|
|
|
// get blobs from index
|
|
|
|
blobSetFromIndex = restic.NewIDSet()
|
|
|
|
rtest.OK(t, repo.ListBlobs(ctx, func(blob restic.PackedBlob) {
|
|
|
|
blobSetFromIndex.Insert(blob.ID)
|
|
|
|
}))
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
rtest.OK(t, err)
|
|
|
|
|
|
|
|
return blobSetFromIndex
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListBlobs(t *testing.T) {
|
|
|
|
|
|
|
|
env, cleanup := withTestEnvironment(t)
|
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
testSetupBackupData(t, env)
|
|
|
|
opts := BackupOptions{}
|
|
|
|
|
|
|
|
// first backup
|
|
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9")}, opts, env.gopts)
|
|
|
|
testListSnapshots(t, env.gopts, 1)
|
|
|
|
|
|
|
|
// run the `list blobs` command
|
|
|
|
resticIDs := testRunList(t, env.gopts, "blobs")
|
|
|
|
|
|
|
|
// convert to set
|
|
|
|
testIDSet := restic.NewIDSet(resticIDs...)
|
|
|
|
blobSetFromIndex := testListBlobs(t, env.gopts)
|
|
|
|
|
|
|
|
rtest.Assert(t, blobSetFromIndex.Equals(testIDSet), "the set of restic.ID s should be equal")
|
|
|
|
}
|