diff --git a/libcontainer/integration/bench_test.go b/libcontainer/integration/bench_test.go index da95b20b0..841d3aa06 100644 --- a/libcontainer/integration/bench_test.go +++ b/libcontainer/integration/bench_test.go @@ -1,7 +1,10 @@ package integration import ( + "bytes" + "math/rand" "os" + "strings" "testing" "github.com/opencontainers/runc/libcontainer" @@ -27,9 +30,7 @@ func BenchmarkExecTrue(b *testing.B) { _ = stdinR.Close() defer func() { _ = stdinW.Close() - if _, err := process.Wait(); err != nil { - b.Log(err) - } + waitProcess(process, b) }() ok(b, err) @@ -42,10 +43,81 @@ func BenchmarkExecTrue(b *testing.B) { LogLevel: "0", // Minimize forwardChildLogs involvement. } err := container.Run(exec) - if err != nil { - b.Fatal("exec failed:", err) - } + ok(b, err) waitProcess(exec, b) } b.StopTimer() } + +func genBigEnv(count int) []string { + randStr := func(length int) string { + const charset = "abcdefghijklmnopqrstuvwxyz0123456789_" + b := make([]byte, length) + for i := range b { + b[i] = charset[rand.Intn(len(charset))] + } + return string(b) + } + + envs := make([]string, count) + for i := 0; i < count; i++ { + key := strings.ToUpper(randStr(10)) + value := randStr(20) + envs[i] = key + "=" + value + } + + return envs +} + +func BenchmarkExecInBigEnv(b *testing.B) { + config := newTemplateConfig(b, nil) + container, err := newContainer(b, config) + ok(b, err) + defer destroyContainer(container) + + // Execute a first process in the container + stdinR, stdinW, err := os.Pipe() + ok(b, err) + process := &libcontainer.Process{ + Cwd: "/", + Args: []string{"cat"}, + Env: standardEnvironment, + Stdin: stdinR, + Init: true, + } + err = container.Run(process) + _ = stdinR.Close() + defer func() { + _ = stdinW.Close() + waitProcess(process, b) + }() + ok(b, err) + + const numEnv = 5000 + env := append(standardEnvironment, genBigEnv(numEnv)...) + // Construct the expected output. + var wantOut bytes.Buffer + for _, e := range env { + wantOut.WriteString(e + "\n") + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + buffers := newStdBuffers() + exec := &libcontainer.Process{ + Cwd: "/", + Args: []string{"env"}, + Env: env, + Stdin: buffers.Stdin, + Stdout: buffers.Stdout, + Stderr: buffers.Stderr, + } + err = container.Run(exec) + ok(b, err) + waitProcess(exec, b) + if !bytes.Equal(buffers.Stdout.Bytes(), wantOut.Bytes()) { + b.Fatalf("unexpected output: %s (stderr: %s)", buffers.Stdout, buffers.Stderr) + } + } + b.StopTimer() +}