3
3
package websocket_test
4
4
5
5
import (
6
+ "bytes"
6
7
"context"
8
+ "crypto/rand"
7
9
"fmt"
8
10
"io"
9
11
"io/ioutil"
@@ -48,7 +50,7 @@ func TestConn(t *testing.T) {
48
50
}, & websocket.AcceptOptions {
49
51
CompressionOptions : copts (),
50
52
})
51
- defer tt .done ()
53
+ defer tt .cleanup ()
52
54
53
55
tt .goEchoLoop (c2 )
54
56
@@ -67,15 +69,15 @@ func TestConn(t *testing.T) {
67
69
68
70
t .Run ("badClose" , func (t * testing.T ) {
69
71
tt , c1 , _ := newConnTest (t , nil , nil )
70
- defer tt .done ()
72
+ defer tt .cleanup ()
71
73
72
74
err := c1 .Close (- 1 , "" )
73
75
assert .Contains (t , err , "failed to marshal close frame: status code StatusCode(-1) cannot be set" )
74
76
})
75
77
76
78
t .Run ("ping" , func (t * testing.T ) {
77
79
tt , c1 , c2 := newConnTest (t , nil , nil )
78
- defer tt .done ()
80
+ defer tt .cleanup ()
79
81
80
82
c1 .CloseRead (tt .ctx )
81
83
c2 .CloseRead (tt .ctx )
@@ -91,7 +93,7 @@ func TestConn(t *testing.T) {
91
93
92
94
t .Run ("badPing" , func (t * testing.T ) {
93
95
tt , c1 , c2 := newConnTest (t , nil , nil )
94
- defer tt .done ()
96
+ defer tt .cleanup ()
95
97
96
98
c2 .CloseRead (tt .ctx )
97
99
@@ -104,7 +106,7 @@ func TestConn(t *testing.T) {
104
106
105
107
t .Run ("concurrentWrite" , func (t * testing.T ) {
106
108
tt , c1 , c2 := newConnTest (t , nil , nil )
107
- defer tt .done ()
109
+ defer tt .cleanup ()
108
110
109
111
tt .goDiscardLoop (c2 )
110
112
@@ -129,7 +131,7 @@ func TestConn(t *testing.T) {
129
131
130
132
t .Run ("concurrentWriteError" , func (t * testing.T ) {
131
133
tt , c1 , _ := newConnTest (t , nil , nil )
132
- defer tt .done ()
134
+ defer tt .cleanup ()
133
135
134
136
_ , err := c1 .Writer (tt .ctx , websocket .MessageText )
135
137
assert .Success (t , err )
@@ -143,7 +145,7 @@ func TestConn(t *testing.T) {
143
145
144
146
t .Run ("netConn" , func (t * testing.T ) {
145
147
tt , c1 , c2 := newConnTest (t , nil , nil )
146
- defer tt .done ()
148
+ defer tt .cleanup ()
147
149
148
150
n1 := websocket .NetConn (tt .ctx , c1 , websocket .MessageBinary )
149
151
n2 := websocket .NetConn (tt .ctx , c2 , websocket .MessageBinary )
@@ -179,7 +181,7 @@ func TestConn(t *testing.T) {
179
181
180
182
t .Run ("netConn/BadMsg" , func (t * testing.T ) {
181
183
tt , c1 , c2 := newConnTest (t , nil , nil )
182
- defer tt .done ()
184
+ defer tt .cleanup ()
183
185
184
186
n1 := websocket .NetConn (tt .ctx , c1 , websocket .MessageBinary )
185
187
n2 := websocket .NetConn (tt .ctx , c2 , websocket .MessageText )
@@ -201,7 +203,7 @@ func TestConn(t *testing.T) {
201
203
202
204
t .Run ("wsjson" , func (t * testing.T ) {
203
205
tt , c1 , c2 := newConnTest (t , nil , nil )
204
- defer tt .done ()
206
+ defer tt .cleanup ()
205
207
206
208
tt .goEchoLoop (c2 )
207
209
@@ -227,7 +229,7 @@ func TestConn(t *testing.T) {
227
229
228
230
t .Run ("wspb" , func (t * testing.T ) {
229
231
tt , c1 , c2 := newConnTest (t , nil , nil )
230
- defer tt .done ()
232
+ defer tt .cleanup ()
231
233
232
234
tt .goEchoLoop (c2 )
233
235
@@ -297,14 +299,16 @@ func assertCloseStatus(exp websocket.StatusCode, err error) error {
297
299
}
298
300
299
301
type connTest struct {
300
- t * testing.T
302
+ t testing.TB
301
303
ctx context.Context
302
304
303
305
doneFuncs []func ()
304
306
}
305
307
306
- func newConnTest (t * testing.T , dialOpts * websocket.DialOptions , acceptOpts * websocket.AcceptOptions ) (tt * connTest , c1 , c2 * websocket.Conn ) {
307
- t .Parallel ()
308
+ func newConnTest (t testing.TB , dialOpts * websocket.DialOptions , acceptOpts * websocket.AcceptOptions ) (tt * connTest , c1 , c2 * websocket.Conn ) {
309
+ if t , ok := t .(* testing.T ); ok {
310
+ t .Parallel ()
311
+ }
308
312
t .Helper ()
309
313
310
314
ctx , cancel := context .WithTimeout (context .Background (), time .Second * 30 )
@@ -325,7 +329,7 @@ func (tt *connTest) appendDone(f func()) {
325
329
tt .doneFuncs = append (tt .doneFuncs , f )
326
330
}
327
331
328
- func (tt * connTest ) done () {
332
+ func (tt * connTest ) cleanup () {
329
333
for i := len (tt .doneFuncs ) - 1 ; i >= 0 ; i -- {
330
334
tt .doneFuncs [i ]()
331
335
}
@@ -368,3 +372,95 @@ func (tt *connTest) goDiscardLoop(c *websocket.Conn) {
368
372
}
369
373
})
370
374
}
375
+
376
+ func BenchmarkConn (b * testing.B ) {
377
+ var benchCases = []struct {
378
+ name string
379
+ mode websocket.CompressionMode
380
+ }{
381
+ {
382
+ name : "compressionDisabled" ,
383
+ mode : websocket .CompressionDisabled ,
384
+ },
385
+ {
386
+ name : "compression" ,
387
+ mode : websocket .CompressionContextTakeover ,
388
+ },
389
+ {
390
+ name : "noContextCompression" ,
391
+ mode : websocket .CompressionNoContextTakeover ,
392
+ },
393
+ }
394
+ for _ , bc := range benchCases {
395
+ b .Run (bc .name , func (b * testing.B ) {
396
+ bb , c1 , c2 := newConnTest (b , & websocket.DialOptions {
397
+ CompressionOptions : & websocket.CompressionOptions {Mode : bc .mode },
398
+ }, nil )
399
+ defer bb .cleanup ()
400
+
401
+ bb .goEchoLoop (c2 )
402
+
403
+ const n = 32768
404
+ writeBuf := make ([]byte , n )
405
+ readBuf := make ([]byte , n )
406
+ writes := make (chan websocket.MessageType )
407
+ defer close (writes )
408
+ werrs := make (chan error )
409
+
410
+ go func () {
411
+ for typ := range writes {
412
+ werrs <- c1 .Write (bb .ctx , typ , writeBuf )
413
+ }
414
+ }()
415
+ b .SetBytes (n )
416
+ b .ReportAllocs ()
417
+ b .ResetTimer ()
418
+ for i := 0 ; i < b .N ; i ++ {
419
+ _ , err := rand .Reader .Read (writeBuf )
420
+ if err != nil {
421
+ b .Fatal (err )
422
+ }
423
+
424
+ expType := websocket .MessageBinary
425
+ if writeBuf [0 ]% 2 == 1 {
426
+ expType = websocket .MessageText
427
+ }
428
+ writes <- expType
429
+
430
+ typ , r , err := c1 .Reader (bb .ctx )
431
+ if err != nil {
432
+ b .Fatal (err )
433
+ }
434
+ if expType != typ {
435
+ assert .Equal (b , "data type" , expType , typ )
436
+ }
437
+
438
+ _ , err = io .ReadFull (r , readBuf )
439
+ if err != nil {
440
+ b .Fatal (err )
441
+ }
442
+
443
+ n2 , err := r .Read (readBuf )
444
+ if err != io .EOF {
445
+ assert .Equal (b , "read err" , io .EOF , err )
446
+ }
447
+ if n2 != 0 {
448
+ assert .Equal (b , "n2" , 0 , n2 )
449
+ }
450
+
451
+ if ! bytes .Equal (writeBuf , readBuf ) {
452
+ assert .Equal (b , "msg" , writeBuf , readBuf )
453
+ }
454
+
455
+ err = <- werrs
456
+ if err != nil {
457
+ b .Fatal (err )
458
+ }
459
+ }
460
+ b .StopTimer ()
461
+
462
+ err := c1 .Close (websocket .StatusNormalClosure , "" )
463
+ assert .Success (b , err )
464
+ })
465
+ }
466
+ }
0 commit comments