gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/base/base.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 base holds utility methods common to the base tests. 16 package base 17 18 import ( 19 "context" 20 "fmt" 21 "testing" 22 "time" 23 24 "gvisor.dev/gvisor/pkg/test/dockerutil" 25 "gvisor.dev/gvisor/test/benchmarks/harness" 26 ) 27 28 // ServerArgs wraps args for startServers and runServerWorkload. 29 type ServerArgs struct { 30 Machine harness.Machine 31 Port int 32 RunOpts dockerutil.RunOpts 33 Cmd []string 34 } 35 36 // StartServers starts b.N containers defined by 'runOpts' and 'cmd' and uses 37 // 'machine' to check that each is up. 38 func StartServers(ctx context.Context, b *testing.B, args ServerArgs) []*dockerutil.Container { 39 b.Helper() 40 servers := make([]*dockerutil.Container, 0, b.N) 41 42 // Create N servers and wait until each of them is serving. 43 for i := 0; i < b.N; i++ { 44 server, err := StartServer(ctx, b, args) 45 if err != nil { 46 CleanUpContainers(ctx, servers) 47 b.Fatalf("failed to start server: %v", err) 48 } 49 servers = append(servers, server) 50 } 51 return servers 52 } 53 54 // StartServer starts a single server and cleans it up if it fails. 55 func StartServer(ctx context.Context, b *testing.B, args ServerArgs) (*dockerutil.Container, error) { 56 server := args.Machine.GetContainer(ctx, b) 57 if err := server.Spawn(ctx, args.RunOpts, args.Cmd...); err != nil { 58 server.CleanUp(ctx) 59 return server, fmt.Errorf("failed to spawn server: %v", err) 60 } 61 // Wait until server is running. 62 if err := harness.WaitUntilContainerServing(ctx, args.Machine, server, args.Port); err != nil { 63 server.CleanUp(ctx) 64 return server, fmt.Errorf("failed to wait for serving server %q: %v", server.Name, err) 65 } 66 return server, nil 67 } 68 69 // CleanUpContainers cleans up a slice of containers. 70 func CleanUpContainers(ctx context.Context, containers []*dockerutil.Container) { 71 for _, c := range containers { 72 if c != nil { 73 c.CleanUp(ctx) 74 } 75 } 76 } 77 78 // RedisInstance returns a Redis container and its reachable IP. 79 func RedisInstance(ctx context.Context, b *testing.B, machine harness.Machine) *dockerutil.Container { 80 b.Helper() 81 // Spawn a redis instance for the app to use. 82 redis := machine.GetNativeContainer(ctx, b) 83 if err := redis.Spawn(ctx, dockerutil.RunOpts{ 84 Image: "benchmarks/redis", 85 }); err != nil { 86 redis.CleanUp(ctx) 87 b.Fatalf("failed to spawn redis instance: %v", err) 88 } 89 90 if out, err := redis.WaitForOutput(ctx, "Ready to accept connections", 3*time.Second); err != nil { 91 redis.CleanUp(ctx) 92 b.Fatalf("failed to start redis server: %v %s", err, out) 93 } 94 return redis 95 }