github.com/decred/dcrlnd@v0.7.6/kvdb/postgres_test.go (about) 1 //go:build kvdb_postgres 2 // +build kvdb_postgres 3 4 package kvdb 5 6 import ( 7 "testing" 8 9 "github.com/btcsuite/btcwallet/walletdb" 10 "github.com/decred/dcrlnd/kvdb/postgres" 11 "github.com/stretchr/testify/require" 12 ) 13 14 type m = map[string]interface{} 15 16 func TestPostgres(t *testing.T) { 17 stop, err := postgres.StartEmbeddedPostgres() 18 require.NoError(t, err) 19 defer stop() 20 21 tests := []struct { 22 name string 23 test func(*testing.T, walletdb.DB) 24 expectedDb m 25 }{ 26 { 27 name: "read cursor empty interval", 28 test: testReadCursorEmptyInterval, 29 }, 30 { 31 name: "read cursor non empty interval", 32 test: testReadCursorNonEmptyInterval, 33 }, 34 { 35 name: "read write cursor", 36 test: testReadWriteCursor, 37 expectedDb: m{ 38 "test_kv": []m{ 39 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 40 {"id": int64(4), "key": "da", "parent_id": int64(1), "sequence": nil, "value": "3"}, 41 {"id": int64(6), "key": "a", "parent_id": int64(1), "sequence": nil, "value": "0"}, 42 {"id": int64(7), "key": "f", "parent_id": int64(1), "sequence": nil, "value": "5"}, 43 {"id": int64(3), "key": "c", "parent_id": int64(1), "sequence": nil, "value": "3"}, 44 {"id": int64(9), "key": "cx", "parent_id": int64(1), "sequence": nil, "value": "x"}, 45 {"id": int64(10), "key": "cy", "parent_id": int64(1), "sequence": nil, "value": "y"}, 46 }, 47 }, 48 }, 49 { 50 name: "read write cursor with bucket and value", 51 test: testReadWriteCursorWithBucketAndValue, 52 expectedDb: m{ 53 "test_kv": []m{ 54 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 55 {"id": int64(2), "key": "key", "parent_id": int64(1), "sequence": nil, "value": "val"}, 56 {"id": int64(3), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 57 {"id": int64(4), "key": "pear", "parent_id": int64(1), "sequence": nil, "value": nil}, 58 }, 59 }, 60 }, 61 { 62 name: "bucket creation", 63 test: testBucketCreation, 64 expectedDb: m{ 65 "test_kv": []m{ 66 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 67 {"id": int64(2), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 68 {"id": int64(3), "key": "mango", "parent_id": int64(1), "sequence": nil, "value": nil}, 69 {"id": int64(4), "key": "pear", "parent_id": int64(2), "sequence": nil, "value": nil}, 70 }, 71 }, 72 }, 73 { 74 name: "bucket deletion", 75 test: testBucketDeletion, 76 expectedDb: m{ 77 "test_kv": []m{ 78 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 79 {"id": int64(2), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 80 {"id": int64(3), "key": "key1", "parent_id": int64(2), "sequence": nil, "value": "val1"}, 81 {"id": int64(5), "key": "key3", "parent_id": int64(2), "sequence": nil, "value": "val3"}, 82 }, 83 }, 84 }, 85 { 86 name: "bucket for each", 87 test: func(t *testing.T, db walletdb.DB) { 88 testBucketIterator(t, db, func(bucket walletdb.ReadWriteBucket, 89 callback func(key, val []byte) error) error { 90 91 return bucket.ForEach(callback) 92 }) 93 }, 94 expectedDb: m{ 95 "test_kv": []m{ 96 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 97 {"id": int64(2), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 98 {"id": int64(3), "key": "key1", "parent_id": int64(1), "sequence": nil, "value": "val1"}, 99 {"id": int64(4), "key": "key1", "parent_id": int64(2), "sequence": nil, "value": "val1"}, 100 {"id": int64(5), "key": "key2", "parent_id": int64(1), "sequence": nil, "value": "val2"}, 101 {"id": int64(6), "key": "key2", "parent_id": int64(2), "sequence": nil, "value": "val2"}, 102 {"id": int64(7), "key": "key3", "parent_id": int64(1), "sequence": nil, "value": "val3"}, 103 {"id": int64(8), "key": "key3", "parent_id": int64(2), "sequence": nil, "value": "val3"}, 104 }, 105 }, 106 }, 107 { 108 name: "bucket for all", 109 test: func(t *testing.T, db walletdb.DB) { 110 testBucketIterator(t, db, func(bucket walletdb.ReadWriteBucket, 111 callback func(key, val []byte) error) error { 112 113 return ForAll(bucket, callback) 114 }) 115 }, 116 expectedDb: m{ 117 "test_kv": []m{ 118 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 119 {"id": int64(2), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 120 {"id": int64(3), "key": "key1", "parent_id": int64(1), "sequence": nil, "value": "val1"}, 121 {"id": int64(4), "key": "key1", "parent_id": int64(2), "sequence": nil, "value": "val1"}, 122 {"id": int64(5), "key": "key2", "parent_id": int64(1), "sequence": nil, "value": "val2"}, 123 {"id": int64(6), "key": "key2", "parent_id": int64(2), "sequence": nil, "value": "val2"}, 124 {"id": int64(7), "key": "key3", "parent_id": int64(1), "sequence": nil, "value": "val3"}, 125 {"id": int64(8), "key": "key3", "parent_id": int64(2), "sequence": nil, "value": "val3"}, 126 }, 127 }, 128 }, 129 { 130 name: "bucket for each with error", 131 test: testBucketForEachWithError, 132 expectedDb: m{ 133 "test_kv": []m{ 134 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 135 {"id": int64(2), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 136 {"id": int64(3), "key": "pear", "parent_id": int64(1), "sequence": nil, "value": nil}, 137 {"id": int64(4), "key": "key1", "parent_id": int64(1), "sequence": nil, "value": "val1"}, 138 {"id": int64(5), "key": "key2", "parent_id": int64(1), "sequence": nil, "value": "val2"}, 139 }, 140 }, 141 }, 142 { 143 name: "bucket sequence", 144 test: testBucketSequence, 145 expectedDb: m{ 146 "test_kv": []m{ 147 {"id": int64(2), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 148 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": int64(4), "value": nil}, 149 }, 150 }, 151 }, 152 { 153 name: "key clash", 154 test: testKeyClash, 155 expectedDb: m{ 156 "test_kv": []m{ 157 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 158 {"id": int64(2), "key": "key", "parent_id": int64(1), "sequence": nil, "value": "val"}, 159 {"id": int64(3), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": nil}, 160 }, 161 }, 162 }, 163 { 164 name: "bucket create delete", 165 test: testBucketCreateDelete, 166 expectedDb: m{ 167 "test_kv": []m{ 168 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 169 {"id": int64(3), "key": "banana", "parent_id": int64(1), "sequence": nil, "value": "value"}, 170 }, 171 }, 172 }, 173 { 174 name: "tx manual commit", 175 test: testTxManualCommit, 176 expectedDb: m{ 177 "test_kv": []m{ 178 {"id": int64(1), "key": "apple", "parent_id": nil, "sequence": nil, "value": nil}, 179 {"id": int64(2), "key": "testKey", "parent_id": int64(1), "sequence": nil, "value": "testVal"}, 180 }, 181 }, 182 }, 183 { 184 name: "tx rollback", 185 test: testTxRollback, 186 expectedDb: m{ 187 "test_kv": []m(nil), 188 }, 189 }, 190 { 191 name: "top level bucket creation", 192 test: testTopLevelBucketCreation, 193 }, 194 { 195 name: "bucket operation", 196 test: testBucketOperations, 197 }, 198 { 199 name: "sub bucket sequence", 200 test: testSubBucketSequence, 201 }, 202 } 203 204 for _, test := range tests { 205 t.Run(test.name, func(t *testing.T) { 206 f, err := postgres.NewFixture("") 207 require.NoError(t, err) 208 209 test.test(t, f.Db) 210 211 if test.expectedDb != nil { 212 dump, err := f.Dump() 213 require.NoError(t, err) 214 require.Equal(t, test.expectedDb, dump) 215 } 216 }) 217 } 218 }