2017-03-16 06:20:04 +00:00
|
|
|
package testsuite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/docker/containerd/snapshot/storage"
|
|
|
|
)
|
|
|
|
|
2017-03-22 06:16:39 +00:00
|
|
|
// Benchmarks returns a benchmark suite using the provided metadata store
|
|
|
|
// creation method
|
2017-03-16 06:20:04 +00:00
|
|
|
func Benchmarks(b *testing.B, name string, metaFn func(context.Context, string) (storage.MetaStore, error)) {
|
|
|
|
b.Run("StatActive", makeBench(b, name, metaFn, statActiveBenchmark))
|
|
|
|
b.Run("StatCommitted", makeBench(b, name, metaFn, statCommittedBenchmark))
|
|
|
|
b.Run("CreateActive", makeBench(b, name, metaFn, createActiveBenchmark))
|
|
|
|
b.Run("Remove", makeBench(b, name, metaFn, removeBenchmark))
|
|
|
|
b.Run("Commit", makeBench(b, name, metaFn, commitBenchmark))
|
|
|
|
b.Run("GetActive", makeBench(b, name, metaFn, getActiveBenchmark))
|
|
|
|
b.Run("WriteTransaction", openCloseWritable(b, name, metaFn))
|
|
|
|
b.Run("ReadTransaction", openCloseReadonly(b, name, metaFn))
|
|
|
|
}
|
|
|
|
|
|
|
|
// makeBench creates a benchmark with a writable transaction
|
|
|
|
func makeBench(b *testing.B, name string, metaFn func(context.Context, string) (storage.MetaStore, error), fn func(context.Context, *testing.B, storage.MetaStore)) func(b *testing.B) {
|
|
|
|
return func(b *testing.B) {
|
|
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := ioutil.TempDir("", "metastore-bench-"+name+"-")
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
|
|
|
ms, err := metaFn(ctx, tmpDir)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, t, err := ms.TransactionContext(ctx, true)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
defer t.Commit()
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
fn(ctx, b, ms)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func openCloseWritable(b *testing.B, name string, metaFn func(context.Context, string) (storage.MetaStore, error)) func(b *testing.B) {
|
|
|
|
return func(b *testing.B) {
|
|
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := ioutil.TempDir("", "metastore-bench-"+name+"-")
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
|
|
|
ms, err := metaFn(ctx, tmpDir)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
_, t, err := ms.TransactionContext(ctx, true)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := t.Commit(); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func openCloseReadonly(b *testing.B, name string, metaFn func(context.Context, string) (storage.MetaStore, error)) func(b *testing.B) {
|
|
|
|
return func(b *testing.B) {
|
|
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := ioutil.TempDir("", "metastore-bench-"+name+"-")
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
|
|
|
ms, err := metaFn(ctx, tmpDir)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
_, t, err := ms.TransactionContext(ctx, false)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := t.Rollback(); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createActiveFromBase(ctx context.Context, ms storage.MetaStore, active, base string) error {
|
|
|
|
if _, err := ms.CreateActive(ctx, "bottom", "", false); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, err := ms.Commit(ctx, "bottom", base); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := ms.CreateActive(ctx, active, base, false)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func statActiveBenchmark(ctx context.Context, b *testing.B, ms storage.MetaStore) {
|
|
|
|
if err := createActiveFromBase(ctx, ms, "active", "base"); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
_, err := ms.Stat(ctx, "active")
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func statCommittedBenchmark(ctx context.Context, b *testing.B, ms storage.MetaStore) {
|
|
|
|
if err := createActiveFromBase(ctx, ms, "active", "base"); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
if _, err := ms.Commit(ctx, "active", "committed"); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
_, err := ms.Stat(ctx, "committed")
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createActiveBenchmark(ctx context.Context, b *testing.B, ms storage.MetaStore) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if _, err := ms.CreateActive(ctx, "active", "", false); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.StopTimer()
|
2017-03-16 17:05:46 +00:00
|
|
|
if _, _, err := ms.Remove(ctx, "active"); err != nil {
|
2017-03-16 06:20:04 +00:00
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.StartTimer()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func removeBenchmark(ctx context.Context, b *testing.B, ms storage.MetaStore) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
b.StopTimer()
|
|
|
|
if _, err := ms.CreateActive(ctx, "active", "", false); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.StartTimer()
|
2017-03-16 17:05:46 +00:00
|
|
|
if _, _, err := ms.Remove(ctx, "active"); err != nil {
|
2017-03-16 06:20:04 +00:00
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func commitBenchmark(ctx context.Context, b *testing.B, ms storage.MetaStore) {
|
|
|
|
b.StopTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if _, err := ms.CreateActive(ctx, "active", "", false); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.StartTimer()
|
|
|
|
if _, err := ms.Commit(ctx, "active", "committed"); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.StopTimer()
|
2017-03-16 17:05:46 +00:00
|
|
|
if _, _, err := ms.Remove(ctx, "committed"); err != nil {
|
2017-03-16 06:20:04 +00:00
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func getActiveBenchmark(ctx context.Context, b *testing.B, ms storage.MetaStore) {
|
|
|
|
var base string
|
|
|
|
for i := 1; i <= 10; i++ {
|
|
|
|
if _, err := ms.CreateActive(ctx, "tmp", base, false); err != nil {
|
|
|
|
b.Fatalf("create active failed: %+v", err)
|
|
|
|
}
|
|
|
|
base = fmt.Sprintf("base-%d", i)
|
|
|
|
if _, err := ms.Commit(ctx, "tmp", base); err != nil {
|
|
|
|
b.Fatalf("commit failed: %+v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := ms.CreateActive(ctx, "active", base, false); err != nil {
|
|
|
|
b.Fatalf("create active failed: %+v", err)
|
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
if _, err := ms.GetActive(ctx, "active"); err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|