| 
									
										
										
										
											2016-08-01 20:04:23 +02:00
										 |  |  | package repository_test | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-06-05 23:56:59 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 	"math/rand" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2020-11-02 12:55:34 +01:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2017-07-23 14:21:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/restic/restic/internal/repository" | 
					
						
							| 
									
										
										
										
											2017-07-24 17:42:25 +02:00
										 |  |  | 	"github.com/restic/restic/internal/restic" | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | func randomSize(min, max int) int { | 
					
						
							|  |  |  | 	return rand.Intn(max-min) + min | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func createRandomBlobs(t testing.TB, repo restic.Repository, blobs int, pData float32) { | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 	for i := 0; i < blobs; i++ { | 
					
						
							|  |  |  | 		var ( | 
					
						
							| 
									
										
										
										
											2016-08-31 20:58:57 +02:00
										 |  |  | 			tpe    restic.BlobType | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 			length int | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if rand.Float32() < pData { | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 			tpe = restic.DataBlob | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 			length = randomSize(10*1024, 1024*1024) // 10KiB to 1MiB of data | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 			tpe = restic.TreeBlob | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 			length = randomSize(1*1024, 20*1024) // 1KiB to 20KiB | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 09:54:24 +01:00
										 |  |  | 		buf := make([]byte, length) | 
					
						
							|  |  |  | 		rand.Read(buf) | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-06 22:20:44 +02:00
										 |  |  | 		id, exists, err := repo.SaveBlob(context.TODO(), tpe, buf, restic.ID{}, false) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("SaveFrom() error %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-06 22:20:44 +02:00
										 |  |  | 		if exists { | 
					
						
							|  |  |  | 			t.Errorf("duplicate blob %v/%v ignored", id, restic.DataBlob) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		if rand.Float32() < 0.2 { | 
					
						
							| 
									
										
										
										
											2017-11-22 06:27:29 -05:00
										 |  |  | 			if err = repo.Flush(context.Background()); err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 				t.Fatalf("repo.Flush() returned error %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 06:27:29 -05:00
										 |  |  | 	if err := repo.Flush(context.Background()); err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		t.Fatalf("repo.Flush() returned error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | func createRandomWrongBlob(t testing.TB, repo restic.Repository) { | 
					
						
							|  |  |  | 	length := randomSize(10*1024, 1024*1024) // 10KiB to 1MiB of data | 
					
						
							|  |  |  | 	buf := make([]byte, length) | 
					
						
							|  |  |  | 	rand.Read(buf) | 
					
						
							|  |  |  | 	id := restic.Hash(buf) | 
					
						
							|  |  |  | 	// invert first data byte | 
					
						
							|  |  |  | 	buf[0] ^= 0xff | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, _, err := repo.SaveBlob(context.TODO(), restic.DataBlob, buf, id, false) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("SaveFrom() error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := repo.Flush(context.Background()); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("repo.Flush() returned error %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | // selectBlobs splits the list of all blobs randomly into two lists. A blob | 
					
						
							|  |  |  | // will be contained in the firstone ith probability p. | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func selectBlobs(t *testing.T, repo restic.Repository, p float32) (list1, list2 restic.BlobSet) { | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 	list1 = restic.NewBlobSet() | 
					
						
							|  |  |  | 	list2 = restic.NewBlobSet() | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 	blobs := restic.NewBlobSet() | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 11:16:38 +02:00
										 |  |  | 	err := repo.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error { | 
					
						
							| 
									
										
										
										
											2018-01-23 21:43:21 -05:00
										 |  |  | 		entries, _, err := repo.ListPack(context.TODO(), id, size) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("error listing pack %v: %v", id, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for _, entry := range entries { | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 			h := restic.BlobHandle{ID: entry.ID, Type: entry.Type} | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 			if blobs.Has(h) { | 
					
						
							|  |  |  | 				t.Errorf("ignoring duplicate blob %v", h) | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:36 +01:00
										 |  |  | 				return nil | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			blobs.Insert(h) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 			if rand.Float32() <= p { | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 				list1.Insert(restic.BlobHandle{ID: entry.ID, Type: entry.Type}) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2016-08-31 23:07:50 +02:00
										 |  |  | 				list2.Insert(restic.BlobHandle{ID: entry.ID, Type: entry.Type}) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:36 +01:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return list1, list2 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func listPacks(t *testing.T, repo restic.Repository) restic.IDSet { | 
					
						
							| 
									
										
										
										
											2016-08-31 20:29:54 +02:00
										 |  |  | 	list := restic.NewIDSet() | 
					
						
							| 
									
										
										
										
											2020-08-16 11:16:38 +02:00
										 |  |  | 	err := repo.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error { | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		list.Insert(id) | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:36 +01:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return list | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func findPacksForBlobs(t *testing.T, repo restic.Repository, blobs restic.BlobSet) restic.IDSet { | 
					
						
							| 
									
										
										
										
											2016-08-31 20:29:54 +02:00
										 |  |  | 	packs := restic.NewIDSet() | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	idx := repo.Index() | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 	for h := range blobs { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		list := idx.Lookup(h) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 		if len(list) == 0 { | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 			t.Fatal("Failed to find blob", h.ID.Str(), "with type", h.Type) | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 		for _, pb := range list { | 
					
						
							|  |  |  | 			packs.Insert(pb.PackID) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-08-01 20:24:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return packs | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func repack(t *testing.T, repo restic.Repository, packs restic.IDSet, blobs restic.BlobSet) { | 
					
						
							| 
									
										
										
										
											2021-09-12 00:03:41 +02:00
										 |  |  | 	repackedBlobs, err := repository.Repack(context.TODO(), repo, repo, packs, blobs, nil) | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-15 14:40:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for id := range repackedBlobs { | 
					
						
							| 
									
										
										
										
											2020-08-16 11:16:38 +02:00
										 |  |  | 		err = repo.Backend().Remove(context.TODO(), restic.Handle{Type: restic.PackFile, Name: id.String()}) | 
					
						
							| 
									
										
										
										
											2017-06-15 14:40:34 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func saveIndex(t *testing.T, repo restic.Repository) { | 
					
						
							| 
									
										
										
										
											2017-06-05 23:56:59 +02:00
										 |  |  | 	if err := repo.SaveIndex(context.TODO()); err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 		t.Fatalf("repo.SaveIndex() %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func rebuildIndex(t *testing.T, repo restic.Repository) { | 
					
						
							| 
									
										
										
										
											2020-10-10 22:29:55 +02:00
										 |  |  | 	err := repo.SetIndex(repository.NewMasterIndex()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	packs := make(map[restic.ID]int64) | 
					
						
							|  |  |  | 	err = repo.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error { | 
					
						
							|  |  |  | 		packs[id] = size | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = repo.(*repository.Repository).CreateIndexFromPacks(context.TODO(), packs, nil) | 
					
						
							| 
									
										
										
										
											2017-03-01 13:44:56 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:36 +01:00
										 |  |  | 	err = repo.List(context.TODO(), restic.IndexFile, func(id restic.ID, size int64) error { | 
					
						
							| 
									
										
										
										
											2017-06-05 23:56:59 +02:00
										 |  |  | 		h := restic.Handle{ | 
					
						
							| 
									
										
										
										
											2017-03-01 13:44:56 +01:00
										 |  |  | 			Type: restic.IndexFile, | 
					
						
							|  |  |  | 			Name: id.String(), | 
					
						
							| 
									
										
										
										
											2017-06-05 23:56:59 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-21 17:25:36 +01:00
										 |  |  | 		return repo.Backend().Remove(context.TODO(), h) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2017-03-01 13:44:56 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 22:29:55 +02:00
										 |  |  | 	_, err = (repo.Index()).(*repository.MasterIndex). | 
					
						
							| 
									
										
										
										
											2020-10-18 09:24:34 +02:00
										 |  |  | 		Save(context.TODO(), repo, restic.NewIDSet(), nil, nil) | 
					
						
							| 
									
										
										
										
											2020-10-10 22:29:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-01 13:44:56 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | func reloadIndex(t *testing.T, repo restic.Repository) { | 
					
						
							| 
									
										
										
										
											2021-01-30 16:32:00 +01:00
										 |  |  | 	err := repo.SetIndex(repository.NewMasterIndex()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 23:56:59 +02:00
										 |  |  | 	if err := repo.LoadIndex(context.TODO()); err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 		t.Fatalf("error loading new index: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRepack(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-29 23:16:16 +02:00
										 |  |  | 	repository.TestAllVersions(t, testRepack) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testRepack(t *testing.T, version uint) { | 
					
						
							|  |  |  | 	repo, cleanup := repository.TestRepositoryWithVersion(t, version) | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 	defer cleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 12:55:34 +01:00
										 |  |  | 	seed := time.Now().UnixNano() | 
					
						
							| 
									
										
										
										
											2018-01-23 21:41:39 +01:00
										 |  |  | 	rand.Seed(seed) | 
					
						
							|  |  |  | 	t.Logf("rand seed is %v", seed) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 20:42:11 +02:00
										 |  |  | 	createRandomBlobs(t, repo, 100, 0.7) | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	packsBefore := listPacks(t, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Running repack on empty ID sets should not do anything at all. | 
					
						
							|  |  |  | 	repack(t, repo, nil, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	packsAfter := listPacks(t, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !packsAfter.Equals(packsBefore) { | 
					
						
							|  |  |  | 		t.Fatalf("packs are not equal, Repack modified something. Before:\n  %v\nAfter:\n  %v", | 
					
						
							|  |  |  | 			packsBefore, packsAfter) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	saveIndex(t, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	removeBlobs, keepBlobs := selectBlobs(t, repo, 0.2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	removePacks := findPacksForBlobs(t, repo, removeBlobs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	repack(t, repo, removePacks, keepBlobs) | 
					
						
							|  |  |  | 	rebuildIndex(t, repo) | 
					
						
							|  |  |  | 	reloadIndex(t, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	packsAfter = listPacks(t, repo) | 
					
						
							|  |  |  | 	for id := range removePacks { | 
					
						
							|  |  |  | 		if packsAfter.Has(id) { | 
					
						
							|  |  |  | 			t.Errorf("pack %v still present although it should have been repacked and removed", id.Str()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	idx := repo.Index() | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for h := range keepBlobs { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		list := idx.Lookup(h) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 		if len(list) == 0 { | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 			t.Errorf("unable to find blob %v in repo", h.ID.Str()) | 
					
						
							|  |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 		if len(list) != 1 { | 
					
						
							|  |  |  | 			t.Errorf("expected one pack in the list, got: %v", list) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pb := list[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 		if removePacks.Has(pb.PackID) { | 
					
						
							|  |  |  | 			t.Errorf("lookup returned pack ID %v that should've been removed", pb.PackID) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 	for h := range removeBlobs { | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 		if _, found := repo.LookupBlobSize(h.ID, h.Type); found { | 
					
						
							| 
									
										
										
										
											2016-08-03 22:38:05 +02:00
										 |  |  | 			t.Errorf("blob %v still contained in the repo", h) | 
					
						
							| 
									
										
										
										
											2016-08-01 18:55:07 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-12 00:03:41 +02:00
										 |  |  | func TestRepackCopy(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-29 23:16:16 +02:00
										 |  |  | 	repository.TestAllVersions(t, testRepackCopy) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testRepackCopy(t *testing.T, version uint) { | 
					
						
							|  |  |  | 	repo, cleanup := repository.TestRepositoryWithVersion(t, version) | 
					
						
							| 
									
										
										
										
											2021-09-12 00:03:41 +02:00
										 |  |  | 	defer cleanup() | 
					
						
							| 
									
										
										
										
											2022-04-29 23:16:16 +02:00
										 |  |  | 	dstRepo, dstCleanup := repository.TestRepositoryWithVersion(t, version) | 
					
						
							| 
									
										
										
										
											2021-09-12 00:03:41 +02:00
										 |  |  | 	defer dstCleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	seed := time.Now().UnixNano() | 
					
						
							|  |  |  | 	rand.Seed(seed) | 
					
						
							|  |  |  | 	t.Logf("rand seed is %v", seed) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	createRandomBlobs(t, repo, 100, 0.7) | 
					
						
							|  |  |  | 	saveIndex(t, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, keepBlobs := selectBlobs(t, repo, 0.2) | 
					
						
							|  |  |  | 	copyPacks := findPacksForBlobs(t, repo, keepBlobs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err := repository.Repack(context.TODO(), repo, dstRepo, copyPacks, keepBlobs, nil) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rebuildIndex(t, dstRepo) | 
					
						
							|  |  |  | 	reloadIndex(t, dstRepo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	idx := dstRepo.Index() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for h := range keepBlobs { | 
					
						
							|  |  |  | 		list := idx.Lookup(h) | 
					
						
							|  |  |  | 		if len(list) == 0 { | 
					
						
							|  |  |  | 			t.Errorf("unable to find blob %v in repo", h.ID.Str()) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if len(list) != 1 { | 
					
						
							|  |  |  | 			t.Errorf("expected one pack in the list, got: %v", list) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | func TestRepackWrongBlob(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-29 23:16:16 +02:00
										 |  |  | 	repository.TestAllVersions(t, testRepackWrongBlob) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testRepackWrongBlob(t *testing.T, version uint) { | 
					
						
							|  |  |  | 	repo, cleanup := repository.TestRepositoryWithVersion(t, version) | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | 	defer cleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 12:55:34 +01:00
										 |  |  | 	seed := time.Now().UnixNano() | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | 	rand.Seed(seed) | 
					
						
							|  |  |  | 	t.Logf("rand seed is %v", seed) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	createRandomBlobs(t, repo, 5, 0.7) | 
					
						
							|  |  |  | 	createRandomWrongBlob(t, repo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// just keep all blobs, but also rewrite every pack | 
					
						
							|  |  |  | 	_, keepBlobs := selectBlobs(t, repo, 0) | 
					
						
							|  |  |  | 	rewritePacks := findPacksForBlobs(t, repo, keepBlobs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-12 00:03:41 +02:00
										 |  |  | 	_, err := repository.Repack(context.TODO(), repo, repo, rewritePacks, keepBlobs, nil) | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("expected repack to fail but got no error") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-02 12:53:45 +01:00
										 |  |  | 	t.Logf("found expected error: %v", err) | 
					
						
							| 
									
										
										
										
											2020-03-31 17:04:48 +02:00
										 |  |  | } |