b3b51923dc
These encoders can be composed to create composite types without incurring additional allocations that would be required to pass the truncated types through the generic interface.
408 lines
8.3 KiB
Go
408 lines
8.3 KiB
Go
package tlv_test
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/lightningnetwork/lnd/tlv"
|
|
)
|
|
|
|
var tuint16Tests = []struct {
|
|
value uint16
|
|
size uint64
|
|
bytes []byte
|
|
}{
|
|
{
|
|
value: 0x0000,
|
|
size: 0,
|
|
bytes: []byte{},
|
|
},
|
|
{
|
|
value: 0x0001,
|
|
size: 1,
|
|
bytes: []byte{0x01},
|
|
},
|
|
{
|
|
value: 0x00ff,
|
|
size: 1,
|
|
bytes: []byte{0xff},
|
|
},
|
|
{
|
|
value: 0x0100,
|
|
size: 2,
|
|
bytes: []byte{0x01, 0x00},
|
|
},
|
|
{
|
|
value: 0xffff,
|
|
size: 2,
|
|
bytes: []byte{0xff, 0xff},
|
|
},
|
|
}
|
|
|
|
// TestSizeTUint16 asserts that SizeTUint16 computes the proper truncated size
|
|
// along boundary conditions of the input space.
|
|
func TestSizeTUint16(t *testing.T) {
|
|
for _, test := range tuint16Tests {
|
|
name := fmt.Sprintf("0x%x", test.value)
|
|
t.Run(name, func(t *testing.T) {
|
|
size := tlv.SizeTUint16(test.value)
|
|
if test.size != size {
|
|
t.Fatalf("size mismatch, expected: %d got: %d",
|
|
test.size, size)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestTUint16 asserts that ETUint16 outputs the proper encoding of a truncated
|
|
// uint16, and that DTUint16 is able to parse the output.
|
|
func TestTUint16(t *testing.T) {
|
|
var buf [8]byte
|
|
for _, test := range tuint16Tests {
|
|
test := test
|
|
|
|
if len(test.bytes) != int(test.size) {
|
|
t.Fatalf("invalid test case, "+
|
|
"len(bytes)[%d] != size[%d]",
|
|
len(test.bytes), test.size)
|
|
}
|
|
|
|
name := fmt.Sprintf("0x%x", test.value)
|
|
t.Run(name, func(t *testing.T) {
|
|
// Test generic encoder.
|
|
var b bytes.Buffer
|
|
err := tlv.ETUint16(&b, &test.value, &buf)
|
|
if err != nil {
|
|
t.Fatalf("unable to encode tuint16: %v", err)
|
|
}
|
|
|
|
if bytes.Compare(b.Bytes(), test.bytes) != 0 {
|
|
t.Fatalf("encoding mismatch, "+
|
|
"expected: %x, got: %x",
|
|
test.bytes, b.Bytes())
|
|
}
|
|
|
|
// Test non-generic encoder.
|
|
var b2 bytes.Buffer
|
|
err = tlv.ETUint16T(&b2, test.value, &buf)
|
|
if err != nil {
|
|
t.Fatalf("unable to encode tuint16: %v", err)
|
|
}
|
|
|
|
if !bytes.Equal(b2.Bytes(), test.bytes) {
|
|
t.Fatalf("encoding mismatch, "+
|
|
"expected: %x, got: %x",
|
|
test.bytes, b2.Bytes())
|
|
}
|
|
|
|
var value uint16
|
|
r := bytes.NewReader(b.Bytes())
|
|
err = tlv.DTUint16(r, &value, &buf, test.size)
|
|
if err != nil {
|
|
t.Fatalf("unable to decode tuint16: %v", err)
|
|
}
|
|
|
|
if value != test.value {
|
|
t.Fatalf("decoded value mismatch, "+
|
|
"expected: %d, got: %d",
|
|
test.value, value)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
var tuint32Tests = []struct {
|
|
value uint32
|
|
size uint64
|
|
bytes []byte
|
|
}{
|
|
{
|
|
value: 0x00000000,
|
|
size: 0,
|
|
bytes: []byte{},
|
|
},
|
|
{
|
|
value: 0x00000001,
|
|
size: 1,
|
|
bytes: []byte{0x01},
|
|
},
|
|
{
|
|
value: 0x000000ff,
|
|
size: 1,
|
|
bytes: []byte{0xff},
|
|
},
|
|
{
|
|
value: 0x00000100,
|
|
size: 2,
|
|
bytes: []byte{0x01, 0x00},
|
|
},
|
|
{
|
|
value: 0x0000ffff,
|
|
size: 2,
|
|
bytes: []byte{0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x00010000,
|
|
size: 3,
|
|
bytes: []byte{0x01, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0x00ffffff,
|
|
size: 3,
|
|
bytes: []byte{0xff, 0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x01000000,
|
|
size: 4,
|
|
bytes: []byte{0x01, 0x00, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0xffffffff,
|
|
size: 4,
|
|
bytes: []byte{0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
}
|
|
|
|
// TestSizeTUint32 asserts that SizeTUint32 computes the proper truncated size
|
|
// along boundary conditions of the input space.
|
|
func TestSizeTUint32(t *testing.T) {
|
|
for _, test := range tuint32Tests {
|
|
name := fmt.Sprintf("0x%x", test.value)
|
|
t.Run(name, func(t *testing.T) {
|
|
size := tlv.SizeTUint32(test.value)
|
|
if test.size != size {
|
|
t.Fatalf("size mismatch, expected: %d got: %d",
|
|
test.size, size)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestTUint32 asserts that ETUint32 outputs the proper encoding of a truncated
|
|
// uint32, and that DTUint32 is able to parse the output.
|
|
func TestTUint32(t *testing.T) {
|
|
var buf [8]byte
|
|
for _, test := range tuint32Tests {
|
|
test := test
|
|
|
|
if len(test.bytes) != int(test.size) {
|
|
t.Fatalf("invalid test case, "+
|
|
"len(bytes)[%d] != size[%d]",
|
|
len(test.bytes), test.size)
|
|
}
|
|
|
|
name := fmt.Sprintf("0x%x", test.value)
|
|
t.Run(name, func(t *testing.T) {
|
|
// Test generic encoder.
|
|
var b bytes.Buffer
|
|
err := tlv.ETUint32(&b, &test.value, &buf)
|
|
if err != nil {
|
|
t.Fatalf("unable to encode tuint32: %v", err)
|
|
}
|
|
|
|
if bytes.Compare(b.Bytes(), test.bytes) != 0 {
|
|
t.Fatalf("encoding mismatch, "+
|
|
"expected: %x, got: %x",
|
|
test.bytes, b.Bytes())
|
|
}
|
|
|
|
// Test non-generic encoder.
|
|
var b2 bytes.Buffer
|
|
err = tlv.ETUint32T(&b2, test.value, &buf)
|
|
if err != nil {
|
|
t.Fatalf("unable to encode tuint32: %v", err)
|
|
}
|
|
|
|
if !bytes.Equal(b2.Bytes(), test.bytes) {
|
|
t.Fatalf("encoding mismatch, "+
|
|
"expected: %x, got: %x",
|
|
test.bytes, b2.Bytes())
|
|
}
|
|
|
|
var value uint32
|
|
r := bytes.NewReader(b.Bytes())
|
|
err = tlv.DTUint32(r, &value, &buf, test.size)
|
|
if err != nil {
|
|
t.Fatalf("unable to decode tuint32: %v", err)
|
|
}
|
|
|
|
if value != test.value {
|
|
t.Fatalf("decoded value mismatch, "+
|
|
"expected: %d, got: %d",
|
|
test.value, value)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
var tuint64Tests = []struct {
|
|
value uint64
|
|
size uint64
|
|
bytes []byte
|
|
}{
|
|
{
|
|
value: 0x0000000000000000,
|
|
size: 0,
|
|
bytes: []byte{},
|
|
},
|
|
{
|
|
value: 0x0000000000000001,
|
|
size: 1,
|
|
bytes: []byte{0x01},
|
|
},
|
|
{
|
|
value: 0x00000000000000ff,
|
|
size: 1,
|
|
bytes: []byte{0xff},
|
|
},
|
|
{
|
|
value: 0x0000000000000100,
|
|
size: 2,
|
|
bytes: []byte{0x01, 0x00},
|
|
},
|
|
{
|
|
value: 0x000000000000ffff,
|
|
size: 2,
|
|
bytes: []byte{0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x0000000000010000,
|
|
size: 3,
|
|
bytes: []byte{0x01, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0x0000000000ffffff,
|
|
size: 3,
|
|
bytes: []byte{0xff, 0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x0000000001000000,
|
|
size: 4,
|
|
bytes: []byte{0x01, 0x00, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0x00000000ffffffff,
|
|
size: 4,
|
|
bytes: []byte{0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x0000000100000000,
|
|
size: 5,
|
|
bytes: []byte{0x01, 0x00, 0x00, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0x000000ffffffffff,
|
|
size: 5,
|
|
bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x0000010000000000,
|
|
size: 6,
|
|
bytes: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0x0000ffffffffffff,
|
|
size: 6,
|
|
bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x0001000000000000,
|
|
size: 7,
|
|
bytes: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0x00ffffffffffffff,
|
|
size: 7,
|
|
bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
{
|
|
value: 0x0100000000000000,
|
|
size: 8,
|
|
bytes: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
},
|
|
{
|
|
value: 0xffffffffffffffff,
|
|
size: 8,
|
|
bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
}
|
|
|
|
// TestSizeTUint64 asserts that SizeTUint64 computes the proper truncated size
|
|
// along boundary conditions of the input space.
|
|
func TestSizeTUint64(t *testing.T) {
|
|
for _, test := range tuint64Tests {
|
|
if len(test.bytes) != int(test.size) {
|
|
t.Fatalf("invalid test case, "+
|
|
"len(bytes)[%d] != size[%d]",
|
|
len(test.bytes), test.size)
|
|
}
|
|
|
|
name := fmt.Sprintf("0x%x", test.value)
|
|
t.Run(name, func(t *testing.T) {
|
|
size := tlv.SizeTUint64(test.value)
|
|
if test.size != size {
|
|
t.Fatalf("size mismatch, expected: %d got: %d",
|
|
test.size, size)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestTUint64 asserts that ETUint64 outputs the proper encoding of a truncated
|
|
// uint64, and that DTUint64 is able to parse the output.
|
|
func TestTUint64(t *testing.T) {
|
|
var buf [8]byte
|
|
for _, test := range tuint64Tests {
|
|
test := test
|
|
|
|
if len(test.bytes) != int(test.size) {
|
|
t.Fatalf("invalid test case, "+
|
|
"len(bytes)[%d] != size[%d]",
|
|
len(test.bytes), test.size)
|
|
}
|
|
|
|
name := fmt.Sprintf("0x%x", test.value)
|
|
t.Run(name, func(t *testing.T) {
|
|
// Test generic encoder.
|
|
var b bytes.Buffer
|
|
err := tlv.ETUint64(&b, &test.value, &buf)
|
|
if err != nil {
|
|
t.Fatalf("unable to encode tuint64: %v", err)
|
|
}
|
|
|
|
if bytes.Compare(b.Bytes(), test.bytes) != 0 {
|
|
t.Fatalf("encoding mismatch, "+
|
|
"expected: %x, got: %x",
|
|
test.bytes, b.Bytes())
|
|
}
|
|
|
|
// Test non-generic encoder.
|
|
var b2 bytes.Buffer
|
|
err = tlv.ETUint64T(&b2, test.value, &buf)
|
|
if err != nil {
|
|
t.Fatalf("unable to encode tuint64: %v", err)
|
|
}
|
|
|
|
if !bytes.Equal(b2.Bytes(), test.bytes) {
|
|
t.Fatalf("encoding mismatch, "+
|
|
"expected: %x, got: %x",
|
|
test.bytes, b2.Bytes())
|
|
}
|
|
|
|
var value uint64
|
|
r := bytes.NewReader(b.Bytes())
|
|
err = tlv.DTUint64(r, &value, &buf, test.size)
|
|
if err != nil {
|
|
t.Fatalf("unable to decode tuint64: %v", err)
|
|
}
|
|
|
|
if value != test.value {
|
|
t.Fatalf("decoded value mismatch, "+
|
|
"expected: %d, got: %d",
|
|
test.value, value)
|
|
}
|
|
})
|
|
}
|
|
}
|