diff --git a/engine/env_test.go b/engine/env_test.go index 39669d6780..104b0db5bf 100644 --- a/engine/env_test.go +++ b/engine/env_test.go @@ -1,7 +1,10 @@ package engine import ( + "bytes" "testing" + + "github.com/dotcloud/docker/pkg/testutils" ) func TestEnvLenZero(t *testing.T) { @@ -143,3 +146,126 @@ func TestMultiMap(t *testing.T) { t.Fatalf("%#v", v) } } + +func testMap(l int) [][2]string { + res := make([][2]string, l) + for i := 0; i < l; i++ { + t := [2]string{testutils.RandomString(5), testutils.RandomString(20)} + res[i] = t + } + return res +} + +func BenchmarkSet(b *testing.B) { + fix := testMap(100) + b.ResetTimer() + for i := 0; i < b.N; i++ { + env := &Env{} + for _, kv := range fix { + env.Set(kv[0], kv[1]) + } + } +} + +func BenchmarkSetJson(b *testing.B) { + fix := testMap(100) + type X struct { + f string + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + env := &Env{} + for _, kv := range fix { + if err := env.SetJson(kv[0], X{kv[1]}); err != nil { + b.Fatal(err) + } + } + } +} + +func BenchmarkGet(b *testing.B) { + fix := testMap(100) + env := &Env{} + for _, kv := range fix { + env.Set(kv[0], kv[1]) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, kv := range fix { + env.Get(kv[0]) + } + } +} + +func BenchmarkGetJson(b *testing.B) { + fix := testMap(100) + env := &Env{} + type X struct { + f string + } + for _, kv := range fix { + env.SetJson(kv[0], X{kv[1]}) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, kv := range fix { + if err := env.GetJson(kv[0], &X{}); err != nil { + b.Fatal(err) + } + } + } +} + +func BenchmarkEncode(b *testing.B) { + fix := testMap(100) + env := &Env{} + type X struct { + f string + } + // half a json + for i, kv := range fix { + if i%2 != 0 { + if err := env.SetJson(kv[0], X{kv[1]}); err != nil { + b.Fatal(err) + } + continue + } + env.Set(kv[0], kv[1]) + } + var writer bytes.Buffer + b.ResetTimer() + for i := 0; i < b.N; i++ { + env.Encode(&writer) + writer.Reset() + } +} + +func BenchmarkDecode(b *testing.B) { + fix := testMap(100) + env := &Env{} + type X struct { + f string + } + // half a json + for i, kv := range fix { + if i%2 != 0 { + if err := env.SetJson(kv[0], X{kv[1]}); err != nil { + b.Fatal(err) + } + continue + } + env.Set(kv[0], kv[1]) + } + var writer bytes.Buffer + env.Encode(&writer) + denv := &Env{} + reader := bytes.NewReader(writer.Bytes()) + b.ResetTimer() + for i := 0; i < b.N; i++ { + err := denv.Decode(reader) + if err != nil { + b.Fatal(err) + } + reader.Seek(0, 0) + } +} diff --git a/pkg/testutils/testutils.go b/pkg/testutils/testutils.go index 4655e5844d..9c664ff253 100644 --- a/pkg/testutils/testutils.go +++ b/pkg/testutils/testutils.go @@ -1,10 +1,15 @@ package testutils import ( + "math/rand" "testing" "time" ) +const chars = "abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` " + // Timeout calls f and waits for 100ms for it to complete. // If it doesn't, it causes the tests to fail. // t must be a valid testing context. @@ -21,3 +26,12 @@ func Timeout(t *testing.T, f func()) { case <-onDone: } } + +// RandomString returns random string of specified length +func RandomString(length int) string { + res := make([]byte, length) + for i := 0; i < length; i++ { + res[i] = chars[rand.Intn(len(chars))] + } + return string(res) +}