gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/benchmarks/tools/iperf.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 tools 16 17 import ( 18 "fmt" 19 "regexp" 20 "strconv" 21 "testing" 22 ) 23 24 // Iperf is for the client side of `iperf`. 25 type Iperf struct { 26 Num int // Number of bytes to send in KB. 27 Parallel int // Number of parallel threads. 28 } 29 30 // MakeCmd returns a iperf client command. 31 func (i *Iperf) MakeCmd(host string, port int) []string { 32 cmd := []string{"iperf"} 33 cmd = append(cmd, "--format", "K") // Output in KBytes. 34 cmd = append(cmd, "--realtime") // Measured in realtime. 35 cmd = append(cmd, "--len", "128K") // Length of data buffer per request. 36 n := i.Num 37 if i.Parallel > 0 { 38 n = i.Num / i.Parallel 39 } 40 cmd = append(cmd, "--num", fmt.Sprintf("%dK", n)) // Number of requests to send. 41 cmd = append(cmd, "--client", host) 42 cmd = append(cmd, "--port", fmt.Sprintf("%d", port)) 43 if i.Parallel > 0 { 44 cmd = append(cmd, "--parallel", fmt.Sprintf("%d", i.Parallel)) 45 } 46 return cmd 47 } 48 49 // Report parses output from iperf client and reports metrics. 50 func (i *Iperf) Report(b *testing.B, output string) { 51 b.Helper() 52 // Parse bandwidth and report it. 53 bW, err := i.bandwidth(output) 54 if err != nil { 55 b.Fatalf("failed to parse bandwitdth from %s: %v", output, err) 56 } 57 b.SetBytes(128 * 1024) // Measure Bytes/sec for b.N, although below is iperf output. 58 ReportCustomMetric(b, bW*1024, "bandwidth" /*metric name*/, "bytes_per_second" /*unit*/) 59 } 60 61 // bandwidth parses the Bandwidth number from an iperf report. A sample is below. 62 func (i *Iperf) bandwidth(data string) (float64, error) { 63 re := regexp.MustCompile(`\[\s*\d+\][^\n]+\s+(\d+\.?\d*)\s+KBytes/sec`) 64 match := re.FindStringSubmatch(data) 65 if len(match) < 1 { 66 return 0, fmt.Errorf("failed get bandwidth: %s", data) 67 } 68 return strconv.ParseFloat(match[1], 64) 69 }