Support for title in test results and improvement to handshake code. (#137)

* Take rate input as bits/s

* Update README.md

* Fix throttling to be as precise as possible.

* Minor doc fix.

* Update README.md

* Add support for title, improve handshake code.

* Update README.md
This commit is contained in:
Pankaj Garg 2020-12-02 02:08:55 -08:00 committed by GitHub
parent 8f994d1400
commit 46d0e6286c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 13 deletions

View file

@ -271,6 +271,9 @@ In this mode, Ethr client can only talk to an Ethr server.
-w <number> -w <number>
Use specified number of iterations for warmup. Use specified number of iterations for warmup.
Default: 1 Default: 1
-T <string>
Use the given title in log files for logging results.
Default: <empty>
``` ```
### External Mode Parameters ### External Mode Parameters
``` ```
@ -317,6 +320,9 @@ few types of measurements, such as Ping, Connections/s and TraceRoute.
-w <number> -w <number>
Use specified number of iterations for warmup. Use specified number of iterations for warmup.
Default: 1 Default: 1
-T <string>
Use the given title in log files for logging results.
Default: <empty>
``` ```
# Status # Status

View file

@ -69,8 +69,8 @@ func runDurationTimer(d time.Duration, toStop chan int) {
}() }()
} }
func initClient() { func initClient(title string) {
initClientUI() initClientUI(title)
} }
func handshakeWithServer(test *ethrTest, conn net.Conn) (err error) { func handshakeWithServer(test *ethrTest, conn net.Conn) (err error) {
@ -117,8 +117,8 @@ func getServerIPandPort(server string) (string, string, string, error) {
return hostName, hostIP, port, err return hostName, hostIP, port, err
} }
func runClient(testID EthrTestID, clientParam EthrClientParam, server string) { func runClient(testID EthrTestID, title string, clientParam EthrClientParam, server string) {
initClient() initClient(title)
hostName, hostIP, port, err := getServerIPandPort(server) hostName, hostIP, port, err := getServerIPandPort(server)
if err != nil { if err != nil {
return return

View file

@ -12,11 +12,16 @@ import (
) )
type clientUI struct { type clientUI struct {
title string
} }
func (u *clientUI) fini() { func (u *clientUI) fini() {
} }
func (u *clientUI) getTitle() string {
return u.title
}
func (u *clientUI) printMsg(format string, a ...interface{}) { func (u *clientUI) printMsg(format string, a ...interface{}) {
s := fmt.Sprintf(format, a...) s := fmt.Sprintf(format, a...)
logInfo(s) logInfo(s)
@ -74,8 +79,8 @@ func (u *clientUI) emitStats(netStats ethrNetStat) {
func (u *clientUI) printTestResults(s []string) { func (u *clientUI) printTestResults(s []string) {
} }
func initClientUI() { func initClientUI(title string) {
cli := &clientUI{} cli := &clientUI{title}
ui = cli ui = cli
} }

14
ethr.go
View file

@ -69,6 +69,7 @@ func main() {
reverse := flag.Bool("r", false, "") reverse := flag.Bool("r", false, "")
testTypePtr := flag.String("t", "", "") testTypePtr := flag.String("t", "", "")
tos := flag.Int("tos", 0, "") tos := flag.Int("tos", 0, "")
title := flag.String("T", "", "")
thCount := flag.Int("n", 1, "") thCount := flag.Int("n", 1, "")
wc := flag.Int("w", 1, "") wc := flag.Int("w", 1, "")
xClientDest := flag.String("x", "", "") xClientDest := flag.String("x", "", "")
@ -121,6 +122,9 @@ func main() {
if *wc != 1 { if *wc != 1 {
printServerModeArgError("wc") printServerModeArgError("wc")
} }
if *title != "" {
printServerModeArgError("T")
}
} else if *clientDest != "" || *xClientDest != "" { } else if *clientDest != "" || *xClientDest != "" {
if *clientDest != "" && *xClientDest != "" { if *clientDest != "" && *xClientDest != "" {
printUsageError("Invalid argument, both \"-c\" and \"-x\" cannot be specified at the same time.") printUsageError("Invalid argument, both \"-c\" and \"-x\" cannot be specified at the same time.")
@ -244,7 +248,7 @@ func main() {
validateClientParams(testId, clientParam) validateClientParams(testId, clientParam)
rServer := destination rServer := destination
runClient(testId, clientParam, rServer) runClient(testId, *title, clientParam, rServer)
} }
} }
@ -421,6 +425,7 @@ func ethrUsage() {
printTestType() printTestType()
printToSUsage() printToSUsage()
printWarmupUsage() printWarmupUsage()
printTitleUsage()
fmt.Println("\nMode: External") fmt.Println("\nMode: External")
fmt.Println("================================================================================") fmt.Println("================================================================================")
@ -436,6 +441,7 @@ func ethrUsage() {
printExtTestType() printExtTestType()
printToSUsage() printToSUsage()
printWarmupUsage() printWarmupUsage()
printTitleUsage()
} }
func printFlagUsage(flag, info string, helptext ...string) { func printFlagUsage(flag, info string, helptext ...string) {
@ -575,3 +581,9 @@ func printIPUsage() {
"This must be a valid IPv4 or IPv6 address.", "This must be a valid IPv4 or IPv6 address.",
"Default: <empty> - Any IP") "Default: <empty> - Any IP")
} }
func printTitleUsage() {
printFlagUsage("T", "<string>",
"Use the given title in log files for logging results.",
"Default: <empty>")
}

6
log.go
View file

@ -24,12 +24,14 @@ const (
type logMessage struct { type logMessage struct {
Time string Time string
Title string
Type string Type string
Message string Message string
} }
type logLatencyData struct { type logLatencyData struct {
Time string Time string
Title string
Type string Type string
RemoteAddr string RemoteAddr string
Protocol string Protocol string
@ -46,6 +48,7 @@ type logLatencyData struct {
type logTestResults struct { type logTestResults struct {
Time string Time string
Title string
Type string Type string
RemoteAddr string RemoteAddr string
Protocol string Protocol string
@ -89,6 +92,7 @@ func logMsg(prefix, msg string) {
if loggingActive { if loggingActive {
logData := logMessage{} logData := logMessage{}
logData.Time = time.Now().UTC().Format(time.RFC3339) logData.Time = time.Now().UTC().Format(time.RFC3339)
logData.Title = ui.getTitle()
logData.Type = prefix logData.Type = prefix
logData.Message = msg logData.Message = msg
logJSON, _ := json.Marshal(logData) logJSON, _ := json.Marshal(logData)
@ -112,6 +116,7 @@ func logResults(s []string) {
if loggingActive { if loggingActive {
logData := logTestResults{} logData := logTestResults{}
logData.Time = time.Now().UTC().Format(time.RFC3339) logData.Time = time.Now().UTC().Format(time.RFC3339)
logData.Title = ui.getTitle()
logData.Type = "TestResult" logData.Type = "TestResult"
logData.RemoteAddr = s[0] logData.RemoteAddr = s[0]
logData.Protocol = s[1] logData.Protocol = s[1]
@ -128,6 +133,7 @@ func logLatency(remoteIP, proto string, avg, min, p50, p90, p95, p99, p999, p999
if loggingActive { if loggingActive {
logData := logLatencyData{} logData := logLatencyData{}
logData.Time = time.Now().UTC().Format(time.RFC3339) logData.Time = time.Now().UTC().Format(time.RFC3339)
logData.Title = ui.getTitle()
logData.Type = "LatencyResult" logData.Type = "LatencyResult"
logData.RemoteAddr = remoteIP logData.RemoteAddr = remoteIP
logData.Protocol = proto logData.Protocol = proto

View file

@ -123,8 +123,8 @@ func srvrHandleNewTcpConn(conn net.Conn) {
safeDeleteTest(test) safeDeleteTest(test)
}() }()
// Always increment CPS count and then check if the test is Bandwidth // Always increment CPS count and then check if the test is Bandwidth etc. and handle
// etc. and handle those cases as well. // those cases as well.
atomic.AddUint64(&test.testResult.cps, 1) atomic.AddUint64(&test.testResult.cps, 1)
testID, clientParam, err := handshakeWithClient(test, conn) testID, clientParam, err := handshakeWithClient(test, conn)

View file

@ -141,6 +141,10 @@ func (u *serverTui) fini() {
tm.Close() tm.Close()
} }
func (u *serverTui) getTitle() string {
return ""
}
func (u *serverTui) printMsg(format string, a ...interface{}) { func (u *serverTui) printMsg(format string, a ...interface{}) {
s := fmt.Sprintf(format, a...) s := fmt.Sprintf(format, a...)
logInfo(s) logInfo(s)
@ -300,6 +304,10 @@ func initServerCli() {
func (u *serverCli) fini() { func (u *serverCli) fini() {
} }
func (u *serverCli) getTitle() string {
return ""
}
func (u *serverCli) printMsg(format string, a ...interface{}) { func (u *serverCli) printMsg(format string, a ...interface{}) {
s := fmt.Sprintf(format, a...) s := fmt.Sprintf(format, a...)
fmt.Println(s) fmt.Println(s)

View file

@ -8,7 +8,9 @@ package main
import ( import (
"bytes" "bytes"
"container/list" "container/list"
"encoding/binary"
"encoding/gob" "encoding/gob"
"io"
"net" "net"
"os" "os"
"sync" "sync"
@ -319,14 +321,24 @@ func createAckMsg() (ethrMsg *EthrMsg) {
func recvSessionMsg(conn net.Conn) (ethrMsg *EthrMsg) { func recvSessionMsg(conn net.Conn) (ethrMsg *EthrMsg) {
ethrMsg = &EthrMsg{} ethrMsg = &EthrMsg{}
ethrMsg.Type = EthrInv ethrMsg.Type = EthrInv
// TODO: Assuming max ethr message size as 4096 sent over gob. msgBytes := make([]byte, 4)
msgBytes := make([]byte, 4096) _, err := io.ReadFull(conn, msgBytes)
n, err := conn.Read(msgBytes)
if err != nil { if err != nil {
ui.printDbg("Error receiving message on control channel. Error: %v", err) ui.printDbg("Error receiving message on control channel. Error: %v", err)
return return
} }
ethrMsg = decodeMsg(msgBytes[:n]) msgSize := binary.BigEndian.Uint32(msgBytes[0:])
// TODO: Assuming max ethr message size as 16K sent over gob.
if msgSize > 16384 {
return
}
msgBytes = make([]byte, msgSize)
_, err = io.ReadFull(conn, msgBytes)
if err != nil {
ui.printDbg("Error receiving message on control channel. Error: %v", err)
return
}
ethrMsg = decodeMsg(msgBytes)
return return
} }
@ -341,6 +353,13 @@ func sendSessionMsg(conn net.Conn, ethrMsg *EthrMsg) (err error) {
ui.printDbg("Error sending message on control channel. Message: %v, Error: %v", ethrMsg, err) ui.printDbg("Error sending message on control channel. Message: %v, Error: %v", ethrMsg, err)
return return
} }
msgSize := len(msgBytes)
tempBuf := make([]byte, 4)
binary.BigEndian.PutUint32(tempBuf[0:], uint32(msgSize))
_, err = conn.Write(tempBuf)
if err != nil {
ui.printDbg("Error sending message on control channel. Message: %v, Error: %v", ethrMsg, err)
}
_, err = conn.Write(msgBytes) _, err = conn.Write(msgBytes)
if err != nil { if err != nil {
ui.printDbg("Error sending message on control channel. Message: %v, Error: %v", ethrMsg, err) ui.printDbg("Error sending message on control channel. Message: %v, Error: %v", ethrMsg, err)

1
ui.go
View file

@ -211,6 +211,7 @@ func printDivider2() {
type ethrUI interface { type ethrUI interface {
fini() fini()
getTitle() string
printMsg(format string, a ...interface{}) printMsg(format string, a ...interface{})
printErr(format string, a ...interface{}) printErr(format string, a ...interface{})
printDbg(format string, a ...interface{}) printDbg(format string, a ...interface{})