github.com/mckael/restic@v0.8.3/internal/backend/test/benchmarks.go (about) 1 package test 2 3 import ( 4 "bytes" 5 "context" 6 "io" 7 "testing" 8 9 "github.com/restic/restic/internal/restic" 10 "github.com/restic/restic/internal/test" 11 ) 12 13 func saveRandomFile(t testing.TB, be restic.Backend, length int) ([]byte, restic.Handle) { 14 data := test.Random(23, length) 15 id := restic.Hash(data) 16 handle := restic.Handle{Type: restic.DataFile, Name: id.String()} 17 if err := be.Save(context.TODO(), handle, bytes.NewReader(data)); err != nil { 18 t.Fatalf("Save() error: %+v", err) 19 } 20 return data, handle 21 } 22 23 func remove(t testing.TB, be restic.Backend, h restic.Handle) { 24 if err := be.Remove(context.TODO(), h); err != nil { 25 t.Fatalf("Remove() returned error: %v", err) 26 } 27 } 28 29 // BenchmarkLoadFile benchmarks the Load() method of a backend by 30 // loading a complete file. 31 func (s *Suite) BenchmarkLoadFile(t *testing.B) { 32 be := s.open(t) 33 defer s.close(t, be) 34 35 length := 1<<24 + 2123 36 data, handle := saveRandomFile(t, be, length) 37 defer remove(t, be, handle) 38 39 buf := make([]byte, length) 40 41 t.SetBytes(int64(length)) 42 t.ResetTimer() 43 44 for i := 0; i < t.N; i++ { 45 var n int 46 err := be.Load(context.TODO(), handle, 0, 0, func(rd io.Reader) (ierr error) { 47 n, ierr = io.ReadFull(rd, buf) 48 return ierr 49 }) 50 if err != nil { 51 t.Fatal(err) 52 } 53 54 if n != length { 55 t.Fatalf("wrong number of bytes read: want %v, got %v", length, n) 56 } 57 58 if !bytes.Equal(data, buf) { 59 t.Fatalf("wrong bytes returned") 60 } 61 } 62 } 63 64 // BenchmarkLoadPartialFile benchmarks the Load() method of a backend by 65 // loading the remainder of a file starting at a given offset. 66 func (s *Suite) BenchmarkLoadPartialFile(t *testing.B) { 67 be := s.open(t) 68 defer s.close(t, be) 69 70 datalength := 1<<24 + 2123 71 data, handle := saveRandomFile(t, be, datalength) 72 defer remove(t, be, handle) 73 74 testLength := datalength/4 + 555 75 76 buf := make([]byte, testLength) 77 78 t.SetBytes(int64(testLength)) 79 t.ResetTimer() 80 81 for i := 0; i < t.N; i++ { 82 var n int 83 err := be.Load(context.TODO(), handle, testLength, 0, func(rd io.Reader) (ierr error) { 84 n, ierr = io.ReadFull(rd, buf) 85 return ierr 86 }) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 if n != testLength { 92 t.Fatalf("wrong number of bytes read: want %v, got %v", testLength, n) 93 } 94 95 if !bytes.Equal(data[:testLength], buf) { 96 t.Fatalf("wrong bytes returned") 97 } 98 99 } 100 } 101 102 // BenchmarkLoadPartialFileOffset benchmarks the Load() method of a 103 // backend by loading a number of bytes of a file starting at a given offset. 104 func (s *Suite) BenchmarkLoadPartialFileOffset(t *testing.B) { 105 be := s.open(t) 106 defer s.close(t, be) 107 108 datalength := 1<<24 + 2123 109 data, handle := saveRandomFile(t, be, datalength) 110 defer remove(t, be, handle) 111 112 testLength := datalength/4 + 555 113 testOffset := 8273 114 115 buf := make([]byte, testLength) 116 117 t.SetBytes(int64(testLength)) 118 t.ResetTimer() 119 120 for i := 0; i < t.N; i++ { 121 var n int 122 err := be.Load(context.TODO(), handle, testLength, int64(testOffset), func(rd io.Reader) (ierr error) { 123 n, ierr = io.ReadFull(rd, buf) 124 return ierr 125 }) 126 if err != nil { 127 t.Fatal(err) 128 } 129 130 if n != testLength { 131 t.Fatalf("wrong number of bytes read: want %v, got %v", testLength, n) 132 } 133 134 if !bytes.Equal(data[testOffset:testOffset+testLength], buf) { 135 t.Fatalf("wrong bytes returned") 136 } 137 138 } 139 } 140 141 // BenchmarkSave benchmarks the Save() method of a backend. 142 func (s *Suite) BenchmarkSave(t *testing.B) { 143 be := s.open(t) 144 defer s.close(t, be) 145 146 length := 1<<24 + 2123 147 data := test.Random(23, length) 148 id := restic.Hash(data) 149 handle := restic.Handle{Type: restic.DataFile, Name: id.String()} 150 151 rd := bytes.NewReader(data) 152 153 t.SetBytes(int64(length)) 154 t.ResetTimer() 155 156 for i := 0; i < t.N; i++ { 157 if _, err := rd.Seek(0, 0); err != nil { 158 t.Fatal(err) 159 } 160 161 if err := be.Save(context.TODO(), handle, rd); err != nil { 162 t.Fatal(err) 163 } 164 165 if err := be.Remove(context.TODO(), handle); err != nil { 166 t.Fatal(err) 167 } 168 } 169 }