1+ //go:build goexperiment.synctest
2+
13package simconn
24
35import (
46 "fmt"
57 "math"
68 "testing"
9+ "testing/synctest"
710 "time"
811)
912
@@ -23,90 +26,92 @@ func (r *testRouter) RecvPacketBlocking(p Packet) {
2326
2427const 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
112117type 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