Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
fhltang committed Sep 3, 2022
2 parents b88795b + f2d6e9b commit 04cd0e6
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 134 deletions.
43 changes: 34 additions & 9 deletions internal/emitter/humanreadable.go
Expand Up @@ -91,23 +91,48 @@ func (h HumanReadable) OnComplete(test spec.TestKind) error {

// OnSummary handles the summary event.
func (h HumanReadable) OnSummary(s *Summary) error {
const summaryFormat = `%15s: %s
%15s: %s
const summaryHeaderFormat = `
Test results
%10s: %s
%10s: %s
`
const downloadFormat = `
%22s
%15s: %7.1f %s
%15s: %7.1f %s
%15s: %7.1f %s
%15s: %7.2f %s
`
_, err := fmt.Fprintf(h.out, summaryFormat,
const uploadFormat = `
%20s
%15s: %7.1f %s
%15s: %7.1f %s
`
_, err := fmt.Fprintf(h.out, summaryHeaderFormat,
"Server", s.ServerFQDN,
"Client", s.ClientIP,
"Latency", s.MinRTT.Value, s.MinRTT.Unit,
"Download", s.Download.Value, s.Upload.Unit,
"Upload", s.Upload.Value, s.Upload.Unit,
"Retransmission", s.DownloadRetrans.Value, s.DownloadRetrans.Unit)
"Client", s.ClientIP)
if err != nil {
return err
}

if s.Download != nil {
_, err := fmt.Fprintf(h.out, downloadFormat, "Download",
"Throughput", s.Download.Throughput.Value, s.Download.Throughput.Unit,
"Latency", s.Download.Latency.Value, s.Download.Latency.Unit,
"Retransmission", s.Download.Retransmission.Value, s.Download.Retransmission.Unit)
if err != nil {
return err
}
}

if s.Upload != nil {
_, err := fmt.Fprintf(h.out, uploadFormat, "Upload",
"Throughput", s.Upload.Throughput.Value, s.Upload.Throughput.Unit,
"Latency", s.Upload.Latency.Value, s.Upload.Latency.Unit)
if err != nil {
return err
}
}

return nil
}
68 changes: 43 additions & 25 deletions internal/emitter/humanreadable_test.go
Expand Up @@ -2,7 +2,6 @@ package emitter

import (
"errors"
"fmt"
"reflect"
"testing"

Expand Down Expand Up @@ -227,31 +226,49 @@ func TestHumanReadableOnCompleteFailure(t *testing.T) {
}

func TestHumanReadableOnSummary(t *testing.T) {
expected := ` Server: test
Client: test
expectedHeader := `
Test results
Server: test
Client: test
`
expectedUpload := `
Upload
Throughput: 100.0 Mbit/s
Latency: 10.0 ms
Download: 100.0 Mbit/s
Upload: 100.0 Mbit/s
Retransmission: 1.00 %
`
expectedDownload := `
Download
Throughput: 100.0 Mbit/s
Latency: 10.0 ms
Retransmission: 1.0 %
`
summary := &Summary{
ClientIP: "test",
ServerFQDN: "test",
Download: ValueUnitPair{
Value: 100.0,
Unit: "Mbit/s",
},
Upload: ValueUnitPair{
Value: 100.0,
Unit: "Mbit/s",
Download: &SubtestSummary{
Throughput: ValueUnitPair{
Value: 100.0,
Unit: "Mbit/s",
},
Latency: ValueUnitPair{
Value: 10.0,
Unit: "ms",
},
Retransmission: ValueUnitPair{
Value: 1.0,
Unit: "%",
},
},
DownloadRetrans: ValueUnitPair{
Value: 1.0,
Unit: "%",
},
MinRTT: ValueUnitPair{
Value: 10.0,
Unit: "ms",
Upload: &SubtestSummary{
Throughput: ValueUnitPair{
Value: 100.0,
Unit: "Mbit/s",
},
Latency: ValueUnitPair{
Value: 10.0,
Unit: "ms",
},
},
}
sw := &mocks.SavingWriter{}
Expand All @@ -261,12 +278,13 @@ func TestHumanReadableOnSummary(t *testing.T) {
t.Fatal(err)
}

if len(sw.Data) != 1 {
t.Fatal("invalid length")
if len(sw.Data) == 0 {
t.Fatal("no data written")
}
if string(sw.Data[0]) != expected {
fmt.Println(string(sw.Data[0]))
fmt.Println(expected)

if string(sw.Data[0]) != expectedHeader ||
string(sw.Data[1]) != expectedDownload ||
string(sw.Data[2]) != expectedUpload {
t.Fatal("OnSummary(): unexpected data")
}
}
Expand Down
5 changes: 1 addition & 4 deletions internal/emitter/json_test.go
Expand Up @@ -317,11 +317,8 @@ func TestJSONOnSummary(t *testing.T) {
if output.ClientIP != summary.ClientIP ||
output.ServerFQDN != summary.ServerFQDN ||
output.ServerIP != summary.ServerIP ||
output.DownloadUUID != summary.DownloadUUID ||
output.Download != summary.Download ||
output.Upload != summary.Upload ||
output.DownloadRetrans != summary.DownloadRetrans ||
output.MinRTT != summary.MinRTT {
output.Upload != summary.Upload {
t.Fatal("OnSummary(): unexpected output")
}

Expand Down
8 changes: 4 additions & 4 deletions internal/emitter/prometheus.go
Expand Up @@ -69,11 +69,11 @@ func (p Prometheus) OnComplete(test spec.TestKind) error {
// OnSummary handles the summary event, emitted after the test is over.
func (p *Prometheus) OnSummary(s *Summary) error {
// Note this assumes download and upload test result units are Mbit/s.
p.download.Set(s.Download.Value * 1000.0 * 1000.0)
p.upload.Set(s.Upload.Value * 1000.0 * 1000.0)
p.download.Set(s.Download.Throughput.Value * 1000.0 * 1000.0)
p.upload.Set(s.Upload.Throughput.Value * 1000.0 * 1000.0)

// Note this assumes RTT units are millisecs
p.rtt.Set(s.MinRTT.Value / 1000.0)
// Note this assumes Latency units are millisecs
p.rtt.Set(s.Download.Latency.Value / 1000.0)

success := p.lastSuccess.WithLabelValues(
s.ClientIP,
Expand Down
35 changes: 18 additions & 17 deletions internal/emitter/summary.go
Expand Up @@ -6,6 +6,20 @@ type ValueUnitPair struct {
Unit string
}

// SubtestSummary contains all the results of a single subtest (download or
// upload). All the values are from the server's perspective, except for the
// download throughput.
type SubtestSummary struct {
// UUID is the unique identified of this subtest.
UUID string
// Throughput is the measured throughput during this subtest.
Throughput ValueUnitPair
// Latency is the MinRTT value of the latest measurement, in milliseconds.
Latency ValueUnitPair
// Retransmission is BytesRetrans / BytesSent from TCPInfo
Retransmission ValueUnitPair
}

// Summary is a struct containing the values displayed to the user at
// the end of an ndt7 test.
type Summary struct {
Expand All @@ -24,24 +38,11 @@ type Summary struct {
// ClientIP is the port of the client.
ClientPort string

// DownloadUUID is the UUID of the download test.
// TODO: add UploadUUID after we start processing counterflow messages.
DownloadUUID string

// Download is the download speed, in Mbit/s. This is measured at the
// receiver.
Download ValueUnitPair

// Upload is the upload speed, in Mbit/s. This is measured at the sender.
Upload ValueUnitPair

// DownloadRetrans is the retransmission rate. This is based on the TCPInfo
// values provided by the server during a download test.
DownloadRetrans ValueUnitPair
// Download is a summary of the download subtest.
Download *SubtestSummary

// RTT is the round-trip time of the latest measurement, in milliseconds.
// This is provided by the server during a download test.
MinRTT ValueUnitPair
// Upload is a summary of the upload subtest.
Upload *SubtestSummary
}

// NewSummary returns a new Summary struct for a given FQDN.
Expand Down
4 changes: 3 additions & 1 deletion internal/mocks/writer.go
Expand Up @@ -23,6 +23,8 @@ type SavingWriter struct {

// Write appends data to sw.Data. It never fails.
func (sw *SavingWriter) Write(data []byte) (int, error) {
sw.Data = append(sw.Data, data)
d := make([]byte, len(data))
copy(d, data)
sw.Data = append(sw.Data, d)
return len(data), nil
}

0 comments on commit 04cd0e6

Please sign in to comment.