Skip to content

Commit 2ce387a

Browse files
committed
Only test bandwidth limiter with synctest enabled
1 parent 34df566 commit 2ce387a

File tree

2 files changed

+161
-150
lines changed

2 files changed

+161
-150
lines changed

.github/actions/go-test-setup/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ runs:
99
shell: bash
1010
# This matches only tests with "NoCover" in their test name to avoid running all tests again.
1111
run: go test -tags nocover -run NoCover -v ./...
12+
- name: Run synctests tests. These are tests that require go 1.24 and the experimental testing/synctest package
13+
shell: bash
14+
if: ${{ contains(matrix.go, '1.24') }}
15+
run: go test -tags goexperiment.synctest -run "_synctest$" -v ./...
1216
- name: Install testing tools
1317
shell: bash
1418
run: cd scripts/test_analysis && go install ./cmd/gotest2sql

p2p/net/simconn/simlink_test.go

Lines changed: 157 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
//go:build goexperiment.synctest
2+
13
package simconn
24

35
import (
46
"fmt"
57
"math"
68
"testing"
9+
"testing/synctest"
710
"time"
811
)
912

@@ -23,90 +26,92 @@ func (r *testRouter) RecvPacketBlocking(p Packet) {
2326

2427
const Mibps = 1_000_000
2528

26-
func TestBandwidthLimiterAndLatency(t *testing.T) {
27-
for _, testUpload := range []bool{true, false} {
28-
t.Run(fmt.Sprintf("testing upload=%t", testUpload), func(t *testing.T) {
29-
const expectedSpeed = 10 * Mibps
30-
const expectedLatency = 10 * time.Millisecond
31-
const MTU = 1400
32-
linkSettings := LinkSettings{
33-
BitsPerSecond: expectedSpeed,
34-
MTU: MTU,
35-
Latency: expectedLatency,
36-
}
29+
func TestBandwidthLimiterAndLatency_synctest(t *testing.T) {
30+
synctest.Run(func() {
31+
for _, testUpload := range []bool{true, false} {
32+
t.Run(fmt.Sprintf("testing upload=%t", testUpload), func(t *testing.T) {
33+
const expectedSpeed = 10 * Mibps
34+
const expectedLatency = 10 * time.Millisecond
35+
const MTU = 1400
36+
linkSettings := LinkSettings{
37+
BitsPerSecond: expectedSpeed,
38+
MTU: MTU,
39+
Latency: expectedLatency,
40+
}
3741

38-
recvStartTimeChan := make(chan time.Time, 1)
39-
recvStarted := false
40-
bytesRead := 0
41-
packetHandler := func(p Packet) {
42-
if !recvStarted {
43-
recvStarted = true
44-
recvStartTimeChan <- time.Now()
42+
recvStartTimeChan := make(chan time.Time, 1)
43+
recvStarted := false
44+
bytesRead := 0
45+
packetHandler := func(p Packet) {
46+
if !recvStarted {
47+
recvStarted = true
48+
recvStartTimeChan <- time.Now()
49+
}
50+
bytesRead += len(p.buf)
4551
}
46-
bytesRead += len(p.buf)
47-
}
4852

49-
router := &testRouter{}
50-
if testUpload {
51-
router.onSend = packetHandler
52-
} else {
53-
router.onRecv = packetHandler
54-
}
55-
link := SimulatedLink{
56-
UplinkSettings: linkSettings,
57-
DownlinkSettings: linkSettings,
58-
UploadPacket: router,
59-
DownloadPacket: router,
60-
}
53+
router := &testRouter{}
54+
if testUpload {
55+
router.onSend = packetHandler
56+
} else {
57+
router.onRecv = packetHandler
58+
}
59+
link := SimulatedLink{
60+
UplinkSettings: linkSettings,
61+
DownlinkSettings: linkSettings,
62+
UploadPacket: router,
63+
DownloadPacket: router,
64+
}
6165

62-
link.Start()
63-
64-
// Send 10MiB of data
65-
chunk := make([]byte, MTU)
66-
bytesSent := 0
67-
68-
sendStartTime := time.Now()
69-
{
70-
totalBytes := 10 << 20
71-
// Blast a bunch of packets
72-
for bytesSent < totalBytes {
73-
// This sleep shouldn't limit the speed. 1400 Bytes/100us = 14KB/ms = 14MB/s = 14*8 Mbps
74-
// but it acts as a simple pacer to avoid just dropping the packets when the link is saturated.
75-
time.Sleep(100 * time.Microsecond)
76-
if testUpload {
77-
_ = link.SendPacket(Packet{buf: chunk})
78-
} else {
79-
link.RecvPacket(Packet{buf: chunk})
66+
link.Start()
67+
68+
// Send 10MiB of data
69+
chunk := make([]byte, MTU)
70+
bytesSent := 0
71+
72+
sendStartTime := time.Now()
73+
{
74+
totalBytes := 10 << 20
75+
// Blast a bunch of packets
76+
for bytesSent < totalBytes {
77+
// This sleep shouldn't limit the speed. 1400 Bytes/100us = 14KB/ms = 14MB/s = 14*8 Mbps
78+
// but it acts as a simple pacer to avoid just dropping the packets when the link is saturated.
79+
time.Sleep(100 * time.Microsecond)
80+
if testUpload {
81+
_ = link.SendPacket(Packet{buf: chunk})
82+
} else {
83+
link.RecvPacket(Packet{buf: chunk})
84+
}
85+
bytesSent += len(chunk)
8086
}
81-
bytesSent += len(chunk)
8287
}
83-
}
8488

85-
// Wait for delayed packets to be sent
86-
time.Sleep(40 * time.Millisecond)
87-
fmt.Printf("sent: %d\n", bytesSent)
89+
// Wait for delayed packets to be sent
90+
time.Sleep(40 * time.Millisecond)
91+
fmt.Printf("sent: %d\n", bytesSent)
8892

89-
link.Close()
90-
fmt.Printf("bytesRead: %d\n", bytesRead)
91-
recvStartTime := <-recvStartTimeChan
92-
duration := time.Since(recvStartTime)
93+
link.Close()
94+
fmt.Printf("bytesRead: %d\n", bytesRead)
95+
recvStartTime := <-recvStartTimeChan
96+
duration := time.Since(recvStartTime)
9397

94-
observedLatency := recvStartTime.Sub(sendStartTime)
95-
percentErrorLatency := math.Abs(observedLatency.Seconds()-expectedLatency.Seconds()) / expectedLatency.Seconds()
96-
t.Logf("observed latency: %s, expected latency: %s, percent error: %f\n", observedLatency, expectedLatency, percentErrorLatency)
97-
if percentErrorLatency > 0.20 {
98-
t.Fatalf("observed latency %s is wrong", observedLatency)
99-
}
98+
observedLatency := recvStartTime.Sub(sendStartTime)
99+
percentErrorLatency := math.Abs(observedLatency.Seconds()-expectedLatency.Seconds()) / expectedLatency.Seconds()
100+
t.Logf("observed latency: %s, expected latency: %s, percent error: %f\n", observedLatency, expectedLatency, percentErrorLatency)
101+
if percentErrorLatency > 0.20 {
102+
t.Fatalf("observed latency %s is wrong", observedLatency)
103+
}
100104

101-
observedSpeed := 8 * float64(bytesRead) / duration.Seconds()
102-
t.Logf("observed speed: %f Mbps over %s\n", observedSpeed/Mibps, duration)
103-
percentErrorSpeed := math.Abs(observedSpeed-float64(expectedSpeed)) / float64(expectedSpeed)
104-
t.Logf("observed speed: %f Mbps, expected speed: %d Mbps, percent error: %f\n", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
105-
if percentErrorSpeed > 0.20 {
106-
t.Fatalf("observed speed %f Mbps is too far from expected speed %d Mbps. Percent error: %f", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
107-
}
108-
})
109-
}
105+
observedSpeed := 8 * float64(bytesRead) / duration.Seconds()
106+
t.Logf("observed speed: %f Mbps over %s\n", observedSpeed/Mibps, duration)
107+
percentErrorSpeed := math.Abs(observedSpeed-float64(expectedSpeed)) / float64(expectedSpeed)
108+
t.Logf("observed speed: %f Mbps, expected speed: %d Mbps, percent error: %f\n", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
109+
if percentErrorSpeed > 0.20 {
110+
t.Fatalf("observed speed %f Mbps is too far from expected speed %d Mbps. Percent error: %f", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
111+
}
112+
})
113+
}
114+
})
110115
}
111116

112117
type linkAdapter struct {
@@ -121,82 +126,84 @@ func (c *linkAdapter) SendPacket(p Packet) error {
121126
return nil
122127
}
123128

124-
func TestBandwidthLimiterAndLatencyConnectedLinks(t *testing.T) {
125-
const expectedSpeed = 100 * Mibps
126-
const latencyOfOneLink = 10 * time.Millisecond
127-
const expectedLatency = 2 * latencyOfOneLink
128-
const MTU = 1400
129-
linkSettings := LinkSettings{
130-
BitsPerSecond: expectedSpeed,
131-
MTU: MTU,
132-
Latency: latencyOfOneLink,
133-
}
134-
135-
recvStartTimeChan := make(chan time.Time, 1)
136-
recvStarted := false
137-
bytesRead := 0
138-
packetHandler := func(p Packet) {
139-
if !recvStarted {
140-
recvStarted = true
141-
recvStartTimeChan <- time.Now()
129+
func TestBandwidthLimiterAndLatencyConnectedLinks_synctest(t *testing.T) {
130+
synctest.Run(func() {
131+
const expectedSpeed = 100 * Mibps
132+
const latencyOfOneLink = 10 * time.Millisecond
133+
const expectedLatency = 2 * latencyOfOneLink
134+
const MTU = 1400
135+
linkSettings := LinkSettings{
136+
BitsPerSecond: expectedSpeed,
137+
MTU: MTU,
138+
Latency: latencyOfOneLink,
139+
}
140+
141+
recvStartTimeChan := make(chan time.Time, 1)
142+
recvStarted := false
143+
bytesRead := 0
144+
packetHandler := func(p Packet) {
145+
if !recvStarted {
146+
recvStarted = true
147+
recvStartTimeChan <- time.Now()
148+
}
149+
bytesRead += len(p.buf)
150+
}
151+
r := &testRouter{
152+
onRecv: packetHandler,
153+
}
154+
155+
link2 := SimulatedLink{
156+
UplinkSettings: linkSettings,
157+
DownlinkSettings: linkSettings,
158+
DownloadPacket: r,
142159
}
143-
bytesRead += len(p.buf)
144-
}
145-
r := &testRouter{
146-
onRecv: packetHandler,
147-
}
148-
149-
link2 := SimulatedLink{
150-
UplinkSettings: linkSettings,
151-
DownlinkSettings: linkSettings,
152-
DownloadPacket: r,
153-
}
154-
link1 := SimulatedLink{
155-
UplinkSettings: linkSettings,
156-
DownlinkSettings: linkSettings,
157-
UploadPacket: &linkAdapter{link: &link2},
158-
}
159-
160-
link1.Start()
161-
link2.Start()
162-
163-
// Send 10MiB of data
164-
chunk := make([]byte, MTU)
165-
bytesSent := 0
166-
167-
sendStartTime := time.Now()
168-
{
169-
totalBytes := 10 << 20
170-
// Blast a bunch of packets
171-
for bytesSent < totalBytes {
172-
time.Sleep(100 * time.Microsecond)
173-
_ = link1.SendPacket(Packet{buf: chunk})
174-
bytesSent += len(chunk)
160+
link1 := SimulatedLink{
161+
UplinkSettings: linkSettings,
162+
DownlinkSettings: linkSettings,
163+
UploadPacket: &linkAdapter{link: &link2},
164+
}
165+
166+
link1.Start()
167+
link2.Start()
168+
169+
// Send 10MiB of data
170+
chunk := make([]byte, MTU)
171+
bytesSent := 0
172+
173+
sendStartTime := time.Now()
174+
{
175+
totalBytes := 10 << 20
176+
// Blast a bunch of packets
177+
for bytesSent < totalBytes {
178+
time.Sleep(100 * time.Microsecond)
179+
_ = link1.SendPacket(Packet{buf: chunk})
180+
bytesSent += len(chunk)
181+
}
182+
}
183+
184+
// Wait for delayed packets to be sent
185+
time.Sleep(40 * time.Millisecond)
186+
fmt.Printf("sent: %d\n", bytesSent)
187+
188+
link1.Close()
189+
link2.Close()
190+
fmt.Printf("bytesRead: %d\n", bytesRead)
191+
recvStartTime := <-recvStartTimeChan
192+
duration := time.Since(recvStartTime)
193+
194+
observedLatency := recvStartTime.Sub(sendStartTime)
195+
percentErrorLatency := math.Abs(observedLatency.Seconds()-expectedLatency.Seconds()) / expectedLatency.Seconds()
196+
t.Logf("observed latency: %s, expected latency: %s, percent error: %f\n", observedLatency, expectedLatency, percentErrorLatency)
197+
if percentErrorLatency > 0.20 {
198+
t.Fatalf("observed latency %s is wrong", observedLatency)
199+
}
200+
201+
observedSpeed := 8 * float64(bytesRead) / duration.Seconds()
202+
t.Logf("observed speed: %f Mbps over %s\n", observedSpeed/Mibps, duration)
203+
percentErrorSpeed := math.Abs(observedSpeed-float64(expectedSpeed)) / float64(expectedSpeed)
204+
t.Logf("observed speed: %f Mbps, expected speed: %d Mbps, percent error: %f\n", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
205+
if percentErrorSpeed > 0.20 {
206+
t.Fatalf("observed speed %f Mbps is too far from expected speed %d Mbps. Percent error: %f", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
175207
}
176-
}
177-
178-
// Wait for delayed packets to be sent
179-
time.Sleep(40 * time.Millisecond)
180-
fmt.Printf("sent: %d\n", bytesSent)
181-
182-
link1.Close()
183-
link2.Close()
184-
fmt.Printf("bytesRead: %d\n", bytesRead)
185-
recvStartTime := <-recvStartTimeChan
186-
duration := time.Since(recvStartTime)
187-
188-
observedLatency := recvStartTime.Sub(sendStartTime)
189-
percentErrorLatency := math.Abs(observedLatency.Seconds()-expectedLatency.Seconds()) / expectedLatency.Seconds()
190-
t.Logf("observed latency: %s, expected latency: %s, percent error: %f\n", observedLatency, expectedLatency, percentErrorLatency)
191-
if percentErrorLatency > 0.20 {
192-
t.Fatalf("observed latency %s is wrong", observedLatency)
193-
}
194-
195-
observedSpeed := 8 * float64(bytesRead) / duration.Seconds()
196-
t.Logf("observed speed: %f Mbps over %s\n", observedSpeed/Mibps, duration)
197-
percentErrorSpeed := math.Abs(observedSpeed-float64(expectedSpeed)) / float64(expectedSpeed)
198-
t.Logf("observed speed: %f Mbps, expected speed: %d Mbps, percent error: %f\n", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
199-
if percentErrorSpeed > 0.20 {
200-
t.Fatalf("observed speed %f Mbps is too far from expected speed %d Mbps. Percent error: %f", observedSpeed/Mibps, expectedSpeed/Mibps, percentErrorSpeed)
201-
}
208+
})
202209
}

0 commit comments

Comments
 (0)