github.com/containerd/Containerd@v1.4.13/snapshots/storage/metastore_bench_test.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package storage 18 19 import ( 20 "context" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "testing" 25 26 "github.com/containerd/containerd/snapshots" 27 ) 28 29 // Benchmarks returns a benchmark suite using the provided metadata store 30 // creation method 31 func Benchmarks(b *testing.B, name string, metaFn metaFactory) { 32 b.Run("StatActive", makeBench(b, name, metaFn, statActiveBenchmark)) 33 b.Run("StatCommitted", makeBench(b, name, metaFn, statCommittedBenchmark)) 34 b.Run("CreateActive", makeBench(b, name, metaFn, createActiveBenchmark)) 35 b.Run("Remove", makeBench(b, name, metaFn, removeBenchmark)) 36 b.Run("Commit", makeBench(b, name, metaFn, commitBenchmark)) 37 b.Run("GetActive", makeBench(b, name, metaFn, getActiveBenchmark)) 38 b.Run("WriteTransaction", openCloseWritable(b, name, metaFn)) 39 b.Run("ReadTransaction", openCloseReadonly(b, name, metaFn)) 40 } 41 42 // makeBench creates a benchmark with a writable transaction 43 func makeBench(b *testing.B, name string, metaFn metaFactory, fn func(context.Context, *testing.B, *MetaStore)) func(b *testing.B) { 44 return func(b *testing.B) { 45 ctx := context.Background() 46 tmpDir, err := ioutil.TempDir("", "metastore-bench-"+name+"-") 47 if err != nil { 48 b.Fatal(err) 49 } 50 defer os.RemoveAll(tmpDir) 51 52 ms, err := metaFn(tmpDir) 53 if err != nil { 54 b.Fatal(err) 55 } 56 57 ctx, t, err := ms.TransactionContext(ctx, true) 58 if err != nil { 59 b.Fatal(err) 60 } 61 defer t.Commit() 62 63 b.ResetTimer() 64 fn(ctx, b, ms) 65 } 66 } 67 68 func openCloseWritable(b *testing.B, name string, metaFn metaFactory) func(b *testing.B) { 69 return func(b *testing.B) { 70 ctx := context.Background() 71 tmpDir, err := ioutil.TempDir("", "metastore-bench-"+name+"-") 72 if err != nil { 73 b.Fatal(err) 74 } 75 defer os.RemoveAll(tmpDir) 76 77 ms, err := metaFn(tmpDir) 78 if err != nil { 79 b.Fatal(err) 80 } 81 82 b.ResetTimer() 83 84 for i := 0; i < b.N; i++ { 85 _, t, err := ms.TransactionContext(ctx, true) 86 if err != nil { 87 b.Fatal(err) 88 } 89 if err := t.Commit(); err != nil { 90 b.Fatal(err) 91 } 92 } 93 } 94 } 95 96 func openCloseReadonly(b *testing.B, name string, metaFn metaFactory) func(b *testing.B) { 97 return func(b *testing.B) { 98 ctx := context.Background() 99 tmpDir, err := ioutil.TempDir("", "metastore-bench-"+name+"-") 100 if err != nil { 101 b.Fatal(err) 102 } 103 defer os.RemoveAll(tmpDir) 104 105 ms, err := metaFn(tmpDir) 106 if err != nil { 107 b.Fatal(err) 108 } 109 110 b.ResetTimer() 111 112 for i := 0; i < b.N; i++ { 113 _, t, err := ms.TransactionContext(ctx, false) 114 if err != nil { 115 b.Fatal(err) 116 } 117 if err := t.Rollback(); err != nil { 118 b.Fatal(err) 119 } 120 } 121 } 122 } 123 124 func createActiveFromBase(ctx context.Context, ms *MetaStore, active, base string) error { 125 if _, err := CreateSnapshot(ctx, snapshots.KindActive, "bottom", ""); err != nil { 126 return err 127 } 128 if _, err := CommitActive(ctx, "bottom", base, snapshots.Usage{}); err != nil { 129 return err 130 } 131 132 _, err := CreateSnapshot(ctx, snapshots.KindActive, active, base) 133 return err 134 } 135 136 func statActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) { 137 if err := createActiveFromBase(ctx, ms, "active", "base"); err != nil { 138 b.Fatal(err) 139 } 140 141 b.ResetTimer() 142 for i := 0; i < b.N; i++ { 143 _, _, _, err := GetInfo(ctx, "active") 144 if err != nil { 145 b.Fatal(err) 146 } 147 } 148 } 149 150 func statCommittedBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) { 151 if err := createActiveFromBase(ctx, ms, "active", "base"); err != nil { 152 b.Fatal(err) 153 } 154 if _, err := CommitActive(ctx, "active", "committed", snapshots.Usage{}); err != nil { 155 b.Fatal(err) 156 } 157 158 b.ResetTimer() 159 for i := 0; i < b.N; i++ { 160 _, _, _, err := GetInfo(ctx, "committed") 161 if err != nil { 162 b.Fatal(err) 163 } 164 } 165 } 166 167 func createActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) { 168 for i := 0; i < b.N; i++ { 169 if _, err := CreateSnapshot(ctx, snapshots.KindActive, "active", ""); err != nil { 170 b.Fatal(err) 171 } 172 b.StopTimer() 173 if _, _, err := Remove(ctx, "active"); err != nil { 174 b.Fatal(err) 175 } 176 b.StartTimer() 177 } 178 } 179 180 func removeBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) { 181 for i := 0; i < b.N; i++ { 182 b.StopTimer() 183 if _, err := CreateSnapshot(ctx, snapshots.KindActive, "active", ""); err != nil { 184 b.Fatal(err) 185 } 186 b.StartTimer() 187 if _, _, err := Remove(ctx, "active"); err != nil { 188 b.Fatal(err) 189 } 190 } 191 } 192 193 func commitBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) { 194 b.StopTimer() 195 for i := 0; i < b.N; i++ { 196 if _, err := CreateSnapshot(ctx, snapshots.KindActive, "active", ""); err != nil { 197 b.Fatal(err) 198 } 199 b.StartTimer() 200 if _, err := CommitActive(ctx, "active", "committed", snapshots.Usage{}); err != nil { 201 b.Fatal(err) 202 } 203 b.StopTimer() 204 if _, _, err := Remove(ctx, "committed"); err != nil { 205 b.Fatal(err) 206 } 207 } 208 } 209 210 func getActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) { 211 var base string 212 for i := 1; i <= 10; i++ { 213 if _, err := CreateSnapshot(ctx, snapshots.KindActive, "tmp", base); err != nil { 214 b.Fatalf("create active failed: %+v", err) 215 } 216 base = fmt.Sprintf("base-%d", i) 217 if _, err := CommitActive(ctx, "tmp", base, snapshots.Usage{}); err != nil { 218 b.Fatalf("commit failed: %+v", err) 219 } 220 221 } 222 223 if _, err := CreateSnapshot(ctx, snapshots.KindActive, "active", base); err != nil { 224 b.Fatalf("create active failed: %+v", err) 225 } 226 b.ResetTimer() 227 228 for i := 0; i < b.N; i++ { 229 if _, err := GetSnapshot(ctx, "active"); err != nil { 230 b.Fatal(err) 231 } 232 } 233 }