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