added linux iperf processing
This commit is contained in:
27
.idea/workspace.xml
generated
27
.idea/workspace.xml
generated
@@ -2,22 +2,13 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="fc2840de-29dc-4fca-8e0e-a283562f60ca" name="Default Changelist" comment="">
|
<list default="true" id="fc2840de-29dc-4fca-8e0e-a283562f60ca" name="Default Changelist" comment="">
|
||||||
<change afterPath="$PROJECT_DIR$/reporter.go" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/reporter_linux.go" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/reporter_windows.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/bindata.go" beforeDir="false" afterPath="$PROJECT_DIR$/bindata.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/client.go" beforeDir="false" afterPath="$PROJECT_DIR$/client.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/cmd/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/main.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/execute.go" beforeDir="false" afterPath="$PROJECT_DIR$/execute.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/iperf.go" beforeDir="false" afterPath="$PROJECT_DIR$/iperf.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/protocol.go" beforeDir="false" afterPath="$PROJECT_DIR$/protocol.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/report.go" beforeDir="false" afterPath="$PROJECT_DIR$/report.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/report.go" beforeDir="false" afterPath="$PROJECT_DIR$/report.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/sample.json" beforeDir="false" afterPath="$PROJECT_DIR$/sample.json" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/reporter.go" beforeDir="false" afterPath="$PROJECT_DIR$/reporter.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/server.go" beforeDir="false" afterPath="$PROJECT_DIR$/server.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/shared.go" beforeDir="false" afterPath="$PROJECT_DIR$/shared.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/shared.go" beforeDir="false" afterPath="$PROJECT_DIR$/shared.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/tests/client/client.go" beforeDir="false" afterPath="$PROJECT_DIR$/tests/client/client.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/tests/client/client.go" beforeDir="false" afterPath="$PROJECT_DIR$/tests/client/client.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/tests/server/server.go" beforeDir="false" afterPath="$PROJECT_DIR$/tests/server/server.go" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -58,6 +49,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="C:\Users\BGrewell\source\repos\go-iperf" />
|
||||||
<recent name="C:\Users\BGrewell\repos\go-iperf\embedded" />
|
<recent name="C:\Users\BGrewell\repos\go-iperf\embedded" />
|
||||||
</key>
|
</key>
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
@@ -117,15 +109,4 @@
|
|||||||
<component name="VgoProject">
|
<component name="VgoProject">
|
||||||
<integration-enabled>true</integration-enabled>
|
<integration-enabled>true</integration-enabled>
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
|
||||||
<breakpoint-manager>
|
|
||||||
<breakpoints>
|
|
||||||
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
|
|
||||||
<url>file://$PROJECT_DIR$/tests/client/client.go</url>
|
|
||||||
<line>57</line>
|
|
||||||
<option name="timeStamp" value="5" />
|
|
||||||
</line-breakpoint>
|
|
||||||
</breakpoints>
|
|
||||||
</breakpoint-manager>
|
|
||||||
</component>
|
|
||||||
</project>
|
</project>
|
||||||
16
report.go
16
report.go
@@ -27,13 +27,15 @@ func (si *StreamInterval) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StreamIntervalReport struct {
|
type StreamIntervalReport struct {
|
||||||
Socket int `json:"socket"`
|
Socket int `json:"socket"`
|
||||||
StartInterval float32 `json:"start"`
|
StartInterval float32 `json:"start"`
|
||||||
EndInterval float32 `json:"end"`
|
EndInterval float32 `json:"end"`
|
||||||
Seconds float32 `json:"seconds"`
|
Seconds float32 `json:"seconds"`
|
||||||
Bytes int `json:"bytes"`
|
Bytes int `json:"bytes"`
|
||||||
BitsPerSecond float64 `json:"bits_per_second"`
|
BitsPerSecond float64 `json:"bits_per_second"`
|
||||||
Omitted bool `json:"omitted"`
|
Retransmissions int `json:"retransmissions"`
|
||||||
|
CongestionWindow int `json:"congestion_window"`
|
||||||
|
Omitted bool `json:"omitted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sir *StreamIntervalReport) String() string {
|
func (sir *StreamIntervalReport) String() string {
|
||||||
|
|||||||
79
reporter.go
79
reporter.go
@@ -1,18 +1,9 @@
|
|||||||
package iperf
|
package iperf
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/BGrewell/tail"
|
|
||||||
"github.com/BGrewell/go-conversions"
|
|
||||||
"log"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Reporter struct {
|
type Reporter struct {
|
||||||
ReportingChannel chan *StreamIntervalReport
|
ReportingChannel chan *StreamIntervalReport
|
||||||
LogFile string
|
LogFile string
|
||||||
running bool
|
running bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reporter) Start() {
|
func (r *Reporter) Start() {
|
||||||
@@ -25,68 +16,4 @@ func (r *Reporter) Stop() {
|
|||||||
close(r.ReportingChannel)
|
close(r.ReportingChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reporter) runLogProcessor() {
|
// runLogProcessor is OS specific because of differences in iperf on Windows and Linux
|
||||||
tailer, err := tail.TailFile(r.LogFile, tail.Config{
|
|
||||||
Follow: true,
|
|
||||||
ReOpen: true,
|
|
||||||
Poll: true,
|
|
||||||
MustExist: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to tail log file: %v", err)
|
|
||||||
}
|
|
||||||
for line := range tailer.Lines {
|
|
||||||
// TODO: For now this only cares about individual streams it ignores the sum lines
|
|
||||||
if len(line.Text) > 5 {
|
|
||||||
id := line.Text[1:4]
|
|
||||||
stream, err := strconv.Atoi(strings.TrimSpace(id))
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fields := strings.Fields(line.Text[5:])
|
|
||||||
if len(fields) >= 6 {
|
|
||||||
if fields[0] == "local" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
timeFields := strings.Split(fields[0], "-")
|
|
||||||
start, err := strconv.ParseFloat(timeFields[0], 32)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("failed to convert start time: %s\n", err)
|
|
||||||
}
|
|
||||||
end, err := strconv.ParseFloat(timeFields[1], 32)
|
|
||||||
transferedStr := fmt.Sprintf("%s%s", fields[2], fields[3])
|
|
||||||
transferedBytes, err := conversions.StringBitRateToInt(transferedStr)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("failed to convert units: %s\n", err)
|
|
||||||
}
|
|
||||||
transferedBytes = transferedBytes / 8
|
|
||||||
rateStr := fmt.Sprintf("%s%s", fields[4], fields[5])
|
|
||||||
rate, err := conversions.StringBitRateToInt(rateStr)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("failed to convert units: %s\n", err)
|
|
||||||
}
|
|
||||||
omitted := false
|
|
||||||
if len(fields) >= 7 && fields[6] == "(omitted)" {
|
|
||||||
omitted = true
|
|
||||||
}
|
|
||||||
report := &StreamIntervalReport{
|
|
||||||
Socket: stream,
|
|
||||||
StartInterval: float32(start),
|
|
||||||
EndInterval: float32(end),
|
|
||||||
Seconds: float32(end - start),
|
|
||||||
Bytes: int(transferedBytes),
|
|
||||||
BitsPerSecond: float64(rate),
|
|
||||||
Omitted: omitted,
|
|
||||||
}
|
|
||||||
r.ReportingChannel <- report
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !r.running {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
118
reporter_linux.go
Normal file
118
reporter_linux.go
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package iperf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/BGrewell/go-conversions"
|
||||||
|
"github.com/BGrewell/tail"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Connecting to host 10.254.100.100, port 5201
|
||||||
|
[ 4] local 192.168.3.182 port 54104 connected to 10.254.100.100 port 5201
|
||||||
|
[ ID] Interval Transfer Bandwidth Retr Cwnd
|
||||||
|
[ 4] 0.00-1.00 sec 109 MBytes 913 Mbits/sec 13 634 KBytes (omitted)
|
||||||
|
[ 4] 1.00-2.00 sec 110 MBytes 927 Mbits/sec 7 550 KBytes (omitted)
|
||||||
|
[ 4] 2.00-3.00 sec 109 MBytes 918 Mbits/sec 6 559 KBytes (omitted)
|
||||||
|
[ 4] 3.00-4.00 sec 111 MBytes 930 Mbits/sec 6 690 KBytes (omitted)
|
||||||
|
[ 4] 4.00-5.00 sec 111 MBytes 933 Mbits/sec 0 803 KBytes (omitted)
|
||||||
|
[ 4] 5.00-6.00 sec 111 MBytes 933 Mbits/sec 6 673 KBytes (omitted)
|
||||||
|
[ 4] 6.00-7.00 sec 111 MBytes 932 Mbits/sec 6 605 KBytes (omitted)
|
||||||
|
[ 4] 7.00-8.00 sec 110 MBytes 925 Mbits/sec 0 732 KBytes (omitted)
|
||||||
|
[ 4] 8.00-9.00 sec 111 MBytes 932 Mbits/sec 0 840 KBytes (omitted)
|
||||||
|
[ 4] 9.00-10.00 sec 110 MBytes 923 Mbits/sec 6 690 KBytes (omitted)
|
||||||
|
[ 4] 0.00-1.00 sec 111 MBytes 928 Mbits/sec 6 618 KBytes
|
||||||
|
[ 4] 1.00-2.00 sec 111 MBytes 931 Mbits/sec 0 745 KBytes
|
||||||
|
[ 4] 2.00-3.00 sec 111 MBytes 929 Mbits/sec 11 614 KBytes
|
||||||
|
[ 4] 3.00-4.00 sec 110 MBytes 922 Mbits/sec 6 551 KBytes
|
||||||
|
[ 4] 4.00-5.00 sec 111 MBytes 933 Mbits/sec 6 519 KBytes
|
||||||
|
[ 4] 5.00-6.00 sec 111 MBytes 928 Mbits/sec 0 663 KBytes
|
||||||
|
[ 4] 6.00-7.00 sec 111 MBytes 932 Mbits/sec 0 783 KBytes
|
||||||
|
[ 4] 7.00-8.00 sec 111 MBytes 933 Mbits/sec 6 656 KBytes
|
||||||
|
[ 4] 8.00-9.00 sec 111 MBytes 933 Mbits/sec 6 598 KBytes
|
||||||
|
[ 4] 9.00-10.00 sec 110 MBytes 925 Mbits/sec 0 728 KBytes
|
||||||
|
[ 4] 10.00-11.00 sec 111 MBytes 933 Mbits/sec 0 839 KBytes
|
||||||
|
[ 4] 11.00-12.00 sec 109 MBytes 918 Mbits/sec 6 680 KBytes
|
||||||
|
[ 4] 12.00-12.24 sec 25.0 MBytes 888 Mbits/sec 0 711 KBytes
|
||||||
|
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
[ ID] Interval Transfer Bandwidth Retr
|
||||||
|
[ 4] 0.00-12.24 sec 1.32 GBytes 928 Mbits/sec 47 sender
|
||||||
|
[ 4] 0.00-12.24 sec 0.00 Bytes 0.00 bits/sec receiver
|
||||||
|
|
||||||
|
iperf Done.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (r *Reporter) runLogProcessor() {
|
||||||
|
tailer, err := tail.TailFile(r.LogFile, tail.Config{
|
||||||
|
Follow: true,
|
||||||
|
ReOpen: true,
|
||||||
|
Poll: true,
|
||||||
|
MustExist: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to tail log file: %v", err)
|
||||||
|
}
|
||||||
|
for line := range tailer.Lines {
|
||||||
|
// TODO: For now this only cares about individual streams it ignores the sum lines
|
||||||
|
if len(line.Text) > 5 {
|
||||||
|
id := line.Text[1:4]
|
||||||
|
stream, err := strconv.Atoi(strings.TrimSpace(id))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields := strings.Fields(line.Text[5:])
|
||||||
|
if len(fields) >= 6 {
|
||||||
|
if fields[0] == "local" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
timeFields := strings.Split(fields[0], "-")
|
||||||
|
start, err := strconv.ParseFloat(timeFields[0], 32)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert start time: %s\n", err)
|
||||||
|
}
|
||||||
|
end, err := strconv.ParseFloat(timeFields[1], 32)
|
||||||
|
transferedStr := fmt.Sprintf("%s%s", fields[2], fields[3])
|
||||||
|
transferedBytes, err := conversions.StringBitRateToInt(transferedStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert units: %s\n", err)
|
||||||
|
}
|
||||||
|
transferedBytes = transferedBytes / 8
|
||||||
|
rateStr := fmt.Sprintf("%s%s", fields[4], fields[5])
|
||||||
|
rate, err := conversions.StringBitRateToInt(rateStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert units: %s\n", err)
|
||||||
|
}
|
||||||
|
retrans := strconv.Atoi(fields[6])
|
||||||
|
cwndStr := fmt.Sprintf("%s%s", fields[7], fields[8])
|
||||||
|
cwnd, err := conversions.StringBitRateToInt(cwndStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert units: %s\n", err)
|
||||||
|
}
|
||||||
|
cwnd = cwnd / 8
|
||||||
|
omitted := false
|
||||||
|
if len(fields) >= 10 && fields[9] == "(omitted)" {
|
||||||
|
omitted = true
|
||||||
|
}
|
||||||
|
report := &StreamIntervalReport{
|
||||||
|
Socket: stream,
|
||||||
|
StartInterval: float32(start),
|
||||||
|
EndInterval: float32(end),
|
||||||
|
Seconds: float32(end - start),
|
||||||
|
Bytes: int(transferedBytes),
|
||||||
|
BitsPerSecond: float64(rate),
|
||||||
|
Retransmissions: retrans,
|
||||||
|
CongestionWindow: cwnd,
|
||||||
|
Omitted: omitted,
|
||||||
|
}
|
||||||
|
r.ReportingChannel <- report
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !r.running {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
reporter_windows.go
Normal file
73
reporter_windows.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package iperf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/BGrewell/go-conversions"
|
||||||
|
"github.com/BGrewell/tail"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *Reporter) runLogProcessor() {
|
||||||
|
tailer, err := tail.TailFile(r.LogFile, tail.Config{
|
||||||
|
Follow: true,
|
||||||
|
ReOpen: true,
|
||||||
|
Poll: true,
|
||||||
|
MustExist: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to tail log file: %v", err)
|
||||||
|
}
|
||||||
|
for line := range tailer.Lines {
|
||||||
|
// TODO: For now this only cares about individual streams it ignores the sum lines
|
||||||
|
if len(line.Text) > 5 {
|
||||||
|
id := line.Text[1:4]
|
||||||
|
stream, err := strconv.Atoi(strings.TrimSpace(id))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields := strings.Fields(line.Text[5:])
|
||||||
|
if len(fields) >= 6 {
|
||||||
|
if fields[0] == "local" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
timeFields := strings.Split(fields[0], "-")
|
||||||
|
start, err := strconv.ParseFloat(timeFields[0], 32)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert start time: %s\n", err)
|
||||||
|
}
|
||||||
|
end, err := strconv.ParseFloat(timeFields[1], 32)
|
||||||
|
transferedStr := fmt.Sprintf("%s%s", fields[2], fields[3])
|
||||||
|
transferedBytes, err := conversions.StringBitRateToInt(transferedStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert units: %s\n", err)
|
||||||
|
}
|
||||||
|
transferedBytes = transferedBytes / 8
|
||||||
|
rateStr := fmt.Sprintf("%s%s", fields[4], fields[5])
|
||||||
|
rate, err := conversions.StringBitRateToInt(rateStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to convert units: %s\n", err)
|
||||||
|
}
|
||||||
|
omitted := false
|
||||||
|
if len(fields) >= 7 && fields[6] == "(omitted)" {
|
||||||
|
omitted = true
|
||||||
|
}
|
||||||
|
report := &StreamIntervalReport{
|
||||||
|
Socket: stream,
|
||||||
|
StartInterval: float32(start),
|
||||||
|
EndInterval: float32(end),
|
||||||
|
Seconds: float32(end - start),
|
||||||
|
Bytes: int(transferedBytes),
|
||||||
|
BitsPerSecond: float64(rate),
|
||||||
|
Omitted: omitted,
|
||||||
|
}
|
||||||
|
r.ReportingChannel <- report
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !r.running {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TestMode string
|
type TestMode string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MODE_JSON TestMode = "json"
|
MODE_JSON TestMode = "json"
|
||||||
MODE_LIVE TestMode = "live"
|
MODE_LIVE TestMode = "live"
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method 1: Wait for the test to finish by pulling from the 'Done' channel which will block until something is put in or it's closed
|
// Method 1: Wait for the test to finish by pulling from the 'Done' channel which will block until something is put in or it's closed
|
||||||
<- c.Done
|
<-c.Done
|
||||||
|
|
||||||
// Method 2: Poll the c.Running state and wait for it to be 'false'
|
// Method 2: Poll the c.Running state and wait for it to be 'false'
|
||||||
//for c.Running {
|
//for c.Running {
|
||||||
|
|||||||
Reference in New Issue
Block a user