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 }