File tree Expand file tree Collapse file tree 2 files changed +98
-0
lines changed Expand file tree Collapse file tree 2 files changed +98
-0
lines changed Original file line number Diff line number Diff line change 1+ package helpers
2+
3+ import (
4+ "io"
5+ "time"
6+ )
7+
8+ // ReadWithTimeout reads data until it gets the desired number of bytes or times out.
9+ //
10+ // This is an inefficient implementation that should only be used in tests.
11+ func ReadWithTimeout (r io.Reader , n int , timeout time.Duration ) []byte {
12+ byteCh := make (chan byte )
13+ closer := make (chan struct {})
14+
15+ go func () {
16+ count := 0
17+ for {
18+ select {
19+ case <- closer :
20+ return
21+ default :
22+ b := make ([]byte , 1 )
23+ got , err := r .Read (b )
24+ if err != nil {
25+ return
26+ }
27+ if got > 0 {
28+ byteCh <- b [0 ]
29+ }
30+ count ++
31+ if count >= n {
32+ return
33+ }
34+ }
35+ }
36+ }()
37+
38+ buf := make ([]byte , 0 , n )
39+ deadline := time .After (timeout )
40+
41+ ReadLoop:
42+ for {
43+ select {
44+ case b := <- byteCh :
45+ buf = append (buf , b )
46+ if len (buf ) >= n {
47+ break ReadLoop
48+ }
49+ case <- deadline :
50+ break ReadLoop
51+ }
52+ }
53+ close (closer )
54+ return buf
55+ }
Original file line number Diff line number Diff line change 1+ package helpers
2+
3+ import (
4+ "bytes"
5+ "io"
6+ "testing"
7+ "time"
8+
9+ "github.com/stretchr/testify/assert"
10+ )
11+
12+ func TestReadWithTimeout (t * testing.T ) {
13+ var buf1 bytes.Buffer
14+ data := ReadWithTimeout (& buf1 , 5 , time .Millisecond * 50 )
15+ assert .Len (t , data , 0 )
16+
17+ var buf2 bytes.Buffer
18+ buf2 .WriteString ("he" )
19+ data = ReadWithTimeout (& buf2 , 5 , time .Millisecond * 50 )
20+ assert .Equal (t , "he" , string (data ))
21+
22+ var buf3 bytes.Buffer
23+ buf3 .WriteString ("hello" )
24+ data = ReadWithTimeout (& buf3 , 5 , time .Millisecond * 50 )
25+ assert .Equal (t , "hello" , string (data ))
26+
27+ r1 , w1 := io .Pipe ()
28+ go func () {
29+ w1 .Write ([]byte ("good" ))
30+ time .Sleep (10 * time .Millisecond )
31+ w1 .Write ([]byte ("bye" ))
32+ }()
33+ data = ReadWithTimeout (r1 , 7 , time .Millisecond * 100 )
34+ assert .Equal (t , "goodbye" , string (data ))
35+
36+ r2 , w2 := io .Pipe ()
37+ go func () {
38+ w2 .Write ([]byte ("good" ))
39+ }()
40+ data = ReadWithTimeout (r2 , 7 , time .Millisecond * 100 )
41+ time .Sleep (time .Millisecond * 100 )
42+ assert .Equal (t , "good" , string (data ))
43+ }
You can’t perform that action at this time.
0 commit comments