github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/memsys/iosgl_test.go (about) 1 // Package memsys provides memory management and Slab allocation 2 // with io.Reader and io.Writer interfaces on top of a scatter-gather lists 3 // (of reusable buffers) 4 /* 5 * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved. 6 */ 7 package memsys_test 8 9 import ( 10 "bytes" 11 "io" 12 "strings" 13 "testing/iotest" 14 15 "github.com/NVIDIA/aistore/cmn/cos" 16 "github.com/NVIDIA/aistore/memsys" 17 "github.com/NVIDIA/aistore/tools/cryptorand" 18 . "github.com/onsi/ginkgo/v2" 19 . "github.com/onsi/gomega" 20 ) 21 22 func randReader(size int64) ([]byte, io.Reader) { 23 buf := make([]byte, size) 24 cryptorand.Read(buf) 25 return buf, bytes.NewBuffer(buf) 26 } 27 28 var _ = Describe("SGL", func() { 29 mm := memsys.PageMM() 30 31 It("should perform write and read for SGL", func() { 32 sgl := mm.NewSGL(0) 33 err := cos.FloodWriter(sgl, 10*cos.MiB) 34 Expect(err).ToNot(HaveOccurred()) 35 err = iotest.TestReader(sgl, sgl.Bytes()) 36 Expect(err).ToNot(HaveOccurred()) 37 }) 38 39 It("should read lines from SGL", func() { 40 rnd := cos.NowRand() 41 sgl := mm.NewSGL(0) 42 num := int(rnd.Int63n(1000) + 1) 43 arr := make([]string, num) 44 str := []byte("A") 45 for i := range num { 46 str[0] = byte('A' + i%26) 47 // NOTE in re (+1): skipping zero-length lines 48 arr[i] = strings.Repeat(string(str), int(rnd.Int63n(256)+1)) + "\n" 49 sgl.Write([]byte(arr[i])) 50 } 51 i := 0 52 for { 53 line, err := sgl.NextLine(nil, true) 54 if err == io.EOF { 55 break 56 } 57 Expect(err).ToNot(HaveOccurred()) 58 l := len(arr[i]) 59 Expect(line).To(BeEquivalentTo([]byte(arr[i][:l-1]))) 60 i++ 61 } 62 Expect(i).To(Equal(num)) 63 }) 64 65 It("should properly write to SGL using WriteByte method", func() { 66 size := int64(cos.MiB) 67 buf, _ := randReader(size) 68 69 sgl := mm.NewSGL(cos.KiB) 70 71 for i := range size { 72 err := sgl.WriteByte(buf[i]) 73 Expect(err).ToNot(HaveOccurred()) 74 } 75 b := sgl.ReadAll() 76 Expect(b).To(HaveLen(int(size))) 77 Expect(b).To(BeEquivalentTo(buf)) 78 }) 79 80 Describe("ReadFrom", func() { 81 It("should properly write to SGL using ReadFrom method", func() { 82 size := int64(11*cos.MiB + 2*cos.KiB + 123) 83 buf, r := randReader(size) 84 85 sgl := mm.NewSGL(0) 86 87 n, err := sgl.ReadFrom(r) 88 Expect(err).ToNot(HaveOccurred()) 89 Expect(n).To(Equal(size)) 90 91 b := sgl.ReadAll() 92 Expect(b).To(HaveLen(int(size))) 93 Expect(b).To(BeEquivalentTo(buf)) 94 }) 95 96 It("should properly write to SGL with big slab using ReadFrom method", func() { 97 size := int64(11*cos.MiB + 2*cos.KiB + 123) 98 buf, r := randReader(size) 99 100 sgl := mm.NewSGL(0, memsys.MaxPageSlabSize) 101 102 n, err := sgl.ReadFrom(r) 103 Expect(err).ToNot(HaveOccurred()) 104 Expect(n).To(Equal(size)) 105 106 b := sgl.ReadAll() 107 Expect(b).To(HaveLen(int(size))) 108 Expect(b).To(BeEquivalentTo(buf)) 109 }) 110 111 It("should properly write to preallocated SGL using ReadFrom method", func() { 112 size := int64(11*cos.MiB + 2*cos.KiB + 123) 113 buf, r := randReader(size) 114 115 sgl := mm.NewSGL(size) 116 117 n, err := sgl.ReadFrom(r) 118 Expect(err).ToNot(HaveOccurred()) 119 Expect(n).To(Equal(size)) 120 121 b := sgl.ReadAll() 122 Expect(b).To(HaveLen(int(size))) 123 Expect(b).To(BeEquivalentTo(buf)) 124 }) 125 126 It("should properly write multiple times to SGL using ReadFrom method", func() { 127 size := int64(11*cos.MiB + 2*cos.KiB + 123) 128 _, r := randReader(size) 129 130 sgl := mm.NewSGL(size) 131 n, err := sgl.ReadFrom(r) 132 Expect(err).ToNot(HaveOccurred()) 133 Expect(n).To(Equal(size)) 134 135 _, r = randReader(size) 136 n, err = sgl.ReadFrom(r) 137 Expect(err).ToNot(HaveOccurred()) 138 Expect(n).To(Equal(size)) 139 140 b := sgl.ReadAll() 141 Expect(b).To(HaveLen(2 * int(size))) 142 }) 143 }) 144 })