github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/metrics/encoding/protobuf/buffer_test.go (about)

     1  // Copyright (c) 2018 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package protobuf
    22  
    23  import (
    24  	"testing"
    25  
    26  	"github.com/m3db/m3/src/x/pool"
    27  
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  func TestBufferWithPool(t *testing.T) {
    32  	buckets := []pool.Bucket{
    33  		{Capacity: 16, Count: 1},
    34  	}
    35  	p := pool.NewBytesPool(buckets, nil)
    36  	p.Init()
    37  	data := p.Get(16)[:16]
    38  	data[0] = 0xff
    39  
    40  	buf := NewBuffer(data, p.Put)
    41  	require.NotNil(t, buf.buf)
    42  
    43  	buf.Close()
    44  	require.Nil(t, buf.finalizer)
    45  	require.Nil(t, buf.buf)
    46  
    47  	// Verify that closing the buffer returns the buffer to pool.
    48  	buf2 := p.Get(16)[:16]
    49  	require.Equal(t, byte(0xff), buf2[0])
    50  
    51  	// Verify that closing the buffer a second time is a no op.
    52  	buf.Close()
    53  	buf3 := p.Get(16)[:16]
    54  	require.NotEqual(t, 0xff, buf3[0])
    55  }
    56  
    57  func TestBufferNilPool(t *testing.T) {
    58  	data := make([]byte, 16)
    59  	buf := NewBuffer(data, nil)
    60  	require.Equal(t, data, buf.Bytes())
    61  	require.NotNil(t, buf.buf)
    62  
    63  	buf.Close()
    64  	require.Nil(t, buf.finalizer)
    65  	require.Nil(t, buf.buf)
    66  }
    67  
    68  func TestBufferTruncate(t *testing.T) {
    69  	data := []byte{1, 2, 3, 4}
    70  	buf := NewBuffer(data, nil)
    71  	require.Equal(t, data, buf.Bytes())
    72  
    73  	for i := len(data); i >= 0; i-- {
    74  		buf.Truncate(i)
    75  		require.Equal(t, data[:i], buf.Bytes())
    76  	}
    77  }
    78  
    79  func TestAllocate(t *testing.T) {
    80  	buckets := []pool.Bucket{
    81  		{Capacity: 16, Count: 1},
    82  		{Capacity: 32, Count: 1},
    83  	}
    84  	p := pool.NewBytesPool(buckets, nil)
    85  	p.Init()
    86  
    87  	// Verify allocating a byte slice of size 16 will return a byte
    88  	// slice of exactly the same size.
    89  	res := allocate(p, 16)
    90  	require.Equal(t, 16, len(res))
    91  
    92  	// Verify allocating a byte slice of size 24 will return a byte
    93  	// slice whose size is larger than 24.
    94  	res = allocate(p, 24)
    95  	require.True(t, len(res) > 24)
    96  }
    97  
    98  func TestAllocateNilPool(t *testing.T) {
    99  	res := allocate(nil, 12)
   100  	require.Equal(t, 12, len(res))
   101  }
   102  
   103  func TestEnsureBufferSizeEnoughCapacity(t *testing.T) {
   104  	buf := []byte{1, 2, 0, 0, 0}
   105  	res := ensureBufferSize(buf, nil, 3, dontCopyData)
   106  	require.Equal(t, buf, res)
   107  	buf[0] = 4
   108  	require.Equal(t, byte(4), res[0])
   109  }
   110  
   111  func TestEnsureBufferSizeSmallTargetSizeDontCopyData(t *testing.T) {
   112  	buckets := []pool.Bucket{
   113  		{Capacity: 16, Count: 1},
   114  		{Capacity: 32, Count: 1},
   115  	}
   116  	p := pool.NewBytesPool(buckets, nil)
   117  	p.Init()
   118  
   119  	buf := p.Get(16)[:16]
   120  	buf[0] = 12
   121  	res := ensureBufferSize(buf, p, 24, dontCopyData)
   122  	require.Equal(t, make([]byte, 32), res)
   123  
   124  	// Verify the original buffer has been returned to pool.
   125  	buf2 := p.Get(16)[:16]
   126  	require.Equal(t, byte(12), buf2[0])
   127  }
   128  
   129  func TestEnsureBufferSizeLargeTargetSizeDontCopyData(t *testing.T) {
   130  	buckets := []pool.Bucket{
   131  		{Capacity: 16, Count: 1},
   132  		{Capacity: 32, Count: 1},
   133  	}
   134  	p := pool.NewBytesPool(buckets, nil)
   135  	p.Init()
   136  
   137  	buf := p.Get(16)[:16]
   138  	buf[0] = 12
   139  	res := ensureBufferSize(buf, p, 128, dontCopyData)
   140  	require.Equal(t, make([]byte, 128), res)
   141  
   142  	// Verify the original buffer has been returned to pool.
   143  	buf2 := p.Get(16)[:16]
   144  	require.Equal(t, byte(12), buf2[0])
   145  }
   146  
   147  func TestEnsureBufferSizeSmallTargetSizeCopyData(t *testing.T) {
   148  	buckets := []pool.Bucket{
   149  		{Capacity: 16, Count: 1},
   150  		{Capacity: 32, Count: 1},
   151  	}
   152  	p := pool.NewBytesPool(buckets, nil)
   153  	p.Init()
   154  
   155  	buf := p.Get(16)[:16]
   156  	buf[0] = 12
   157  	res := ensureBufferSize(buf, p, 24, copyData)
   158  	require.Equal(t, 32, len(res))
   159  	require.Equal(t, byte(12), res[0])
   160  
   161  	// Verify the returned value is a copy of the original slice.
   162  	buf[0] = 34
   163  	require.Equal(t, byte(12), res[0])
   164  
   165  	// Verify the original buffer has been returned to pool.
   166  	buf2 := p.Get(16)[:16]
   167  	require.Equal(t, byte(34), buf2[0])
   168  }
   169  
   170  func TestEnsureBufferSizeLargeTargetSizeCopyData(t *testing.T) {
   171  	buckets := []pool.Bucket{
   172  		{Capacity: 16, Count: 1},
   173  		{Capacity: 32, Count: 1},
   174  	}
   175  	p := pool.NewBytesPool(buckets, nil)
   176  	p.Init()
   177  
   178  	buf := p.Get(16)[:16]
   179  	buf[0] = 12
   180  	res := ensureBufferSize(buf, p, 128, copyData)
   181  	require.Equal(t, 128, len(res))
   182  	require.Equal(t, byte(12), res[0])
   183  
   184  	// Verify the returned value is a copy of the original slice.
   185  	buf[0] = 34
   186  	require.Equal(t, byte(12), res[0])
   187  
   188  	// Verify the original buffer has been returned to pool.
   189  	buf2 := p.Get(16)[:16]
   190  	require.Equal(t, byte(34), buf2[0])
   191  }
   192  
   193  func TestEnsureBufferSizeNilPool(t *testing.T) {
   194  	buf := []byte{1, 2, 0, 0, 0}
   195  	res := ensureBufferSize(buf, nil, 20, copyData)
   196  	require.Equal(t, 20, len(res))
   197  	require.Equal(t, byte(1), res[0])
   198  	require.Equal(t, byte(2), res[1])
   199  
   200  	// Verify the returned value is a copy of the original slice.
   201  	buf[0] = 123
   202  	require.Equal(t, byte(1), res[0])
   203  }