google.golang.org/grpc@v1.72.2/mem/buffer_pool_test.go (about) 1 /* 2 * 3 * Copyright 2023 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package mem_test 20 21 import ( 22 "bytes" 23 "testing" 24 "unsafe" 25 26 "google.golang.org/grpc/mem" 27 ) 28 29 func (s) TestBufferPool(t *testing.T) { 30 var poolSizes = []int{4, 8, 16, 32} 31 pools := []mem.BufferPool{ 32 mem.NopBufferPool{}, 33 mem.NewTieredBufferPool(poolSizes...), 34 } 35 36 testSizes := append([]int{1}, poolSizes...) 37 testSizes = append(testSizes, 64) 38 39 for _, p := range pools { 40 for _, l := range testSizes { 41 bs := p.Get(l) 42 if len(*bs) != l { 43 t.Fatalf("Get(%d) returned buffer of length %d, want %d", l, len(*bs), l) 44 } 45 46 p.Put(bs) 47 } 48 } 49 } 50 51 func (s) TestBufferPoolClears(t *testing.T) { 52 pool := mem.NewTieredBufferPool(4) 53 54 for { 55 buf1 := pool.Get(4) 56 copy(*buf1, "1234") 57 pool.Put(buf1) 58 59 buf2 := pool.Get(4) 60 if unsafe.SliceData(*buf1) != unsafe.SliceData(*buf2) { 61 pool.Put(buf2) 62 // This test is only relevant if a buffer is reused, otherwise try again. This 63 // can happen if a GC pause happens between putting the buffer back in the pool 64 // and getting a new one. 65 continue 66 } 67 68 if !bytes.Equal(*buf1, make([]byte, 4)) { 69 t.Fatalf("buffer not cleared") 70 } 71 break 72 } 73 } 74 75 func (s) TestBufferPoolIgnoresShortBuffers(t *testing.T) { 76 pool := mem.NewTieredBufferPool(10, 20) 77 buf := pool.Get(1) 78 if cap(*buf) != 10 { 79 t.Fatalf("Get(1) returned buffer with capacity: %d, want 10", cap(*buf)) 80 } 81 82 // Insert a short buffer into the pool, which is currently empty. 83 short := make([]byte, 1) 84 pool.Put(&short) 85 // Then immediately request a buffer that would be pulled from the pool where the 86 // short buffer would have been returned. If the short buffer is pulled from the 87 // pool, it could cause a panic. 88 pool.Get(10) 89 }