github.com/del680202/goofys@v0.19.1-0.20180727070818-6a609fafa266/internal/buffer_pool_test.go (about) 1 // Copyright 2015 - 2017 Ka-Hing Cheung 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package internal 16 17 import ( 18 "bytes" 19 "io" 20 "sync" 21 "time" 22 23 "github.com/sirupsen/logrus" 24 . "gopkg.in/check.v1" 25 ) 26 27 type BufferTest struct { 28 } 29 30 var _ = Suite(&BufferTest{}) 31 var ignored2 = logrus.DebugLevel 32 33 type SeqReader struct { 34 cur int64 35 } 36 37 func (r *SeqReader) Read(p []byte) (n int, err error) { 38 n = len(p) 39 for i := range p { 40 r.cur++ 41 p[i] = byte(r.cur) 42 } 43 44 return 45 } 46 47 func (r *SeqReader) Seek(offset int64, whence int) (int64, error) { 48 switch whence { 49 case 0: 50 r.cur = offset 51 case 1: 52 r.cur += offset 53 default: 54 panic("unsupported whence") 55 } 56 57 return r.cur, nil 58 59 } 60 61 type SlowReader struct { 62 r io.Reader 63 sleep time.Duration 64 } 65 66 func (r *SlowReader) Read(p []byte) (n int, err error) { 67 time.Sleep(r.sleep) 68 return r.r.Read(p[:MinInt(len(p), 1336)]) 69 } 70 71 func (r *SlowReader) Close() error { 72 if reader, ok := r.r.(io.ReadCloser); ok { 73 return reader.Close() 74 } 75 return nil 76 } 77 78 func CompareReader(r1, r2 io.Reader) (int, error) { 79 var buf1 [1337]byte 80 var buf2 [1337]byte 81 82 for { 83 nread, err := r1.Read(buf1[:]) 84 if err != nil && err != io.EOF { 85 return -1, err 86 } 87 88 if nread == 0 { 89 break 90 } 91 92 nread2, err := io.ReadFull(r2, buf2[:nread]) 93 if err != nil { 94 return -1, err 95 } 96 97 if bytes.Compare(buf1[:], buf2[:]) != 0 { 98 // fallback to slow path to find the exact point of divergent 99 for i, b := range buf1 { 100 if buf2[i] != b { 101 return i, nil 102 } 103 } 104 105 if nread2 > nread { 106 return nread, nil 107 } 108 } 109 } 110 111 // should have consumed all of r2 112 nread2, err := r2.Read(buf2[:]) 113 if nread2 == 0 || err == io.ErrUnexpectedEOF { 114 return -1, nil 115 } else { 116 return nread2, err 117 } 118 } 119 120 func (s *BufferTest) TestMBuf(t *C) { 121 h := NewBufferPool(1000 * 1024 * 1024) 122 123 n := uint64(2 * BUF_SIZE) 124 mb := MBuf{}.Init(h, n, false) 125 t.Assert(len(mb.buffers), Equals, 2) 126 127 r := io.LimitReader(&SeqReader{}, int64(n)) 128 129 for { 130 nread, err := mb.WriteFrom(r) 131 t.Assert(err, IsNil) 132 if nread == 0 { 133 break 134 } 135 } 136 t.Assert(mb.wbuf, Equals, 1) 137 t.Assert(mb.wp, Equals, BUF_SIZE) 138 139 diff, err := CompareReader(mb, io.LimitReader(&SeqReader{}, int64(n))) 140 t.Assert(err, IsNil) 141 t.Assert(diff, Equals, -1) 142 143 t.Assert(mb.rbuf, Equals, 1) 144 t.Assert(mb.rp, Equals, BUF_SIZE) 145 146 t.Assert(h.numBuffers, Equals, uint64(2)) 147 mb.Free() 148 t.Assert(h.numBuffers, Equals, uint64(0)) 149 } 150 151 func (s *BufferTest) TestBufferWrite(t *C) { 152 h := NewBufferPool(1000 * 1024 * 1024) 153 154 n := uint64(2 * BUF_SIZE) 155 mb := MBuf{}.Init(h, n, true) 156 t.Assert(len(mb.buffers), Equals, 2) 157 158 nwritten, err := io.Copy(mb, io.LimitReader(&SeqReader{}, int64(n))) 159 t.Assert(nwritten, Equals, int64(n)) 160 t.Assert(err, IsNil) 161 162 diff, err := CompareReader(mb, io.LimitReader(&SeqReader{}, int64(n))) 163 t.Assert(err, IsNil) 164 t.Assert(diff, Equals, -1) 165 166 cur, err := mb.Seek(0, 1) 167 t.Assert(err, IsNil) 168 t.Assert(cur, Equals, int64(n)) 169 170 cur, err = mb.Seek(0, 2) 171 t.Assert(err, IsNil) 172 t.Assert(cur, Equals, int64(n)) 173 174 cur, err = mb.Seek(0, 0) 175 t.Assert(err, IsNil) 176 t.Assert(cur, Equals, int64(0)) 177 t.Assert(mb.rbuf, Equals, 0) 178 t.Assert(mb.rp, Equals, 0) 179 180 diff, err = CompareReader(mb, io.LimitReader(&SeqReader{}, int64(n))) 181 t.Assert(err, IsNil) 182 t.Assert(diff, Equals, -1) 183 } 184 185 func (s *BufferTest) TestBufferLen(t *C) { 186 h := NewBufferPool(1000 * 1024 * 1024) 187 188 n := uint64(2*BUF_SIZE - 1) 189 mb := MBuf{}.Init(h, n, true) 190 t.Assert(len(mb.buffers), Equals, 2) 191 192 nwritten, err := io.Copy(mb, io.LimitReader(&SeqReader{}, int64(n))) 193 t.Assert(nwritten, Equals, int64(n)) 194 t.Assert(err, IsNil) 195 t.Assert(mb.Len(), Equals, int(n)) 196 } 197 198 func (s *BufferTest) TestBuffer(t *C) { 199 h := NewBufferPool(1000 * 1024 * 1024) 200 201 n := uint64(2 * BUF_SIZE) 202 mb := MBuf{}.Init(h, n, false) 203 t.Assert(len(mb.buffers), Equals, 2) 204 205 r := func() (io.ReadCloser, error) { 206 return &SlowReader{io.LimitReader(&SeqReader{}, int64(n)), 1 * time.Millisecond}, nil 207 } 208 209 b := Buffer{}.Init(mb, r) 210 211 diff, err := CompareReader(b, io.LimitReader(&SeqReader{}, int64(n))) 212 t.Assert(err, IsNil) 213 t.Assert(diff, Equals, -1) 214 t.Assert(b.buf, IsNil) 215 t.Assert(b.reader, NotNil) 216 t.Assert(h.numBuffers, Equals, uint64(0)) 217 } 218 219 func (s *BufferTest) TestPool(t *C) { 220 const MAX = 8 221 pool := BufferPool{maxBuffers: MAX}.Init() 222 var wg sync.WaitGroup 223 224 for i := 0; i < 10; i++ { 225 wg.Add(1) 226 go func() { 227 var inner sync.WaitGroup 228 for j := 0; j < 30; j++ { 229 inner.Add(1) 230 buf := pool.RequestBuffer() 231 go func() { 232 time.Sleep(1000 * time.Millisecond) 233 pool.Free(buf) 234 inner.Done() 235 }() 236 inner.Wait() 237 } 238 wg.Done() 239 }() 240 } 241 242 wg.Wait() 243 } 244 245 func (s *BufferTest) TestIssue193(t *C) { 246 h := NewBufferPool(1000 * 1024 * 1024) 247 248 n := uint64(2 * BUF_SIZE) 249 mb := MBuf{}.Init(h, n, false) 250 251 r := func() (io.ReadCloser, error) { 252 return &SlowReader{io.LimitReader(&SeqReader{}, int64(n)), 1 * time.Millisecond}, nil 253 } 254 255 b := Buffer{}.Init(mb, r) 256 b.Close() 257 258 // readloop would have caused a panic 259 }