2016-08-07 17:19:00 +02:00
|
|
|
package index
|
|
|
|
|
|
|
|
import (
|
|
|
|
"restic"
|
2016-08-07 18:45:25 +02:00
|
|
|
"restic/backend"
|
2016-08-07 17:19:00 +02:00
|
|
|
"restic/backend/local"
|
|
|
|
"restic/repository"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
snapshotTime = time.Unix(1470492820, 207401672)
|
|
|
|
snapshots = 3
|
|
|
|
depth = 3
|
|
|
|
)
|
|
|
|
|
2016-08-07 21:56:06 +02:00
|
|
|
func createFilledRepo(t testing.TB, snapshots int, dup float32) (*repository.Repository, func()) {
|
2016-08-07 17:19:00 +02:00
|
|
|
repo, cleanup := repository.TestRepository(t)
|
|
|
|
|
|
|
|
for i := 0; i < 3; i++ {
|
2016-08-07 21:56:06 +02:00
|
|
|
restic.TestCreateSnapshot(t, repo, snapshotTime.Add(time.Duration(i)*time.Second), depth, dup)
|
2016-08-07 17:19:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return repo, cleanup
|
|
|
|
}
|
|
|
|
|
2016-08-07 18:45:25 +02:00
|
|
|
func validateIndex(t testing.TB, repo *repository.Repository, idx *Index) {
|
|
|
|
for id := range repo.List(backend.Data, nil) {
|
|
|
|
if _, ok := idx.Packs[id]; !ok {
|
|
|
|
t.Errorf("pack %v missing from index", id.Str())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-07 17:19:00 +02:00
|
|
|
func TestIndexNew(t *testing.T) {
|
2016-08-07 21:56:06 +02:00
|
|
|
repo, cleanup := createFilledRepo(t, 3, 0)
|
2016-08-07 17:19:00 +02:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
idx, err := New(repo)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("New() returned error %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if idx == nil {
|
|
|
|
t.Fatalf("New() returned nil index")
|
|
|
|
}
|
2016-08-07 18:45:25 +02:00
|
|
|
|
|
|
|
validateIndex(t, repo, idx)
|
2016-08-07 17:19:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestIndexLoad(t *testing.T) {
|
2016-08-07 21:56:06 +02:00
|
|
|
repo, cleanup := createFilledRepo(t, 3, 0)
|
2016-08-07 17:19:00 +02:00
|
|
|
defer cleanup()
|
|
|
|
|
2016-08-07 18:45:25 +02:00
|
|
|
loadIdx, err := Load(repo)
|
2016-08-07 17:19:00 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Load() returned error %v", err)
|
|
|
|
}
|
|
|
|
|
2016-08-07 18:45:25 +02:00
|
|
|
if loadIdx == nil {
|
2016-08-07 17:19:00 +02:00
|
|
|
t.Fatalf("Load() returned nil index")
|
|
|
|
}
|
2016-08-07 18:45:25 +02:00
|
|
|
|
|
|
|
validateIndex(t, repo, loadIdx)
|
|
|
|
|
|
|
|
newIdx, err := New(repo)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("New() returned error %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(loadIdx.Packs) != len(newIdx.Packs) {
|
|
|
|
t.Errorf("number of packs does not match: want %v, got %v",
|
|
|
|
len(loadIdx.Packs), len(newIdx.Packs))
|
|
|
|
}
|
|
|
|
|
|
|
|
validateIndex(t, repo, newIdx)
|
|
|
|
|
|
|
|
for packID, packNew := range newIdx.Packs {
|
|
|
|
packLoad, ok := loadIdx.Packs[packID]
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
t.Errorf("loaded index does not list pack %v", packID.Str())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(packNew.Entries) != len(packLoad.Entries) {
|
|
|
|
t.Errorf(" number of entries in pack %v does not match: %d != %d\n %v\n %v",
|
|
|
|
packID.Str(), len(packNew.Entries), len(packLoad.Entries),
|
|
|
|
packNew.Entries, packLoad.Entries)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, entryNew := range packNew.Entries {
|
|
|
|
found := false
|
|
|
|
for _, entryLoad := range packLoad.Entries {
|
|
|
|
if !entryLoad.ID.Equal(entryNew.ID) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if entryLoad.Type != entryNew.Type {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if entryLoad.Offset != entryNew.Offset {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if entryLoad.Length != entryNew.Length {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
t.Errorf("blob not found in loaded index: %v", entryNew)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-07 17:19:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func openRepo(t testing.TB, dir, password string) *repository.Repository {
|
|
|
|
b, err := local.Open(dir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("open backend %v failed: %v", dir, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r := repository.New(b)
|
|
|
|
err = r.SearchKey(password)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to open repo with password: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkIndexNew(b *testing.B) {
|
2016-08-07 21:56:06 +02:00
|
|
|
repo, cleanup := createFilledRepo(b, 3, 0)
|
2016-08-07 17:19:00 +02:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
idx, err := New(repo)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
b.Fatalf("New() returned error %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if idx == nil {
|
|
|
|
b.Fatalf("New() returned nil index")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-07 21:57:31 +02:00
|
|
|
|
|
|
|
func TestIndexDuplicateBlobs(t *testing.T) {
|
|
|
|
repo, cleanup := createFilledRepo(t, 3, 0.05)
|
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
idx, err := New(repo)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
dups := idx.DuplicateBlobs()
|
|
|
|
if len(dups) == 0 {
|
|
|
|
t.Errorf("no duplicate blobs found")
|
|
|
|
}
|
|
|
|
}
|