github.com/wph95/goofys@v0.24.1-0.20200907140828-7bc615e8492e/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 "io/ioutil" 21 "sync" 22 "time" 23 24 "github.com/sirupsen/logrus" 25 . "gopkg.in/check.v1" 26 ) 27 28 type BufferTest struct { 29 } 30 31 var _ = Suite(&BufferTest{}) 32 var ignored2 = logrus.DebugLevel 33 34 type SeqReader struct { 35 cur int64 36 } 37 38 func (r *SeqReader) Read(p []byte) (n int, err error) { 39 n = len(p) 40 for i := range p { 41 r.cur++ 42 p[i] = byte(r.cur) 43 } 44 45 return 46 } 47 48 func (r *SeqReader) Seek(offset int64, whence int) (int64, error) { 49 switch whence { 50 case 0: 51 r.cur = offset 52 case 1: 53 r.cur += offset 54 default: 55 panic("unsupported whence") 56 } 57 58 return r.cur, nil 59 60 } 61 62 type SlowReader struct { 63 r io.Reader 64 sleep time.Duration 65 } 66 67 func (r *SlowReader) Read(p []byte) (n int, err error) { 68 time.Sleep(r.sleep) 69 return r.r.Read(p[:MinInt(len(p), 1336)]) 70 } 71 72 func (r *SlowReader) Close() error { 73 if reader, ok := r.r.(io.ReadCloser); ok { 74 return reader.Close() 75 } 76 return nil 77 } 78 79 func CompareReader(r1, r2 io.Reader, bufSize int) (int, error) { 80 if bufSize == 0 { 81 bufSize = 1337 82 } 83 buf1 := make([]byte, bufSize) 84 buf2 := make([]byte, bufSize) 85 86 for { 87 nread, err := r1.Read(buf1[:]) 88 if err != nil && err != io.EOF { 89 return -1, err 90 } 91 92 if nread == 0 { 93 break 94 } 95 96 nread2, err2 := io.ReadFull(r2, buf2[:nread]) 97 if err2 != nil && err != err2 { 98 return -1, err2 99 } 100 101 if bytes.Compare(buf1[:], buf2[:]) != 0 { 102 // fallback to slow path to find the exact point of divergent 103 for i, b := range buf1 { 104 if buf2[i] != b { 105 return i, nil 106 } 107 } 108 109 if nread2 > nread { 110 return nread, nil 111 } 112 } 113 } 114 115 // should have consumed all of r2 116 nread2, err := r2.Read(buf2[:]) 117 if nread2 == 0 || err == io.ErrUnexpectedEOF { 118 return -1, nil 119 } else { 120 if err == io.EOF { 121 err = nil 122 } 123 return nread2, err 124 } 125 } 126 127 func (s *BufferTest) TestMBuf(t *C) { 128 h := NewBufferPool(1000 * 1024 * 1024) 129 130 n := uint64(2 * BUF_SIZE) 131 mb := MBuf{}.Init(h, n, false) 132 t.Assert(len(mb.buffers), Equals, 2) 133 134 r := io.LimitReader(&SeqReader{}, int64(n)) 135 136 for { 137 nread, err := mb.WriteFrom(r) 138 t.Assert(err, IsNil) 139 if nread == 0 { 140 break 141 } 142 } 143 t.Assert(mb.wbuf, Equals, 1) 144 t.Assert(mb.wp, Equals, BUF_SIZE) 145 146 diff, err := CompareReader(mb, io.LimitReader(&SeqReader{}, int64(n)), 0) 147 t.Assert(err, IsNil) 148 t.Assert(diff, Equals, -1) 149 150 t.Assert(mb.rbuf, Equals, 1) 151 t.Assert(mb.rp, Equals, BUF_SIZE) 152 153 t.Assert(h.numBuffers, Equals, uint64(2)) 154 mb.Free() 155 t.Assert(h.numBuffers, Equals, uint64(0)) 156 } 157 158 func (s *BufferTest) TestBufferWrite(t *C) { 159 h := NewBufferPool(1000 * 1024 * 1024) 160 161 n := uint64(2 * BUF_SIZE) 162 mb := MBuf{}.Init(h, n, true) 163 t.Assert(len(mb.buffers), Equals, 2) 164 165 nwritten, err := io.Copy(mb, io.LimitReader(&SeqReader{}, int64(n))) 166 t.Assert(nwritten, Equals, int64(n)) 167 t.Assert(err, IsNil) 168 169 diff, err := CompareReader(mb, io.LimitReader(&SeqReader{}, int64(n)), 0) 170 t.Assert(err, IsNil) 171 t.Assert(diff, Equals, -1) 172 173 cur, err := mb.Seek(0, 1) 174 t.Assert(err, IsNil) 175 t.Assert(cur, Equals, int64(n)) 176 177 cur, err = mb.Seek(0, 2) 178 t.Assert(err, IsNil) 179 t.Assert(cur, Equals, int64(n)) 180 181 cur, err = mb.Seek(0, 0) 182 t.Assert(err, IsNil) 183 t.Assert(cur, Equals, int64(0)) 184 t.Assert(mb.rbuf, Equals, 0) 185 t.Assert(mb.rp, Equals, 0) 186 187 diff, err = CompareReader(mb, io.LimitReader(&SeqReader{}, int64(n)), 0) 188 t.Assert(err, IsNil) 189 t.Assert(diff, Equals, -1) 190 } 191 192 func (s *BufferTest) TestBufferLen(t *C) { 193 h := NewBufferPool(1000 * 1024 * 1024) 194 195 n := uint64(2*BUF_SIZE - 1) 196 mb := MBuf{}.Init(h, n, true) 197 t.Assert(len(mb.buffers), Equals, 2) 198 199 nwritten, err := io.Copy(mb, io.LimitReader(&SeqReader{}, int64(n))) 200 t.Assert(nwritten, Equals, int64(n)) 201 t.Assert(err, IsNil) 202 t.Assert(mb.Len(), Equals, int(n)) 203 } 204 205 func (s *BufferTest) TestBuffer(t *C) { 206 h := NewBufferPool(1000 * 1024 * 1024) 207 208 n := uint64(2 * BUF_SIZE) 209 mb := MBuf{}.Init(h, n, false) 210 t.Assert(len(mb.buffers), Equals, 2) 211 212 r := func() (io.ReadCloser, error) { 213 return &SlowReader{io.LimitReader(&SeqReader{}, int64(n)), 1 * time.Millisecond}, nil 214 } 215 216 b := Buffer{}.Init(mb, r) 217 218 diff, err := CompareReader(b, io.LimitReader(&SeqReader{}, int64(n)), 0) 219 t.Assert(err, IsNil) 220 t.Assert(diff, Equals, -1) 221 t.Assert(b.buf, IsNil) 222 t.Assert(b.reader, NotNil) 223 t.Assert(h.numBuffers, Equals, uint64(0)) 224 } 225 226 // io.Limitedreader does not return EOF the first time limit is 227 // reached, unlike the reader you get from http 228 type OneByteReader struct { 229 read bool 230 } 231 232 func (r *OneByteReader) Read(p []byte) (n int, err error) { 233 err = io.EOF 234 if r.read { 235 return 236 } 237 p[0] = 1 238 n = 1 239 r.read = true 240 return 241 } 242 243 func (s *BufferTest) TestBufferTiny(t *C) { 244 h := NewBufferPool(1000 * 1024 * 1024) 245 246 n := uint64(1) 247 mb := MBuf{}.Init(h, n, false) 248 t.Assert(len(mb.buffers), Equals, 1) 249 250 r := func() (io.ReadCloser, error) { 251 return ioutil.NopCloser(&OneByteReader{}), nil 252 } 253 254 b := Buffer{}.Init(mb, r) 255 256 diff, err := CompareReader(b, &OneByteReader{}, 0) 257 t.Assert(err, IsNil) 258 t.Assert(diff, Equals, -1) 259 t.Assert(b.buf, IsNil) 260 t.Assert(b.reader, NotNil) 261 t.Assert(h.numBuffers, Equals, uint64(0)) 262 } 263 264 func (s *BufferTest) TestPool(t *C) { 265 const MAX = 8 266 pool := BufferPool{maxBuffers: MAX}.Init() 267 var wg sync.WaitGroup 268 269 for i := 0; i < 10; i++ { 270 wg.Add(1) 271 go func() { 272 var inner sync.WaitGroup 273 for j := 0; j < 30; j++ { 274 inner.Add(1) 275 buf := pool.RequestBuffer() 276 go func() { 277 time.Sleep(1000 * time.Millisecond) 278 pool.Free(buf) 279 inner.Done() 280 }() 281 inner.Wait() 282 } 283 wg.Done() 284 }() 285 } 286 287 wg.Wait() 288 } 289 290 func (s *BufferTest) TestIssue193(t *C) { 291 h := NewBufferPool(1000 * 1024 * 1024) 292 293 n := uint64(2 * BUF_SIZE) 294 mb := MBuf{}.Init(h, n, false) 295 296 r := func() (io.ReadCloser, error) { 297 return &SlowReader{io.LimitReader(&SeqReader{}, int64(n)), 1 * time.Millisecond}, nil 298 } 299 300 b := Buffer{}.Init(mb, r) 301 b.Close() 302 303 // readloop would have caused a panic 304 } 305 306 func (s *BufferTest) TestCGroupMemory(t *C) { 307 //test getMemoryCgroupPath() 308 test_input := `11:hugetlb:/ 309 10:memory:/user.slice 310 9:cpuset:/ 311 8:blkio:/user.slice 312 7:perf_event:/ 313 6:net_prio,net_cls:/ 314 5:cpuacct,cpu:/user.slice 315 4:devices:/user.slice 316 3:freezer:/ 317 2:pids:/ 318 1:name=systemd:/user.slice/user-1000.slice/session-1759.scope` 319 mem_path, _ := getMemoryCgroupPath(test_input) 320 t.Assert(mem_path, Equals, "/user.slice") 321 }