go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/data/chunkstream/buffer_test.go (about) 1 // Copyright 2015 The LUCI Authors. 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 chunkstream 16 17 import ( 18 "fmt" 19 "testing" 20 21 . "github.com/smartystreets/goconvey/convey" 22 ) 23 24 func TestBuffer(t *testing.T) { 25 Convey(`An empty Buffer instance`, t, func() { 26 b := Buffer{} 27 28 Convey(`Has a length of zero.`, func() { 29 So(b.Len(), ShouldEqual, 0) 30 }) 31 32 Convey(`Has a FirstChunk of nil.`, func() { 33 So(b.FirstChunk(), ShouldEqual, nil) 34 }) 35 36 Convey(`Will panic if more than zero bytes are consumed.`, func() { 37 So(func() { b.Consume(1) }, ShouldPanic) 38 }) 39 40 Convey(`When Appending an empty chunk`, func() { 41 c := tc() 42 b.Append(c) 43 44 Convey(`Has a FirstChunk of nil.`, func() { 45 So(b.FirstChunk(), ShouldEqual, nil) 46 }) 47 48 Convey(`The Chunk is released.`, func() { 49 So(c.released, ShouldBeTrue) 50 }) 51 }) 52 53 for _, chunks := range [][]*testChunk{ 54 {}, 55 {tc()}, 56 {tc(0, 1, 2), tc(), tc(3, 4, 5)}, 57 } { 58 Convey(fmt.Sprintf(`With chunks %v, can append.`, chunks), func() { 59 size := int64(0) 60 coalesced := []byte(nil) 61 for _, c := range chunks { 62 b.Append(c) 63 coalesced = append(coalesced, c.Bytes()...) 64 size += int64(c.Len()) 65 So(b.Len(), ShouldEqual, size) 66 } 67 So(b.Bytes(), ShouldResemble, coalesced) 68 69 Convey(`Can consume chunk-at-a-time.`, func() { 70 for i, c := range chunks { 71 if c.Len() > 0 { 72 So(b.FirstChunk(), ShouldEqual, chunks[i]) 73 } 74 So(b.Len(), ShouldEqual, size) 75 b.Consume(int64(c.Len())) 76 size -= int64(c.Len()) 77 } 78 So(b.Len(), ShouldEqual, 0) 79 80 Convey(`All chunks are released.`, func() { 81 for _, c := range chunks { 82 So(c.released, ShouldBeTrue) 83 } 84 }) 85 }) 86 87 Convey(`Can consume byte-at-a-time.`, func() { 88 for i := int64(0); i < size; i++ { 89 So(b.Len(), ShouldEqual, (size - i)) 90 So(b.Bytes(), ShouldResemble, coalesced[i:]) 91 b.Consume(1) 92 } 93 So(b.Len(), ShouldEqual, 0) 94 95 Convey(`All chunks are released.`, func() { 96 for _, c := range chunks { 97 So(c.released, ShouldBeTrue) 98 } 99 }) 100 }) 101 102 Convey(`Can consume two bytes at a time.`, func() { 103 for i := int64(0); i < size; i += 2 { 104 // Final byte(s), make sure we don't over-consume. 105 if b.Len() < 2 { 106 i = b.Len() 107 } 108 109 So(b.Len(), ShouldEqual, (size - i)) 110 So(b.Bytes(), ShouldResemble, coalesced[i:]) 111 b.Consume(2) 112 } 113 So(b.Len(), ShouldEqual, 0) 114 115 Convey(`All chunks are released.`, func() { 116 for _, c := range chunks { 117 So(c.released, ShouldBeTrue) 118 } 119 }) 120 }) 121 122 Convey(`Can consume all at once.`, func() { 123 b.Consume(size) 124 So(b.Len(), ShouldEqual, 0) 125 126 Convey(`All chunks are released.`, func() { 127 for _, c := range chunks { 128 So(c.released, ShouldBeTrue) 129 } 130 }) 131 }) 132 }) 133 } 134 }) 135 }