| 
									
										
										
										
											2015-05-09 23:52:03 +02:00
										 |  |  | package repository_test | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 	"crypto/rand" | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	"crypto/sha256" | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-07-04 16:52:17 +02:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/restic/restic" | 
					
						
							|  |  |  | 	"github.com/restic/restic/backend" | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 	"github.com/restic/restic/pack" | 
					
						
							| 
									
										
										
										
											2015-07-04 16:52:17 +02:00
										 |  |  | 	"github.com/restic/restic/repository" | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 	. "github.com/restic/restic/test" | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type testJSONStruct struct { | 
					
						
							|  |  |  | 	Foo uint32 | 
					
						
							|  |  |  | 	Bar string | 
					
						
							|  |  |  | 	Baz []byte | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | var repoTests = []testJSONStruct{ | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	testJSONStruct{Foo: 23, Bar: "Teststring", Baz: []byte("xx")}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSaveJSON(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 	for _, obj := range repoTests { | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 		data, err := json.Marshal(obj) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 		data = append(data, '\n') | 
					
						
							|  |  |  | 		h := sha256.Sum256(data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 		id, err := repo.SaveJSON(pack.Tree, obj) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-25 17:05:45 +02:00
										 |  |  | 		Assert(t, h == id, | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 			"TestSaveJSON: wrong plaintext ID: expected %02x, got %02x", | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 			h, id) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkSaveJSON(t *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 	obj := repoTests[0] | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	data, err := json.Marshal(obj) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	data = append(data, '\n') | 
					
						
							|  |  |  | 	h := sha256.Sum256(data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 	t.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	for i := 0; i < t.N; i++ { | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 		id, err := repo.SaveJSON(pack.Tree, obj) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-25 17:05:45 +02:00
										 |  |  | 		Assert(t, h == id, | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 			"TestSaveJSON: wrong plaintext ID: expected %02x, got %02x", | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 			h, id) | 
					
						
							| 
									
										
										
										
											2015-02-16 19:32:36 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | var testSizes = []int{5, 23, 2<<18 + 23, 1 << 20} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | func TestSave(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for _, size := range testSizes { | 
					
						
							|  |  |  | 		data := make([]byte, size) | 
					
						
							|  |  |  | 		_, err := io.ReadFull(rand.Reader, data) | 
					
						
							|  |  |  | 		OK(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		id := backend.Hash(data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// save | 
					
						
							| 
									
										
										
										
											2015-07-02 23:00:54 +02:00
										 |  |  | 		sid, err := repo.SaveAndEncrypt(pack.Data, data, nil) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Equals(t, id, sid) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 		OK(t, repo.Flush()) | 
					
						
							| 
									
										
										
										
											2015-10-12 22:34:12 +02:00
										 |  |  | 		// OK(t, repo.SaveIndex()) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// read back | 
					
						
							| 
									
										
										
										
											2015-07-26 14:25:01 +02:00
										 |  |  | 		buf, err := repo.LoadBlob(pack.Data, id, make([]byte, size)) | 
					
						
							| 
									
										
										
										
											2015-10-12 22:07:56 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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 20:00:23 +01:00
										 |  |  | func TestSaveFrom(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for _, size := range testSizes { | 
					
						
							|  |  |  | 		data := make([]byte, size) | 
					
						
							|  |  |  | 		_, err := io.ReadFull(rand.Reader, data) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 		id := backend.Hash(data) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// save | 
					
						
							| 
									
										
										
										
											2015-07-25 17:05:45 +02:00
										 |  |  | 		err = repo.SaveFrom(pack.Data, &id, uint(size), bytes.NewReader(data)) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 		OK(t, repo.Flush()) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 		// read back | 
					
						
							| 
									
										
										
										
											2015-07-26 14:25:01 +02:00
										 |  |  | 		buf, err := repo.LoadBlob(pack.Data, id, make([]byte, size)) | 
					
						
							| 
									
										
										
										
											2015-10-12 22:07:56 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		Assert(t, len(buf) == len(data), | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 			"number of bytes read back does not match: expected %d, got %d", | 
					
						
							|  |  |  | 			len(data), len(buf)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		Assert(t, bytes.Equal(buf, data), | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 			"data does not match: expected %02x, got %02x", | 
					
						
							|  |  |  | 			data, buf) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkSaveFrom(t *testing.B) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	size := 4 << 20 // 4MiB | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	data := make([]byte, size) | 
					
						
							|  |  |  | 	_, err := io.ReadFull(rand.Reader, data) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-25 17:05:45 +02:00
										 |  |  | 	id := backend.ID(sha256.Sum256(data)) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	t.ResetTimer() | 
					
						
							|  |  |  | 	t.SetBytes(int64(size)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < t.N; i++ { | 
					
						
							|  |  |  | 		// save | 
					
						
							| 
									
										
										
										
											2015-07-25 17:05:45 +02:00
										 |  |  | 		err = repo.SaveFrom(pack.Data, &id, uint(size), bytes.NewReader(data)) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 		OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-16 20:00:23 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-17 23:05:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | func TestLoadJSONPack(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-28 13:15:35 +02:00
										 |  |  | 	if BenchArchiveDirectory == "" { | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 		t.Skip("benchdir not set, skipping") | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// archive a few files | 
					
						
							| 
									
										
										
										
											2015-06-28 13:15:35 +02:00
										 |  |  | 	sn := SnapshotDir(t, repo, BenchArchiveDirectory, nil) | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 	OK(t, repo.Flush()) | 
					
						
							| 
									
										
										
										
											2015-03-28 15:07:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | 	tree := restic.NewTree() | 
					
						
							| 
									
										
										
										
											2015-07-25 17:05:45 +02:00
										 |  |  | 	err := repo.LoadJSONPack(pack.Tree, *sn.Tree, &tree) | 
					
						
							| 
									
										
										
										
											2015-04-09 21:15:48 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-04 20:40:17 +02:00
										 |  |  | func TestLoadJSONUnpacked(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-06-26 22:12:04 +02:00
										 |  |  | 	repo := SetupRepo() | 
					
						
							|  |  |  | 	defer TeardownRepo(repo) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-28 13:15:35 +02:00
										 |  |  | 	if BenchArchiveDirectory == "" { | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 		t.Skip("benchdir not set, skipping") | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 	// archive a snapshot | 
					
						
							|  |  |  | 	sn := restic.Snapshot{} | 
					
						
							|  |  |  | 	sn.Hostname = "foobar" | 
					
						
							|  |  |  | 	sn.Username = "test!" | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 	id, err := repo.SaveJSONUnpacked(backend.Snapshot, &sn) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 	var sn2 restic.Snapshot | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// restore | 
					
						
							| 
									
										
										
										
											2015-05-09 13:32:52 +02:00
										 |  |  | 	err = repo.LoadJSONUnpacked(backend.Snapshot, id, &sn2) | 
					
						
							| 
									
										
										
										
											2015-04-26 17:44:38 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Equals(t, sn.Hostname, sn2.Hostname) | 
					
						
							|  |  |  | 	Equals(t, sn.Username, sn2.Username) | 
					
						
							| 
									
										
										
										
											2015-02-18 22:46:09 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-04 16:52:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | var repoFixture = filepath.Join("testdata", "test-repo.tar.gz") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-08 12:22:17 +02:00
										 |  |  | func TestRepositoryLoadIndex(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-04 16:52:17 +02: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 22:34:12 +02:00
										 |  |  | 			repo.SetIndex(repository.NewMasterIndex()) | 
					
						
							| 
									
										
										
										
											2015-07-04 16:52:17 +02:00
										 |  |  | 			OK(b, repo.LoadIndex()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } |