unvendored other main
This commit is contained in:
parent
28d19e43f8
commit
daefb15f3d
220
vendor/github.com/traetox/speedtest/main.go
generated
vendored
220
vendor/github.com/traetox/speedtest/main.go
generated
vendored
@ -1,220 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Bowery/prompt"
|
|
||||||
"github.com/bndr/gotabulate"
|
|
||||||
"github.com/joliv/spark"
|
|
||||||
stdn "github.com/traetox/speedtest/speedtestdotnet"
|
|
||||||
//stdn "./speedtestdotnet" //for testing
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
tableFormat = "simple"
|
|
||||||
maxFailureCount = 3
|
|
||||||
initialTestCount = 5
|
|
||||||
basePingCount = 5
|
|
||||||
fullTestCount = 20
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
speedtestDuration = flag.Int("t", 3, "Target duration for speedtests (in seconds)")
|
|
||||||
search = flag.String("s", "", "Server name substring to search candidate servers")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Parse()
|
|
||||||
if *speedtestDuration <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "Invalid test duration")
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
cfg, err := stdn.GetConfig()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("ERROR: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(cfg.Servers) <= 0 {
|
|
||||||
fmt.Printf("No acceptable servers found\n")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var headers []string
|
|
||||||
var data [][]string
|
|
||||||
var testServers []stdn.Testserver
|
|
||||||
if *search == "" {
|
|
||||||
fmt.Printf("Gathering server list and testing...\n")
|
|
||||||
if testServers, err = autoGetTestServers(cfg); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
fmt.Printf("%d Closest responding servers:\n", len(testServers))
|
|
||||||
for i := range testServers {
|
|
||||||
data = append(data, []string{fmt.Sprintf("%d", i),
|
|
||||||
testServers[i].Name, testServers[i].Sponsor,
|
|
||||||
fmt.Sprintf("%.02f", testServers[i].Distance),
|
|
||||||
fmt.Sprintf("%s", testServers[i].Latency)})
|
|
||||||
}
|
|
||||||
headers = []string{"ID", "Name", "Sponsor", "Distance (km)", "Latency (ms)"}
|
|
||||||
} else {
|
|
||||||
if testServers, err = getSearchServers(cfg, *search); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
headers = []string{"ID", "Name", "Sponsor", "Distance (km)"}
|
|
||||||
fmt.Printf("%d Matching servers:\n", len(testServers))
|
|
||||||
for i := range testServers {
|
|
||||||
data = append(data, []string{fmt.Sprintf("%d", i),
|
|
||||||
testServers[i].Name, testServers[i].Sponsor,
|
|
||||||
fmt.Sprintf("%.02f", testServers[i].Distance)})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
t := gotabulate.Create(data)
|
|
||||||
t.SetHeaders(headers)
|
|
||||||
t.SetWrapStrings(false)
|
|
||||||
fmt.Printf("%s", t.Render(tableFormat))
|
|
||||||
fmt.Printf("Enter server ID for bandwidth test, or \"quit\" to exit\n")
|
|
||||||
for {
|
|
||||||
s, err := prompt.Basic("ID> ", true)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("input failure \"%v\"\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
//be REALLY forgiving on exit logic
|
|
||||||
if strings.HasPrefix(strings.ToLower(s), "exit") {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(strings.ToLower(s), "quit") {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
//try to convert the string to a number
|
|
||||||
id, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "\"%s\" is not a valid id\n", s)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if id > uint64(len(testServers)) {
|
|
||||||
fmt.Fprintf(os.Stderr, "No server with ID \"%d\" available\n", id)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err = fullTest(testServers[id]); err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
fmt.Fprintf(os.Stderr, "Error, the remote server kicked us.\n")
|
|
||||||
fmt.Fprintf(os.Stderr, "Maximum request size may have changed\n")
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "Test failed with unknown error: %v\n", err)
|
|
||||||
}
|
|
||||||
os.Exit(-1)
|
|
||||||
} else {
|
|
||||||
break //we are done
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLatency(server stdn.Testserver) error {
|
|
||||||
//perform a full latency test
|
|
||||||
durs, err := server.Ping(fullTestCount)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var avg, max, min uint64
|
|
||||||
var latencies []float64
|
|
||||||
for i := range durs {
|
|
||||||
ms := uint64(durs[i].Nanoseconds() / 1000000)
|
|
||||||
latencies = append(latencies, float64(ms))
|
|
||||||
avg += ms
|
|
||||||
if ms > max {
|
|
||||||
max = ms
|
|
||||||
}
|
|
||||||
if ms < min || min == 0 {
|
|
||||||
min = ms
|
|
||||||
}
|
|
||||||
}
|
|
||||||
avg = avg / uint64(len(durs))
|
|
||||||
median := durs[len(durs)/2].Nanoseconds() / 1000000
|
|
||||||
sparkline := spark.Line(latencies)
|
|
||||||
fmt.Printf("Latency: %s\t%dms avg\t%dms median\t%dms max\t%dms min\n", sparkline, avg, median, max, min)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDownstream(server stdn.Testserver) error {
|
|
||||||
bps, err := server.Downstream(*speedtestDuration)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("Download: %s\n", stdn.HumanSpeed(bps))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func testUpstream(server stdn.Testserver) error {
|
|
||||||
bps, err := server.Upstream(*speedtestDuration)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("Upload: %s\n", stdn.HumanSpeed(bps))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fullTest(server stdn.Testserver) error {
|
|
||||||
if err := testLatency(server); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := testDownstream(server); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := testUpstream(server); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func autoGetTestServers(cfg *stdn.Config) ([]stdn.Testserver, error) {
|
|
||||||
//get the first 5 closest servers
|
|
||||||
testServers := []stdn.Testserver{}
|
|
||||||
failures := 0
|
|
||||||
for i := range cfg.Servers {
|
|
||||||
if failures >= maxFailureCount {
|
|
||||||
if len(testServers) > 0 {
|
|
||||||
return testServers, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("Failed to perform latency test on closest servers\n")
|
|
||||||
}
|
|
||||||
if len(testServers) >= initialTestCount {
|
|
||||||
return testServers, nil
|
|
||||||
}
|
|
||||||
//get a latency from the server, the last latency will also be store in the
|
|
||||||
//server structure
|
|
||||||
if _, err := cfg.Servers[i].MedianPing(basePingCount); err != nil {
|
|
||||||
failures++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
testServers = append(testServers, cfg.Servers[i])
|
|
||||||
}
|
|
||||||
return testServers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSearchServers(cfg *stdn.Config, query string) ([]stdn.Testserver, error) {
|
|
||||||
//get the first 5 closest servers
|
|
||||||
testServers := []stdn.Testserver{}
|
|
||||||
for i := range cfg.Servers {
|
|
||||||
if strings.Contains(strings.ToLower(cfg.Servers[i].Name), strings.ToLower(query)) {
|
|
||||||
testServers = append(testServers, cfg.Servers[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(testServers) == 0 {
|
|
||||||
return nil, errors.New("no servers found")
|
|
||||||
}
|
|
||||||
return testServers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user