gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/base/startup_test.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package startup_test 16 17 import ( 18 "context" 19 "fmt" 20 "os" 21 "testing" 22 23 "gvisor.dev/gvisor/pkg/test/dockerutil" 24 "gvisor.dev/gvisor/test/benchmarks/base" 25 "gvisor.dev/gvisor/test/benchmarks/harness" 26 "gvisor.dev/gvisor/test/metricsviz" 27 ) 28 29 // BenchmarkStartEmpty times startup time for an empty container. 30 func BenchmarkStartupEmpty(b *testing.B) { 31 machine, err := harness.GetMachine() 32 if err != nil { 33 b.Fatalf("failed to get machine: %v", err) 34 } 35 defer machine.CleanUp() 36 37 ctx := context.Background() 38 b.StopTimer() 39 b.ResetTimer() 40 for i := 0; i < b.N; i++ { 41 harness.DebugLog(b, "Running container: %d", i) 42 container := machine.GetContainer(ctx, b) 43 b.StartTimer() 44 if err := container.Spawn(ctx, dockerutil.RunOpts{ 45 Image: "benchmarks/alpine", 46 }, "sleep", "100"); err != nil { 47 b.Fatalf("failed to start container: %v", err) 48 } 49 b.StopTimer() 50 if i == 0 { 51 metricsviz.FromContainerLogs(ctx, b, container) 52 } 53 container.CleanUp(ctx) 54 harness.DebugLog(b, "Ran container: %d", i) 55 } 56 } 57 58 // BenchmarkStartupNginx times startup for a Nginx instance. 59 // Time is measured from start until the first request is served. 60 func BenchmarkStartupNginx(b *testing.B) { 61 // The machine to hold Nginx and the Node Server. 62 machine, err := harness.GetMachine() 63 if err != nil { 64 b.Fatalf("failed to get machine with: %v", err) 65 } 66 defer machine.CleanUp() 67 68 ctx := context.Background() 69 runOpts := dockerutil.RunOpts{ 70 Image: "benchmarks/nginx", 71 } 72 runServerWorkload(ctx, b, 73 base.ServerArgs{ 74 Machine: machine, 75 RunOpts: runOpts, 76 Port: 80, 77 Cmd: []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"}, 78 }) 79 } 80 81 // BenchmarkStartupNode times startup for a Node application instance. 82 // Time is measured from start until the first request is served. 83 // Note that the Node app connects to a Redis instance before serving. 84 func BenchmarkStartupNode(b *testing.B) { 85 machine, err := harness.GetMachine() 86 if err != nil { 87 b.Fatalf("failed to get machine with: %v", err) 88 } 89 defer machine.CleanUp() 90 91 ctx := context.Background() 92 redis := base.RedisInstance(ctx, b, machine) 93 defer redis.CleanUp(ctx) 94 runOpts := dockerutil.RunOpts{ 95 Image: "benchmarks/node", 96 WorkDir: "/usr/src/app", 97 Links: []string{redis.MakeLink("redis")}, 98 } 99 100 cmd := []string{"node", "index.js", "redis"} 101 runServerWorkload(ctx, b, 102 base.ServerArgs{ 103 Machine: machine, 104 Port: 8080, 105 RunOpts: runOpts, 106 Cmd: cmd, 107 }) 108 } 109 110 // runServerWorkload runs a server workload defined by 'runOpts' and 'cmd'. 111 // 'clientMachine' is used to connect to the server on 'serverMachine'. 112 func runServerWorkload(ctx context.Context, b *testing.B, args base.ServerArgs) { 113 b.ResetTimer() 114 for i := 0; i < b.N; i++ { 115 harness.DebugLog(b, "Running iteration: %d", i) 116 if err := func() error { 117 server := args.Machine.GetContainer(ctx, b) 118 defer func() { 119 b.StopTimer() 120 metricsviz.FromContainerLogs(ctx, b, server) 121 // Cleanup servers as we run so that we can go indefinitely. 122 server.CleanUp(ctx) 123 b.StartTimer() 124 }() 125 harness.DebugLog(b, "Spawning container: %s", args.RunOpts.Image) 126 if err := server.Spawn(ctx, args.RunOpts, args.Cmd...); err != nil { 127 return fmt.Errorf("failed to spawn node instance: %v", err) 128 } 129 130 // Wait until the Client sees the server as up. 131 harness.DebugLog(b, "Waiting for container to start.") 132 if err := harness.WaitUntilContainerServing(ctx, args.Machine, server, args.Port); err != nil { 133 return fmt.Errorf("failed to wait for serving: %v", err) 134 } 135 return nil 136 }(); err != nil { 137 b.Fatal(err) 138 } 139 harness.DebugLog(b, "Ran iteration: %d", i) 140 } 141 } 142 143 // TestMain is the main method for package network. 144 func TestMain(m *testing.M) { 145 harness.Init() 146 os.Exit(m.Run()) 147 }