github.com/advanderveer/restic@v0.8.1-0.20171209104529-42a8c19aaea6/internal/restic/find_test.go (about) 1 package restic_test 2 3 import ( 4 "bufio" 5 "context" 6 "encoding/json" 7 "flag" 8 "fmt" 9 "os" 10 "path/filepath" 11 "sort" 12 "testing" 13 "time" 14 15 "github.com/restic/restic/internal/repository" 16 "github.com/restic/restic/internal/restic" 17 ) 18 19 func loadIDSet(t testing.TB, filename string) restic.BlobSet { 20 f, err := os.Open(filename) 21 if err != nil { 22 t.Logf("unable to open golden file %v: %v", filename, err) 23 return restic.NewBlobSet() 24 } 25 26 sc := bufio.NewScanner(f) 27 28 blobs := restic.NewBlobSet() 29 for sc.Scan() { 30 var h restic.BlobHandle 31 err := json.Unmarshal([]byte(sc.Text()), &h) 32 if err != nil { 33 t.Errorf("file %v contained invalid blob: %#v", filename, err) 34 continue 35 } 36 37 blobs.Insert(h) 38 } 39 40 if err = f.Close(); err != nil { 41 t.Errorf("closing file %v failed with error %v", filename, err) 42 } 43 44 return blobs 45 } 46 47 func saveIDSet(t testing.TB, filename string, s restic.BlobSet) { 48 f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 49 if err != nil { 50 t.Fatalf("unable to update golden file %v: %v", filename, err) 51 return 52 } 53 54 var hs restic.BlobHandles 55 for h := range s { 56 hs = append(hs, h) 57 } 58 59 sort.Sort(hs) 60 61 enc := json.NewEncoder(f) 62 for _, h := range hs { 63 err = enc.Encode(h) 64 if err != nil { 65 t.Fatalf("Encode() returned error: %v", err) 66 } 67 } 68 69 if err = f.Close(); err != nil { 70 t.Fatalf("close file %v returned error: %v", filename, err) 71 } 72 } 73 74 var updateGoldenFiles = flag.Bool("update", false, "update golden files in testdata/") 75 76 const ( 77 findTestSnapshots = 3 78 findTestDepth = 2 79 ) 80 81 var findTestTime = time.Unix(1469960361, 23) 82 83 func TestFindUsedBlobs(t *testing.T) { 84 repo, cleanup := repository.TestRepository(t) 85 defer cleanup() 86 87 var snapshots []*restic.Snapshot 88 for i := 0; i < findTestSnapshots; i++ { 89 sn := restic.TestCreateSnapshot(t, repo, findTestTime.Add(time.Duration(i)*time.Second), findTestDepth, 0) 90 t.Logf("snapshot %v saved, tree %v", sn.ID().Str(), sn.Tree.Str()) 91 snapshots = append(snapshots, sn) 92 } 93 94 for i, sn := range snapshots { 95 usedBlobs := restic.NewBlobSet() 96 err := restic.FindUsedBlobs(context.TODO(), repo, *sn.Tree, usedBlobs, restic.NewBlobSet()) 97 if err != nil { 98 t.Errorf("FindUsedBlobs returned error: %v", err) 99 continue 100 } 101 102 if len(usedBlobs) == 0 { 103 t.Errorf("FindUsedBlobs returned an empty set") 104 continue 105 } 106 107 goldenFilename := filepath.Join("testdata", fmt.Sprintf("used_blobs_snapshot%d", i)) 108 want := loadIDSet(t, goldenFilename) 109 110 if !want.Equals(usedBlobs) { 111 t.Errorf("snapshot %d: wrong list of blobs returned:\n missing blobs: %v\n extra blobs: %v", 112 i, want.Sub(usedBlobs), usedBlobs.Sub(want)) 113 } 114 115 if *updateGoldenFiles { 116 saveIDSet(t, goldenFilename, usedBlobs) 117 } 118 } 119 } 120 121 func BenchmarkFindUsedBlobs(b *testing.B) { 122 repo, cleanup := repository.TestRepository(b) 123 defer cleanup() 124 125 sn := restic.TestCreateSnapshot(b, repo, findTestTime, findTestDepth, 0) 126 127 b.ResetTimer() 128 129 for i := 0; i < b.N; i++ { 130 seen := restic.NewBlobSet() 131 blobs := restic.NewBlobSet() 132 err := restic.FindUsedBlobs(context.TODO(), repo, *sn.Tree, blobs, seen) 133 if err != nil { 134 b.Error(err) 135 } 136 137 b.Logf("found %v blobs", len(blobs)) 138 } 139 }