gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/base/size_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 size_test 16 17 import ( 18 "context" 19 "os" 20 "testing" 21 "time" 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/benchmarks/tools" 27 "gvisor.dev/gvisor/test/metricsviz" 28 ) 29 30 // BenchmarkSizeEmpty creates N empty containers and reads memory usage from 31 // /proc/meminfo. 32 func BenchmarkSizeEmpty(b *testing.B) { 33 machine, err := harness.GetMachine() 34 if err != nil { 35 b.Fatalf("failed to get machine: %v", err) 36 } 37 defer machine.CleanUp() 38 meminfo := tools.Meminfo{} 39 ctx := context.Background() 40 containers := make([]*dockerutil.Container, 0, b.N) 41 42 // DropCaches before the test. 43 harness.DropCaches(machine) 44 45 // Check available memory on 'machine'. 46 cmd, args := meminfo.MakeCmd() 47 before, err := machine.RunCommand(cmd, args...) 48 if err != nil { 49 b.Fatalf("failed to get meminfo: %v", err) 50 } 51 52 // Make N containers. 53 for i := 0; i < b.N; i++ { 54 container := machine.GetContainer(ctx, b) 55 containers = append(containers, container) 56 if err := container.Spawn(ctx, dockerutil.RunOpts{ 57 Image: "benchmarks/alpine", 58 }, "sh", "-c", "echo Hello && sleep 1000"); err != nil { 59 base.CleanUpContainers(ctx, containers) 60 b.Fatalf("failed to run container: %v", err) 61 } 62 if i == 0 { 63 defer metricsviz.FromContainerLogs(ctx, b, container) 64 } 65 if _, err := container.WaitForOutputSubmatch(ctx, "Hello", 5*time.Second); err != nil { 66 base.CleanUpContainers(ctx, containers) 67 b.Fatalf("failed to read container output: %v", err) 68 } 69 } 70 71 // Drop caches again before second measurement. 72 harness.DropCaches(machine) 73 74 // Check available memory after containers are up. 75 after, err := machine.RunCommand(cmd, args...) 76 base.CleanUpContainers(ctx, containers) 77 if err != nil { 78 b.Fatalf("failed to get meminfo: %v", err) 79 } 80 meminfo.Report(b, before, after) 81 } 82 83 // BenchmarkSizeNginx starts N containers running Nginx, checks that they're 84 // serving, and checks memory used based on /proc/meminfo. 85 func BenchmarkSizeNginx(b *testing.B) { 86 machine, err := harness.GetMachine() 87 if err != nil { 88 b.Fatalf("failed to get machine with: %v", err) 89 } 90 defer machine.CleanUp() 91 92 // DropCaches for the first measurement. 93 harness.DropCaches(machine) 94 95 // Measure MemAvailable before creating containers. 96 meminfo := tools.Meminfo{} 97 cmd, args := meminfo.MakeCmd() 98 before, err := machine.RunCommand(cmd, args...) 99 if err != nil { 100 b.Fatalf("failed to run meminfo command: %v", err) 101 } 102 103 // Make N Nginx containers. 104 ctx := context.Background() 105 runOpts := dockerutil.RunOpts{ 106 Image: "benchmarks/nginx", 107 } 108 const port = 80 109 servers := base.StartServers(ctx, b, 110 base.ServerArgs{ 111 Machine: machine, 112 Port: port, 113 RunOpts: runOpts, 114 Cmd: []string{"nginx", "-c", "/etc/nginx/nginx_gofer.conf"}, 115 }) 116 defer base.CleanUpContainers(ctx, servers) 117 if len(servers) > 0 { 118 defer metricsviz.FromContainerLogs(ctx, b, servers[0]) 119 } 120 121 // DropCaches after servers are created. 122 harness.DropCaches(machine) 123 // Take after measurement. 124 after, err := machine.RunCommand(cmd, args...) 125 if err != nil { 126 b.Fatalf("failed to run meminfo command: %v", err) 127 } 128 meminfo.Report(b, before, after) 129 } 130 131 // BenchmarkSizeNode starts N containers running a Node app, checks that 132 // they're serving, and checks memory used based on /proc/meminfo. 133 func BenchmarkSizeNode(b *testing.B) { 134 machine, err := harness.GetMachine() 135 if err != nil { 136 b.Fatalf("failed to get machine with: %v", err) 137 } 138 defer machine.CleanUp() 139 140 // Make a redis instance for Node to connect. 141 ctx := context.Background() 142 redis := base.RedisInstance(ctx, b, machine) 143 defer redis.CleanUp(ctx) 144 145 // DropCaches after redis is created. 146 harness.DropCaches(machine) 147 148 // Take before measurement. 149 meminfo := tools.Meminfo{} 150 cmd, args := meminfo.MakeCmd() 151 before, err := machine.RunCommand(cmd, args...) 152 if err != nil { 153 b.Fatalf("failed to run meminfo commend: %v", err) 154 } 155 156 // Create N Node servers. 157 runOpts := dockerutil.RunOpts{ 158 Image: "benchmarks/node", 159 WorkDir: "/usr/src/app", 160 Links: []string{redis.MakeLink("redis")}, 161 } 162 nodeCmd := []string{"node", "index.js", "redis"} 163 const port = 8080 164 servers := base.StartServers(ctx, b, 165 base.ServerArgs{ 166 Machine: machine, 167 Port: port, 168 RunOpts: runOpts, 169 Cmd: nodeCmd, 170 }) 171 defer base.CleanUpContainers(ctx, servers) 172 if len(servers) > 0 { 173 defer metricsviz.FromContainerLogs(ctx, b, servers[0]) 174 } 175 176 // DropCaches after servers are created. 177 harness.DropCaches(machine) 178 // Take after measurement. 179 cmd, args = meminfo.MakeCmd() 180 after, err := machine.RunCommand(cmd, args...) 181 if err != nil { 182 b.Fatalf("failed to run meminfo command: %v", err) 183 } 184 meminfo.Report(b, before, after) 185 } 186 187 // TestMain is the main method for package network. 188 func TestMain(m *testing.M) { 189 harness.Init() 190 os.Exit(m.Run()) 191 }