github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/primitive/vint_test.go (about)

     1  // Copyright 2021 DataStax
     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 primitive
    16  
    17  import (
    18  	"bytes"
    19  	"errors"
    20  	"io"
    21  	"math"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  var (
    28  	vintMaxInt32Bytes = []byte{0xf0, 0xff, 0xff, 0xff, 0xfe}
    29  	vintMinInt32Bytes = []byte{0xf0, 0xff, 0xff, 0xff, 0xff}
    30  	vintMaxInt64Bytes = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}
    31  	vintMinInt64Bytes = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
    32  )
    33  
    34  func TestReadUnsignedVint(t *testing.T) {
    35  	tests := []struct {
    36  		name     string
    37  		source   []byte
    38  		wantVint uint64
    39  		wantRead int
    40  		wantErr  string
    41  	}{
    42  		{"1", []byte{1}, 1, 1, ""},
    43  		{"2", []byte{2}, 2, 1, ""},
    44  		{"3", []byte{3}, 3, 1, ""},
    45  		{"max int32", vintMaxInt32Bytes, encodeZigZag(math.MaxInt32), 5, ""},
    46  		{"min int32", vintMinInt32Bytes, encodeZigZag(math.MinInt32), 5, ""},
    47  		{"max int64", vintMaxInt64Bytes, encodeZigZag(math.MaxInt64), 9, ""},
    48  		{"min int64", vintMinInt64Bytes, encodeZigZag(math.MinInt64), 9, ""},
    49  		{"empty", []byte{}, 0, 0, "cannot read [unsigned vint]: EOF"},
    50  		{"wrong length", []byte{255}, 0, 1, "cannot read [unsigned vint]: EOF"},
    51  		{"wrong length 2", []byte{255, 0, 0, 0, 0, 0, 0, 0}, 0, 8, "cannot read [unsigned vint]: unexpected EOF"},
    52  	}
    53  	for _, tt := range tests {
    54  		t.Run(tt.name, func(t *testing.T) {
    55  			source := bytes.NewReader(tt.source)
    56  			gotVint, gotRead, gotErr := ReadUnsignedVint(source)
    57  			if tt.wantErr == "" {
    58  				assert.NoError(t, gotErr)
    59  			} else {
    60  				assert.EqualError(t, gotErr, tt.wantErr)
    61  			}
    62  			assert.Equal(t, tt.wantVint, gotVint)
    63  			assert.Equal(t, tt.wantRead, gotRead)
    64  		})
    65  	}
    66  }
    67  
    68  func TestWriteUnsignedVint(t *testing.T) {
    69  	tests := []struct {
    70  		name        string
    71  		val         uint64
    72  		wantBytes   []byte
    73  		wantWritten int
    74  		wantErr     string
    75  	}{
    76  		{"1", 1, []byte{1}, 1, ""},
    77  		{"2", 2, []byte{2}, 1, ""},
    78  		{"3", 3, []byte{3}, 1, ""},
    79  		{"max int32", encodeZigZag(math.MaxInt32), vintMaxInt32Bytes, 5, ""},
    80  		{"min int32", encodeZigZag(math.MinInt32), vintMinInt32Bytes, 5, ""},
    81  		{"max int64", encodeZigZag(math.MaxInt64), vintMaxInt64Bytes, 9, ""},
    82  		{"min int64", encodeZigZag(math.MinInt64), vintMinInt64Bytes, 9, ""},
    83  		{"write failed", 0, nil, 0, "cannot write [unsigned vint]: write failed"},
    84  	}
    85  	for _, tt := range tests {
    86  		t.Run(tt.name, func(t *testing.T) {
    87  			var dest io.Writer
    88  			if tt.wantErr == "" {
    89  				dest = &bytes.Buffer{}
    90  			} else {
    91  				dest = mockWriter{}
    92  			}
    93  			gotWritten, gotErr := WriteUnsignedVint(tt.val, dest)
    94  			if tt.wantErr == "" {
    95  				assert.NoError(t, gotErr)
    96  				assert.Equal(t, tt.wantBytes, dest.(*bytes.Buffer).Bytes())
    97  			} else {
    98  				assert.EqualError(t, gotErr, tt.wantErr)
    99  			}
   100  			assert.Equal(t, tt.wantWritten, gotWritten)
   101  		})
   102  	}
   103  }
   104  
   105  func TestLengthOfUnsignedVint(t *testing.T) {
   106  	assert.Equal(t, 1, LengthOfUnsignedVint(1))
   107  	assert.Equal(t, 1, LengthOfUnsignedVint(2))
   108  	assert.Equal(t, 1, LengthOfUnsignedVint(3))
   109  	assert.Equal(t, 5, LengthOfUnsignedVint(encodeZigZag(math.MaxInt32)))
   110  	assert.Equal(t, 5, LengthOfUnsignedVint(encodeZigZag(math.MinInt32)))
   111  	assert.Equal(t, 9, LengthOfUnsignedVint(encodeZigZag(math.MaxInt64)))
   112  	assert.Equal(t, 9, LengthOfUnsignedVint(encodeZigZag(math.MinInt64)))
   113  }
   114  
   115  func TestReadVint(t *testing.T) {
   116  	tests := []struct {
   117  		name     string
   118  		source   []byte
   119  		wantVint int64
   120  		wantRead int
   121  		err      string
   122  	}{
   123  		{"1", []byte{2}, 1, 1, ""},
   124  		{"2", []byte{4}, 2, 1, ""},
   125  		{"3", []byte{6}, 3, 1, ""},
   126  		{"-1", []byte{1}, -1, 1, ""},
   127  		{"-2", []byte{3}, -2, 1, ""},
   128  		{"-3", []byte{5}, -3, 1, ""},
   129  		{"max int32", vintMaxInt32Bytes, math.MaxInt32, 5, ""},
   130  		{"min int32", vintMinInt32Bytes, math.MinInt32, 5, ""},
   131  		{"max int64", vintMaxInt64Bytes, math.MaxInt64, 9, ""},
   132  		{"min int64", vintMinInt64Bytes, math.MinInt64, 9, ""},
   133  		{"empty", []byte{}, 0, 0, "cannot read [vint]: cannot read [unsigned vint]: EOF"},
   134  		{"wrong length", []byte{255}, 0, 1, "cannot read [vint]: cannot read [unsigned vint]: EOF"},
   135  		{"wrong length 2", []byte{255, 0, 0, 0, 0, 0, 0, 0}, 0, 8, "cannot read [vint]: cannot read [unsigned vint]: unexpected EOF"},
   136  	}
   137  	for _, tt := range tests {
   138  		t.Run(tt.name, func(t *testing.T) {
   139  			source := bytes.NewReader(tt.source)
   140  			gotVint, gotRead, err := ReadVint(source)
   141  			if tt.err == "" {
   142  				assert.NoError(t, err)
   143  			} else {
   144  				assert.EqualError(t, err, tt.err)
   145  			}
   146  			assert.Equal(t, tt.wantVint, gotVint)
   147  			assert.Equal(t, tt.wantRead, gotRead)
   148  		})
   149  	}
   150  }
   151  
   152  func TestWriteVint(t *testing.T) {
   153  	tests := []struct {
   154  		name        string
   155  		val         int64
   156  		wantBytes   []byte
   157  		wantWritten int
   158  		wantErr     string
   159  	}{
   160  		{"1", 1, []byte{2}, 1, ""},
   161  		{"2", 2, []byte{4}, 1, ""},
   162  		{"3", 3, []byte{6}, 1, ""},
   163  		{"-1", -1, []byte{1}, 1, ""},
   164  		{"-2", -2, []byte{3}, 1, ""},
   165  		{"-3", -3, []byte{5}, 1, ""},
   166  		{"max int32", math.MaxInt32, vintMaxInt32Bytes, 5, ""},
   167  		{"min int32", math.MinInt32, vintMinInt32Bytes, 5, ""},
   168  		{"max int64", math.MaxInt64, vintMaxInt64Bytes, 9, ""},
   169  		{"min int64", math.MinInt64, vintMinInt64Bytes, 9, ""},
   170  		{"write failed", 0, nil, 0, "cannot write [vint]: cannot write [unsigned vint]: write failed"},
   171  	}
   172  	for _, tt := range tests {
   173  		t.Run(tt.name, func(t *testing.T) {
   174  			var dest io.Writer
   175  			if tt.wantErr == "" {
   176  				dest = &bytes.Buffer{}
   177  			} else {
   178  				dest = mockWriter{}
   179  			}
   180  			gotWritten, gotErr := WriteVint(tt.val, dest)
   181  			if tt.wantErr == "" {
   182  				assert.NoError(t, gotErr)
   183  				assert.Equal(t, tt.wantBytes, dest.(*bytes.Buffer).Bytes())
   184  			} else {
   185  				assert.EqualError(t, gotErr, tt.wantErr)
   186  			}
   187  			assert.Equal(t, tt.wantWritten, gotWritten)
   188  		})
   189  	}
   190  }
   191  
   192  func TestLengthOfVint(t *testing.T) {
   193  	assert.Equal(t, 1, LengthOfVint(1))
   194  	assert.Equal(t, 1, LengthOfVint(2))
   195  	assert.Equal(t, 1, LengthOfVint(3))
   196  	assert.Equal(t, 1, LengthOfVint(-1))
   197  	assert.Equal(t, 1, LengthOfVint(-2))
   198  	assert.Equal(t, 1, LengthOfVint(-3))
   199  	assert.Equal(t, 5, LengthOfVint(math.MaxInt32))
   200  	assert.Equal(t, 5, LengthOfVint(math.MinInt32))
   201  	assert.Equal(t, 9, LengthOfVint(math.MaxInt64))
   202  	assert.Equal(t, 9, LengthOfVint(math.MinInt64))
   203  }
   204  
   205  type mockWriter struct{}
   206  
   207  func (m mockWriter) Write(_ []byte) (n int, err error) { return 0, errors.New("write failed") }