Merge pull request #3387 from cfromknecht/tlv-primtive-test
tlv: add tests for all primitive encodings
This commit is contained in:
commit
938516ec5a
@ -71,7 +71,7 @@ func EUint8(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
_, err := w.Write(buf[:1])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "uint8"}
|
||||
return NewTypeForEncodingErr(val, "uint8")
|
||||
}
|
||||
|
||||
// EUint8T encodes a uint8 val to the provided io.Writer. This method is exposed
|
||||
@ -91,7 +91,7 @@ func EUint16(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
_, err := w.Write(buf[:2])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "uint16"}
|
||||
return NewTypeForEncodingErr(val, "uint16")
|
||||
}
|
||||
|
||||
// EUint16T encodes a uint16 val to the provided io.Writer. This method is
|
||||
@ -111,7 +111,7 @@ func EUint32(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
_, err := w.Write(buf[:4])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "uint32"}
|
||||
return NewTypeForEncodingErr(val, "uint32")
|
||||
}
|
||||
|
||||
// EUint32T encodes a uint32 val to the provided io.Writer. This method is
|
||||
@ -131,7 +131,7 @@ func EUint64(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
_, err := w.Write(buf[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "uint64"}
|
||||
return NewTypeForEncodingErr(val, "uint64")
|
||||
}
|
||||
|
||||
// EUint64T encodes a uint64 val to the provided io.Writer. This method is
|
||||
@ -153,7 +153,7 @@ func DUint8(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
*i = buf[0]
|
||||
return nil
|
||||
}
|
||||
return ErrTypeForDecoding{val, "uint8", l, 1}
|
||||
return NewTypeForDecodingErr(val, "uint8", l, 1)
|
||||
}
|
||||
|
||||
// DUint16 is a Decoder for uint16 values. An error is returned if val is not a
|
||||
@ -166,7 +166,7 @@ func DUint16(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
*i = byteOrder.Uint16(buf[:2])
|
||||
return nil
|
||||
}
|
||||
return ErrTypeForDecoding{val, "uint16", l, 2}
|
||||
return NewTypeForDecodingErr(val, "uint16", l, 2)
|
||||
}
|
||||
|
||||
// DUint32 is a Decoder for uint32 values. An error is returned if val is not a
|
||||
@ -179,7 +179,7 @@ func DUint32(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
*i = byteOrder.Uint32(buf[:4])
|
||||
return nil
|
||||
}
|
||||
return ErrTypeForDecoding{val, "uint32", l, 4}
|
||||
return NewTypeForDecodingErr(val, "uint32", l, 4)
|
||||
}
|
||||
|
||||
// DUint64 is a Decoder for uint64 values. An error is returned if val is not a
|
||||
@ -192,7 +192,7 @@ func DUint64(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
*i = byteOrder.Uint64(buf[:])
|
||||
return nil
|
||||
}
|
||||
return ErrTypeForDecoding{val, "uint64", l, 8}
|
||||
return NewTypeForDecodingErr(val, "uint64", l, 8)
|
||||
}
|
||||
|
||||
// EBytes32 is an Encoder for 32-byte arrays. An error is returned if val is not
|
||||
@ -202,7 +202,7 @@ func EBytes32(w io.Writer, val interface{}, _ *[8]byte) error {
|
||||
_, err := w.Write(b[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "[32]byte"}
|
||||
return NewTypeForEncodingErr(val, "[32]byte")
|
||||
}
|
||||
|
||||
// DBytes32 is a Decoder for 32-byte arrays. An error is returned if val is not
|
||||
@ -212,7 +212,7 @@ func DBytes32(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
|
||||
_, err := io.ReadFull(r, b[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForDecoding{val, "[32]byte", l, 32}
|
||||
return NewTypeForDecodingErr(val, "[32]byte", l, 32)
|
||||
}
|
||||
|
||||
// EBytes33 is an Encoder for 33-byte arrays. An error is returned if val is not
|
||||
@ -222,7 +222,7 @@ func EBytes33(w io.Writer, val interface{}, _ *[8]byte) error {
|
||||
_, err := w.Write(b[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "[33]byte"}
|
||||
return NewTypeForEncodingErr(val, "[33]byte")
|
||||
}
|
||||
|
||||
// DBytes33 is a Decoder for 33-byte arrays. An error is returned if val is not
|
||||
@ -232,7 +232,7 @@ func DBytes33(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
|
||||
_, err := io.ReadFull(r, b[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForDecoding{val, "[33]byte", l, 33}
|
||||
return NewTypeForDecodingErr(val, "[33]byte", l, 33)
|
||||
}
|
||||
|
||||
// EBytes64 is an Encoder for 64-byte arrays. An error is returned if val is not
|
||||
@ -242,7 +242,7 @@ func EBytes64(w io.Writer, val interface{}, _ *[8]byte) error {
|
||||
_, err := w.Write(b[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "[64]byte"}
|
||||
return NewTypeForEncodingErr(val, "[64]byte")
|
||||
}
|
||||
|
||||
// DBytes64 is an Decoder for 64-byte arrays. An error is returned if val is not
|
||||
@ -252,7 +252,7 @@ func DBytes64(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
|
||||
_, err := io.ReadFull(r, b[:])
|
||||
return err
|
||||
}
|
||||
return ErrTypeForDecoding{val, "[64]byte", l, 64}
|
||||
return NewTypeForDecodingErr(val, "[64]byte", l, 64)
|
||||
}
|
||||
|
||||
// EPubKey is an Encoder for *btcec.PublicKey values. An error is returned if
|
||||
@ -262,7 +262,7 @@ func EPubKey(w io.Writer, val interface{}, _ *[8]byte) error {
|
||||
_, err := w.Write((*pk).SerializeCompressed())
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "*btcec.PublicKey"}
|
||||
return NewTypeForEncodingErr(val, "*btcec.PublicKey")
|
||||
}
|
||||
|
||||
// DPubKey is a Decoder for *btcec.PublicKey values. An error is returned if val
|
||||
@ -284,7 +284,7 @@ func DPubKey(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
return ErrTypeForDecoding{val, "*btcec.PublicKey", l, 33}
|
||||
return NewTypeForDecodingErr(val, "*btcec.PublicKey", l, 33)
|
||||
}
|
||||
|
||||
// EVarBytes is an Encoder for variable byte slices. An error is returned if val
|
||||
@ -294,7 +294,7 @@ func EVarBytes(w io.Writer, val interface{}, _ *[8]byte) error {
|
||||
_, err := w.Write(*b)
|
||||
return err
|
||||
}
|
||||
return ErrTypeForEncoding{val, "[]byte"}
|
||||
return NewTypeForEncodingErr(val, "[]byte")
|
||||
}
|
||||
|
||||
// DVarBytes is a Decoder for variable byte slices. An error is returned if val
|
||||
@ -305,5 +305,5 @@ func DVarBytes(r io.Reader, val interface{}, _ *[8]byte, l uint64) error {
|
||||
_, err := io.ReadFull(r, *b)
|
||||
return err
|
||||
}
|
||||
return ErrTypeForDecoding{val, "[]byte", l, l}
|
||||
return NewTypeForDecodingErr(val, "[]byte", l, l)
|
||||
}
|
||||
|
242
tlv/primitive_test.go
Normal file
242
tlv/primitive_test.go
Normal file
@ -0,0 +1,242 @@
|
||||
package tlv_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
)
|
||||
|
||||
var testPK, _ = btcec.ParsePubKey([]byte{0x02,
|
||||
0x3d, 0xa0, 0x92, 0xf6, 0x98, 0x0e, 0x58, 0xd2,
|
||||
0xc0, 0x37, 0x17, 0x31, 0x80, 0xe9, 0xa4, 0x65,
|
||||
0x47, 0x60, 0x26, 0xee, 0x50, 0xf9, 0x66, 0x95,
|
||||
0x96, 0x3e, 0x8e, 0xfe, 0x43, 0x6f, 0x54, 0xeb,
|
||||
}, btcec.S256())
|
||||
|
||||
type primitive struct {
|
||||
u8 byte
|
||||
u16 uint16
|
||||
u32 uint32
|
||||
u64 uint64
|
||||
b32 [32]byte
|
||||
b33 [33]byte
|
||||
b64 [64]byte
|
||||
pk *btcec.PublicKey
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// TestWrongEncodingType asserts that all primitives encoders will fail with a
|
||||
// ErrTypeForEncoding when an incorrect type is provided.
|
||||
func TestWrongEncodingType(t *testing.T) {
|
||||
encoders := []tlv.Encoder{
|
||||
tlv.EUint8,
|
||||
tlv.EUint16,
|
||||
tlv.EUint32,
|
||||
tlv.EUint64,
|
||||
tlv.EBytes32,
|
||||
tlv.EBytes33,
|
||||
tlv.EBytes64,
|
||||
tlv.EPubKey,
|
||||
tlv.EVarBytes,
|
||||
}
|
||||
|
||||
// We'll use an int32 since it is not a primitive type, which should
|
||||
// cause the primitive encoders to fail with an ErrTypeForEncoding
|
||||
// failure.
|
||||
var (
|
||||
value int32
|
||||
buf [8]byte
|
||||
b bytes.Buffer
|
||||
)
|
||||
for _, encoder := range encoders {
|
||||
err := encoder(&b, &value, &buf)
|
||||
if _, ok := err.(tlv.ErrTypeForEncoding); !ok {
|
||||
t.Fatalf("expected error of type ErrTypeForEncoding, "+
|
||||
"got %T", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestWrongDecodingType asserts that all primitives decoders will fail with a
|
||||
// ErrTypeForDecoding when an incorrect type is provided.
|
||||
func TestWrongDecodingType(t *testing.T) {
|
||||
decoders := []tlv.Decoder{
|
||||
tlv.DUint8,
|
||||
tlv.DUint16,
|
||||
tlv.DUint32,
|
||||
tlv.DUint64,
|
||||
tlv.DBytes32,
|
||||
tlv.DBytes33,
|
||||
tlv.DBytes64,
|
||||
tlv.DPubKey,
|
||||
tlv.DVarBytes,
|
||||
}
|
||||
|
||||
// We'll use an int32 since it is not a primitive type, which should
|
||||
// cause the primitive decoders to fail with an ErrTypeForDecoding
|
||||
// failure.
|
||||
var (
|
||||
value int32
|
||||
buf [8]byte
|
||||
b bytes.Buffer
|
||||
)
|
||||
for _, decoder := range decoders {
|
||||
err := decoder(&b, &value, &buf, 0)
|
||||
if _, ok := err.(tlv.ErrTypeForDecoding); !ok {
|
||||
t.Fatalf("expected error of type ErrTypeForDecoding, "+
|
||||
"got %T", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type fieldEncoder struct {
|
||||
val interface{}
|
||||
encoder tlv.Encoder
|
||||
}
|
||||
|
||||
type fieldDecoder struct {
|
||||
val interface{}
|
||||
decoder tlv.Decoder
|
||||
size uint64
|
||||
}
|
||||
|
||||
// TestPrimitiveEncodings tests that we are able to serialize all known
|
||||
// primitive field types. After successfully encoding, we check that we are able
|
||||
// to decode the output and arrive at the same fields.
|
||||
func TestPrimitiveEncodings(t *testing.T) {
|
||||
prim := primitive{
|
||||
u8: 0x01,
|
||||
u16: 0x0201,
|
||||
u32: 0x02000001,
|
||||
u64: 0x0200000000000001,
|
||||
b32: [32]byte{0x02, 0x01},
|
||||
b33: [33]byte{0x03, 0x01},
|
||||
b64: [64]byte{0x02, 0x01},
|
||||
pk: testPK,
|
||||
bytes: []byte{0xaa, 0xbb},
|
||||
}
|
||||
|
||||
encoders := []fieldEncoder{
|
||||
{
|
||||
val: &prim.u8,
|
||||
encoder: tlv.EUint8,
|
||||
},
|
||||
{
|
||||
val: &prim.u16,
|
||||
encoder: tlv.EUint16,
|
||||
},
|
||||
{
|
||||
val: &prim.u32,
|
||||
encoder: tlv.EUint32,
|
||||
},
|
||||
{
|
||||
val: &prim.u64,
|
||||
encoder: tlv.EUint64,
|
||||
},
|
||||
{
|
||||
val: &prim.b32,
|
||||
encoder: tlv.EBytes32,
|
||||
},
|
||||
{
|
||||
val: &prim.b33,
|
||||
encoder: tlv.EBytes33,
|
||||
},
|
||||
{
|
||||
val: &prim.b64,
|
||||
encoder: tlv.EBytes64,
|
||||
},
|
||||
{
|
||||
val: &prim.pk,
|
||||
encoder: tlv.EPubKey,
|
||||
},
|
||||
{
|
||||
val: &prim.bytes,
|
||||
encoder: tlv.EVarBytes,
|
||||
},
|
||||
}
|
||||
|
||||
// First we'll encode the primitive fields into a buffer.
|
||||
var (
|
||||
b bytes.Buffer
|
||||
buf [8]byte
|
||||
)
|
||||
for _, field := range encoders {
|
||||
err := field.encoder(&b, field.val, &buf)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to encode %T: %v",
|
||||
field.val, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Next, we'll attempt to decode the primitive fields into a separate
|
||||
// primitive struct.
|
||||
r := bytes.NewReader(b.Bytes())
|
||||
var prim2 primitive
|
||||
|
||||
decoders := []fieldDecoder{
|
||||
{
|
||||
val: &prim2.u8,
|
||||
decoder: tlv.DUint8,
|
||||
size: 1,
|
||||
},
|
||||
{
|
||||
val: &prim2.u16,
|
||||
decoder: tlv.DUint16,
|
||||
size: 2,
|
||||
},
|
||||
{
|
||||
val: &prim2.u32,
|
||||
decoder: tlv.DUint32,
|
||||
size: 4,
|
||||
},
|
||||
{
|
||||
val: &prim2.u64,
|
||||
decoder: tlv.DUint64,
|
||||
size: 8,
|
||||
},
|
||||
{
|
||||
val: &prim2.b32,
|
||||
decoder: tlv.DBytes32,
|
||||
size: 32,
|
||||
},
|
||||
{
|
||||
val: &prim2.b33,
|
||||
decoder: tlv.DBytes33,
|
||||
size: 33,
|
||||
},
|
||||
{
|
||||
val: &prim2.b64,
|
||||
decoder: tlv.DBytes64,
|
||||
size: 64,
|
||||
},
|
||||
{
|
||||
val: &prim2.pk,
|
||||
decoder: tlv.DPubKey,
|
||||
size: 33,
|
||||
},
|
||||
{
|
||||
val: &prim2.bytes,
|
||||
decoder: tlv.DVarBytes,
|
||||
size: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, field := range decoders {
|
||||
err := field.decoder(r, field.val, &buf, field.size)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to decode %T: %v",
|
||||
field.val, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, we'll compare that the original and the decode structs are
|
||||
// equal.
|
||||
if !reflect.DeepEqual(prim, prim2) {
|
||||
t.Fatalf("primitive mismatch, "+
|
||||
"expected: %v, got: %v",
|
||||
prim, prim2)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user