github.com/decred/dcrlnd@v0.7.6/tlv/primitive_test.go (about)

     1  package tlv_test
     2  
     3  import (
     4  	"bytes"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
     9  	"github.com/decred/dcrlnd/tlv"
    10  )
    11  
    12  var testPK, _ = secp256k1.ParsePubKey([]byte{0x02,
    13  	0x3d, 0xa0, 0x92, 0xf6, 0x98, 0x0e, 0x58, 0xd2,
    14  	0xc0, 0x37, 0x17, 0x31, 0x80, 0xe9, 0xa4, 0x65,
    15  	0x47, 0x60, 0x26, 0xee, 0x50, 0xf9, 0x66, 0x95,
    16  	0x96, 0x3e, 0x8e, 0xfe, 0x43, 0x6f, 0x54, 0xeb,
    17  })
    18  
    19  type primitive struct {
    20  	u8    byte
    21  	u16   uint16
    22  	u32   uint32
    23  	u64   uint64
    24  	b32   [32]byte
    25  	b33   [33]byte
    26  	b64   [64]byte
    27  	pk    *secp256k1.PublicKey
    28  	bytes []byte
    29  }
    30  
    31  // TestWrongEncodingType asserts that all primitives encoders will fail with a
    32  // ErrTypeForEncoding when an incorrect type is provided.
    33  func TestWrongEncodingType(t *testing.T) {
    34  	encoders := []tlv.Encoder{
    35  		tlv.EUint8,
    36  		tlv.EUint16,
    37  		tlv.EUint32,
    38  		tlv.EUint64,
    39  		tlv.EBytes32,
    40  		tlv.EBytes33,
    41  		tlv.EBytes64,
    42  		tlv.EPubKey,
    43  		tlv.EVarBytes,
    44  	}
    45  
    46  	// We'll use an int32 since it is not a primitive type, which should
    47  	// cause the primitive encoders to fail with an ErrTypeForEncoding
    48  	// failure.
    49  	var (
    50  		value int32
    51  		buf   [8]byte
    52  		b     bytes.Buffer
    53  	)
    54  	for _, encoder := range encoders {
    55  		err := encoder(&b, &value, &buf)
    56  		if _, ok := err.(tlv.ErrTypeForEncoding); !ok {
    57  			t.Fatalf("expected error of type ErrTypeForEncoding, "+
    58  				"got %T", err)
    59  		}
    60  	}
    61  }
    62  
    63  // TestWrongDecodingType asserts that all primitives decoders will fail with a
    64  // ErrTypeForDecoding when an incorrect type is provided.
    65  func TestWrongDecodingType(t *testing.T) {
    66  	decoders := []tlv.Decoder{
    67  		tlv.DUint8,
    68  		tlv.DUint16,
    69  		tlv.DUint32,
    70  		tlv.DUint64,
    71  		tlv.DBytes32,
    72  		tlv.DBytes33,
    73  		tlv.DBytes64,
    74  		tlv.DPubKey,
    75  		tlv.DVarBytes,
    76  	}
    77  
    78  	// We'll use an int32 since it is not a primitive type, which should
    79  	// cause the primitive decoders to fail with an ErrTypeForDecoding
    80  	// failure.
    81  	var (
    82  		value int32
    83  		buf   [8]byte
    84  		b     bytes.Buffer
    85  	)
    86  	for _, decoder := range decoders {
    87  		err := decoder(&b, &value, &buf, 0)
    88  		if _, ok := err.(tlv.ErrTypeForDecoding); !ok {
    89  			t.Fatalf("expected error of type ErrTypeForDecoding, "+
    90  				"got %T", err)
    91  		}
    92  	}
    93  }
    94  
    95  type fieldEncoder struct {
    96  	val     interface{}
    97  	encoder tlv.Encoder
    98  }
    99  
   100  type fieldDecoder struct {
   101  	val     interface{}
   102  	decoder tlv.Decoder
   103  	size    uint64
   104  }
   105  
   106  // TestPrimitiveEncodings tests that we are able to serialize all known
   107  // primitive field types. After successfully encoding, we check that we are able
   108  // to decode the output and arrive at the same fields.
   109  func TestPrimitiveEncodings(t *testing.T) {
   110  	prim := primitive{
   111  		u8:    0x01,
   112  		u16:   0x0201,
   113  		u32:   0x02000001,
   114  		u64:   0x0200000000000001,
   115  		b32:   [32]byte{0x02, 0x01},
   116  		b33:   [33]byte{0x03, 0x01},
   117  		b64:   [64]byte{0x02, 0x01},
   118  		pk:    testPK,
   119  		bytes: []byte{0xaa, 0xbb},
   120  	}
   121  
   122  	encoders := []fieldEncoder{
   123  		{
   124  			val:     &prim.u8,
   125  			encoder: tlv.EUint8,
   126  		},
   127  		{
   128  			val:     &prim.u16,
   129  			encoder: tlv.EUint16,
   130  		},
   131  		{
   132  			val:     &prim.u32,
   133  			encoder: tlv.EUint32,
   134  		},
   135  		{
   136  			val:     &prim.u64,
   137  			encoder: tlv.EUint64,
   138  		},
   139  		{
   140  			val:     &prim.b32,
   141  			encoder: tlv.EBytes32,
   142  		},
   143  		{
   144  			val:     &prim.b33,
   145  			encoder: tlv.EBytes33,
   146  		},
   147  		{
   148  			val:     &prim.b64,
   149  			encoder: tlv.EBytes64,
   150  		},
   151  		{
   152  			val:     &prim.pk,
   153  			encoder: tlv.EPubKey,
   154  		},
   155  		{
   156  			val:     &prim.bytes,
   157  			encoder: tlv.EVarBytes,
   158  		},
   159  	}
   160  
   161  	// First we'll encode the primitive fields into a buffer.
   162  	var (
   163  		b   bytes.Buffer
   164  		buf [8]byte
   165  	)
   166  	for _, field := range encoders {
   167  		err := field.encoder(&b, field.val, &buf)
   168  		if err != nil {
   169  			t.Fatalf("unable to encode %T: %v",
   170  				field.val, err)
   171  		}
   172  	}
   173  
   174  	// Next, we'll attempt to decode the primitive fields into a separate
   175  	// primitive struct.
   176  	r := bytes.NewReader(b.Bytes())
   177  	var prim2 primitive
   178  
   179  	decoders := []fieldDecoder{
   180  		{
   181  			val:     &prim2.u8,
   182  			decoder: tlv.DUint8,
   183  			size:    1,
   184  		},
   185  		{
   186  			val:     &prim2.u16,
   187  			decoder: tlv.DUint16,
   188  			size:    2,
   189  		},
   190  		{
   191  			val:     &prim2.u32,
   192  			decoder: tlv.DUint32,
   193  			size:    4,
   194  		},
   195  		{
   196  			val:     &prim2.u64,
   197  			decoder: tlv.DUint64,
   198  			size:    8,
   199  		},
   200  		{
   201  			val:     &prim2.b32,
   202  			decoder: tlv.DBytes32,
   203  			size:    32,
   204  		},
   205  		{
   206  			val:     &prim2.b33,
   207  			decoder: tlv.DBytes33,
   208  			size:    33,
   209  		},
   210  		{
   211  			val:     &prim2.b64,
   212  			decoder: tlv.DBytes64,
   213  			size:    64,
   214  		},
   215  		{
   216  			val:     &prim2.pk,
   217  			decoder: tlv.DPubKey,
   218  			size:    33,
   219  		},
   220  		{
   221  			val:     &prim2.bytes,
   222  			decoder: tlv.DVarBytes,
   223  			size:    2,
   224  		},
   225  	}
   226  
   227  	for _, field := range decoders {
   228  		err := field.decoder(r, field.val, &buf, field.size)
   229  		if err != nil {
   230  			t.Fatalf("unable to decode %T: %v",
   231  				field.val, err)
   232  		}
   233  	}
   234  
   235  	// Finally, we'll compare that the original and the decode structs are
   236  	// equal.
   237  	if !reflect.DeepEqual(prim, prim2) {
   238  		t.Fatalf("primitive mismatch, "+
   239  			"expected: %v, got: %v",
   240  			prim, prim2)
   241  	}
   242  }