github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/morebufio/readerat_test.go (about) 1 package morebufio 2 3 import ( 4 "context" 5 "io" 6 "math/rand" 7 "strconv" 8 "strings" 9 "testing" 10 11 "github.com/Schaudge/grailbase/ioctx" 12 "github.com/Schaudge/grailbase/traverse" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestReaderAt(t *testing.T) { 18 const want = "abcdefghijklmnopqrstuvwxyz" 19 ctx := context.Background() 20 rawReaderAt := ioctx.FromStdReaderAt(strings.NewReader(want)) 21 22 t.Run("sequential", func(t *testing.T) { 23 bufAt := NewReaderAtSize(rawReaderAt, 5) 24 got := make([]byte, 0, len(want)) 25 for len(got) < len(want) { 26 n, err := bufAt.ReadAt(ctx, got[len(got):cap(got)], int64(len(got))) 27 got = got[:len(got)+n] 28 if err == io.EOF { 29 break 30 } 31 require.NoError(t, err) 32 } 33 assert.Equal(t, want, string(got)) 34 }) 35 36 t.Run("random", func(t *testing.T) { 37 rnd := rand.New(rand.NewSource(1)) 38 for _, parallelism := range []int{1, len(want) / 2} { 39 t.Run(strconv.Itoa(parallelism), func(t *testing.T) { 40 bufAt := NewReaderAtSize(rawReaderAt, 5) 41 got := make([]byte, len(want)) 42 perm := rnd.Perm(len(want) / 2) 43 _ = traverse.T{Limit: parallelism}.Each(len(perm), func(permIdx int) error { 44 i := perm[permIdx] 45 start := i * 2 46 limit := start + 2 47 if limit > len(got) { 48 limit -= 1 49 } 50 n, err := bufAt.ReadAt(ctx, got[start:limit], int64(start)) 51 assert.Equal(t, limit-start, n) 52 if limit < len(got) || err != io.EOF { 53 require.NoError(t, err) 54 } 55 return nil 56 }) 57 assert.Equal(t, want, string(got)) 58 }) 59 } 60 }) 61 }