github.com/containerd/containerd@v22.0.0-20200918172823-438c87b8e050+incompatible/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  }