tlv/varint_test: add tests vectors for custom Read/WriteVarInt
This commit is contained in:
parent
3afcb1f224
commit
75fcf1cee1
217
tlv/varint_test.go
Normal file
217
tlv/varint_test.go
Normal file
@ -0,0 +1,217 @@
|
||||
package tlv_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
)
|
||||
|
||||
type varIntTest struct {
|
||||
Name string
|
||||
Value uint64
|
||||
Bytes []byte
|
||||
ExpErr error
|
||||
}
|
||||
|
||||
var writeVarIntTests = []varIntTest{
|
||||
{
|
||||
Name: "zero",
|
||||
Value: 0x00,
|
||||
Bytes: []byte{0x00},
|
||||
},
|
||||
{
|
||||
Name: "one byte high",
|
||||
Value: 0xfc,
|
||||
Bytes: []byte{0xfc},
|
||||
},
|
||||
{
|
||||
Name: "two byte low",
|
||||
Value: 0xfd,
|
||||
Bytes: []byte{0xfd, 0x00, 0xfd},
|
||||
},
|
||||
{
|
||||
Name: "two byte high",
|
||||
Value: 0xffff,
|
||||
Bytes: []byte{0xfd, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "four byte low",
|
||||
Value: 0x10000,
|
||||
Bytes: []byte{0xfe, 0x00, 0x01, 0x00, 0x00},
|
||||
},
|
||||
{
|
||||
Name: "four byte high",
|
||||
Value: 0xffffffff,
|
||||
Bytes: []byte{0xfe, 0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "eight byte low",
|
||||
Value: 0x100000000,
|
||||
Bytes: []byte{0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00},
|
||||
},
|
||||
{
|
||||
Name: "eight byte high",
|
||||
Value: math.MaxUint64,
|
||||
Bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
}
|
||||
|
||||
// TestWriteVarInt asserts the behavior of tlv.WriteVarInt under various
|
||||
// positive and negative test cases.
|
||||
func TestWriteVarInt(t *testing.T) {
|
||||
for _, test := range writeVarIntTests {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
testWriteVarInt(t, test)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testWriteVarInt(t *testing.T, test varIntTest) {
|
||||
var (
|
||||
w bytes.Buffer
|
||||
buf [8]byte
|
||||
)
|
||||
err := tlv.WriteVarInt(&w, test.Value, &buf)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to encode %d as varint: %v",
|
||||
test.Value, err)
|
||||
}
|
||||
|
||||
if bytes.Compare(w.Bytes(), test.Bytes) != 0 {
|
||||
t.Fatalf("expected bytes: %v, got %v",
|
||||
test.Bytes, w.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
var readVarIntTests = []varIntTest{
|
||||
{
|
||||
Name: "zero",
|
||||
Value: 0x00,
|
||||
Bytes: []byte{0x00},
|
||||
},
|
||||
{
|
||||
Name: "one byte high",
|
||||
Value: 0xfc,
|
||||
Bytes: []byte{0xfc},
|
||||
},
|
||||
{
|
||||
Name: "two byte low",
|
||||
Value: 0xfd,
|
||||
Bytes: []byte{0xfd, 0x00, 0xfd},
|
||||
},
|
||||
{
|
||||
Name: "two byte high",
|
||||
Value: 0xffff,
|
||||
Bytes: []byte{0xfd, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "four byte low",
|
||||
Value: 0x10000,
|
||||
Bytes: []byte{0xfe, 0x00, 0x01, 0x00, 0x00},
|
||||
},
|
||||
{
|
||||
Name: "four byte high",
|
||||
Value: 0xffffffff,
|
||||
Bytes: []byte{0xfe, 0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "eight byte low",
|
||||
Value: 0x100000000,
|
||||
Bytes: []byte{0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00},
|
||||
},
|
||||
{
|
||||
Name: "eight byte high",
|
||||
Value: math.MaxUint64,
|
||||
Bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
Name: "two byte not canonical",
|
||||
Bytes: []byte{0xfd, 0x00, 0xfc},
|
||||
ExpErr: tlv.ErrVarIntNotCanonical,
|
||||
},
|
||||
{
|
||||
Name: "four byte not canonical",
|
||||
Bytes: []byte{0xfe, 0x00, 0x00, 0xff, 0xff},
|
||||
ExpErr: tlv.ErrVarIntNotCanonical,
|
||||
},
|
||||
{
|
||||
Name: "eight byte not canonical",
|
||||
Bytes: []byte{0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},
|
||||
ExpErr: tlv.ErrVarIntNotCanonical,
|
||||
},
|
||||
{
|
||||
Name: "two byte short read",
|
||||
Bytes: []byte{0xfd, 0x00},
|
||||
ExpErr: io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
Name: "four byte short read",
|
||||
Bytes: []byte{0xfe, 0xff, 0xff},
|
||||
ExpErr: io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
Name: "eight byte short read",
|
||||
Bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
ExpErr: io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
Name: "one byte no read",
|
||||
Bytes: []byte{},
|
||||
ExpErr: io.EOF,
|
||||
},
|
||||
// The following cases are the reason for needing to make a custom
|
||||
// version of the varint for the tlv package. For the varint encodings
|
||||
// in btcd's wire package these would return io.EOF, since it is
|
||||
// actually a composite of two calls to io.ReadFull. In TLV, we need to
|
||||
// be able to distinguish whether no bytes were read at all from no
|
||||
// Bytes being read on the second read as the latter is not a proper TLV
|
||||
// stream. We handle this by returning io.ErrUnexpectedEOF if we
|
||||
// encounter io.EOF on any of these secondary reads for larger values.
|
||||
{
|
||||
Name: "two byte no read",
|
||||
Bytes: []byte{0xfd},
|
||||
ExpErr: io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
Name: "four byte no read",
|
||||
Bytes: []byte{0xfe},
|
||||
ExpErr: io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
Name: "eight byte no read",
|
||||
Bytes: []byte{0xff},
|
||||
ExpErr: io.ErrUnexpectedEOF,
|
||||
},
|
||||
}
|
||||
|
||||
// TestReadVarInt asserts the behavior of tlv.ReadVarInt under various positive
|
||||
// and negative test cases.
|
||||
func TestReadVarInt(t *testing.T) {
|
||||
for _, test := range readVarIntTests {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
testReadVarInt(t, test)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testReadVarInt(t *testing.T, test varIntTest) {
|
||||
var buf [8]byte
|
||||
r := bytes.NewReader(test.Bytes)
|
||||
val, err := tlv.ReadVarInt(r, &buf)
|
||||
if err != nil && err != test.ExpErr {
|
||||
t.Fatalf("expected decoding error: %v, got: %v",
|
||||
test.ExpErr, err)
|
||||
}
|
||||
|
||||
// If we expected a decoding error, there's no point checking the value.
|
||||
if test.ExpErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if val != test.Value {
|
||||
t.Fatalf("expected value: %d, got %d", test.Value, val)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user