2
2
mirror of https://github.com/octoleo/restic.git synced 2024-06-01 00:20:48 +00:00
restic/src/restic/repository/repository_test.go

260 lines
5.2 KiB
Go
Raw Normal View History

package repository_test
import (
"bytes"
2015-02-16 19:00:23 +00:00
"crypto/rand"
"crypto/sha256"
2015-02-16 19:00:23 +00:00
"io"
mrand "math/rand"
2015-07-04 14:52:17 +00:00
"path/filepath"
"testing"
"restic"
"restic/repository"
. "restic/test"
)
2015-02-16 19:00:23 +00:00
var testSizes = []int{5, 23, 2<<18 + 23, 1 << 20}
func TestSave(t *testing.T) {
repo := SetupRepo()
defer TeardownRepo(repo)
for _, size := range testSizes {
data := make([]byte, size)
_, err := io.ReadFull(rand.Reader, data)
OK(t, err)
2016-08-31 18:29:54 +00:00
id := restic.Hash(data)
// save
sid, err := repo.SaveBlob(restic.DataBlob, data, restic.ID{})
OK(t, err)
Equals(t, id, sid)
2015-05-09 11:32:52 +00:00
OK(t, repo.Flush())
2015-10-12 20:34:12 +00:00
// OK(t, repo.SaveIndex())
// read back
buf := make([]byte, size)
2016-09-03 18:20:14 +00:00
n, err := repo.LoadBlob(restic.DataBlob, id, buf)
2015-10-12 20:07:56 +00:00
OK(t, err)
Equals(t, len(buf), n)
Assert(t, len(buf) == len(data),
"number of bytes read back does not match: expected %d, got %d",
len(data), len(buf))
Assert(t, bytes.Equal(buf, data),
"data does not match: expected %02x, got %02x",
data, buf)
}
}
2015-02-16 19:00:23 +00:00
func TestSaveFrom(t *testing.T) {
repo := SetupRepo()
defer TeardownRepo(repo)
2015-02-16 19:00:23 +00:00
for _, size := range testSizes {
data := make([]byte, size)
_, err := io.ReadFull(rand.Reader, data)
2015-04-09 19:15:48 +00:00
OK(t, err)
2015-02-16 19:00:23 +00:00
2016-08-31 18:29:54 +00:00
id := restic.Hash(data)
2015-02-16 19:00:23 +00:00
// save
id2, err := repo.SaveBlob(restic.DataBlob, data, id)
2015-04-09 19:15:48 +00:00
OK(t, err)
2016-05-08 11:13:29 +00:00
Equals(t, id, id2)
2015-02-16 19:00:23 +00:00
2015-05-09 11:32:52 +00:00
OK(t, repo.Flush())
2015-02-16 19:00:23 +00:00
// read back
buf := make([]byte, size)
2016-09-03 18:20:14 +00:00
n, err := repo.LoadBlob(restic.DataBlob, id, buf)
2015-10-12 20:07:56 +00:00
OK(t, err)
Equals(t, len(buf), n)
2015-02-16 19:00:23 +00:00
2015-04-09 19:15:48 +00:00
Assert(t, len(buf) == len(data),
2015-02-16 19:00:23 +00:00
"number of bytes read back does not match: expected %d, got %d",
len(data), len(buf))
2015-04-09 19:15:48 +00:00
Assert(t, bytes.Equal(buf, data),
2015-02-16 19:00:23 +00:00
"data does not match: expected %02x, got %02x",
data, buf)
}
}
2016-05-08 11:13:29 +00:00
func BenchmarkSaveAndEncrypt(t *testing.B) {
repo := SetupRepo()
defer TeardownRepo(repo)
2015-02-16 19:00:23 +00:00
size := 4 << 20 // 4MiB
data := make([]byte, size)
_, err := io.ReadFull(rand.Reader, data)
2015-04-09 19:15:48 +00:00
OK(t, err)
2015-02-16 19:00:23 +00:00
2016-08-31 18:29:54 +00:00
id := restic.ID(sha256.Sum256(data))
2015-02-16 19:00:23 +00:00
t.ResetTimer()
t.SetBytes(int64(size))
for i := 0; i < t.N; i++ {
// save
_, err = repo.SaveBlob(restic.DataBlob, data, id)
2015-04-09 19:15:48 +00:00
OK(t, err)
2015-02-16 19:00:23 +00:00
}
}
2015-02-17 22:05:23 +00:00
func TestLoadTree(t *testing.T) {
repo := SetupRepo()
defer TeardownRepo(repo)
2015-06-28 11:15:35 +00:00
if BenchArchiveDirectory == "" {
2015-05-09 11:32:52 +00:00
t.Skip("benchdir not set, skipping")
}
// archive a few files
2015-06-28 11:15:35 +00:00
sn := SnapshotDir(t, repo, BenchArchiveDirectory, nil)
2015-05-09 11:32:52 +00:00
OK(t, repo.Flush())
_, err := repo.LoadTree(*sn.Tree)
2015-04-09 19:15:48 +00:00
OK(t, err)
}
func BenchmarkLoadTree(t *testing.B) {
2015-10-26 19:47:48 +00:00
repo := SetupRepo()
defer TeardownRepo(repo)
if BenchArchiveDirectory == "" {
t.Skip("benchdir not set, skipping")
}
// archive a few files
sn := SnapshotDir(t, repo, BenchArchiveDirectory, nil)
OK(t, repo.Flush())
t.ResetTimer()
for i := 0; i < t.N; i++ {
_, err := repo.LoadTree(*sn.Tree)
2015-10-26 19:47:48 +00:00
OK(t, err)
}
}
func TestLoadJSONUnpacked(t *testing.T) {
repo := SetupRepo()
defer TeardownRepo(repo)
2015-06-28 11:15:35 +00:00
if BenchArchiveDirectory == "" {
2015-05-09 11:32:52 +00:00
t.Skip("benchdir not set, skipping")
}
// archive a snapshot
sn := restic.Snapshot{}
sn.Hostname = "foobar"
sn.Username = "test!"
2016-08-31 18:29:54 +00:00
id, err := repo.SaveJSONUnpacked(restic.SnapshotFile, &sn)
OK(t, err)
var sn2 restic.Snapshot
// restore
2016-08-31 18:29:54 +00:00
err = repo.LoadJSONUnpacked(restic.SnapshotFile, id, &sn2)
OK(t, err)
Equals(t, sn.Hostname, sn2.Hostname)
Equals(t, sn.Username, sn2.Username)
}
2015-07-04 14:52:17 +00:00
var repoFixture = filepath.Join("testdata", "test-repo.tar.gz")
func TestRepositoryLoadIndex(t *testing.T) {
2015-07-04 14:52:17 +00:00
WithTestEnvironment(t, repoFixture, func(repodir string) {
repo := OpenLocalRepo(t, repodir)
OK(t, repo.LoadIndex())
})
}
func BenchmarkLoadIndex(b *testing.B) {
WithTestEnvironment(b, repoFixture, func(repodir string) {
repo := OpenLocalRepo(b, repodir)
b.ResetTimer()
for i := 0; i < b.N; i++ {
2015-10-12 20:34:12 +00:00
repo.SetIndex(repository.NewMasterIndex())
2015-07-04 14:52:17 +00:00
OK(b, repo.LoadIndex())
}
})
}
// saveRandomDataBlobs generates random data blobs and saves them to the repository.
func saveRandomDataBlobs(t testing.TB, repo restic.Repository, num int, sizeMax int) {
for i := 0; i < num; i++ {
size := mrand.Int() % sizeMax
buf := make([]byte, size)
_, err := io.ReadFull(rand.Reader, buf)
OK(t, err)
_, err = repo.SaveBlob(restic.DataBlob, buf, restic.ID{})
OK(t, err)
}
}
func TestRepositoryIncrementalIndex(t *testing.T) {
repo := SetupRepo()
defer TeardownRepo(repo)
repository.IndexFull = func(*repository.Index) bool { return true }
// add 15 packs
for j := 0; j < 5; j++ {
// add 3 packs, write intermediate index
for i := 0; i < 3; i++ {
saveRandomDataBlobs(t, repo, 5, 1<<15)
OK(t, repo.Flush())
}
OK(t, repo.SaveFullIndex())
}
// add another 5 packs
for i := 0; i < 5; i++ {
saveRandomDataBlobs(t, repo, 5, 1<<15)
OK(t, repo.Flush())
}
// save final index
OK(t, repo.SaveIndex())
type packEntry struct {
2016-08-31 18:29:54 +00:00
id restic.ID
indexes []*repository.Index
}
2016-08-31 18:29:54 +00:00
packEntries := make(map[restic.ID]map[restic.ID]struct{})
2016-08-31 18:29:54 +00:00
for id := range repo.List(restic.IndexFile, nil) {
idx, err := repository.LoadIndex(repo, id)
OK(t, err)
for pb := range idx.Each(nil) {
if _, ok := packEntries[pb.PackID]; !ok {
2016-08-31 18:29:54 +00:00
packEntries[pb.PackID] = make(map[restic.ID]struct{})
}
packEntries[pb.PackID][id] = struct{}{}
}
}
for packID, ids := range packEntries {
if len(ids) > 1 {
t.Errorf("pack %v listed in %d indexes\n", packID, len(ids))
}
}
}