Skip to content

Commit 3afeb7d

Browse files
committedAug 27, 2023
Add PacketBuffer unit tests
Adds PacketBuffer unit tests. Signed-off-by: Daniel Mangum <[email protected]>
1 parent eb305b1 commit 3afeb7d

File tree

1 file changed

+345
-0
lines changed

1 file changed

+345
-0
lines changed
 

‎internal/net/buffer_test.go

+345
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
2+
// SPDX-License-Identifier: MIT
3+
4+
// Package net implements DTLS specific networking primitives.
5+
package net
6+
7+
import (
8+
"bytes"
9+
"errors"
10+
"io"
11+
"net"
12+
"testing"
13+
"time"
14+
15+
"github.com/stretchr/testify/assert"
16+
)
17+
18+
func TestBuffer(t *testing.T) {
19+
assert := assert.New(t)
20+
21+
buffer := NewPacketBuffer()
22+
packet := make([]byte, 4)
23+
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5684")
24+
assert.NoError(err)
25+
26+
// Write once.
27+
n, err := buffer.WriteTo([]byte{0, 1}, addr)
28+
assert.NoError(err)
29+
assert.Equal(2, n)
30+
31+
// Read once.
32+
var raddr net.Addr
33+
n, raddr, err = buffer.ReadFrom(packet)
34+
assert.NoError(err)
35+
assert.Equal(2, n)
36+
assert.Equal([]byte{0, 1}, packet[:n])
37+
assert.Equal(addr, raddr)
38+
39+
// Read deadline.
40+
err = buffer.SetReadDeadline(time.Unix(0, 1))
41+
assert.NoError(err)
42+
n, raddr, err = buffer.ReadFrom(packet)
43+
assert.EqualError(err, ErrTimeout.Error())
44+
assert.Equal(0, n)
45+
assert.Equal(nil, raddr)
46+
47+
// Reset deadline.
48+
err = buffer.SetReadDeadline(time.Time{})
49+
assert.NoError(err)
50+
51+
// Write twice.
52+
n, err = buffer.WriteTo([]byte{2, 3, 4}, addr)
53+
assert.NoError(err)
54+
assert.Equal(3, n)
55+
56+
n, err = buffer.WriteTo([]byte{5, 6, 7}, addr)
57+
assert.NoError(err)
58+
assert.Equal(3, n)
59+
60+
// Read twice.
61+
n, raddr, err = buffer.ReadFrom(packet)
62+
assert.NoError(err)
63+
assert.Equal(3, n)
64+
assert.Equal([]byte{2, 3, 4}, packet[:n])
65+
assert.Equal(addr, raddr)
66+
67+
n, raddr, err = buffer.ReadFrom(packet)
68+
assert.NoError(err)
69+
assert.Equal(3, n)
70+
assert.Equal([]byte{5, 6, 7}, packet[:n])
71+
assert.Equal(addr, raddr)
72+
73+
// Write once prior to close.
74+
_, err = buffer.WriteTo([]byte{3}, addr)
75+
assert.NoError(err)
76+
77+
// Close.
78+
assert.NoError(buffer.Close())
79+
80+
// Future writes will error.
81+
_, err = buffer.WriteTo([]byte{4}, addr)
82+
assert.Error(err)
83+
84+
// But we can read the remaining data.
85+
n, raddr, err = buffer.ReadFrom(packet)
86+
assert.NoError(err)
87+
assert.Equal(1, n)
88+
assert.Equal([]byte{3}, packet[:n])
89+
assert.Equal(addr, raddr)
90+
91+
// Until EOF.
92+
_, _, err = buffer.ReadFrom(packet)
93+
assert.Equal(io.EOF, err)
94+
}
95+
96+
func TestShortBuffer(t *testing.T) {
97+
assert := assert.New(t)
98+
99+
buffer := NewPacketBuffer()
100+
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5684")
101+
assert.NoError(err)
102+
103+
// Write once.
104+
n, err := buffer.WriteTo([]byte{0, 1, 2, 3}, addr)
105+
assert.NoError(err)
106+
assert.Equal(4, n)
107+
108+
// Try to read with a short buffer.
109+
packet := make([]byte, 3)
110+
var raddr net.Addr
111+
n, raddr, err = buffer.ReadFrom(packet)
112+
assert.Equal(io.ErrShortBuffer, err)
113+
assert.Equal(nil, raddr)
114+
assert.Equal(0, n)
115+
116+
// Close.
117+
assert.NoError(buffer.Close())
118+
119+
// Make sure you can Close twice.
120+
assert.NoError(buffer.Close())
121+
}
122+
123+
func TestWraparound(t *testing.T) {
124+
assert := assert.New(t)
125+
126+
buffer := NewPacketBuffer()
127+
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5684")
128+
assert.NoError(err)
129+
130+
// Write multiple.
131+
n, err := buffer.WriteTo([]byte{0, 1, 2, 3}, addr)
132+
assert.NoError(err)
133+
assert.Equal(4, n)
134+
135+
n, err = buffer.WriteTo([]byte{4, 5}, addr)
136+
assert.NoError(err)
137+
assert.Equal(2, n)
138+
139+
n, err = buffer.WriteTo([]byte{6, 7, 8}, addr)
140+
assert.NoError(err)
141+
assert.Equal(3, n)
142+
143+
// Verify underlying buffer length.
144+
// Packet 1: buffer does not grow.
145+
// Packet 2: buffer doubles from 1 to 2.
146+
// Packet 3: buffer doubles from 2 to 4.
147+
assert.Equal(4, len(buffer.packets))
148+
149+
// Read once.
150+
packet := make([]byte, 4)
151+
var raddr net.Addr
152+
n, raddr, err = buffer.ReadFrom(packet)
153+
assert.NoError(err)
154+
assert.Equal(4, n)
155+
assert.Equal([]byte{0, 1, 2, 3}, packet[:n])
156+
assert.Equal(addr, raddr)
157+
158+
// Write again.
159+
n, err = buffer.WriteTo([]byte{9, 10, 11}, addr)
160+
assert.NoError(err)
161+
assert.Equal(3, n)
162+
163+
// Verify underlying buffer length.
164+
// No change in buffer size.
165+
assert.Equal(4, len(buffer.packets))
166+
167+
// Write again and verify buffer grew.
168+
n, err = buffer.WriteTo([]byte{12, 13, 14, 15, 16, 17, 18, 19}, addr)
169+
assert.NoError(err)
170+
assert.Equal(8, n)
171+
assert.Equal(4, len(buffer.packets))
172+
173+
// Close.
174+
assert.NoError(buffer.Close())
175+
}
176+
177+
func TestBufferAsync(t *testing.T) {
178+
assert := assert.New(t)
179+
180+
buffer := NewPacketBuffer()
181+
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5684")
182+
assert.NoError(err)
183+
184+
// Start up a goroutine to start a blocking read.
185+
done := make(chan struct{})
186+
go func() {
187+
packet := make([]byte, 4)
188+
189+
n, raddr, rErr := buffer.ReadFrom(packet)
190+
assert.NoError(rErr)
191+
assert.Equal(2, n)
192+
assert.Equal([]byte{0, 1}, packet[:n])
193+
assert.Equal(addr, raddr)
194+
195+
_, _, err = buffer.ReadFrom(packet)
196+
assert.Equal(io.EOF, err)
197+
198+
close(done)
199+
}()
200+
201+
// Wait for the reader to start reading.
202+
time.Sleep(time.Millisecond)
203+
204+
// Write once
205+
n, err := buffer.WriteTo([]byte{0, 1}, addr)
206+
assert.NoError(err)
207+
assert.Equal(2, n)
208+
209+
// Wait for the reader to start reading again.
210+
time.Sleep(time.Millisecond)
211+
212+
// Close will unblock the reader.
213+
assert.NoError(buffer.Close())
214+
215+
<-done
216+
}
217+
218+
func benchmarkBufferWR(b *testing.B, size int64, write bool, grow int) { // nolint:unparam
219+
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5684")
220+
if err != nil {
221+
b.Fatalf("net.ResolveUDPAddr: %v", err)
222+
}
223+
buffer := NewPacketBuffer()
224+
packet := make([]byte, size)
225+
226+
// Grow the buffer first
227+
pad := make([]byte, 1022)
228+
for len(buffer.packets) < grow {
229+
if _, err := buffer.WriteTo(pad, addr); err != nil {
230+
b.Fatalf("Write: %v", err)
231+
}
232+
}
233+
for buffer.read != buffer.write {
234+
if _, _, err := buffer.ReadFrom(pad); err != nil {
235+
b.Fatalf("ReadFrom: %v", err)
236+
}
237+
}
238+
239+
if write {
240+
if _, err := buffer.WriteTo(packet, addr); err != nil {
241+
b.Fatalf("Write: %v", err)
242+
}
243+
}
244+
245+
b.SetBytes(size)
246+
b.ResetTimer()
247+
248+
for i := 0; i < b.N; i++ {
249+
if _, err := buffer.WriteTo(packet, addr); err != nil {
250+
b.Fatalf("Write: %v", err)
251+
}
252+
if _, _, err := buffer.ReadFrom(packet); err != nil {
253+
b.Fatalf("Write: %v", err)
254+
}
255+
}
256+
}
257+
258+
// In this benchmark, the buffer is often empty, which is hopefully
259+
// typical of real usage.
260+
func BenchmarkBufferWR14(b *testing.B) {
261+
benchmarkBufferWR(b, 14, false, 128)
262+
}
263+
264+
func BenchmarkBufferWR140(b *testing.B) {
265+
benchmarkBufferWR(b, 140, false, 128)
266+
}
267+
268+
func BenchmarkBufferWR1400(b *testing.B) {
269+
benchmarkBufferWR(b, 1400, false, 128)
270+
}
271+
272+
// Here, the buffer never becomes empty, which forces wraparound
273+
func BenchmarkBufferWWR14(b *testing.B) {
274+
benchmarkBufferWR(b, 14, true, 128)
275+
}
276+
277+
func BenchmarkBufferWWR140(b *testing.B) {
278+
benchmarkBufferWR(b, 140, true, 128)
279+
}
280+
281+
func BenchmarkBufferWWR1400(b *testing.B) {
282+
benchmarkBufferWR(b, 1400, true, 128)
283+
}
284+
285+
func benchmarkBuffer(b *testing.B, size int64) {
286+
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:5684")
287+
if err != nil {
288+
b.Fatalf("net.ResolveUDPAddr: %v", err)
289+
}
290+
buffer := NewPacketBuffer()
291+
b.SetBytes(size)
292+
293+
done := make(chan struct{})
294+
go func() {
295+
packet := make([]byte, size)
296+
297+
for {
298+
_, _, err := buffer.ReadFrom(packet)
299+
if errors.Is(err, io.EOF) {
300+
break
301+
} else if err != nil {
302+
b.Error(err)
303+
break
304+
}
305+
}
306+
307+
close(done)
308+
}()
309+
310+
packet := make([]byte, size)
311+
312+
b.ResetTimer()
313+
314+
for i := 0; i < b.N; i++ {
315+
var err error
316+
for {
317+
_, err = buffer.WriteTo(packet, addr)
318+
if !errors.Is(err, bytes.ErrTooLarge) {
319+
break
320+
}
321+
time.Sleep(time.Microsecond)
322+
}
323+
if err != nil {
324+
b.Fatal(err)
325+
}
326+
}
327+
328+
if err := buffer.Close(); err != nil {
329+
b.Fatal(err)
330+
}
331+
332+
<-done
333+
}
334+
335+
func BenchmarkBuffer14(b *testing.B) {
336+
benchmarkBuffer(b, 14)
337+
}
338+
339+
func BenchmarkBuffer140(b *testing.B) {
340+
benchmarkBuffer(b, 140)
341+
}
342+
343+
func BenchmarkBuffer1400(b *testing.B) {
344+
benchmarkBuffer(b, 1400)
345+
}

0 commit comments

Comments
 (0)