mirror of
https://github.com/microsoft/ethr.git
synced 2024-09-20 06:46:14 +08:00
Refactor command line usage functions (#87)
* Created an internal package as an initial framework for refactoring * Refactored command line usage functions into the new internal package
This commit is contained in:
parent
90c8f2467c
commit
1c9b13b30e
210
ethr.go
210
ethr.go
|
@ -8,193 +8,17 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/microsoft/ethr/internal/cmd"
|
||||
)
|
||||
|
||||
const defaultLogFileName = "./ethrs.log for server, ./ethrc.log for client"
|
||||
|
||||
var gVersion string
|
||||
|
||||
func printFlagUsage(flag, info string, helptext ...string) {
|
||||
fmt.Printf("\t-%s %s\n", flag, info)
|
||||
for _, help := range helptext {
|
||||
fmt.Printf("\t\t%s\n", help)
|
||||
}
|
||||
}
|
||||
|
||||
func printServerUsage() {
|
||||
printFlagUsage("s", "", "Run in server mode.")
|
||||
}
|
||||
|
||||
func printClientUsage() {
|
||||
printFlagUsage("c", "<server>", "Run in client mode and connect to <server>.",
|
||||
"Server is specified using name, FQDN or IP address.")
|
||||
}
|
||||
|
||||
func printExtClientUsage() {
|
||||
printFlagUsage("c", "<destination>", "Run in external client mode and connect to <destination>.",
|
||||
"<destination> is specified using host:port format.",
|
||||
"Example: www.microsoft.com:443 or 10.1.0.4:22 etc.")
|
||||
}
|
||||
|
||||
func printPortUsage() {
|
||||
printFlagUsage("ports", "<k=v,...>", "Use custom port numbers instead of default ones.",
|
||||
"A comma separated list of key=value pair is used.",
|
||||
"Key specifies the protocol, and value specifies base port.",
|
||||
"Ports used for various tests are calculated from base port.",
|
||||
"Example: For TCP, Bw: 9999, CPS: 9998, PPS: 9997, Latency: 9996",
|
||||
"Control is used for control channel communication for ethr.",
|
||||
"Note: Same configuration must be used on both client & server.",
|
||||
"Default: 'control=8888,tcp=9999,udp=9999,http=9899,https=9799'")
|
||||
}
|
||||
|
||||
func printExtPortUsage() {
|
||||
printFlagUsage("ports", "<k=v,...>", "Use custom port numbers instead of default ones.",
|
||||
"A comma separated list of key=value pair is used.",
|
||||
"Key specifies the protocol, and value specifies the port.",
|
||||
"Default: 'tcp=9999,http=9899,https=9799'")
|
||||
}
|
||||
|
||||
func printTestType() {
|
||||
printFlagUsage("t", "<test>", "Test to run (\"b\", \"c\", \"p\", or \"l\")",
|
||||
"b: Bandwidth",
|
||||
"c: Connections/s or Requests/s",
|
||||
"p: Packets/s",
|
||||
"l: Latency, Loss & Jitter",
|
||||
"Default: b - Bandwidth measurement.")
|
||||
}
|
||||
|
||||
func printExtTestType() {
|
||||
printFlagUsage("t", "<test>", "Test to run (\"b\", \"c\", or \"cl\")",
|
||||
"b: Bandwidth",
|
||||
"c: Connections/s or Requests/s",
|
||||
"cl: TCP connection setup latency",
|
||||
"Default: cl - TCP connection setup latency.")
|
||||
}
|
||||
|
||||
func printThreadUsage() {
|
||||
printFlagUsage("n", "<number>", "Number of Parallel Sessions (and Threads).",
|
||||
"0: Equal to number of CPUs",
|
||||
"Default: 1")
|
||||
}
|
||||
|
||||
func printDurationUsage() {
|
||||
printFlagUsage("d", "<duration>",
|
||||
"Duration for the test (format: <num>[ms | s | m | h]",
|
||||
"0: Run forever",
|
||||
"Default: 10s")
|
||||
}
|
||||
|
||||
func printGapUsage() {
|
||||
printFlagUsage("g", "<gap>",
|
||||
"Time interval between successive measurements (format: <num>[ms | s | m | h]",
|
||||
"0: No gap",
|
||||
"Default: 1s")
|
||||
}
|
||||
|
||||
func printBufLenUsage() {
|
||||
printFlagUsage("l", "<length>",
|
||||
"Length of buffer to use (format: <num>[KB | MB | GB])",
|
||||
"Only valid for Bandwidth tests. Max 1GB.",
|
||||
"Default: 16KB")
|
||||
}
|
||||
|
||||
func printProtocolUsage() {
|
||||
printFlagUsage("p", "<protocol>",
|
||||
"Protocol (\"tcp\", \"udp\", \"http\", \"https\", or \"icmp\")",
|
||||
"Default: tcp")
|
||||
}
|
||||
|
||||
func printExtProtocolUsage() {
|
||||
printFlagUsage("p", "<protocol>",
|
||||
"Protocol (\"tcp\", \"http\", \"https\", or \"icmp\")",
|
||||
"Default: tcp")
|
||||
}
|
||||
|
||||
func printIterationUsage() {
|
||||
printFlagUsage("i", "<iterations>",
|
||||
"Number of round trip iterations for each latency measurement.",
|
||||
"Default: 1000")
|
||||
}
|
||||
|
||||
func printModeUsage() {
|
||||
printFlagUsage("m", "<mode>",
|
||||
"'-m x' MUST be specified for external mode.")
|
||||
}
|
||||
|
||||
func printNoConnStatUsage() {
|
||||
printFlagUsage("ncs", "",
|
||||
"No per Connection Stats would be printed if this flag is specified.",
|
||||
"This is useful to suppress verbose logging when large number of",
|
||||
"connections are used as specified by -n option for Bandwidth tests.")
|
||||
}
|
||||
|
||||
func printIgnoreCertUsage() {
|
||||
printFlagUsage("ic", "",
|
||||
"Ignore Certificate is useful for HTTPS tests, for cases where a",
|
||||
"middle box like a proxy is not able to supply a valid Ethr cert.")
|
||||
}
|
||||
|
||||
func ethrUsage() {
|
||||
fmt.Println("\nEthr - A comprehensive network performance measurement tool.")
|
||||
fmt.Println("Version: " + gVersion)
|
||||
fmt.Println("It supports 4 modes. Usage of each mode is described below:")
|
||||
|
||||
fmt.Println("\nCommon Parameters")
|
||||
fmt.Println("================================================================================")
|
||||
printFlagUsage("h", "", "Help")
|
||||
printFlagUsage("no", "", "Disable logging to file. Logging to file is enabled by default.")
|
||||
printFlagUsage("o", "<filename>", "Name of log file. By default, following file names are used:",
|
||||
"Server mode: 'ethrs.log'",
|
||||
"Client mode: 'ethrc.log'",
|
||||
"External server mode: 'ethrxs.log'",
|
||||
"External client mode: 'ethrxc.log'")
|
||||
printFlagUsage("debug", "", "Enable debug information in logging output.")
|
||||
printFlagUsage("4", "", "Use only IP v4 version")
|
||||
printFlagUsage("6", "", "Use only IP v6 version")
|
||||
|
||||
fmt.Println("\nMode: Server")
|
||||
fmt.Println("================================================================================")
|
||||
printServerUsage()
|
||||
printFlagUsage("ui", "", "Show output in text UI.")
|
||||
printPortUsage()
|
||||
|
||||
fmt.Println("\nMode: Client")
|
||||
fmt.Println("================================================================================")
|
||||
printClientUsage()
|
||||
printFlagUsage("r", "", "For Bandwidth tests, send data from server to client.")
|
||||
printDurationUsage()
|
||||
printThreadUsage()
|
||||
printNoConnStatUsage()
|
||||
printBufLenUsage()
|
||||
printProtocolUsage()
|
||||
printIgnoreCertUsage()
|
||||
printPortUsage()
|
||||
printTestType()
|
||||
printIterationUsage()
|
||||
|
||||
fmt.Println("\nMode: External Server")
|
||||
fmt.Println("================================================================================")
|
||||
printModeUsage()
|
||||
printServerUsage()
|
||||
printExtPortUsage()
|
||||
|
||||
fmt.Println("\nMode: External Client")
|
||||
fmt.Println("================================================================================")
|
||||
printModeUsage()
|
||||
printExtClientUsage()
|
||||
printDurationUsage()
|
||||
printThreadUsage()
|
||||
printNoConnStatUsage()
|
||||
printBufLenUsage()
|
||||
printExtProtocolUsage()
|
||||
printExtTestType()
|
||||
printGapUsage()
|
||||
}
|
||||
|
||||
func main() {
|
||||
//
|
||||
// If version is not set via ldflags, then default to UNKNOWN
|
||||
|
@ -211,7 +35,7 @@ func main() {
|
|||
//
|
||||
runtime.GOMAXPROCS(1024)
|
||||
|
||||
flag.Usage = ethrUsage
|
||||
flag.Usage = func() { cmd.EthrUsage(gVersion) }
|
||||
isServer := flag.Bool("s", false, "")
|
||||
clientDest := flag.String("c", "", "")
|
||||
testTypePtr := flag.String("t", "", "")
|
||||
|
@ -257,13 +81,13 @@ func main() {
|
|||
case "x":
|
||||
xMode = true
|
||||
default:
|
||||
printUsageError("Invalid value for execution mode (-m).")
|
||||
cmd.PrintUsageError("Invalid value for execution mode (-m).")
|
||||
}
|
||||
mode := ethrModeInv
|
||||
|
||||
if *isServer {
|
||||
if *clientDest != "" {
|
||||
printUsageError("Invalid arguments, \"-c\" cannot be used with \"-s\".")
|
||||
cmd.PrintUsageError("Invalid arguments, \"-c\" cannot be used with \"-s\".")
|
||||
}
|
||||
if xMode {
|
||||
mode = ethrModeExtServer
|
||||
|
@ -277,11 +101,11 @@ func main() {
|
|||
mode = ethrModeClient
|
||||
}
|
||||
} else {
|
||||
printUsageError("Invalid arguments, use either \"-s\" or \"-c\".")
|
||||
cmd.PrintUsageError("Invalid arguments, use either \"-s\" or \"-c\".")
|
||||
}
|
||||
|
||||
if *reverse && mode != ethrModeClient {
|
||||
printUsageError("Invalid arguments, \"-r\" can only be used in client mode.")
|
||||
cmd.PrintUsageError("Invalid arguments, \"-r\" can only be used in client mode.")
|
||||
}
|
||||
|
||||
if *use4 && !*use6 {
|
||||
|
@ -292,11 +116,11 @@ func main() {
|
|||
|
||||
bufLen := unitToNumber(*bufLenStr)
|
||||
if bufLen == 0 {
|
||||
printUsageError(fmt.Sprintf("Invalid length specified: %s" + *bufLenStr))
|
||||
cmd.PrintUsageError(fmt.Sprintf("Invalid length specified: %s" + *bufLenStr))
|
||||
}
|
||||
|
||||
if *rttCount <= 0 {
|
||||
printUsageError(fmt.Sprintf("Invalid RTT count for latency test: %d", *rttCount))
|
||||
cmd.PrintUsageError(fmt.Sprintf("Invalid RTT count for latency test: %d", *rttCount))
|
||||
}
|
||||
|
||||
var testType EthrTestType
|
||||
|
@ -323,7 +147,7 @@ func main() {
|
|||
case "cl":
|
||||
testType = ConnLatency
|
||||
default:
|
||||
printUsageError(fmt.Sprintf("Invalid value \"%s\" specified for parameter \"-t\".\n"+
|
||||
cmd.PrintUsageError(fmt.Sprintf("Invalid value \"%s\" specified for parameter \"-t\".\n"+
|
||||
"Valid parameters and values are:\n", *testTypePtr))
|
||||
}
|
||||
|
||||
|
@ -341,7 +165,7 @@ func main() {
|
|||
case "ICMP":
|
||||
proto = ICMP
|
||||
default:
|
||||
printUsageError(fmt.Sprintf("Invalid value \"%s\" specified for parameter \"-p\".\n"+
|
||||
cmd.PrintUsageError(fmt.Sprintf("Invalid value \"%s\" specified for parameter \"-p\".\n"+
|
||||
"Valid parameters and values are:\n", *protocol))
|
||||
}
|
||||
|
||||
|
@ -400,12 +224,12 @@ func main() {
|
|||
}
|
||||
|
||||
func emitUnsupportedTest(testParam EthrTestParam) {
|
||||
printUsageError(fmt.Sprintf("\"%s\" test for \"%s\" is not supported.\n",
|
||||
cmd.PrintUsageError(fmt.Sprintf("\"%s\" test for \"%s\" is not supported.\n",
|
||||
testToString(testParam.TestID.Type), protoToString(testParam.TestID.Protocol)))
|
||||
}
|
||||
|
||||
func printReverseModeError() {
|
||||
printUsageError("Reverse mode (-r) is only supported for TCP Bandwidth tests.")
|
||||
cmd.PrintUsageError("Reverse mode (-r) is only supported for TCP Bandwidth tests.")
|
||||
}
|
||||
|
||||
func validateTestParam(mode ethrMode, testParam EthrTestParam) {
|
||||
|
@ -430,7 +254,7 @@ func validateTestParam(mode ethrMode, testParam EthrTestParam) {
|
|||
}
|
||||
if testType == Bandwidth {
|
||||
if testParam.BufferSize > (64 * 1024) {
|
||||
printUsageError("Maximum supported buffer size for UDP is 64K\n")
|
||||
cmd.PrintUsageError("Maximum supported buffer size for UDP is 64K\n")
|
||||
}
|
||||
}
|
||||
if testParam.Reverse {
|
||||
|
@ -459,9 +283,3 @@ func validateTestParam(mode ethrMode, testParam EthrTestParam) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printUsageError(s string) {
|
||||
fmt.Printf("Error: %s\n", s)
|
||||
fmt.Printf("Please use \"ethr -h\" for ethr command line arguments.\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
61
internal/cmd/cmd.go
Normal file
61
internal/cmd/cmd.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package cmd
|
||||
|
||||
import "fmt"
|
||||
|
||||
// EthrUsage prints the command-line usage text
|
||||
func EthrUsage(gVersion string) {
|
||||
fmt.Println("\nEthr - A comprehensive network performance measurement tool.")
|
||||
fmt.Println("Version: " + gVersion)
|
||||
fmt.Println("It supports 4 modes. Usage of each mode is described below:")
|
||||
|
||||
fmt.Println("\nCommon Parameters")
|
||||
fmt.Println("================================================================================")
|
||||
PrintFlagUsage("h", "", "Help")
|
||||
PrintFlagUsage("no", "", "Disable logging to file. Logging to file is enabled by default.")
|
||||
PrintFlagUsage("o", "<filename>", "Name of log file. By default, following file names are used:",
|
||||
"Server mode: 'ethrs.log'",
|
||||
"Client mode: 'ethrc.log'",
|
||||
"External server mode: 'ethrxs.log'",
|
||||
"External client mode: 'ethrxc.log'")
|
||||
PrintFlagUsage("debug", "", "Enable debug information in logging output.")
|
||||
PrintFlagUsage("4", "", "Use only IP v4 version")
|
||||
PrintFlagUsage("6", "", "Use only IP v6 version")
|
||||
|
||||
fmt.Println("\nMode: Server")
|
||||
fmt.Println("================================================================================")
|
||||
PrintServerUsage()
|
||||
PrintFlagUsage("ui", "", "Show output in text UI.")
|
||||
PrintPortUsage()
|
||||
|
||||
fmt.Println("\nMode: Client")
|
||||
fmt.Println("================================================================================")
|
||||
PrintClientUsage()
|
||||
PrintFlagUsage("r", "", "For Bandwidth tests, send data from server to client.")
|
||||
PrintDurationUsage()
|
||||
PrintThreadUsage()
|
||||
PrintNoConnStatUsage()
|
||||
PrintBufLenUsage()
|
||||
PrintProtocolUsage()
|
||||
PrintIgnoreCertUsage()
|
||||
PrintPortUsage()
|
||||
PrintTestType()
|
||||
PrintIterationUsage()
|
||||
|
||||
fmt.Println("\nMode: External Server")
|
||||
fmt.Println("================================================================================")
|
||||
PrintModeUsage()
|
||||
PrintServerUsage()
|
||||
PrintExtPortUsage()
|
||||
|
||||
fmt.Println("\nMode: External Client")
|
||||
fmt.Println("================================================================================")
|
||||
PrintModeUsage()
|
||||
PrintExtClientUsage()
|
||||
PrintDurationUsage()
|
||||
PrintThreadUsage()
|
||||
PrintNoConnStatUsage()
|
||||
PrintBufLenUsage()
|
||||
PrintExtProtocolUsage()
|
||||
PrintExtTestType()
|
||||
PrintGapUsage()
|
||||
}
|
132
internal/cmd/usage_helpers.go
Normal file
132
internal/cmd/usage_helpers.go
Normal file
|
@ -0,0 +1,132 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func PrintFlagUsage(flag, info string, helptext ...string) {
|
||||
fmt.Printf("\t-%s %s\n", flag, info)
|
||||
for _, help := range helptext {
|
||||
fmt.Printf("\t\t%s\n", help)
|
||||
}
|
||||
}
|
||||
|
||||
func PrintServerUsage() {
|
||||
PrintFlagUsage("s", "", "Run in server mode.")
|
||||
}
|
||||
|
||||
func PrintClientUsage() {
|
||||
PrintFlagUsage("c", "<server>", "Run in client mode and connect to <server>.",
|
||||
"Server is specified using name, FQDN or IP address.")
|
||||
}
|
||||
|
||||
func PrintExtClientUsage() {
|
||||
PrintFlagUsage("c", "<destination>", "Run in external client mode and connect to <destination>.",
|
||||
"<destination> is specified using host:port format.",
|
||||
"Example: www.microsoft.com:443 or 10.1.0.4:22 etc.")
|
||||
}
|
||||
|
||||
func PrintPortUsage() {
|
||||
PrintFlagUsage("ports", "<k=v,...>", "Use custom port numbers instead of default ones.",
|
||||
"A comma separated list of key=value pair is used.",
|
||||
"Key specifies the protocol, and value specifies base port.",
|
||||
"Ports used for various tests are calculated from base port.",
|
||||
"Example: For TCP, Bw: 9999, CPS: 9998, PPS: 9997, Latency: 9996",
|
||||
"Control is used for control channel communication for ethr.",
|
||||
"Note: Same configuration must be used on both client & server.",
|
||||
"Default: 'control=8888,tcp=9999,udp=9999,http=9899,https=9799'")
|
||||
}
|
||||
|
||||
func PrintExtPortUsage() {
|
||||
PrintFlagUsage("ports", "<k=v,...>", "Use custom port numbers instead of default ones.",
|
||||
"A comma separated list of key=value pair is used.",
|
||||
"Key specifies the protocol, and value specifies the port.",
|
||||
"Default: 'tcp=9999,http=9899,https=9799'")
|
||||
}
|
||||
|
||||
func PrintTestType() {
|
||||
PrintFlagUsage("t", "<test>", "Test to run (\"b\", \"c\", \"p\", or \"l\")",
|
||||
"b: Bandwidth",
|
||||
"c: Connections/s or Requests/s",
|
||||
"p: Packets/s",
|
||||
"l: Latency, Loss & Jitter",
|
||||
"Default: b - Bandwidth measurement.")
|
||||
}
|
||||
|
||||
func PrintExtTestType() {
|
||||
PrintFlagUsage("t", "<test>", "Test to run (\"b\", \"c\", or \"cl\")",
|
||||
"b: Bandwidth",
|
||||
"c: Connections/s or Requests/s",
|
||||
"cl: TCP connection setup latency",
|
||||
"Default: cl - TCP connection setup latency.")
|
||||
}
|
||||
|
||||
func PrintThreadUsage() {
|
||||
PrintFlagUsage("n", "<number>", "Number of Parallel Sessions (and Threads).",
|
||||
"0: Equal to number of CPUs",
|
||||
"Default: 1")
|
||||
}
|
||||
|
||||
func PrintDurationUsage() {
|
||||
PrintFlagUsage("d", "<duration>",
|
||||
"Duration for the test (format: <num>[ms | s | m | h]",
|
||||
"0: Run forever",
|
||||
"Default: 10s")
|
||||
}
|
||||
|
||||
func PrintGapUsage() {
|
||||
PrintFlagUsage("g", "<gap>",
|
||||
"Time interval between successive measurements (format: <num>[ms | s | m | h]",
|
||||
"0: No gap",
|
||||
"Default: 1s")
|
||||
}
|
||||
|
||||
func PrintBufLenUsage() {
|
||||
PrintFlagUsage("l", "<length>",
|
||||
"Length of buffer to use (format: <num>[KB | MB | GB])",
|
||||
"Only valid for Bandwidth tests. Max 1GB.",
|
||||
"Default: 16KB")
|
||||
}
|
||||
|
||||
func PrintProtocolUsage() {
|
||||
PrintFlagUsage("p", "<protocol>",
|
||||
"Protocol (\"tcp\", \"udp\", \"http\", \"https\", or \"icmp\")",
|
||||
"Default: tcp")
|
||||
}
|
||||
|
||||
func PrintExtProtocolUsage() {
|
||||
PrintFlagUsage("p", "<protocol>",
|
||||
"Protocol (\"tcp\", \"http\", \"https\", or \"icmp\")",
|
||||
"Default: tcp")
|
||||
}
|
||||
|
||||
func PrintIterationUsage() {
|
||||
PrintFlagUsage("i", "<iterations>",
|
||||
"Number of round trip iterations for each latency measurement.",
|
||||
"Default: 1000")
|
||||
}
|
||||
|
||||
func PrintModeUsage() {
|
||||
PrintFlagUsage("m", "<mode>",
|
||||
"'-m x' MUST be specified for external mode.")
|
||||
}
|
||||
|
||||
func PrintNoConnStatUsage() {
|
||||
PrintFlagUsage("ncs", "",
|
||||
"No per Connection Stats would be printed if this flag is specified.",
|
||||
"This is useful to suppress verbose logging when large number of",
|
||||
"connections are used as specified by -n option for Bandwidth tests.")
|
||||
}
|
||||
|
||||
func PrintIgnoreCertUsage() {
|
||||
PrintFlagUsage("ic", "",
|
||||
"Ignore Certificate is useful for HTTPS tests, for cases where a",
|
||||
"middle box like a proxy is not able to supply a valid Ethr cert.")
|
||||
}
|
||||
|
||||
func PrintUsageError(s string) {
|
||||
fmt.Printf("Error: %s\n", s)
|
||||
fmt.Printf("Please use \"ethr -h\" for ethr command line arguments.\n")
|
||||
os.Exit(1)
|
||||
}
|
Loading…
Reference in a new issue