gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/network/iperf_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 package network 15 16 import ( 17 "context" 18 "fmt" 19 "os" 20 "testing" 21 "time" 22 23 "gvisor.dev/gvisor/pkg/test/dockerutil" 24 "gvisor.dev/gvisor/pkg/test/testutil" 25 "gvisor.dev/gvisor/test/benchmarks/harness" 26 "gvisor.dev/gvisor/test/benchmarks/tools" 27 "gvisor.dev/gvisor/test/metricsviz" 28 ) 29 30 func BenchmarkIperfOneConnection(b *testing.B) { 31 clientMachine, err := harness.GetMachine() 32 if err != nil { 33 b.Fatalf("failed to get machine: %v", err) 34 } 35 defer clientMachine.CleanUp() 36 37 serverMachine, err := harness.GetMachine() 38 if err != nil { 39 b.Fatalf("failed to get machine: %v", err) 40 } 41 defer serverMachine.CleanUp() 42 ctx := context.Background() 43 for _, bm := range []struct { 44 name string 45 clientFunc func(context.Context, testutil.Logger) *dockerutil.Container 46 serverFunc func(context.Context, testutil.Logger) *dockerutil.Container 47 }{ 48 // We are either measuring the server or the client. The other should be 49 // runc. e.g. Upload sees how fast the runtime under test uploads to a native 50 // server. 51 { 52 name: "Upload", 53 clientFunc: clientMachine.GetContainer, 54 serverFunc: serverMachine.GetNativeContainer, 55 }, 56 { 57 name: "Download", 58 clientFunc: clientMachine.GetNativeContainer, 59 serverFunc: serverMachine.GetContainer, 60 }, 61 } { 62 name, err := tools.ParametersToName(tools.Parameter{ 63 Name: "operation", 64 Value: bm.name, 65 }) 66 if err != nil { 67 b.Fatalf("Failed to parse parameters: %v", err) 68 } 69 b.Run(name, func(b *testing.B) { 70 // Set up the containers. 71 server := bm.serverFunc(ctx, b) 72 defer server.CleanUp(ctx) 73 defer metricsviz.FromNamedContainerLogs(ctx, b, server, "server") 74 client := bm.clientFunc(ctx, b) 75 defer client.CleanUp(ctx) 76 defer metricsviz.FromNamedContainerLogs(ctx, b, server, "client") 77 78 // iperf server listens on port 5001 by default. 79 port := 5001 80 81 // Start the server. 82 if err := server.Spawn(ctx, dockerutil.RunOpts{ 83 Image: "benchmarks/iperf", 84 Ports: []int{port}, 85 }, "iperf", "-s"); err != nil { 86 b.Fatalf("failed to start server with: %v", err) 87 } 88 if out, err := server.WaitForOutput(ctx, fmt.Sprintf("Server listening on TCP port %d", port), 10*time.Second); err != nil { 89 b.Fatalf("failed to wait for iperf server: %v %s", err, out) 90 } 91 92 iperf := tools.Iperf{ 93 Num: b.N, // KB for the client to send. 94 } 95 96 // Run the client. 97 b.ResetTimer() 98 out, err := client.Run(ctx, dockerutil.RunOpts{ 99 Image: "benchmarks/iperf", 100 Links: []string{server.MakeLink("iperfsrv")}, 101 }, iperf.MakeCmd("iperfsrv", port)...) 102 if err != nil { 103 b.Fatalf("failed to run client: %v", err) 104 } 105 b.StopTimer() 106 iperf.Report(b, out) 107 b.StartTimer() 108 }) 109 } 110 } 111 112 func BenchmarkIperfManyConnections(b *testing.B) { 113 clientMachine, err := harness.GetMachine() 114 if err != nil { 115 b.Fatalf("failed to get machine: %v", err) 116 } 117 defer clientMachine.CleanUp() 118 119 serverMachine, err := harness.GetMachine() 120 if err != nil { 121 b.Fatalf("failed to get machine: %v", err) 122 } 123 defer serverMachine.CleanUp() 124 ctx := context.Background() 125 for _, bm := range []struct { 126 name string 127 length int 128 parallel int 129 clientFunc func(context.Context, testutil.Logger) *dockerutil.Container 130 serverFunc func(context.Context, testutil.Logger) *dockerutil.Container 131 }{ 132 // We are either measuring the server or the client. The other should be 133 // runc. e.g. Upload sees how fast the runtime under test uploads to a native 134 // server. 135 { 136 name: "Upload", 137 parallel: 4, 138 clientFunc: clientMachine.GetContainer, 139 serverFunc: serverMachine.GetNativeContainer, 140 }, 141 { 142 name: "Download", 143 parallel: 4, 144 clientFunc: clientMachine.GetNativeContainer, 145 serverFunc: serverMachine.GetContainer, 146 }, 147 { 148 name: "Upload", 149 parallel: 16, 150 clientFunc: clientMachine.GetContainer, 151 serverFunc: serverMachine.GetNativeContainer, 152 }, 153 { 154 name: "Download", 155 parallel: 16, 156 clientFunc: clientMachine.GetNativeContainer, 157 serverFunc: serverMachine.GetContainer, 158 }, 159 { 160 name: "Upload", 161 parallel: 64, 162 clientFunc: clientMachine.GetContainer, 163 serverFunc: serverMachine.GetNativeContainer, 164 }, 165 { 166 name: "Download", 167 parallel: 64, 168 clientFunc: clientMachine.GetNativeContainer, 169 serverFunc: serverMachine.GetContainer, 170 }, 171 } { 172 name, err := tools.ParametersToName(tools.Parameter{ 173 Name: "operation", 174 Value: bm.name, 175 }, tools.Parameter{ 176 Name: "parallel", 177 Value: fmt.Sprintf("%d", bm.parallel), 178 }) 179 if err != nil { 180 b.Fatalf("Failed to parse parameters: %v", err) 181 } 182 b.Run(name, func(b *testing.B) { 183 // Set up the containers. 184 server := bm.serverFunc(ctx, b) 185 defer server.CleanUp(ctx) 186 defer metricsviz.FromNamedContainerLogs(ctx, b, server, "server") 187 client := bm.clientFunc(ctx, b) 188 defer client.CleanUp(ctx) 189 defer metricsviz.FromNamedContainerLogs(ctx, b, client, "client") 190 191 // iperf server listens on port 5001 by default. 192 port := 5001 193 194 // Start the server. 195 if err := server.Spawn(ctx, dockerutil.RunOpts{ 196 Image: "benchmarks/iperf", 197 Ports: []int{port}, 198 }, "iperf", "-s"); err != nil { 199 b.Fatalf("failed to start server with: %v", err) 200 } 201 if out, err := server.WaitForOutput(ctx, fmt.Sprintf("Server listening on TCP port %d", port), 10*time.Second); err != nil { 202 b.Fatalf("failed to wait for iperf server: %v %s", err, out) 203 } 204 205 iperf := tools.Iperf{ 206 Num: b.N, // KB for the client to send. 207 Parallel: bm.parallel, 208 } 209 210 // Run the client. 211 b.ResetTimer() 212 out, err := client.Run(ctx, dockerutil.RunOpts{ 213 Image: "benchmarks/iperf", 214 Links: []string{server.MakeLink("iperfsrv")}, 215 }, iperf.MakeCmd("iperfsrv", port)...) 216 if err != nil { 217 b.Fatalf("failed to run client: %v", err) 218 } 219 b.StopTimer() 220 iperf.Report(b, out) 221 b.StartTimer() 222 }) 223 } 224 } 225 226 func TestMain(m *testing.M) { 227 harness.Init() 228 os.Exit(m.Run()) 229 }