33package websocket_test
44
55import (
6+ "bytes"
67 "context"
8+ "crypto/rand"
79 "fmt"
810 "io"
911 "io/ioutil"
@@ -48,7 +50,7 @@ func TestConn(t *testing.T) {
4850 }, & websocket.AcceptOptions {
4951 CompressionOptions : copts (),
5052 })
51- defer tt .done ()
53+ defer tt .cleanup ()
5254
5355 tt .goEchoLoop (c2 )
5456
@@ -67,15 +69,15 @@ func TestConn(t *testing.T) {
6769
6870 t .Run ("badClose" , func (t * testing.T ) {
6971 tt , c1 , _ := newConnTest (t , nil , nil )
70- defer tt .done ()
72+ defer tt .cleanup ()
7173
7274 err := c1 .Close (- 1 , "" )
7375 assert .Contains (t , err , "failed to marshal close frame: status code StatusCode(-1) cannot be set" )
7476 })
7577
7678 t .Run ("ping" , func (t * testing.T ) {
7779 tt , c1 , c2 := newConnTest (t , nil , nil )
78- defer tt .done ()
80+ defer tt .cleanup ()
7981
8082 c1 .CloseRead (tt .ctx )
8183 c2 .CloseRead (tt .ctx )
@@ -91,7 +93,7 @@ func TestConn(t *testing.T) {
9193
9294 t .Run ("badPing" , func (t * testing.T ) {
9395 tt , c1 , c2 := newConnTest (t , nil , nil )
94- defer tt .done ()
96+ defer tt .cleanup ()
9597
9698 c2 .CloseRead (tt .ctx )
9799
@@ -104,7 +106,7 @@ func TestConn(t *testing.T) {
104106
105107 t .Run ("concurrentWrite" , func (t * testing.T ) {
106108 tt , c1 , c2 := newConnTest (t , nil , nil )
107- defer tt .done ()
109+ defer tt .cleanup ()
108110
109111 tt .goDiscardLoop (c2 )
110112
@@ -129,7 +131,7 @@ func TestConn(t *testing.T) {
129131
130132 t .Run ("concurrentWriteError" , func (t * testing.T ) {
131133 tt , c1 , _ := newConnTest (t , nil , nil )
132- defer tt .done ()
134+ defer tt .cleanup ()
133135
134136 _ , err := c1 .Writer (tt .ctx , websocket .MessageText )
135137 assert .Success (t , err )
@@ -143,7 +145,7 @@ func TestConn(t *testing.T) {
143145
144146 t .Run ("netConn" , func (t * testing.T ) {
145147 tt , c1 , c2 := newConnTest (t , nil , nil )
146- defer tt .done ()
148+ defer tt .cleanup ()
147149
148150 n1 := websocket .NetConn (tt .ctx , c1 , websocket .MessageBinary )
149151 n2 := websocket .NetConn (tt .ctx , c2 , websocket .MessageBinary )
@@ -179,7 +181,7 @@ func TestConn(t *testing.T) {
179181
180182 t .Run ("netConn/BadMsg" , func (t * testing.T ) {
181183 tt , c1 , c2 := newConnTest (t , nil , nil )
182- defer tt .done ()
184+ defer tt .cleanup ()
183185
184186 n1 := websocket .NetConn (tt .ctx , c1 , websocket .MessageBinary )
185187 n2 := websocket .NetConn (tt .ctx , c2 , websocket .MessageText )
@@ -201,7 +203,7 @@ func TestConn(t *testing.T) {
201203
202204 t .Run ("wsjson" , func (t * testing.T ) {
203205 tt , c1 , c2 := newConnTest (t , nil , nil )
204- defer tt .done ()
206+ defer tt .cleanup ()
205207
206208 tt .goEchoLoop (c2 )
207209
@@ -227,7 +229,7 @@ func TestConn(t *testing.T) {
227229
228230 t .Run ("wspb" , func (t * testing.T ) {
229231 tt , c1 , c2 := newConnTest (t , nil , nil )
230- defer tt .done ()
232+ defer tt .cleanup ()
231233
232234 tt .goEchoLoop (c2 )
233235
@@ -297,14 +299,16 @@ func assertCloseStatus(exp websocket.StatusCode, err error) error {
297299}
298300
299301type connTest struct {
300- t * testing.T
302+ t testing.TB
301303 ctx context.Context
302304
303305 doneFuncs []func ()
304306}
305307
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+ }
308312 t .Helper ()
309313
310314 ctx , cancel := context .WithTimeout (context .Background (), time .Second * 30 )
@@ -325,7 +329,7 @@ func (tt *connTest) appendDone(f func()) {
325329 tt .doneFuncs = append (tt .doneFuncs , f )
326330}
327331
328- func (tt * connTest ) done () {
332+ func (tt * connTest ) cleanup () {
329333 for i := len (tt .doneFuncs ) - 1 ; i >= 0 ; i -- {
330334 tt .doneFuncs [i ]()
331335 }
@@ -368,3 +372,95 @@ func (tt *connTest) goDiscardLoop(c *websocket.Conn) {
368372 }
369373 })
370374}
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