github.com/bhojpur/cache@v0.0.4/pkg/ioutils/readers_test.go (about) 1 package ioutils 2 3 // Copyright (c) 2018 Bhojpur Consulting Private Limited, India. All rights reserved. 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 import ( 24 "context" 25 "fmt" 26 "io" 27 "strings" 28 "testing" 29 "time" 30 31 "gotest.tools/v3/assert" 32 is "gotest.tools/v3/assert/cmp" 33 ) 34 35 // Implement io.Reader 36 type errorReader struct{} 37 38 func (r *errorReader) Read(p []byte) (int, error) { 39 return 0, fmt.Errorf("error reader always fail") 40 } 41 42 func TestReadCloserWrapperClose(t *testing.T) { 43 reader := strings.NewReader("A string reader") 44 wrapper := NewReadCloserWrapper(reader, func() error { 45 return fmt.Errorf("This will be called when closing") 46 }) 47 err := wrapper.Close() 48 if err == nil || !strings.Contains(err.Error(), "This will be called when closing") { 49 t.Fatalf("readCloserWrapper should have call the anonymous func and thus, fail.") 50 } 51 } 52 53 func TestReaderErrWrapperReadOnError(t *testing.T) { 54 called := false 55 reader := &errorReader{} 56 wrapper := NewReaderErrWrapper(reader, func() { 57 called = true 58 }) 59 _, err := wrapper.Read([]byte{}) 60 assert.Check(t, is.Error(err, "error reader always fail")) 61 if !called { 62 t.Fatalf("readErrWrapper should have call the anonymous function on failure") 63 } 64 } 65 66 func TestReaderErrWrapperRead(t *testing.T) { 67 reader := strings.NewReader("a string reader.") 68 wrapper := NewReaderErrWrapper(reader, func() { 69 t.Fatalf("readErrWrapper should not have called the anonymous function") 70 }) 71 // Read 20 byte (should be ok with the string above) 72 num, err := wrapper.Read(make([]byte, 20)) 73 if err != nil { 74 t.Fatal(err) 75 } 76 if num != 16 { 77 t.Fatalf("readerErrWrapper should have read 16 byte, but read %d", num) 78 } 79 } 80 81 type perpetualReader struct{} 82 83 func (p *perpetualReader) Read(buf []byte) (n int, err error) { 84 for i := 0; i != len(buf); i++ { 85 buf[i] = 'a' 86 } 87 return len(buf), nil 88 } 89 90 func TestCancelReadCloser(t *testing.T) { 91 ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) 92 defer cancel() 93 cancelReadCloser := NewCancelReadCloser(ctx, io.NopCloser(&perpetualReader{})) 94 for { 95 var buf [128]byte 96 _, err := cancelReadCloser.Read(buf[:]) 97 if err == context.DeadlineExceeded { 98 break 99 } else if err != nil { 100 t.Fatalf("got unexpected error: %v", err) 101 } 102 } 103 }