diff --git a/cmd/speedtest/speedtest.go b/cmd/speedtest/speedtest.go index d63e0d239..33646a44f 100644 --- a/cmd/speedtest/speedtest.go +++ b/cmd/speedtest/speedtest.go @@ -110,11 +110,12 @@ func runSpeedtest(ctx context.Context, args []string) error { w := tabwriter.NewWriter(os.Stdout, 12, 0, 0, ' ', tabwriter.TabIndent) fmt.Println("Results:") fmt.Fprintln(w, "Interval\t\tTransfer\t\tBandwidth\t\t") + startTime := results[0].IntervalStart for _, r := range results { if r.Total { fmt.Fprintln(w, "-------------------------------------------------------------------------") } - fmt.Fprintf(w, "%.2f-%.2f\tsec\t%.4f\tMBits\t%.4f\tMbits/sec\t\n", r.IntervalStart.Seconds(), r.IntervalEnd.Seconds(), r.MegaBits(), r.MBitsPerSecond()) + fmt.Fprintf(w, "%.2f-%.2f\tsec\t%.4f\tMBits\t%.4f\tMbits/sec\t\n", r.IntervalStart.Sub(startTime).Seconds(), r.IntervalEnd.Sub(startTime).Seconds(), r.MegaBits(), r.MBitsPerSecond()) } w.Flush() return nil diff --git a/net/speedtest/speedtest.go b/net/speedtest/speedtest.go index adcb2b54d..8f7059b89 100644 --- a/net/speedtest/speedtest.go +++ b/net/speedtest/speedtest.go @@ -11,11 +11,11 @@ import ( ) const ( - blockSize = 32000 // size of the block of data to send + blockSize = 2 * 1024 * 1024 // size of the block of data to send MinDuration = 5 * time.Second // minimum duration for a test DefaultDuration = MinDuration // default duration for a test MaxDuration = 30 * time.Second // maximum duration for a test - version = 1 // value used when comparing client and server versions + version = 2 // value used when comparing client and server versions increment = time.Second // increment to display results for, in seconds minInterval = 10 * time.Millisecond // minimum interval length for a result to be included DefaultPort = 20333 @@ -37,14 +37,14 @@ type configResponse struct { // This represents the Result of a speedtest within a specific interval type Result struct { - Bytes int // number of bytes sent/received during the interval - IntervalStart time.Duration // duration between the start of the interval and the start of the test - IntervalEnd time.Duration // duration between the end of the interval and the start of the test - Total bool // if true, this result struct represents the entire test, rather than a segment of the test + Bytes int // number of bytes sent/received during the interval + IntervalStart time.Time // start of the interval + IntervalEnd time.Time // end of the interval + Total bool // if true, this result struct represents the entire test, rather than a segment of the test } func (r Result) MBitsPerSecond() float64 { - return r.MegaBits() / (r.IntervalEnd - r.IntervalStart).Seconds() + return r.MegaBits() / r.IntervalEnd.Sub(r.IntervalStart).Seconds() } func (r Result) MegaBytes() float64 { @@ -56,7 +56,7 @@ func (r Result) MegaBits() float64 { } func (r Result) Interval() time.Duration { - return r.IntervalEnd - r.IntervalStart + return r.IntervalEnd.Sub(r.IntervalStart) } type Direction int diff --git a/net/speedtest/speedtest_server.go b/net/speedtest/speedtest_server.go index b3571dd96..c83703194 100644 --- a/net/speedtest/speedtest_server.go +++ b/net/speedtest/speedtest_server.go @@ -81,9 +81,6 @@ func doTest(conn net.Conn, conf config) ([]Result, error) { var currentTime time.Time var results []Result - startTime := time.Now() - lastCalculated := startTime - if conf.Direction == Download { conn.SetReadDeadline(time.Now().Add(conf.TestDuration).Add(5 * time.Second)) } else { @@ -94,6 +91,9 @@ func doTest(conn net.Conn, conf config) ([]Result, error) { } + startTime := time.Now() + lastCalculated := startTime + SpeedTestLoop: for { var n int @@ -110,48 +110,37 @@ SpeedTestLoop: return nil, fmt.Errorf("unexpected error has occurred: %w", err) } } else { - // Need to change the data a little bit, to avoid any compression. - for i := range bufferData { - bufferData[i]++ - } n, err = conn.Write(bufferData) if err != nil { // If the write failed, there is most likely something wrong with the connection. return nil, fmt.Errorf("upload failed: %w", err) } } - currentTime = time.Now() intervalBytes += n + currentTime = time.Now() // checks if the current time is more or equal to the lastCalculated time plus the increment - if currentTime.After(lastCalculated.Add(increment)) { - intervalStart := lastCalculated.Sub(startTime) - intervalEnd := currentTime.Sub(startTime) - if (intervalEnd - intervalStart) > minInterval { - results = append(results, Result{Bytes: intervalBytes, IntervalStart: intervalStart, IntervalEnd: intervalEnd, Total: false}) - } + if currentTime.Sub(lastCalculated) >= increment { + results = append(results, Result{Bytes: intervalBytes, IntervalStart: lastCalculated, IntervalEnd: currentTime, Total: false}) lastCalculated = currentTime totalBytes += intervalBytes intervalBytes = 0 } - if conf.Direction == Upload && time.Since(startTime) > conf.TestDuration { + if conf.Direction == Upload && currentTime.Sub(startTime) > conf.TestDuration { break SpeedTestLoop } } // get last segment - intervalStart := lastCalculated.Sub(startTime) - intervalEnd := currentTime.Sub(startTime) - if (intervalEnd - intervalStart) > minInterval { - results = append(results, Result{Bytes: intervalBytes, IntervalStart: intervalStart, IntervalEnd: intervalEnd, Total: false}) + if currentTime.Sub(lastCalculated) > minInterval { + results = append(results, Result{Bytes: intervalBytes, IntervalStart: lastCalculated, IntervalEnd: currentTime, Total: false}) } // get total totalBytes += intervalBytes - intervalEnd = currentTime.Sub(startTime) - if intervalEnd > minInterval { - results = append(results, Result{Bytes: totalBytes, IntervalStart: 0, IntervalEnd: intervalEnd, Total: true}) + if currentTime.Sub(startTime) > minInterval { + results = append(results, Result{Bytes: totalBytes, IntervalStart: startTime, IntervalEnd: currentTime, Total: true}) } return results, nil diff --git a/net/speedtest/speedtest_test.go b/net/speedtest/speedtest_test.go index 5bf089496..cdcd51e5b 100644 --- a/net/speedtest/speedtest_test.go +++ b/net/speedtest/speedtest_test.go @@ -7,6 +7,7 @@ package speedtest import ( "net" "testing" + "time" ) func TestDownload(t *testing.T) { @@ -23,9 +24,9 @@ func TestDownload(t *testing.T) { type state struct { err error } - displayResult := func(t *testing.T, r Result) { + displayResult := func(t *testing.T, r Result, start time.Time) { t.Helper() - t.Logf("{ Megabytes: %.2f, Start: %.1f, End: %.1f, Total: %t }", r.MegaBytes(), r.IntervalStart.Seconds(), r.IntervalEnd.Seconds(), r.Total) + t.Logf("{ Megabytes: %.2f, Start: %.1f, End: %.1f, Total: %t }", r.MegaBytes(), r.IntervalStart.Sub(start).Seconds(), r.IntervalEnd.Sub(start).Seconds(), r.Total) } stateChan := make(chan state, 1) @@ -49,8 +50,9 @@ func TestDownload(t *testing.T) { t.Fatalf("download results: expected length: %d, actual length: %d", expectedLen, len(results)) } + start := results[0].IntervalStart for _, result := range results { - displayResult(t, result) + displayResult(t, result, start) } }) @@ -66,8 +68,9 @@ func TestDownload(t *testing.T) { t.Fatalf("upload results: expected length: %d, actual length: %d", expectedLen, len(results)) } + start := results[0].IntervalStart for _, result := range results { - displayResult(t, result) + displayResult(t, result, start) } })