github.com/decred/dcrlnd@v0.7.6/channeldb/migration16/migration_test.go (about) 1 package migration16 2 3 import ( 4 "encoding/hex" 5 "testing" 6 7 "github.com/decred/dcrlnd/channeldb/migtest" 8 "github.com/decred/dcrlnd/kvdb" 9 ) 10 11 var ( 12 hexStr = migtest.Hex 13 14 hash1Str = "02acee76ebd53d00824410cf6adecad4f50334dac702bd5a2d3ba01b91709f0e" 15 hash1 = hexStr(hash1Str) 16 paymentID1 = hexStr("0000000000000001") 17 18 hash2Str = "62eb3f0a48f954e495d0c14ac63df04a67cefa59dafdbcd3d5046d1f5647840c" 19 hash2 = hexStr(hash2Str) 20 paymentID2 = hexStr("0000000000000002") 21 22 paymentID3 = hexStr("0000000000000003") 23 24 // pre is the data in the payments root bucket in database version 13 format. 25 pre = map[string]interface{}{ 26 // A payment without duplicates. 27 hash1: map[string]interface{}{ 28 "payment-sequence-key": paymentID1, 29 }, 30 31 // A payment with a duplicate. 32 hash2: map[string]interface{}{ 33 "payment-sequence-key": paymentID2, 34 "payment-duplicate-bucket": map[string]interface{}{ 35 paymentID3: map[string]interface{}{ 36 "payment-sequence-key": paymentID3, 37 }, 38 }, 39 }, 40 } 41 42 preFails = map[string]interface{}{ 43 // A payment without duplicates. 44 hash1: map[string]interface{}{ 45 "payment-sequence-key": paymentID1, 46 "payment-duplicate-bucket": map[string]interface{}{ 47 paymentID1: map[string]interface{}{ 48 "payment-sequence-key": paymentID1, 49 }, 50 }, 51 }, 52 } 53 54 // post is the expected data after migration. 55 post = map[string]interface{}{ 56 paymentID1: paymentHashIndex(hash1Str), 57 paymentID2: paymentHashIndex(hash2Str), 58 paymentID3: paymentHashIndex(hash2Str), 59 } 60 ) 61 62 // paymentHashIndex produces a string that represents the value we expect for 63 // our payment indexes from a hex encoded payment hash string. 64 func paymentHashIndex(hashStr string) string { 65 hash, err := hex.DecodeString(hashStr) 66 if err != nil { 67 panic(err) 68 } 69 70 bytes, err := serializePaymentIndexEntry(hash) 71 if err != nil { 72 panic(err) 73 } 74 75 return string(bytes) 76 } 77 78 // MigrateSequenceIndex asserts that the database is properly migrated to 79 // contain a payments index. 80 func TestMigrateSequenceIndex(t *testing.T) { 81 tests := []struct { 82 name string 83 shouldFail bool 84 pre map[string]interface{} 85 post map[string]interface{} 86 }{ 87 { 88 name: "migration ok", 89 shouldFail: false, 90 pre: pre, 91 post: post, 92 }, 93 { 94 name: "duplicate sequence number", 95 shouldFail: true, 96 pre: preFails, 97 post: post, 98 }, 99 { 100 name: "no payments", 101 shouldFail: false, 102 pre: nil, 103 post: nil, 104 }, 105 } 106 107 for _, test := range tests { 108 test := test 109 110 t.Run(test.name, func(t *testing.T) { 111 // Before the migration we have a payments bucket. 112 before := func(tx kvdb.RwTx) error { 113 return migtest.RestoreDB( 114 tx, paymentsRootBucket, test.pre, 115 ) 116 } 117 118 // After the migration, we should have an untouched 119 // payments bucket and a new index bucket. 120 after := func(tx kvdb.RwTx) error { 121 if err := migtest.VerifyDB( 122 tx, paymentsRootBucket, test.pre, 123 ); err != nil { 124 return err 125 } 126 127 // If we expect our migration to fail, we don't 128 // expect an index bucket. 129 if test.shouldFail { 130 return nil 131 } 132 133 return migtest.VerifyDB( 134 tx, paymentsIndexBucket, test.post, 135 ) 136 } 137 138 migtest.ApplyMigration( 139 t, before, after, MigrateSequenceIndex, 140 test.shouldFail, 141 ) 142 }) 143 } 144 }