2017-07-26 09:29:10 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
2024-12-12 12:12:29 +00:00
|
|
|
"fmt"
|
2017-07-26 09:29:10 +00:00
|
|
|
"io"
|
|
|
|
"time"
|
2019-01-27 14:48:43 +00:00
|
|
|
|
2024-12-12 12:12:29 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2017-07-26 09:29:10 +00:00
|
|
|
)
|
|
|
|
|
2024-12-12 12:12:29 +00:00
|
|
|
const (
|
2024-12-13 12:43:37 +00:00
|
|
|
bitsPerByte = 8
|
|
|
|
throughputChunkSize = 1024 * blockSize
|
2024-12-12 12:12:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (s *sparkClient) ExecuteThroughputTest(t *testResult) (err error) {
|
|
|
|
if err = s.runSendTest(t); err != nil {
|
|
|
|
return fmt.Errorf("running send-test: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
2024-12-12 12:12:29 +00:00
|
|
|
|
|
|
|
if err = s.runRecvTest(t); err != nil {
|
|
|
|
return fmt.Errorf("running recv-test: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
|
|
|
|
2024-12-12 12:12:29 +00:00
|
|
|
func (s *sparkClient) runSendTest(t *testResult) (err error) {
|
|
|
|
if err = s.connect(); err != nil {
|
|
|
|
return fmt.Errorf("establishing connection: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
2024-12-12 12:12:29 +00:00
|
|
|
defer func() {
|
|
|
|
if err := s.conn.Close(); err != nil {
|
|
|
|
logrus.WithError(err).Error("closing connection (leaked fd)")
|
|
|
|
}
|
|
|
|
}()
|
2017-07-26 09:29:10 +00:00
|
|
|
|
2024-12-12 12:12:29 +00:00
|
|
|
if err = s.writeCommand("RCV"); err != nil {
|
|
|
|
return fmt.Errorf("sending RCV command: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:43:37 +00:00
|
|
|
if t.Send.Min, t.Send.Max, t.Send.Avg, err = s.runThroughputTest(rand.Reader, s.conn); err != nil {
|
|
|
|
return fmt.Errorf("testing throughput: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-12-12 12:12:29 +00:00
|
|
|
func (s *sparkClient) runRecvTest(t *testResult) (err error) {
|
|
|
|
if err = s.connect(); err != nil {
|
|
|
|
return fmt.Errorf("establishing connection: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
2024-12-12 12:12:29 +00:00
|
|
|
defer func() {
|
|
|
|
if err := s.conn.Close(); err != nil {
|
|
|
|
logrus.WithError(err).Error("closing connection (leaked fd)")
|
|
|
|
}
|
|
|
|
}()
|
2017-07-26 09:29:10 +00:00
|
|
|
|
2024-12-12 12:12:29 +00:00
|
|
|
if err = s.writeCommand("SND"); err != nil {
|
|
|
|
return fmt.Errorf("writing SND command: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:43:37 +00:00
|
|
|
if t.Receive.Min, t.Receive.Max, t.Receive.Avg, err = s.runThroughputTest(s.conn, io.Discard); err != nil {
|
|
|
|
return fmt.Errorf("testing throughput: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (*sparkClient) runThroughputTest(src io.Reader, dst io.Writer) (minT, maxT, avgT float64, err error) {
|
2017-07-26 09:29:10 +00:00
|
|
|
var (
|
2024-12-13 12:43:37 +00:00
|
|
|
dataTxBytes int64
|
|
|
|
testStart = time.Now()
|
2017-07-26 09:29:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
for {
|
2024-12-13 12:43:37 +00:00
|
|
|
segmentStart := time.Now()
|
2017-07-26 09:29:10 +00:00
|
|
|
|
2024-12-13 12:43:37 +00:00
|
|
|
n, err := io.CopyN(dst, src, throughputChunkSize)
|
|
|
|
if err != nil {
|
|
|
|
return 0, 0, 0, fmt.Errorf("copying data: %w", err)
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:43:37 +00:00
|
|
|
dataTxBytes += n
|
|
|
|
|
|
|
|
bps := float64(n*bitsPerByte) / float64(time.Since(segmentStart).Seconds())
|
|
|
|
if bps < minT {
|
|
|
|
minT = bps
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
2024-12-13 12:43:37 +00:00
|
|
|
if bps > maxT {
|
|
|
|
maxT = bps
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|
|
|
|
|
2024-12-13 12:43:37 +00:00
|
|
|
if time.Since(testStart) > throughputTestLength {
|
2017-07-26 09:29:10 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// average bit per second
|
2024-12-13 12:43:37 +00:00
|
|
|
avgT = float64(dataTxBytes*bitsPerByte) / float64(time.Since(testStart).Seconds())
|
2017-07-26 09:29:10 +00:00
|
|
|
|
2024-12-13 12:43:37 +00:00
|
|
|
return minT, maxT, avgT, nil
|
2017-07-26 09:29:10 +00:00
|
|
|
}
|