fix merge error
This commit is contained in:
1
.idea/go-iperf.iml
generated
1
.idea/go-iperf.iml
generated
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module type="WEB_MODULE" version="4">
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/embedded" />
|
<excludeFolder url="file://$MODULE_DIR$/embedded" />
|
||||||
|
|||||||
30
.idea/workspace.xml
generated
30
.idea/workspace.xml
generated
@@ -1,5 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="AutoImportSettings">
|
||||||
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
|
</component>
|
||||||
<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_darwin.go" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/reporter_darwin.go" afterDir="false" />
|
||||||
@@ -44,54 +47,65 @@
|
|||||||
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<recent name="C:\Users\BGrewell\source\repos\go-iperf" />
|
|
||||||
<recent name="C:\Users\BGrewell\repos\go-iperf\embedded" />
|
|
||||||
</key>
|
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="C:\Users\BGrewell\source\repos\go-iperf\tests\server" />
|
<recent name="C:\Users\BGrewell\source\repos\go-iperf\tests\server" />
|
||||||
</key>
|
</key>
|
||||||
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$" />
|
||||||
|
<recent name="C:\Users\BGrewell\source\repos\go-iperf" />
|
||||||
|
<recent name="C:\Users\BGrewell\repos\go-iperf\embedded" />
|
||||||
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Go Build.go build github.com/BGrewell/go-iperf/tests/controller">
|
<component name="RunManager" selected="Go Build.go build github.com/BGrewell/go-iperf/tests/controller">
|
||||||
<configuration name="go build github.com/BGrewell/go-iperf/cmd" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
<configuration name="go build github.com/BGrewell/go-iperf/cmd" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||||
<module name="go-iperf" />
|
<module name="go-iperf" />
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
<kind value="PACKAGE" />
|
<kind value="PACKAGE" />
|
||||||
<filePath value="$PROJECT_DIR$/cmd/main.go" />
|
|
||||||
<package value="github.com/BGrewell/go-iperf/cmd" />
|
<package value="github.com/BGrewell/go-iperf/cmd" />
|
||||||
<directory value="$PROJECT_DIR$" />
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/cmd/main.go" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="go build github.com/BGrewell/go-iperf/tests/client" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
<configuration name="go build github.com/BGrewell/go-iperf/tests/client" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||||
<module name="go-iperf" />
|
<module name="go-iperf" />
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
<kind value="PACKAGE" />
|
<kind value="PACKAGE" />
|
||||||
<filePath value="$PROJECT_DIR$/tests/client/client.go" />
|
|
||||||
<package value="github.com/BGrewell/go-iperf/tests/client" />
|
<package value="github.com/BGrewell/go-iperf/tests/client" />
|
||||||
<directory value="$PROJECT_DIR$" />
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/tests/client/client.go" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="go build github.com/BGrewell/go-iperf/tests/controller" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
<configuration name="go build github.com/BGrewell/go-iperf/tests/controller" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||||
<module name="go-iperf" />
|
<module name="go-iperf" />
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
<kind value="PACKAGE" />
|
<kind value="PACKAGE" />
|
||||||
<filePath value="$PROJECT_DIR$/tests/controller/main.go" />
|
|
||||||
<package value="github.com/BGrewell/go-iperf/tests/controller" />
|
<package value="github.com/BGrewell/go-iperf/tests/controller" />
|
||||||
<directory value="$PROJECT_DIR$" />
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/tests/controller/main.go" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="go build github.com/BGrewell/go-iperf/tests/extract" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="go-iperf" />
|
||||||
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
|
<kind value="PACKAGE" />
|
||||||
|
<package value="github.com/BGrewell/go-iperf/tests/extract" />
|
||||||
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/tests/extract/main.go" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="go build github.com/BGrewell/go-iperf/tests/server" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
<configuration name="go build github.com/BGrewell/go-iperf/tests/server" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||||
<module name="go-iperf" />
|
<module name="go-iperf" />
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
<kind value="PACKAGE" />
|
<kind value="PACKAGE" />
|
||||||
<filePath value="$PROJECT_DIR$/tests/server/server.go" />
|
|
||||||
<package value="github.com/BGrewell/go-iperf/tests/server" />
|
<package value="github.com/BGrewell/go-iperf/tests/server" />
|
||||||
<directory value="$PROJECT_DIR$" />
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/tests/server/server.go" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/controller" />
|
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/controller" />
|
||||||
|
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/extract" />
|
||||||
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/client" />
|
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/client" />
|
||||||
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/server" />
|
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/tests/server" />
|
||||||
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/cmd" />
|
<item itemvalue="Go Build.go build github.com/BGrewell/go-iperf/cmd" />
|
||||||
|
|||||||
244
bindata.go
244
bindata.go
File diff suppressed because one or more lines are too long
35
client.go
35
client.go
@@ -66,6 +66,8 @@ type Client struct {
|
|||||||
Running bool `json:"running" yaml:"running" xml:"running"`
|
Running bool `json:"running" yaml:"running" xml:"running"`
|
||||||
Done chan bool `json:"-" yaml:"-" xml:"-"`
|
Done chan bool `json:"-" yaml:"-" xml:"-"`
|
||||||
Options *ClientOptions `json:"options" yaml:"options" xml:"options"`
|
Options *ClientOptions `json:"options" yaml:"options" xml:"options"`
|
||||||
|
Debug bool `json:"-" yaml:"-" xml:"-"`
|
||||||
|
StdOut bool `json:"-" yaml:"-" xml:"-"`
|
||||||
exitCode *int
|
exitCode *int
|
||||||
report *TestReport
|
report *TestReport
|
||||||
outputStream io.ReadCloser
|
outputStream io.ReadCloser
|
||||||
@@ -487,24 +489,27 @@ func (c *Client) SetModeLive() <-chan *StreamIntervalReport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Start() (err error) {
|
func (c *Client) Start() (err error) {
|
||||||
|
read := make(chan interface{})
|
||||||
cmd, err := c.commandString()
|
cmd, err := c.commandString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var exit chan int
|
var exit chan int
|
||||||
c.outputStream, c.errorStream, exit, c.cancel, err = ExecuteAsyncWithCancel(cmd)
|
c.outputStream, c.errorStream, exit, c.cancel, err = ExecuteAsyncWithCancelReadIndicator(cmd, read)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.Running = true
|
c.Running = true
|
||||||
|
|
||||||
//go func() {
|
//go func() {
|
||||||
// ds := DebugScanner{Silent: false}
|
// ds := DebugScanner{Silent: !c.StdOut}
|
||||||
// ds.Scan(c.outputStream)
|
// ds.Scan(c.outputStream)
|
||||||
//}()
|
//}()
|
||||||
//go func() {
|
go func() {
|
||||||
// ds := DebugScanner{Silent: false}
|
ds := DebugScanner{Silent: !c.Debug}
|
||||||
// ds.Scan(c.errorStream)
|
ds.Scan(c.errorStream)
|
||||||
//}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
var reporter *Reporter
|
var reporter *Reporter
|
||||||
if c.live {
|
if c.live {
|
||||||
@@ -514,11 +519,26 @@ func (c *Client) Start() (err error) {
|
|||||||
}
|
}
|
||||||
reporter.Start()
|
reporter.Start()
|
||||||
} else {
|
} else {
|
||||||
|
if c.Debug {
|
||||||
|
fmt.Println("reading output")
|
||||||
|
}
|
||||||
testOutput, err := ioutil.ReadAll(c.outputStream)
|
testOutput, err := ioutil.ReadAll(c.outputStream)
|
||||||
|
read <- true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
if c.Debug {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.Debug {
|
||||||
|
fmt.Println("parsing output")
|
||||||
}
|
}
|
||||||
c.report, err = Loads(string(testOutput))
|
c.report, err = Loads(string(testOutput))
|
||||||
|
if err != nil && c.Debug {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.Debug {
|
||||||
|
fmt.Println("complete")
|
||||||
}
|
}
|
||||||
exitCode := <-exit
|
exitCode := <-exit
|
||||||
c.exitCode = &exitCode
|
c.exitCode = &exitCode
|
||||||
@@ -535,6 +555,5 @@ func (c *Client) Stop() {
|
|||||||
if c.Running && c.cancel != nil {
|
if c.Running && c.cancel != nil {
|
||||||
c.cancel()
|
c.cancel()
|
||||||
os.Remove(c.reportingFile)
|
os.Remove(c.reportingFile)
|
||||||
c.Done <- true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
api "github.com/BGrewell/go-iperf/api/go"
|
api "github.com/BGrewell/go-iperf/api/go"
|
||||||
@@ -16,6 +17,8 @@ func NewController(port int) (controller *Controller, err error) {
|
|||||||
Port: port,
|
Port: port,
|
||||||
clients: make(map[string]*Client),
|
clients: make(map[string]*Client),
|
||||||
servers: make(map[string]*Server),
|
servers: make(map[string]*Server),
|
||||||
|
clientLock: sync.Mutex{},
|
||||||
|
serverLock: sync.Mutex{},
|
||||||
}
|
}
|
||||||
err = c.startListener()
|
err = c.startListener()
|
||||||
|
|
||||||
@@ -30,6 +33,8 @@ type Controller struct {
|
|||||||
api.UnimplementedCommandServer
|
api.UnimplementedCommandServer
|
||||||
Port int
|
Port int
|
||||||
cmdClient api.CommandClient
|
cmdClient api.CommandClient
|
||||||
|
clientLock sync.Mutex
|
||||||
|
serverLock sync.Mutex
|
||||||
clients map[string]*Client
|
clients map[string]*Client
|
||||||
servers map[string]*Server
|
servers map[string]*Server
|
||||||
}
|
}
|
||||||
@@ -46,7 +51,9 @@ func (c *Controller) GrpcRequestServer(context.Context, *api.StartServerRequest)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.serverLock.Lock()
|
||||||
c.servers[srv.Id] = srv
|
c.servers[srv.Id] = srv
|
||||||
|
c.serverLock.Unlock()
|
||||||
|
|
||||||
reply := &api.StartServerResponse{
|
reply := &api.StartServerResponse{
|
||||||
Id: srv.Id,
|
Id: srv.Id,
|
||||||
@@ -74,6 +81,7 @@ func (c *Controller) startListener() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,13 +90,17 @@ func (c *Controller) NewServer() (server *Server, err error) {
|
|||||||
freePort, err := GetUnusedTcpPort()
|
freePort, err := GetUnusedTcpPort()
|
||||||
s := NewServer()
|
s := NewServer()
|
||||||
s.SetPort(freePort)
|
s.SetPort(freePort)
|
||||||
|
c.serverLock.Lock()
|
||||||
c.servers[s.Id] = s
|
c.servers[s.Id] = s
|
||||||
|
c.serverLock.Unlock()
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopServer shuts down an iperf server and frees any actively used resources
|
// StopServer shuts down an iperf server and frees any actively used resources
|
||||||
func (c *Controller) StopServer(id string) (err error) {
|
func (c *Controller) StopServer(id string) (err error) {
|
||||||
|
c.serverLock.Lock()
|
||||||
delete(c.servers, id)
|
delete(c.servers, id)
|
||||||
|
c.serverLock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +112,7 @@ func (c *Controller) NewClient(serverAddr string) (client *Client, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
reply, err := grpc.GrpcRequestServer(ctx, &api.StartServerRequest{})
|
reply, err := grpc.GrpcRequestServer(ctx, &api.StartServerRequest{})
|
||||||
srvPort := int(reply.ListenPort)
|
srvPort := int(reply.ListenPort)
|
||||||
@@ -108,14 +120,18 @@ func (c *Controller) NewClient(serverAddr string) (client *Client, err error) {
|
|||||||
|
|
||||||
cli := NewClient(serverAddr)
|
cli := NewClient(serverAddr)
|
||||||
cli.SetPort(srvPort)
|
cli.SetPort(srvPort)
|
||||||
|
c.clientLock.Lock()
|
||||||
c.clients[cli.Id] = cli
|
c.clients[cli.Id] = cli
|
||||||
|
c.clientLock.Unlock()
|
||||||
|
|
||||||
return cli, nil
|
return cli, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopClient will clean up the server side connection and shut down any actively used resources
|
// StopClient will clean up the server side connection and shut down any actively used resources
|
||||||
func (c *Controller) StopClient(id string) (err error) {
|
func (c *Controller) StopClient(id string) (err error) {
|
||||||
|
c.clientLock.Lock()
|
||||||
delete(c.clients, id)
|
delete(c.clients, id)
|
||||||
|
c.clientLock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ func ExecuteAsync(cmd string) (outPipe io.ReadCloser, errPipe io.ReadCloser, exi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExecuteAsyncWithCancel(cmd string) (stdOut io.ReadCloser, stdErr io.ReadCloser, exitCode chan int, cancelToken context.CancelFunc, err error) {
|
func ExecuteAsyncWithCancel(cmd string) (stdOut io.ReadCloser, stdErr io.ReadCloser, exitCode chan int, cancelToken context.CancelFunc, err error) {
|
||||||
|
return ExecuteAsyncWithCancelReadIndicator(cmd, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteAsyncWithCancelReadIndicator(cmd string, readIndicator chan interface{}) (stdOut io.ReadCloser, stdErr io.ReadCloser, exitCode chan int, cancelToken context.CancelFunc, err error) {
|
||||||
exitCode = make(chan int)
|
exitCode = make(chan int)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
cmdParts := strings.Fields(cmd)
|
cmdParts := strings.Fields(cmd)
|
||||||
@@ -68,6 +72,11 @@ func ExecuteAsyncWithCancel(cmd string) (stdOut io.ReadCloser, stdErr io.ReadClo
|
|||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
// Note: Wait() will close the Stdout/Stderr and in some cases can do it before we read. In order to prevent
|
||||||
|
// this we need to actually wait until the caller has finished reading.
|
||||||
|
if readIndicator != nil {
|
||||||
|
<- readIndicator
|
||||||
|
}
|
||||||
if err := exe.Wait(); err != nil {
|
if err := exe.Wait(); err != nil {
|
||||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -9,6 +9,7 @@ require (
|
|||||||
github.com/golang/protobuf v1.5.2
|
github.com/golang/protobuf v1.5.2
|
||||||
github.com/google/uuid v1.1.2
|
github.com/google/uuid v1.1.2
|
||||||
github.com/hpcloud/tail v1.0.0 // indirect
|
github.com/hpcloud/tail v1.0.0 // indirect
|
||||||
|
github.com/jteeuwen/go-bindata v3.0.7+incompatible // indirect
|
||||||
google.golang.org/grpc v1.36.1
|
google.golang.org/grpc v1.36.1
|
||||||
google.golang.org/protobuf v1.26.0
|
google.golang.org/protobuf v1.26.0
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -39,6 +39,8 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
|||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/jteeuwen/go-bindata v3.0.7+incompatible h1:91Uy4d9SYVr1kyTJ15wJsog+esAZZl7JmEfTkwmhJts=
|
||||||
|
github.com/jteeuwen/go-bindata v3.0.7+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|||||||
21
iperf.go
21
iperf.go
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Debug = true
|
Debug = false
|
||||||
binaryDir = ""
|
binaryDir = ""
|
||||||
binaryLocation = ""
|
binaryLocation = ""
|
||||||
)
|
)
|
||||||
@@ -22,6 +22,11 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("error initializing iperf: %v", err)
|
log.Fatalf("error initializing iperf: %v", err)
|
||||||
}
|
}
|
||||||
|
} else if runtime.GOOS == "darwin" {
|
||||||
|
err := extractMacEmbeddedBinaries()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error initializing iperf: %v\n", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err := extractLinuxEmbeddedBinaries()
|
err := extractLinuxEmbeddedBinaries()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -34,6 +39,13 @@ func Cleanup() {
|
|||||||
os.RemoveAll(binaryDir)
|
os.RemoveAll(binaryDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExtractBinaries() (err error) {
|
||||||
|
files := []string{"cygwin1.dll", "iperf3.exe", "iperf3", "iperf3.app"}
|
||||||
|
err = extractEmbeddedBinaries(files)
|
||||||
|
fmt.Printf("files extracted to %s\n", binaryDir)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func extractWindowsEmbeddedBinaries() (err error) {
|
func extractWindowsEmbeddedBinaries() (err error) {
|
||||||
files := []string{"cygwin1.dll", "iperf3.exe"}
|
files := []string{"cygwin1.dll", "iperf3.exe"}
|
||||||
err = extractEmbeddedBinaries(files)
|
err = extractEmbeddedBinaries(files)
|
||||||
@@ -48,6 +60,13 @@ func extractLinuxEmbeddedBinaries() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractMacEmbeddedBinaries() (err error) {
|
||||||
|
files := []string{"iperf3.app"}
|
||||||
|
err = extractEmbeddedBinaries(files)
|
||||||
|
binaryLocation = path.Join(binaryDir, "iperf3.app")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func extractEmbeddedBinaries(files []string) (err error) {
|
func extractEmbeddedBinaries(files []string) (err error) {
|
||||||
binaryDir, err = ioutil.TempDir("", "goiperf")
|
binaryDir, err = ioutil.TempDir("", "goiperf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -10,9 +10,47 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
//TODO: This has not been tested on OS X ... my assumption is it is the exact same as linux but if it's not then the
|
//TODO: This has not been tested on OS X ... my assumption is it is the exact same as linux but if it's not then the
|
||||||
// reporting will be broken
|
// reporting will be broken
|
||||||
|
|
||||||
|
=======
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
>>>>>>> 8ad71c4c5699a6d55965c2f1ab99d5c306295c3b
|
||||||
func (r *Reporter) runLogProcessor() {
|
func (r *Reporter) runLogProcessor() {
|
||||||
var err error
|
var err error
|
||||||
r.tailer, err = tail.TailFile(r.LogFile, tail.Config{
|
r.tailer, err = tail.TailFile(r.LogFile, tail.Config{
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ func (r *Reporter) runLogProcessor() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to tail log file: %v", err)
|
log.Fatalf("failed to tail log file: %v", err)
|
||||||
}
|
}
|
||||||
|
if DEBUG {
|
||||||
|
log.Printf("starting to watch log file: %s\n", r.LogFile)
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -63,10 +66,16 @@ func (r *Reporter) runLogProcessor() {
|
|||||||
if line == nil {
|
if line == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if DEBUG {
|
||||||
|
log.Printf("new line: %s\n", line)
|
||||||
|
}
|
||||||
if len(line.Text) > 5 {
|
if len(line.Text) > 5 {
|
||||||
id := line.Text[1:4]
|
id := line.Text[1:4]
|
||||||
stream, err := strconv.Atoi(strings.TrimSpace(id))
|
stream, err := strconv.Atoi(strings.TrimSpace(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if DEBUG {
|
||||||
|
log.Printf("error converting stream id to int: %v\n", err)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fields := strings.Fields(line.Text[5:])
|
fields := strings.Fields(line.Text[5:])
|
||||||
@@ -117,6 +126,9 @@ func (r *Reporter) runLogProcessor() {
|
|||||||
Omitted: omitted,
|
Omitted: omitted,
|
||||||
}
|
}
|
||||||
r.ReportingChannel <- report
|
r.ReportingChannel <- report
|
||||||
|
if DEBUG {
|
||||||
|
log.Println("added report to reporting channel")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-time.After(100 * time.Millisecond):
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
|||||||
10
server.go
10
server.go
@@ -42,6 +42,8 @@ type Server struct {
|
|||||||
Running bool `json:"running" yaml:"running" xml:"running"`
|
Running bool `json:"running" yaml:"running" xml:"running"`
|
||||||
Options *ServerOptions `json:"-" yaml:"-" xml:"-"`
|
Options *ServerOptions `json:"-" yaml:"-" xml:"-"`
|
||||||
ExitCode *int `json:"exit_code" yaml:"exit_code" xml:"exit_code"`
|
ExitCode *int `json:"exit_code" yaml:"exit_code" xml:"exit_code"`
|
||||||
|
Debug bool `json:"-" yaml:"-" xml:"-"`
|
||||||
|
StdOut bool `json:"-" yaml:"-" xml:"-"`
|
||||||
outputStream io.ReadCloser `json:"output_stream" yaml:"output_stream" xml:"output_stream"`
|
outputStream io.ReadCloser `json:"output_stream" yaml:"output_stream" xml:"output_stream"`
|
||||||
errorStream io.ReadCloser `json:"error_stream" yaml:"error_stream" xml:"error_stream"`
|
errorStream io.ReadCloser `json:"error_stream" yaml:"error_stream" xml:"error_stream"`
|
||||||
cancel context.CancelFunc `json:"cancel" yaml:"cancel" xml:"cancel"`
|
cancel context.CancelFunc `json:"cancel" yaml:"cancel" xml:"cancel"`
|
||||||
@@ -79,7 +81,7 @@ func (s *Server) commandString() (cmd string, err error) {
|
|||||||
builder.WriteString(" --json")
|
builder.WriteString(" --json")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Options.LogFile != nil && s.LogFile() != "" {
|
if s.Options.LogFile != nil && s.LogFile() != "" {
|
||||||
fmt.Fprintf(&builder, " --logfile %s --forceflush", s.LogFile())
|
fmt.Fprintf(&builder, " --logfile %s --forceflush", s.LogFile())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,14 +161,16 @@ func (s *Server) Start() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Running = true
|
s.Running = true
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ds := DebugScanner{Silent: true}
|
ds := DebugScanner{Silent: !s.StdOut}
|
||||||
ds.Scan(s.outputStream)
|
ds.Scan(s.outputStream)
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
ds := DebugScanner{Silent: true}
|
ds := DebugScanner{Silent: !s.Debug}
|
||||||
ds.Scan(s.errorStream)
|
ds.Scan(s.errorStream)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
exitCode := <-exit
|
exitCode := <-exit
|
||||||
s.ExitCode = &exitCode
|
s.ExitCode = &exitCode
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DEBUG = false
|
||||||
|
)
|
||||||
|
|
||||||
type TestMode string
|
type TestMode string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
7
tests/extract/main.go
Normal file
7
tests/extract/main.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/BGrewell/go-iperf"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
iperf.ExtractBinaries()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user