forked from cosmos/iavl
-
Notifications
You must be signed in to change notification settings - Fork 4
/
encoding_test.go
122 lines (107 loc) · 3.84 KB
/
encoding_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package iavl
import (
"encoding/binary"
"math"
"testing"
"github.com/stretchr/testify/require"
)
func TestDecodeBytes(t *testing.T) {
bz := []byte{0, 1, 2, 3, 4, 5, 6, 7}
testcases := map[string]struct {
bz []byte
lengthPrefix uint64
expect []byte
expectErr bool
}{
"full": {bz, 8, bz, false},
"empty": {bz, 0, []byte{}, false},
"partial": {bz, 3, []byte{0, 1, 2}, false},
"out of bounds": {bz, 9, nil, true},
"empty input": {[]byte{}, 0, []byte{}, false},
"empty input out of bounds": {[]byte{}, 1, nil, true},
// The following will always fail, since the byte slice is only 8 bytes,
// but we're making sure they don't panic due to overflow issues. See:
// https://github.com/cosmos/iavl/issues/339
"max int32": {bz, uint64(math.MaxInt32), nil, true},
"max int32 -1": {bz, uint64(math.MaxInt32) - 1, nil, true},
"max int32 -10": {bz, uint64(math.MaxInt32) - 10, nil, true},
"max int32 +1": {bz, uint64(math.MaxInt32) + 1, nil, true},
"max int32 +10": {bz, uint64(math.MaxInt32) + 10, nil, true},
"max int32*2": {bz, uint64(math.MaxInt32) * 2, nil, true},
"max int32*2 -1": {bz, uint64(math.MaxInt32)*2 - 1, nil, true},
"max int32*2 -10": {bz, uint64(math.MaxInt32)*2 - 10, nil, true},
"max int32*2 +1": {bz, uint64(math.MaxInt32)*2 + 1, nil, true},
"max int32*2 +10": {bz, uint64(math.MaxInt32)*2 + 10, nil, true},
"max uint32": {bz, uint64(math.MaxUint32), nil, true},
"max uint32 -1": {bz, uint64(math.MaxUint32) - 1, nil, true},
"max uint32 -10": {bz, uint64(math.MaxUint32) - 10, nil, true},
"max uint32 +1": {bz, uint64(math.MaxUint32) + 1, nil, true},
"max uint32 +10": {bz, uint64(math.MaxUint32) + 10, nil, true},
"max uint32*2": {bz, uint64(math.MaxUint32) * 2, nil, true},
"max uint32*2 -1": {bz, uint64(math.MaxUint32)*2 - 1, nil, true},
"max uint32*2 -10": {bz, uint64(math.MaxUint32)*2 - 10, nil, true},
"max uint32*2 +1": {bz, uint64(math.MaxUint32)*2 + 1, nil, true},
"max uint32*2 +10": {bz, uint64(math.MaxUint32)*2 + 10, nil, true},
"max int64": {bz, uint64(math.MaxInt64), nil, true},
"max int64 -1": {bz, uint64(math.MaxInt64) - 1, nil, true},
"max int64 -10": {bz, uint64(math.MaxInt64) - 10, nil, true},
"max int64 +1": {bz, uint64(math.MaxInt64) + 1, nil, true},
"max int64 +10": {bz, uint64(math.MaxInt64) + 10, nil, true},
"max uint64": {bz, uint64(math.MaxUint64), nil, true},
"max uint64 -1": {bz, uint64(math.MaxUint64) - 1, nil, true},
"max uint64 -10": {bz, uint64(math.MaxUint64) - 10, nil, true},
}
for name, tc := range testcases {
tc := tc
t.Run(name, func(t *testing.T) {
// Generate an input slice.
buf := make([]byte, binary.MaxVarintLen64)
varintBytes := binary.PutUvarint(buf, tc.lengthPrefix)
buf = append(buf[:varintBytes], tc.bz...)
// Attempt to decode it.
b, n, err := decodeBytes(buf)
if tc.expectErr {
require.Error(t, err)
require.Equal(t, varintBytes, n)
} else {
require.NoError(t, err)
require.Equal(t, uint64(n), uint64(varintBytes)+tc.lengthPrefix)
require.Equal(t, tc.bz[:tc.lengthPrefix], b)
}
})
}
}
func TestDecodeBytes_invalidVarint(t *testing.T) {
_, _, err := decodeBytes([]byte{0xff})
require.Error(t, err)
}
// sink is kept as a global to ensure that value checks and assignments to it can't be
// optimized away, and this will help us ensure that benchmarks successfully run.
var sink interface{}
func BenchmarkConvertLeafOp(b *testing.B) {
var versions = []int64{
0,
1,
100,
127,
128,
1 << 29,
-0,
-1,
-100,
-127,
-128,
-1 << 29,
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, version := range versions {
sink = convertLeafOp(version)
}
}
if sink == nil {
b.Fatal("Benchmark wasn't run")
}
sink = nil
}