2018-12-03 04:39:13 +08:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Copyright (C) Microsoft. All rights reserved.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
// See LICENSE.txt file in the project root for full license information.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
|
|
|
"time"
|
2018-12-05 12:15:56 +08:00
|
|
|
|
|
|
|
tm "github.com/nsf/termbox-go"
|
2018-12-03 04:39:13 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type ethrTestResultAggregate struct {
|
|
|
|
bw, cps, pps uint64
|
|
|
|
cbw, ccps, cpps uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
var gAggregateTestResults = make(map[EthrProtocol]*ethrTestResultAggregate)
|
|
|
|
|
|
|
|
//
|
|
|
|
// Initialization functions.
|
|
|
|
//
|
2018-12-11 23:28:33 +08:00
|
|
|
func initServerUI(showUI bool) {
|
|
|
|
gAggregateTestResults[TCP] = ðrTestResultAggregate{}
|
|
|
|
gAggregateTestResults[UDP] = ðrTestResultAggregate{}
|
|
|
|
gAggregateTestResults[HTTP] = ðrTestResultAggregate{}
|
|
|
|
gAggregateTestResults[HTTPS] = ðrTestResultAggregate{}
|
|
|
|
gAggregateTestResults[ICMP] = ðrTestResultAggregate{}
|
|
|
|
if !showUI || !initServerTui() {
|
2018-12-03 04:39:13 +08:00
|
|
|
initServerCli()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Text based UI
|
|
|
|
//
|
|
|
|
type serverTui struct {
|
|
|
|
h, w int
|
|
|
|
resX, resY, resW int
|
|
|
|
latX, latY, latW int
|
|
|
|
topVSplitX, topVSplitY, topVSplitH int
|
|
|
|
statX, statY, statW int
|
|
|
|
msgX, msgY, msgW int
|
|
|
|
botVSplitX, botVSplitY, botVSplitH int
|
|
|
|
errX, errY, errW int
|
|
|
|
res table
|
|
|
|
results [][]string
|
|
|
|
resultHdr []string
|
|
|
|
msg table
|
|
|
|
msgRing []string
|
|
|
|
err table
|
|
|
|
errRing []string
|
|
|
|
ringLock sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func initServerTui() bool {
|
|
|
|
err := initServerTuiInternal()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error: Failed to initialize UI.", err)
|
|
|
|
fmt.Println("Using command line view instead of UI")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func initServerTuiInternal() error {
|
|
|
|
err := tm.Init()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
w, h := tm.Size()
|
|
|
|
if h < 40 || w < 80 {
|
|
|
|
tm.Close()
|
|
|
|
s := fmt.Sprintf("Terminal too small (%dwx%dh), must be at least 40hx80w", w, h)
|
|
|
|
return errors.New(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
tm.SetInputMode(tm.InputEsc | tm.InputMouse)
|
|
|
|
tm.Clear(tm.ColorDefault, tm.ColorDefault)
|
|
|
|
tm.Sync()
|
|
|
|
tm.Flush()
|
2020-06-19 01:07:05 +08:00
|
|
|
hideCursor()
|
|
|
|
blockWindowResize()
|
2018-12-03 04:39:13 +08:00
|
|
|
|
|
|
|
tui := &serverTui{}
|
|
|
|
botScnH := 8
|
|
|
|
statScnW := 26
|
|
|
|
tui.h = h
|
|
|
|
tui.w = w
|
|
|
|
tui.resX = 0
|
|
|
|
tui.resY = 2
|
|
|
|
tui.resW = w - statScnW
|
|
|
|
tui.latX = 0
|
|
|
|
tui.latY = h - botScnH
|
|
|
|
tui.latW = w
|
|
|
|
tui.topVSplitX = tui.resW
|
|
|
|
tui.topVSplitY = 1
|
|
|
|
tui.topVSplitH = h - botScnH
|
|
|
|
tui.statX = tui.topVSplitX + 1
|
|
|
|
tui.statY = 2
|
|
|
|
tui.statW = statScnW
|
|
|
|
tui.msgX = 0
|
|
|
|
tui.msgY = h - botScnH + 1
|
|
|
|
tui.msgW = (w+1)/2 + 1
|
|
|
|
tui.botVSplitX = tui.msgW
|
|
|
|
tui.botVSplitY = h - botScnH
|
|
|
|
tui.botVSplitH = botScnH
|
|
|
|
tui.errX = tui.botVSplitX + 1
|
|
|
|
tui.errY = h - botScnH + 1
|
|
|
|
tui.errW = w - tui.msgW - 1
|
|
|
|
tui.res = table{6, []int{13, 5, 7, 7, 7, 8}, 0, 2, 0, justifyRight, noBorder}
|
|
|
|
tui.results = make([][]string, 0)
|
|
|
|
tui.msg = table{1, []int{tui.msgW}, tui.msgX, tui.msgY, 0, justifyLeft, noBorder}
|
|
|
|
tui.msgRing = make([]string, botScnH-1)
|
|
|
|
tui.err = table{1, []int{tui.errW}, tui.errX, tui.errY, 0, justifyLeft, noBorder}
|
|
|
|
tui.errRing = make([]string, botScnH-1)
|
|
|
|
ui = tui
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
switch ev := tm.PollEvent(); ev.Type {
|
|
|
|
case tm.EventKey:
|
|
|
|
if ev.Key == tm.KeyEsc || ev.Key == tm.KeyCtrlC {
|
|
|
|
finiServer()
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
case tm.EventResize:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) fini() {
|
|
|
|
tm.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) printMsg(format string, a ...interface{}) {
|
|
|
|
s := fmt.Sprintf(format, a...)
|
2020-06-19 01:07:05 +08:00
|
|
|
logInfo(s)
|
2018-12-03 04:39:13 +08:00
|
|
|
ss := splitString(s, u.msgW)
|
|
|
|
u.ringLock.Lock()
|
|
|
|
u.msgRing = u.msgRing[len(ss):]
|
|
|
|
u.msgRing = append(u.msgRing, ss...)
|
|
|
|
u.ringLock.Unlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) printErr(format string, a ...interface{}) {
|
|
|
|
s := fmt.Sprintf(format, a...)
|
2020-06-19 01:07:05 +08:00
|
|
|
logError(s)
|
2018-12-03 04:39:13 +08:00
|
|
|
ss := splitString(s, u.errW)
|
|
|
|
u.ringLock.Lock()
|
|
|
|
u.errRing = u.errRing[len(ss):]
|
|
|
|
u.errRing = append(u.errRing, ss...)
|
|
|
|
u.ringLock.Unlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) printDbg(format string, a ...interface{}) {
|
2020-06-19 01:07:05 +08:00
|
|
|
if loggingLevel == LogLevelDebug {
|
|
|
|
s := fmt.Sprintf(format, a...)
|
|
|
|
logDebug(s)
|
|
|
|
ss := splitString(s, u.errW)
|
|
|
|
u.ringLock.Lock()
|
|
|
|
u.errRing = u.errRing[len(ss):]
|
|
|
|
u.errRing = append(u.errRing, ss...)
|
|
|
|
u.ringLock.Unlock()
|
2018-12-11 23:28:33 +08:00
|
|
|
}
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) emitTestResultBegin() {
|
|
|
|
u.results = nil
|
|
|
|
}
|
|
|
|
|
2019-01-21 01:13:47 +08:00
|
|
|
func (u *serverTui) emitTestResult(s *ethrSession, proto EthrProtocol, seconds uint64) {
|
|
|
|
str := getTestResults(s, proto, seconds)
|
2018-12-03 04:39:13 +08:00
|
|
|
if len(str) > 0 {
|
|
|
|
ui.printTestResults(str)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) printTestResults(s []string) {
|
|
|
|
// Log before truncation of remote address.
|
2020-06-19 01:07:05 +08:00
|
|
|
logResults(s)
|
2020-11-10 21:37:52 +08:00
|
|
|
s[0] = truncateStringFromStart(s[0], 13)
|
2018-12-03 04:39:13 +08:00
|
|
|
u.results = append(u.results, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) emitTestResultEnd() {
|
|
|
|
emitAggregateResults()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) emitTestHdr() {
|
|
|
|
s := []string{"RemoteAddress", "Proto", "Bits/s", "Conn/s", "Pkts/s", "Latency"}
|
|
|
|
u.resultHdr = s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) emitLatencyHdr() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverTui) emitLatencyResults(remote, proto string, avg, min, max, p50, p90, p95, p99, p999, p9999 time.Duration) {
|
2020-06-19 01:07:05 +08:00
|
|
|
logLatency(remote, proto, avg, min, max, p50, p90, p95, p99, p999, p9999)
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
2019-01-21 01:13:47 +08:00
|
|
|
func (u *serverTui) paint(seconds uint64) {
|
2018-12-03 04:39:13 +08:00
|
|
|
tm.Clear(tm.ColorDefault, tm.ColorDefault)
|
|
|
|
defer tm.Flush()
|
2020-11-10 21:37:52 +08:00
|
|
|
printCenterText(0, 0, u.w, "Ethr (Version: "+gVersion+")", tm.ColorBlack, tm.ColorWhite)
|
2018-12-03 04:39:13 +08:00
|
|
|
printHLineText(u.resX, u.resY-1, u.resW, "Test Results")
|
|
|
|
printHLineText(u.statX, u.statY-1, u.statW, "Statistics")
|
|
|
|
printVLine(u.topVSplitX, u.topVSplitY, u.topVSplitH)
|
|
|
|
|
|
|
|
printHLineText(u.msgX, u.msgY-1, u.msgW, "Messages")
|
|
|
|
printHLineText(u.errX, u.errY-1, u.errW, "Errors")
|
|
|
|
|
|
|
|
u.ringLock.Lock()
|
|
|
|
u.msg.cr = 0
|
|
|
|
for _, s := range u.msgRing {
|
|
|
|
u.msg.addTblRow([]string{s})
|
|
|
|
}
|
|
|
|
|
|
|
|
u.err.cr = 0
|
|
|
|
for _, s := range u.errRing {
|
|
|
|
u.err.addTblRow([]string{s})
|
|
|
|
}
|
|
|
|
u.ringLock.Unlock()
|
|
|
|
|
|
|
|
printVLine(u.botVSplitX, u.botVSplitY, u.botVSplitH)
|
|
|
|
|
|
|
|
u.res.cr = 0
|
|
|
|
if u.resultHdr != nil {
|
|
|
|
u.res.addTblHdr()
|
|
|
|
u.res.addTblRow(u.resultHdr)
|
|
|
|
u.res.addTblSpr()
|
|
|
|
}
|
|
|
|
for _, s := range u.results {
|
|
|
|
u.res.addTblRow(s)
|
|
|
|
u.res.addTblSpr()
|
|
|
|
}
|
|
|
|
|
2020-06-19 01:07:05 +08:00
|
|
|
if len(gPrevNetStats.netDevStats) == 0 {
|
2018-12-03 04:39:13 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
x := u.statX
|
|
|
|
w := u.statW
|
|
|
|
y := u.statY
|
2020-06-19 01:07:05 +08:00
|
|
|
for _, ns := range gCurNetStats.netDevStats {
|
2019-01-21 01:13:47 +08:00
|
|
|
nsDiff := getNetDevStatDiff(ns, gPrevNetStats, seconds)
|
2018-12-03 04:39:13 +08:00
|
|
|
// TODO: Log the network adapter stats in file as well.
|
2020-06-19 01:07:05 +08:00
|
|
|
printText(x, y, w, fmt.Sprintf("if: %s", ns.interfaceName), tm.ColorWhite, tm.ColorBlack)
|
2018-12-03 04:39:13 +08:00
|
|
|
y++
|
2020-06-19 01:07:05 +08:00
|
|
|
printText(x, y, w, fmt.Sprintf("Tx %sbps", bytesToRate(nsDiff.txBytes)), tm.ColorWhite, tm.ColorBlack)
|
|
|
|
bw := nsDiff.txBytes * 8
|
2018-12-03 04:39:13 +08:00
|
|
|
printUsageBar(x+14, y, 10, bw, KILO, tm.ColorYellow)
|
|
|
|
y++
|
2020-06-19 01:07:05 +08:00
|
|
|
printText(x, y, w, fmt.Sprintf("Rx %sbps", bytesToRate(nsDiff.rxBytes)), tm.ColorWhite, tm.ColorBlack)
|
|
|
|
bw = nsDiff.rxBytes * 8
|
2018-12-03 04:39:13 +08:00
|
|
|
printUsageBar(x+14, y, 10, bw, KILO, tm.ColorGreen)
|
|
|
|
y++
|
2020-06-19 01:07:05 +08:00
|
|
|
printText(x, y, w, fmt.Sprintf("Tx %spps", numberToUnit(nsDiff.txPkts)), tm.ColorWhite, tm.ColorBlack)
|
|
|
|
printUsageBar(x+14, y, 10, nsDiff.txPkts, 10, tm.ColorWhite)
|
2018-12-03 04:39:13 +08:00
|
|
|
y++
|
2020-06-19 01:07:05 +08:00
|
|
|
printText(x, y, w, fmt.Sprintf("Rx %spps", numberToUnit(nsDiff.rxPkts)), tm.ColorWhite, tm.ColorBlack)
|
|
|
|
printUsageBar(x+14, y, 10, nsDiff.rxPkts, 10, tm.ColorCyan)
|
2018-12-03 04:39:13 +08:00
|
|
|
y++
|
|
|
|
printText(x, y, w, "-------------------------", tm.ColorDefault, tm.ColorDefault)
|
|
|
|
y++
|
|
|
|
}
|
|
|
|
printText(x, y, w,
|
2019-01-21 01:13:47 +08:00
|
|
|
fmt.Sprintf("Tcp Retrans: %s",
|
2020-06-19 01:07:05 +08:00
|
|
|
numberToUnit((gCurNetStats.tcpStats.segRetrans-gPrevNetStats.tcpStats.segRetrans)/seconds)),
|
2018-12-03 04:39:13 +08:00
|
|
|
tm.ColorDefault, tm.ColorDefault)
|
|
|
|
}
|
|
|
|
|
2020-06-19 01:07:05 +08:00
|
|
|
var gPrevNetStats ethrNetStat
|
|
|
|
var gCurNetStats ethrNetStat
|
2018-12-03 04:39:13 +08:00
|
|
|
|
2020-06-19 01:07:05 +08:00
|
|
|
func (u *serverTui) emitStats(netStats ethrNetStat) {
|
2018-12-03 04:39:13 +08:00
|
|
|
gPrevNetStats = gCurNetStats
|
|
|
|
gCurNetStats = netStats
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Simple command window based output
|
|
|
|
//
|
|
|
|
type serverCli struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func initServerCli() {
|
|
|
|
cli := &serverCli{}
|
|
|
|
ui = cli
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) fini() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) printMsg(format string, a ...interface{}) {
|
|
|
|
s := fmt.Sprintf(format, a...)
|
|
|
|
fmt.Println(s)
|
2020-06-19 01:07:05 +08:00
|
|
|
logInfo(s)
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) printDbg(format string, a ...interface{}) {
|
2020-06-19 01:07:05 +08:00
|
|
|
if loggingLevel != LogLevelDebug {
|
2019-10-08 05:24:01 +08:00
|
|
|
return
|
2018-12-11 23:28:33 +08:00
|
|
|
}
|
2019-10-08 05:24:01 +08:00
|
|
|
s := fmt.Sprintf(format, a...)
|
|
|
|
fmt.Println(s)
|
2020-06-19 01:07:05 +08:00
|
|
|
logDebug(s)
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) printErr(format string, a ...interface{}) {
|
|
|
|
s := fmt.Sprintf(format, a...)
|
|
|
|
fmt.Println(s)
|
2020-06-19 01:07:05 +08:00
|
|
|
logError(s)
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
2019-01-21 01:13:47 +08:00
|
|
|
func (u *serverCli) paint(seconds uint64) {
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) emitTestResultBegin() {
|
|
|
|
gSessionLock.RLock()
|
|
|
|
l := len(gSessionKeys)
|
|
|
|
gSessionLock.RUnlock()
|
|
|
|
if l > 1 {
|
|
|
|
fmt.Println("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-21 01:13:47 +08:00
|
|
|
func (u *serverCli) emitTestResult(s *ethrSession, proto EthrProtocol, seconds uint64) {
|
|
|
|
str := getTestResults(s, proto, seconds)
|
2018-12-03 04:39:13 +08:00
|
|
|
if len(str) > 0 {
|
|
|
|
ui.printTestResults(str)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) emitTestResultEnd() {
|
|
|
|
emitAggregateResults()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) emitTestHdr() {
|
|
|
|
s := []string{"RemoteAddress", "Proto", "Bits/s", "Conn/s", "Pkt/s", "Latency"}
|
|
|
|
fmt.Println("-----------------------------------------------------------")
|
|
|
|
fmt.Printf("[%13s] %5s %7s %7s %7s %8s\n", s[0], s[1], s[2], s[3], s[4], s[5])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) emitLatencyHdr() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) emitLatencyResults(remote, proto string, avg, min, max, p50, p90, p95, p99, p999, p9999 time.Duration) {
|
2020-06-19 01:07:05 +08:00
|
|
|
logLatency(remote, proto, avg, min, max, p50, p90, p95, p99, p999, p9999)
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
2020-06-19 01:07:05 +08:00
|
|
|
func (u *serverCli) emitStats(netStats ethrNetStat) {
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *serverCli) printTestResults(s []string) {
|
2020-06-19 01:07:05 +08:00
|
|
|
logResults(s)
|
2020-11-10 21:37:52 +08:00
|
|
|
fmt.Printf("[%13s] %5s %7s %7s %7s %8s\n", truncateStringFromStart(s[0], 13),
|
2018-12-03 04:39:13 +08:00
|
|
|
s[1], s[2], s[3], s[4], s[5])
|
|
|
|
}
|
|
|
|
|
|
|
|
func emitAggregateResults() {
|
2018-12-11 23:28:33 +08:00
|
|
|
var protoList = []EthrProtocol{TCP, UDP, HTTP, HTTPS, ICMP}
|
2018-12-03 04:39:13 +08:00
|
|
|
for _, proto := range protoList {
|
|
|
|
emitAggregate(proto)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func emitAggregate(proto EthrProtocol) {
|
|
|
|
str := []string{}
|
|
|
|
aggTestResult, _ := gAggregateTestResults[proto]
|
|
|
|
if aggTestResult.cbw > 1 || aggTestResult.ccps > 1 || aggTestResult.cpps > 1 {
|
|
|
|
str = []string{"[SUM]", protoToString(proto),
|
|
|
|
bytesToRate(aggTestResult.bw),
|
|
|
|
cpsToString(aggTestResult.cps),
|
|
|
|
ppsToString(aggTestResult.pps),
|
|
|
|
""}
|
|
|
|
}
|
|
|
|
aggTestResult.bw = 0
|
|
|
|
aggTestResult.cps = 0
|
|
|
|
aggTestResult.pps = 0
|
|
|
|
aggTestResult.cbw = 0
|
|
|
|
aggTestResult.ccps = 0
|
|
|
|
aggTestResult.cpps = 0
|
|
|
|
if len(str) > 0 {
|
|
|
|
ui.printTestResults(str)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-10 21:37:52 +08:00
|
|
|
func getTestResults(s *ethrSession, proto EthrProtocol, seconds uint64) []string {
|
|
|
|
|
|
|
|
var bwTestOn, cpsTestOn, ppsTestOn, latTestOn bool
|
|
|
|
var bw, cps, pps, latency uint64
|
|
|
|
aggTestResult, _ := gAggregateTestResults[proto]
|
|
|
|
test, found := s.tests[EthrTestID{proto, All}]
|
|
|
|
if found && test.isActive {
|
|
|
|
bwTestOn = true
|
|
|
|
bw = atomic.SwapUint64(&test.testResult.bw, 0)
|
|
|
|
bw /= seconds
|
|
|
|
aggTestResult.bw += bw
|
|
|
|
aggTestResult.cbw++
|
|
|
|
|
|
|
|
if proto == TCP {
|
|
|
|
cpsTestOn = true
|
|
|
|
cps = atomic.SwapUint64(&test.testResult.cps, 0)
|
|
|
|
cps /= seconds
|
|
|
|
aggTestResult.cps += cps
|
|
|
|
aggTestResult.ccps++
|
|
|
|
}
|
|
|
|
|
|
|
|
if proto == UDP {
|
|
|
|
ppsTestOn = true
|
|
|
|
pps = atomic.SwapUint64(&test.testResult.pps, 0)
|
|
|
|
pps /= seconds
|
|
|
|
aggTestResult.pps += pps
|
|
|
|
aggTestResult.cpps++
|
|
|
|
}
|
|
|
|
|
|
|
|
if proto == TCP {
|
|
|
|
latency = atomic.LoadUint64(&test.testResult.latency)
|
|
|
|
if latency > 0 {
|
|
|
|
latTestOn = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if bwTestOn || cpsTestOn || ppsTestOn || latTestOn {
|
|
|
|
var bwStr, cpsStr, ppsStr, latStr string = "-- ", "-- ", "-- ", "-- "
|
|
|
|
if bwTestOn {
|
|
|
|
bwStr = bytesToRate(bw)
|
|
|
|
}
|
|
|
|
if cpsTestOn {
|
|
|
|
cpsStr = cpsToString(cps)
|
|
|
|
}
|
|
|
|
if ppsTestOn {
|
|
|
|
ppsStr = ppsToString(pps)
|
|
|
|
}
|
|
|
|
if latTestOn {
|
|
|
|
latStr = durationToString(time.Duration(latency))
|
|
|
|
}
|
|
|
|
str := []string{s.remoteAddr, protoToString(proto),
|
|
|
|
bwStr, cpsStr, ppsStr, latStr}
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
|
|
|
return []string{}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2019-01-21 01:13:47 +08:00
|
|
|
func getTestResults(s *ethrSession, proto EthrProtocol, seconds uint64) []string {
|
2018-12-03 04:39:13 +08:00
|
|
|
var bwTestOn, cpsTestOn, ppsTestOn, latTestOn bool
|
|
|
|
var bw, cps, pps, latency uint64
|
|
|
|
aggTestResult, _ := gAggregateTestResults[proto]
|
2018-12-11 23:28:33 +08:00
|
|
|
test, found := s.tests[EthrTestID{proto, Bandwidth}]
|
2018-12-03 04:39:13 +08:00
|
|
|
if found && test.isActive {
|
|
|
|
bwTestOn = true
|
|
|
|
bw = atomic.SwapUint64(&test.testResult.data, 0)
|
2019-01-21 01:13:47 +08:00
|
|
|
bw /= seconds
|
2018-12-03 04:39:13 +08:00
|
|
|
aggTestResult.bw += bw
|
|
|
|
aggTestResult.cbw++
|
|
|
|
}
|
2018-12-11 23:28:33 +08:00
|
|
|
test, found = s.tests[EthrTestID{proto, Cps}]
|
2018-12-03 04:39:13 +08:00
|
|
|
if found && test.isActive {
|
|
|
|
cpsTestOn = true
|
|
|
|
cps = atomic.SwapUint64(&test.testResult.data, 0)
|
2019-01-21 01:13:47 +08:00
|
|
|
cps /= seconds
|
2018-12-03 04:39:13 +08:00
|
|
|
aggTestResult.cps += cps
|
|
|
|
aggTestResult.ccps++
|
|
|
|
}
|
2018-12-11 23:28:33 +08:00
|
|
|
test, found = s.tests[EthrTestID{proto, Pps}]
|
2018-12-03 04:39:13 +08:00
|
|
|
if found && test.isActive {
|
|
|
|
ppsTestOn = true
|
|
|
|
pps = atomic.SwapUint64(&test.testResult.data, 0)
|
2019-01-21 01:13:47 +08:00
|
|
|
pps /= seconds
|
2018-12-03 04:39:13 +08:00
|
|
|
aggTestResult.pps += pps
|
|
|
|
aggTestResult.cpps++
|
|
|
|
}
|
2018-12-11 23:28:33 +08:00
|
|
|
test, found = s.tests[EthrTestID{proto, Latency}]
|
2018-12-03 04:39:13 +08:00
|
|
|
if found && test.isActive {
|
|
|
|
latTestOn = true
|
|
|
|
latency = atomic.LoadUint64(&test.testResult.data)
|
|
|
|
}
|
|
|
|
if bwTestOn || cpsTestOn || ppsTestOn || latTestOn {
|
|
|
|
var bwStr, cpsStr, ppsStr, latStr string
|
|
|
|
if bwTestOn {
|
|
|
|
bwStr = bytesToRate(bw)
|
|
|
|
}
|
|
|
|
if cpsTestOn {
|
|
|
|
cpsStr = cpsToString(cps)
|
|
|
|
}
|
|
|
|
if ppsTestOn {
|
|
|
|
ppsStr = ppsToString(pps)
|
|
|
|
}
|
|
|
|
if latTestOn {
|
2020-06-19 01:07:05 +08:00
|
|
|
latStr = durationToString(time.Duration(latency))
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
str := []string{s.remoteAddr, protoToString(proto),
|
|
|
|
bwStr, cpsStr, ppsStr, latStr}
|
|
|
|
return str
|
|
|
|
}
|
|
|
|
|
|
|
|
return []string{}
|
|
|
|
}
|
2020-11-10 21:37:52 +08:00
|
|
|
*/
|