github.com/lightlus/netstack@v1.2.0/tcpip/buffer/view_test.go (about) 1 // Copyright 2018 The gVisor 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 buffer_test contains tests for the VectorisedView type. 16 package buffer 17 18 import ( 19 "reflect" 20 "testing" 21 ) 22 23 // copy returns a deep-copy of the vectorised view. 24 func (vv VectorisedView) copy() VectorisedView { 25 uu := VectorisedView{ 26 views: make([]View, 0, len(vv.views)), 27 size: vv.size, 28 } 29 for _, v := range vv.views { 30 uu.views = append(uu.views, append(View(nil), v...)) 31 } 32 return uu 33 } 34 35 // vv is an helper to build VectorisedView from different strings. 36 func vv(size int, pieces ...string) VectorisedView { 37 views := make([]View, len(pieces)) 38 for i, p := range pieces { 39 views[i] = []byte(p) 40 } 41 42 return NewVectorisedView(size, views) 43 } 44 45 var capLengthTestCases = []struct { 46 comment string 47 in VectorisedView 48 length int 49 want VectorisedView 50 }{ 51 { 52 comment: "Simple case", 53 in: vv(2, "12"), 54 length: 1, 55 want: vv(1, "1"), 56 }, 57 { 58 comment: "Case spanning across two Views", 59 in: vv(4, "123", "4"), 60 length: 2, 61 want: vv(2, "12"), 62 }, 63 { 64 comment: "Corner case with negative length", 65 in: vv(1, "1"), 66 length: -1, 67 want: vv(0), 68 }, 69 { 70 comment: "Corner case with length = 0", 71 in: vv(3, "12", "3"), 72 length: 0, 73 want: vv(0), 74 }, 75 { 76 comment: "Corner case with length = size", 77 in: vv(1, "1"), 78 length: 1, 79 want: vv(1, "1"), 80 }, 81 { 82 comment: "Corner case with length > size", 83 in: vv(1, "1"), 84 length: 2, 85 want: vv(1, "1"), 86 }, 87 } 88 89 func TestCapLength(t *testing.T) { 90 for _, c := range capLengthTestCases { 91 orig := c.in.copy() 92 c.in.CapLength(c.length) 93 if !reflect.DeepEqual(c.in, c.want) { 94 t.Errorf("Test \"%s\" failed when calling CapLength(%d) on %v. Got %v. Want %v", 95 c.comment, c.length, orig, c.in, c.want) 96 } 97 } 98 } 99 100 var trimFrontTestCases = []struct { 101 comment string 102 in VectorisedView 103 count int 104 want VectorisedView 105 }{ 106 { 107 comment: "Simple case", 108 in: vv(2, "12"), 109 count: 1, 110 want: vv(1, "2"), 111 }, 112 { 113 comment: "Case where we trim an entire View", 114 in: vv(2, "1", "2"), 115 count: 1, 116 want: vv(1, "2"), 117 }, 118 { 119 comment: "Case spanning across two Views", 120 in: vv(3, "1", "23"), 121 count: 2, 122 want: vv(1, "3"), 123 }, 124 { 125 comment: "Corner case with negative count", 126 in: vv(1, "1"), 127 count: -1, 128 want: vv(1, "1"), 129 }, 130 { 131 comment: " Corner case with count = 0", 132 in: vv(1, "1"), 133 count: 0, 134 want: vv(1, "1"), 135 }, 136 { 137 comment: "Corner case with count = size", 138 in: vv(1, "1"), 139 count: 1, 140 want: vv(0), 141 }, 142 { 143 comment: "Corner case with count > size", 144 in: vv(1, "1"), 145 count: 2, 146 want: vv(0), 147 }, 148 } 149 150 func TestTrimFront(t *testing.T) { 151 for _, c := range trimFrontTestCases { 152 orig := c.in.copy() 153 c.in.TrimFront(c.count) 154 if !reflect.DeepEqual(c.in, c.want) { 155 t.Errorf("Test \"%s\" failed when calling TrimFront(%d) on %v. Got %v. Want %v", 156 c.comment, c.count, orig, c.in, c.want) 157 } 158 } 159 } 160 161 var toViewCases = []struct { 162 comment string 163 in VectorisedView 164 want View 165 }{ 166 { 167 comment: "Simple case", 168 in: vv(2, "12"), 169 want: []byte("12"), 170 }, 171 { 172 comment: "Case with multiple views", 173 in: vv(2, "1", "2"), 174 want: []byte("12"), 175 }, 176 { 177 comment: "Empty case", 178 in: vv(0), 179 want: []byte(""), 180 }, 181 } 182 183 func TestToView(t *testing.T) { 184 for _, c := range toViewCases { 185 got := c.in.ToView() 186 if !reflect.DeepEqual(got, c.want) { 187 t.Errorf("Test \"%s\" failed when calling ToView() on %v. Got %v. Want %v", 188 c.comment, c.in, got, c.want) 189 } 190 } 191 } 192 193 var toCloneCases = []struct { 194 comment string 195 inView VectorisedView 196 inBuffer []View 197 }{ 198 { 199 comment: "Simple case", 200 inView: vv(1, "1"), 201 inBuffer: make([]View, 1), 202 }, 203 { 204 comment: "Case with multiple views", 205 inView: vv(2, "1", "2"), 206 inBuffer: make([]View, 2), 207 }, 208 { 209 comment: "Case with buffer too small", 210 inView: vv(2, "1", "2"), 211 inBuffer: make([]View, 1), 212 }, 213 { 214 comment: "Case with buffer larger than needed", 215 inView: vv(1, "1"), 216 inBuffer: make([]View, 2), 217 }, 218 { 219 comment: "Case with nil buffer", 220 inView: vv(1, "1"), 221 inBuffer: nil, 222 }, 223 } 224 225 func TestToClone(t *testing.T) { 226 for _, c := range toCloneCases { 227 t.Run(c.comment, func(t *testing.T) { 228 got := c.inView.Clone(c.inBuffer) 229 if !reflect.DeepEqual(got, c.inView) { 230 t.Fatalf("got (%+v).Clone(%+v) = %+v, want = %+v", 231 c.inView, c.inBuffer, got, c.inView) 232 } 233 }) 234 } 235 }