1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
18 check "gopkg.in/check.v1"
21 var _ = check.Suite(&Suite{})
25 func (s *Suite) TestNoWrites(c *check.C) {
30 s.checkReader(c, r1, []byte{}, nil, nil)
31 s.checkReader(c, r2, []byte{}, nil, nil)
34 func (s *Suite) TestNoReaders(c *check.C) {
36 n, err := b.Write([]byte("foobar"))
38 c.Check(n, check.Equals, 6)
39 c.Check(err, check.IsNil)
40 c.Check(err2, check.IsNil)
43 func (s *Suite) TestWriteReadClose(c *check.C) {
44 done := make(chan bool, 2)
46 n, err := b.Write([]byte("foobar"))
47 c.Check(n, check.Equals, 6)
48 c.Check(err, check.IsNil)
51 go s.checkReader(c, r1, []byte("foobar"), nil, done)
52 go s.checkReader(c, r2, []byte("foobar"), nil, done)
53 time.Sleep(time.Millisecond)
54 c.Check(len(done), check.Equals, 0)
60 func (s *Suite) TestPrefillWriteCloseRead(c *check.C) {
61 done := make(chan bool, 2)
62 b := NewBuffer([]byte("baz"))
63 n, err := b.Write([]byte("waz"))
64 c.Check(n, check.Equals, 3)
65 c.Check(err, check.IsNil)
68 go s.checkReader(c, r1, []byte("bazwaz"), nil, done)
70 go s.checkReader(c, r2, []byte("bazwaz"), nil, done)
75 func (s *Suite) TestWriteReadCloseRead(c *check.C) {
76 done := make(chan bool, 1)
79 go s.checkReader(c, r1, []byte("bazwazqux"), nil, done)
81 b.Write([]byte("bazwaz"))
84 r2.Read(make([]byte, 3))
86 b.Write([]byte("qux"))
89 s.checkReader(c, r2, []byte("wazqux"), nil, nil)
93 func (s *Suite) TestReadAtEOF(c *check.C) {
94 buf := make([]byte, 8)
96 b := NewBuffer([]byte{1, 2, 3})
100 c.Check(n, check.Equals, 3)
101 c.Check(err, check.IsNil)
103 // Reading zero bytes at EOF, but before Close(), doesn't
105 done := make(chan bool)
108 n, err = r.Read(buf[:0])
109 c.Check(n, check.Equals, 0)
110 c.Check(err, check.IsNil)
114 case <-time.After(time.Second):
120 // Reading zero bytes after Close() returns EOF
121 n, err = r.Read(buf[:0])
122 c.Check(n, check.Equals, 0)
123 c.Check(err, check.Equals, io.EOF)
125 // Reading from start after Close() returns 3 bytes, then EOF
128 c.Check(n, check.Equals, 3)
130 c.Check(err, check.Equals, io.EOF)
132 n, err = r.Read(buf[:0])
133 c.Check(n, check.Equals, 0)
134 c.Check(err, check.Equals, io.EOF)
136 c.Check(n, check.Equals, 0)
137 c.Check(err, check.Equals, io.EOF)
140 func (s *Suite) TestCloseWithError(c *check.C) {
141 errFake := errors.New("it's not even a real error")
143 done := make(chan bool, 1)
146 go s.checkReader(c, r1, []byte("bazwazqux"), errFake, done)
148 b.Write([]byte("bazwaz"))
151 r2.Read(make([]byte, 3))
153 b.Write([]byte("qux"))
154 b.CloseWithError(errFake)
156 s.checkReader(c, r2, []byte("wazqux"), errFake, nil)
160 // Write n*n bytes, n at a time; read them into n goroutines using
161 // varying buffer sizes; compare checksums.
162 func (s *Suite) TestManyReaders(c *check.C) {
167 expectSum := make(chan []byte)
170 buf := make([]byte, n)
171 for i := 0; i < n; i++ {
172 time.Sleep(10 * time.Nanosecond)
177 expectSum <- hash.Sum(nil)
181 gotSum := make(chan []byte)
182 for i := 0; i < n; i++ {
183 go func(bufSize int) {
185 io.CopyBuffer(got, b.NewReader(), make([]byte, bufSize))
186 gotSum <- got.Sum(nil)
190 expect := <-expectSum
191 for i := 0; i < n; i++ {
192 c.Check(expect, check.DeepEquals, <-gotSum)
196 func (s *Suite) BenchmarkOneReader(c *check.C) {
197 s.benchmarkReaders(c, 1)
200 func (s *Suite) BenchmarkManyReaders(c *check.C) {
201 s.benchmarkReaders(c, 100)
204 func (s *Suite) benchmarkReaders(c *check.C, readers int) {
208 buf := make([]byte, 10000)
210 for i := 0; i < 10; i++ {
213 for i := 0; i < c.N; i++ {
219 var wg sync.WaitGroup
220 for i := 0; i < readers; i++ {
224 nn, _ := io.Copy(ioutil.Discard, b.NewReader())
225 atomic.AddInt64(&n, int64(nn))
230 c.Logf("%d bytes, %.0f MB/s", n, float64(n)/time.Since(t0).Seconds()/1000000)
233 func (s *Suite) checkReader(c *check.C, r io.Reader, expectData []byte, expectError error, done chan bool) {
234 buf, err := ioutil.ReadAll(r)
235 c.Check(err, check.Equals, expectError)
236 c.Check(buf, check.DeepEquals, expectData)
242 // Gocheck boilerplate
243 func Test(t *testing.T) {