summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD7
-rw-r--r--test/benchmarks/base/BUILD40
-rw-r--r--test/benchmarks/base/base.go81
-rw-r--r--test/benchmarks/base/size_test.go92
-rw-r--r--test/benchmarks/base/startup_test.go68
-rw-r--r--test/benchmarks/base/sysbench_test.go5
-rw-r--r--test/benchmarks/fs/BUILD32
-rw-r--r--test/benchmarks/fs/bazel_test.go11
-rw-r--r--test/benchmarks/fs/fio_test.go11
-rw-r--r--test/benchmarks/fs/fs.go31
-rw-r--r--test/benchmarks/harness/harness.go14
11 files changed, 213 insertions, 179 deletions
diff --git a/BUILD b/BUILD
index a133f16e9..0791f9fb4 100644
--- a/BUILD
+++ b/BUILD
@@ -64,9 +64,12 @@ build_test(
"//test/e2e:integration_test",
"//test/image:image_test",
"//test/root:root_test",
- "//test/benchmarks/base:base_test",
+ "//test/benchmarks/base:startup_test",
+ "//test/benchmarks/base:size_test",
+ "//test/benchmarks/base:sysbench_test",
"//test/benchmarks/database:database_test",
- "//test/benchmarks/fs:fs_test",
+ "//test/benchmarks/fs:bazel_test",
+ "//test/benchmarks/fs:fio_test",
"//test/benchmarks/media:media_test",
"//test/benchmarks/ml:ml_test",
"//test/benchmarks/network:network_test",
diff --git a/test/benchmarks/base/BUILD b/test/benchmarks/base/BUILD
index 7dfd4b693..b4b55317b 100644
--- a/test/benchmarks/base/BUILD
+++ b/test/benchmarks/base/BUILD
@@ -8,23 +8,41 @@ go_library(
srcs = [
"base.go",
],
- deps = ["//test/benchmarks/harness"],
+ deps = [
+ "//pkg/test/dockerutil",
+ "//test/benchmarks/harness",
+ ],
)
go_test(
- name = "base_test",
+ name = "startup_test",
size = "enormous",
- srcs = [
- "size_test.go",
- "startup_test.go",
- "sysbench_test.go",
+ srcs = ["startup_test.go"],
+ visibility = ["//:sandbox"],
+ deps = [
+ "//pkg/test/dockerutil",
+ "//test/benchmarks/base",
+ "//test/benchmarks/harness",
],
- library = ":base",
- tags = [
- # Requires docker and runsc to be configured before test runs.
- "manual",
- "local",
+)
+
+go_test(
+ name = "size_test",
+ size = "enormous",
+ srcs = ["size_test.go"],
+ visibility = ["//:sandbox"],
+ deps = [
+ "//pkg/test/dockerutil",
+ "//test/benchmarks/base",
+ "//test/benchmarks/harness",
+ "//test/benchmarks/tools",
],
+)
+
+go_test(
+ name = "sysbench_test",
+ size = "enormous",
+ srcs = ["sysbench_test.go"],
visibility = ["//:sandbox"],
deps = [
"//pkg/test/dockerutil",
diff --git a/test/benchmarks/base/base.go b/test/benchmarks/base/base.go
index 7bac52ff1..979564af9 100644
--- a/test/benchmarks/base/base.go
+++ b/test/benchmarks/base/base.go
@@ -12,20 +12,87 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package base holds base performance benchmarks.
+// Package base holds utility methods common to the base tests.
package base
import (
- "os"
+ "context"
+ "net"
"testing"
+ "time"
+ "gvisor.dev/gvisor/pkg/test/dockerutil"
"gvisor.dev/gvisor/test/benchmarks/harness"
)
-var testHarness harness.Harness
+// ServerArgs wraps args for startServers and runServerWorkload.
+type ServerArgs struct {
+ Machine harness.Machine
+ Port int
+ RunOpts dockerutil.RunOpts
+ Cmd []string
+}
+
+// StartServers starts b.N containers defined by 'runOpts' and 'cmd' and uses
+// 'machine' to check that each is up.
+func StartServers(ctx context.Context, b *testing.B, args ServerArgs) []*dockerutil.Container {
+ b.Helper()
+ servers := make([]*dockerutil.Container, 0, b.N)
+
+ // Create N servers and wait until each of them is serving.
+ for i := 0; i < b.N; i++ {
+ server := args.Machine.GetContainer(ctx, b)
+ servers = append(servers, server)
+ if err := server.Spawn(ctx, args.RunOpts, args.Cmd...); err != nil {
+ CleanUpContainers(ctx, servers)
+ b.Fatalf("failed to spawn node instance: %v", err)
+ }
+
+ // Get the container IP.
+ servingIP, err := server.FindIP(ctx, false)
+ if err != nil {
+ CleanUpContainers(ctx, servers)
+ b.Fatalf("failed to get ip from server: %v", err)
+ }
+
+ // Wait until the server is up.
+ if err := harness.WaitUntilServing(ctx, args.Machine, servingIP, args.Port); err != nil {
+ CleanUpContainers(ctx, servers)
+ b.Fatalf("failed to wait for serving")
+ }
+ }
+ return servers
+}
+
+// CleanUpContainers cleans up a slice of containers.
+func CleanUpContainers(ctx context.Context, containers []*dockerutil.Container) {
+ for _, c := range containers {
+ if c != nil {
+ c.CleanUp(ctx)
+ }
+ }
+}
+
+// RedisInstance returns a Redis container and its reachable IP.
+func RedisInstance(ctx context.Context, b *testing.B, machine harness.Machine) (*dockerutil.Container, net.IP) {
+ b.Helper()
+ // Spawn a redis instance for the app to use.
+ redis := machine.GetNativeContainer(ctx, b)
+ if err := redis.Spawn(ctx, dockerutil.RunOpts{
+ Image: "benchmarks/redis",
+ }); err != nil {
+ redis.CleanUp(ctx)
+ b.Fatalf("failed to spwan redis instance: %v", err)
+ }
-// TestMain is the main method for package network.
-func TestMain(m *testing.M) {
- testHarness.Init()
- os.Exit(m.Run())
+ if out, err := redis.WaitForOutput(ctx, "Ready to accept connections", 3*time.Second); err != nil {
+ redis.CleanUp(ctx)
+ b.Fatalf("failed to start redis server: %v %s", err, out)
+ }
+ redisIP, err := redis.FindIP(ctx, false)
+ if err != nil {
+ redis.CleanUp(ctx)
+ b.Fatalf("failed to get IP from redis instance: %v", err)
+ }
+ return redis, redisIP
}
diff --git a/test/benchmarks/base/size_test.go b/test/benchmarks/base/size_test.go
index 7d3877459..acc49cc7c 100644
--- a/test/benchmarks/base/size_test.go
+++ b/test/benchmarks/base/size_test.go
@@ -12,18 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package base
+package size_test
import (
"context"
+ "os"
"testing"
"time"
"gvisor.dev/gvisor/pkg/test/dockerutil"
+ "gvisor.dev/gvisor/test/benchmarks/base"
"gvisor.dev/gvisor/test/benchmarks/harness"
"gvisor.dev/gvisor/test/benchmarks/tools"
)
+var testHarness harness.Harness
+
// BenchmarkSizeEmpty creates N empty containers and reads memory usage from
// /proc/meminfo.
func BenchmarkSizeEmpty(b *testing.B) {
@@ -53,11 +57,11 @@ func BenchmarkSizeEmpty(b *testing.B) {
if err := container.Spawn(ctx, dockerutil.RunOpts{
Image: "benchmarks/alpine",
}, "sh", "-c", "echo Hello && sleep 1000"); err != nil {
- cleanUpContainers(ctx, containers)
+ base.CleanUpContainers(ctx, containers)
b.Fatalf("failed to run container: %v", err)
}
if _, err := container.WaitForOutputSubmatch(ctx, "Hello", 5*time.Second); err != nil {
- cleanUpContainers(ctx, containers)
+ base.CleanUpContainers(ctx, containers)
b.Fatalf("failed to read container output: %v", err)
}
}
@@ -67,7 +71,7 @@ func BenchmarkSizeEmpty(b *testing.B) {
// Check available memory after containers are up.
after, err := machine.RunCommand(cmd, args...)
- cleanUpContainers(ctx, containers)
+ base.CleanUpContainers(ctx, containers)
if err != nil {
b.Fatalf("failed to get meminfo: %v", err)
}
@@ -100,14 +104,14 @@ func BenchmarkSizeNginx(b *testing.B) {
Image: "benchmarks/nginx",
}
const port = 80
- servers := startServers(ctx, b,
- serverArgs{
- machine: machine,
- port: port,
- runOpts: runOpts,
- cmd: []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"},
+ servers := base.StartServers(ctx, b,
+ base.ServerArgs{
+ Machine: machine,
+ Port: port,
+ RunOpts: runOpts,
+ Cmd: []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"},
})
- defer cleanUpContainers(ctx, servers)
+ defer base.CleanUpContainers(ctx, servers)
// DropCaches after servers are created.
harness.DropCaches(machine)
@@ -130,7 +134,7 @@ func BenchmarkSizeNode(b *testing.B) {
// Make a redis instance for Node to connect.
ctx := context.Background()
- redis, redisIP := redisInstance(ctx, b, machine)
+ redis, redisIP := base.RedisInstance(ctx, b, machine)
defer redis.CleanUp(ctx)
// DropCaches after redis is created.
@@ -152,14 +156,14 @@ func BenchmarkSizeNode(b *testing.B) {
}
nodeCmd := []string{"node", "index.js", redisIP.String()}
const port = 8080
- servers := startServers(ctx, b,
- serverArgs{
- machine: machine,
- port: port,
- runOpts: runOpts,
- cmd: nodeCmd,
+ servers := base.StartServers(ctx, b,
+ base.ServerArgs{
+ Machine: machine,
+ Port: port,
+ RunOpts: runOpts,
+ Cmd: nodeCmd,
})
- defer cleanUpContainers(ctx, servers)
+ defer base.CleanUpContainers(ctx, servers)
// DropCaches after servers are created.
harness.DropCaches(machine)
@@ -172,50 +176,8 @@ func BenchmarkSizeNode(b *testing.B) {
meminfo.Report(b, before, after)
}
-// serverArgs wraps args for startServers and runServerWorkload.
-type serverArgs struct {
- machine harness.Machine
- port int
- runOpts dockerutil.RunOpts
- cmd []string
-}
-
-// startServers starts b.N containers defined by 'runOpts' and 'cmd' and uses
-// 'machine' to check that each is up.
-func startServers(ctx context.Context, b *testing.B, args serverArgs) []*dockerutil.Container {
- b.Helper()
- servers := make([]*dockerutil.Container, 0, b.N)
-
- // Create N servers and wait until each of them is serving.
- for i := 0; i < b.N; i++ {
- server := args.machine.GetContainer(ctx, b)
- servers = append(servers, server)
- if err := server.Spawn(ctx, args.runOpts, args.cmd...); err != nil {
- cleanUpContainers(ctx, servers)
- b.Fatalf("failed to spawn node instance: %v", err)
- }
-
- // Get the container IP.
- servingIP, err := server.FindIP(ctx, false)
- if err != nil {
- cleanUpContainers(ctx, servers)
- b.Fatalf("failed to get ip from server: %v", err)
- }
-
- // Wait until the server is up.
- if err := harness.WaitUntilServing(ctx, args.machine, servingIP, args.port); err != nil {
- cleanUpContainers(ctx, servers)
- b.Fatalf("failed to wait for serving")
- }
- }
- return servers
-}
-
-// cleanUpContainers cleans up a slice of containers.
-func cleanUpContainers(ctx context.Context, containers []*dockerutil.Container) {
- for _, c := range containers {
- if c != nil {
- c.CleanUp(ctx)
- }
- }
+// TestMain is the main method for package network.
+func TestMain(m *testing.M) {
+ testHarness.Init()
+ os.Exit(m.Run())
}
diff --git a/test/benchmarks/base/startup_test.go b/test/benchmarks/base/startup_test.go
index c36a544db..28731f97a 100644
--- a/test/benchmarks/base/startup_test.go
+++ b/test/benchmarks/base/startup_test.go
@@ -12,19 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package base
+package startup_test
import (
"context"
"fmt"
- "net"
+ "os"
"testing"
- "time"
"gvisor.dev/gvisor/pkg/test/dockerutil"
+ "gvisor.dev/gvisor/test/benchmarks/base"
"gvisor.dev/gvisor/test/benchmarks/harness"
)
+var testHarness harness.Harness
+
// BenchmarkStartEmpty times startup time for an empty container.
func BenchmarkStartupEmpty(b *testing.B) {
machine, err := testHarness.GetMachine()
@@ -60,11 +62,11 @@ func BenchmarkStartupNginx(b *testing.B) {
Image: "benchmarks/nginx",
}
runServerWorkload(ctx, b,
- serverArgs{
- machine: machine,
- runOpts: runOpts,
- port: 80,
- cmd: []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"},
+ base.ServerArgs{
+ Machine: machine,
+ RunOpts: runOpts,
+ Port: 80,
+ Cmd: []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"},
})
}
@@ -79,7 +81,7 @@ func BenchmarkStartupNode(b *testing.B) {
defer machine.CleanUp()
ctx := context.Background()
- redis, redisIP := redisInstance(ctx, b, machine)
+ redis, redisIP := base.RedisInstance(ctx, b, machine)
defer redis.CleanUp(ctx)
runOpts := dockerutil.RunOpts{
Image: "benchmarks/node",
@@ -89,52 +91,28 @@ func BenchmarkStartupNode(b *testing.B) {
cmd := []string{"node", "index.js", redisIP.String()}
runServerWorkload(ctx, b,
- serverArgs{
- machine: machine,
- port: 8080,
- runOpts: runOpts,
- cmd: cmd,
+ base.ServerArgs{
+ Machine: machine,
+ Port: 8080,
+ RunOpts: runOpts,
+ Cmd: cmd,
})
}
-// redisInstance returns a Redis container and its reachable IP.
-func redisInstance(ctx context.Context, b *testing.B, machine harness.Machine) (*dockerutil.Container, net.IP) {
- b.Helper()
- // Spawn a redis instance for the app to use.
- redis := machine.GetNativeContainer(ctx, b)
- if err := redis.Spawn(ctx, dockerutil.RunOpts{
- Image: "benchmarks/redis",
- }); err != nil {
- redis.CleanUp(ctx)
- b.Fatalf("failed to spwan redis instance: %v", err)
- }
-
- if out, err := redis.WaitForOutput(ctx, "Ready to accept connections", 3*time.Second); err != nil {
- redis.CleanUp(ctx)
- b.Fatalf("failed to start redis server: %v %s", err, out)
- }
- redisIP, err := redis.FindIP(ctx, false)
- if err != nil {
- redis.CleanUp(ctx)
- b.Fatalf("failed to get IP from redis instance: %v", err)
- }
- return redis, redisIP
-}
-
// runServerWorkload runs a server workload defined by 'runOpts' and 'cmd'.
// 'clientMachine' is used to connect to the server on 'serverMachine'.
-func runServerWorkload(ctx context.Context, b *testing.B, args serverArgs) {
+func runServerWorkload(ctx context.Context, b *testing.B, args base.ServerArgs) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := func() error {
- server := args.machine.GetContainer(ctx, b)
+ server := args.Machine.GetContainer(ctx, b)
defer func() {
b.StopTimer()
// Cleanup servers as we run so that we can go indefinitely.
server.CleanUp(ctx)
b.StartTimer()
}()
- if err := server.Spawn(ctx, args.runOpts, args.cmd...); err != nil {
+ if err := server.Spawn(ctx, args.RunOpts, args.Cmd...); err != nil {
return fmt.Errorf("failed to spawn node instance: %v", err)
}
@@ -144,7 +122,7 @@ func runServerWorkload(ctx context.Context, b *testing.B, args serverArgs) {
}
// Wait until the Client sees the server as up.
- if err := harness.WaitUntilServing(ctx, args.machine, servingIP, args.port); err != nil {
+ if err := harness.WaitUntilServing(ctx, args.Machine, servingIP, args.Port); err != nil {
return fmt.Errorf("failed to wait for serving: %v", err)
}
return nil
@@ -153,3 +131,9 @@ func runServerWorkload(ctx context.Context, b *testing.B, args serverArgs) {
}
}
}
+
+// TestMain is the main method for package network.
+func TestMain(m *testing.M) {
+ testHarness.Init()
+ os.Exit(m.Run())
+}
diff --git a/test/benchmarks/base/sysbench_test.go b/test/benchmarks/base/sysbench_test.go
index 39ced3dab..bbb797e14 100644
--- a/test/benchmarks/base/sysbench_test.go
+++ b/test/benchmarks/base/sysbench_test.go
@@ -12,16 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package base
+package sysbench_test
import (
"context"
"testing"
"gvisor.dev/gvisor/pkg/test/dockerutil"
+ "gvisor.dev/gvisor/test/benchmarks/harness"
"gvisor.dev/gvisor/test/benchmarks/tools"
)
+var testHarness harness.Harness
+
type testCase struct {
name string
test tools.Sysbench
diff --git a/test/benchmarks/fs/BUILD b/test/benchmarks/fs/BUILD
index 45f11372b..021fae38d 100644
--- a/test/benchmarks/fs/BUILD
+++ b/test/benchmarks/fs/BUILD
@@ -1,27 +1,23 @@
-load("//tools:defs.bzl", "go_library", "go_test")
+load("//tools:defs.bzl", "go_test")
package(licenses = ["notice"])
-go_library(
- name = "fs",
- testonly = 1,
- srcs = ["fs.go"],
- deps = ["//test/benchmarks/harness"],
+go_test(
+ name = "bazel_test",
+ size = "enormous",
+ srcs = ["bazel_test.go"],
+ visibility = ["//:sandbox"],
+ deps = [
+ "//pkg/test/dockerutil",
+ "//test/benchmarks/harness",
+ "//test/benchmarks/tools",
+ ],
)
go_test(
- name = "fs_test",
- size = "large",
- srcs = [
- "bazel_test.go",
- "fio_test.go",
- ],
- library = ":fs",
- tags = [
- # Requires docker and runsc to be configured before test runs.
- "local",
- "manual",
- ],
+ name = "fio_test",
+ size = "enormous",
+ srcs = ["fio_test.go"],
visibility = ["//:sandbox"],
deps = [
"//pkg/test/dockerutil",
diff --git a/test/benchmarks/fs/bazel_test.go b/test/benchmarks/fs/bazel_test.go
index 56103639d..53ed3f9f2 100644
--- a/test/benchmarks/fs/bazel_test.go
+++ b/test/benchmarks/fs/bazel_test.go
@@ -11,11 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-package fs
+package bazel_test
import (
"context"
"fmt"
+ "os"
"strings"
"testing"
@@ -24,6 +25,8 @@ import (
"gvisor.dev/gvisor/test/benchmarks/tools"
)
+var h harness.Harness
+
// Note: CleanCache versions of this test require running with root permissions.
func BenchmarkBuildABSL(b *testing.B) {
runBuildBenchmark(b, "benchmarks/absl", "/abseil-cpp", "absl/base/...")
@@ -138,3 +141,9 @@ func runBuildBenchmark(b *testing.B, image, workdir, target string) {
})
}
}
+
+// TestMain is the main method for package fs.
+func TestMain(m *testing.M) {
+ h.Init()
+ os.Exit(m.Run())
+}
diff --git a/test/benchmarks/fs/fio_test.go b/test/benchmarks/fs/fio_test.go
index 5ca191404..96340373c 100644
--- a/test/benchmarks/fs/fio_test.go
+++ b/test/benchmarks/fs/fio_test.go
@@ -11,11 +11,12 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-package fs
+package fio_test
import (
"context"
"fmt"
+ "os"
"path/filepath"
"strings"
"testing"
@@ -26,6 +27,8 @@ import (
"gvisor.dev/gvisor/test/benchmarks/tools"
)
+var h harness.Harness
+
// BenchmarkFio runs fio on the runtime under test. There are 4 basic test
// cases each run on a tmpfs mount and a bind mount. Fio requires root so that
// caches can be dropped.
@@ -179,3 +182,9 @@ func makeMount(machine harness.Machine, mountType mount.Type, target string) (mo
return mount.Mount{}, func() {}, fmt.Errorf("illegal mount time not supported: %v", mountType)
}
}
+
+// TestMain is the main method for package fs.
+func TestMain(m *testing.M) {
+ h.Init()
+ os.Exit(m.Run())
+}
diff --git a/test/benchmarks/fs/fs.go b/test/benchmarks/fs/fs.go
deleted file mode 100644
index e5ca28c3b..000000000
--- a/test/benchmarks/fs/fs.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package fs holds benchmarks around filesystem performance.
-package fs
-
-import (
- "os"
- "testing"
-
- "gvisor.dev/gvisor/test/benchmarks/harness"
-)
-
-var h harness.Harness
-
-// TestMain is the main method for package fs.
-func TestMain(m *testing.M) {
- h.Init()
- os.Exit(m.Run())
-}
diff --git a/test/benchmarks/harness/harness.go b/test/benchmarks/harness/harness.go
index 68bd7b4cf..e14cce987 100644
--- a/test/benchmarks/harness/harness.go
+++ b/test/benchmarks/harness/harness.go
@@ -17,17 +17,31 @@ package harness
import (
"flag"
+ "fmt"
+ "os"
"gvisor.dev/gvisor/pkg/test/dockerutil"
)
+var (
+ help = flag.Bool("help", false, "print this usage message")
+)
+
// Harness is a handle for managing state in benchmark runs.
type Harness struct {
}
// Init performs any harness initilialization before runs.
func (h *Harness) Init() error {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage: %s -- --test.bench=<regex>\n", os.Args[0])
+ flag.PrintDefaults()
+ }
flag.Parse()
+ if flag.NFlag() == 0 || *help {
+ flag.Usage()
+ os.Exit(0)
+ }
dockerutil.EnsureSupportedDockerVersion()
return nil
}