github.com/decred/dcrlnd@v0.7.6/lnwire/extra_bytes_test.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"bytes"
     5  	"math/rand"
     6  	"reflect"
     7  	"testing"
     8  	"testing/quick"
     9  
    10  	"github.com/decred/dcrlnd/tlv"
    11  )
    12  
    13  // TestExtraOpaqueDataEncodeDecode tests that we're able to encode/decode
    14  // arbitrary payloads.
    15  func TestExtraOpaqueDataEncodeDecode(t *testing.T) {
    16  	t.Parallel()
    17  
    18  	type testCase struct {
    19  		// emptyBytes indicates if we should try to encode empty bytes
    20  		// or not.
    21  		emptyBytes bool
    22  
    23  		// inputBytes if emptyBytes is false, then we'll read in this
    24  		// set of bytes instead.
    25  		inputBytes []byte
    26  	}
    27  
    28  	// We should be able to read in an arbitrary set of bytes as an
    29  	// ExtraOpaqueData, then encode those new bytes into a new instance.
    30  	// The final two instances should be identical.
    31  	scenario := func(test testCase) bool {
    32  		var (
    33  			extraData ExtraOpaqueData
    34  			b         bytes.Buffer
    35  		)
    36  
    37  		copy(extraData[:], test.inputBytes)
    38  
    39  		if err := extraData.Encode(&b); err != nil {
    40  			t.Fatalf("unable to encode extra data: %v", err)
    41  			return false
    42  		}
    43  
    44  		var newBytes ExtraOpaqueData
    45  		if err := newBytes.Decode(&b); err != nil {
    46  			t.Fatalf("unable to decode extra bytes: %v", err)
    47  			return false
    48  		}
    49  
    50  		if !bytes.Equal(extraData[:], newBytes[:]) {
    51  			t.Fatalf("expected %x, got %x", extraData,
    52  				newBytes)
    53  			return false
    54  		}
    55  
    56  		return true
    57  	}
    58  
    59  	// We'll make a function to generate random test data. Half of the
    60  	// time, we'll actually feed in blank bytes.
    61  	quickCfg := &quick.Config{
    62  		Values: func(v []reflect.Value, r *rand.Rand) {
    63  
    64  			var newTestCase testCase
    65  			if r.Int31()%2 == 0 {
    66  				newTestCase.emptyBytes = true
    67  			}
    68  
    69  			if !newTestCase.emptyBytes {
    70  				numBytes := r.Int31n(1000)
    71  				newTestCase.inputBytes = make([]byte, numBytes)
    72  
    73  				_, err := r.Read(newTestCase.inputBytes)
    74  				if err != nil {
    75  					t.Fatalf("unable to gen random bytes: %v", err)
    76  					return
    77  				}
    78  			}
    79  
    80  			v[0] = reflect.ValueOf(newTestCase)
    81  		},
    82  	}
    83  
    84  	if err := quick.Check(scenario, quickCfg); err != nil {
    85  		t.Fatalf("encode+decode test failed: %v", err)
    86  	}
    87  }
    88  
    89  type recordProducer struct {
    90  	record tlv.Record
    91  }
    92  
    93  func (r *recordProducer) Record() tlv.Record {
    94  	return r.record
    95  }
    96  
    97  // TestExtraOpaqueDataPackUnpackRecords tests that we're able to pack a set of
    98  // tlv.Records into a stream, and unpack them on the other side to obtain the
    99  // same set of records.
   100  func TestExtraOpaqueDataPackUnpackRecords(t *testing.T) {
   101  	t.Parallel()
   102  
   103  	var (
   104  		type1 tlv.Type = 1
   105  		type2 tlv.Type = 2
   106  
   107  		channelType1 uint8 = 2
   108  		channelType2 uint8
   109  
   110  		hop1 uint32 = 99
   111  		hop2 uint32
   112  	)
   113  	testRecordsProducers := []tlv.RecordProducer{
   114  		&recordProducer{tlv.MakePrimitiveRecord(type1, &channelType1)},
   115  		&recordProducer{tlv.MakePrimitiveRecord(type2, &hop1)},
   116  	}
   117  
   118  	// Now that we have our set of sample records and types, we'll encode
   119  	// them into the passed ExtraOpaqueData instance.
   120  	var extraBytes ExtraOpaqueData
   121  	if err := extraBytes.PackRecords(testRecordsProducers...); err != nil {
   122  		t.Fatalf("unable to pack records: %v", err)
   123  	}
   124  
   125  	// We'll now simulate decoding these types _back_ into records on the
   126  	// other side.
   127  	newRecords := []tlv.RecordProducer{
   128  		&recordProducer{tlv.MakePrimitiveRecord(type1, &channelType2)},
   129  		&recordProducer{tlv.MakePrimitiveRecord(type2, &hop2)},
   130  	}
   131  	typeMap, err := extraBytes.ExtractRecords(newRecords...)
   132  	if err != nil {
   133  		t.Fatalf("unable to extract record: %v", err)
   134  	}
   135  
   136  	// We should find that the new backing values have been populated with
   137  	// the proper value.
   138  	switch {
   139  	case channelType1 != channelType2:
   140  		t.Fatalf("wrong record for channel type: expected %v, got %v",
   141  			channelType1, channelType2)
   142  
   143  	case hop1 != hop2:
   144  		t.Fatalf("wrong record for hop: expected %v, got %v", hop1,
   145  			hop2)
   146  	}
   147  
   148  	// Both types we created above should be found in the type map.
   149  	if _, ok := typeMap[type1]; !ok {
   150  		t.Fatalf("type1 not found in typeMap")
   151  	}
   152  	if _, ok := typeMap[type2]; !ok {
   153  		t.Fatalf("type2 not found in typeMap")
   154  	}
   155  }