code.vegaprotocol.io/vega@v0.79.0/blockexplorer/store/migrator_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package store_test 17 18 import ( 19 "context" 20 "sort" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/blockexplorer/entities" 25 "code.vegaprotocol.io/vega/blockexplorer/store" 26 "code.vegaprotocol.io/vega/libs/config" 27 pb "code.vegaprotocol.io/vega/protos/blockexplorer/api/v1" 28 29 tmTypes "github.com/cometbft/cometbft/abci/types" 30 "github.com/georgysavva/scany/pgxscan" 31 "github.com/jackc/pgx/v4/pgxpool" 32 "github.com/stretchr/testify/assert" 33 "github.com/stretchr/testify/require" 34 ) 35 36 func TestMigratorMigrate(t *testing.T) { 37 // first we need to populate the database with some test data 38 ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 39 t.Cleanup(func() { 40 cleanupTransactionsTest(ctx, t) 41 cancel() 42 }) 43 44 want := populateMigrationData(t, ctx) 45 46 pgConfig, err := config.PostgresConnection{ 47 Host: "", 48 Port: 5432, 49 Username: "vega", 50 Password: "vega", 51 Database: "vega", 52 SocketDir: postgresRuntimePath, 53 }.ToPgxPoolConfig() 54 require.NoError(t, err) 55 56 pool, err := pgxpool.ConnectConfig(ctx, pgConfig) 57 require.NoError(t, err) 58 59 // Confirm that there's no data in the tx_results table first 60 query := `SELECT rowid, block_height, index, created_at, tx_hash, tx_result, submitter, cmd_type 61 FROM tx_results ORDER BY block_height desc, index desc` 62 var rows []entities.TxResultRow 63 require.NoError(t, pgxscan.Select(ctx, pool, &rows, query)) 64 65 assert.Len(t, rows, 0) 66 cfg := store.NewDefaultConfig() 67 cfg.MigratePauseInterval = time.Millisecond * 10 68 69 migrator := store.NewMigrator(pool, cfg) 70 71 err = migrator.Migrate(ctx) 72 73 require.NoError(t, err) 74 75 // now get the data from the new tx_results table and make sure that we have everything we expect 76 require.NoError(t, pgxscan.Select(ctx, pool, &rows, query)) 77 78 sort.Slice(want, func(i, j int) bool { 79 return want[i].Block > want[j].Block || 80 (want[i].Block == want[j].Block && want[i].Index > want[j].Index) 81 }) 82 83 got := make([]*pb.Transaction, 0, len(rows)) 84 85 for _, row := range rows { 86 r, e := row.ToProto() 87 require.NoError(t, e) 88 got = append(got, r) 89 } 90 91 require.Equal(t, want, got) 92 93 // We want to check the old data has been removed 94 sql := `select table_name from information_schema.tables where table_name = 'tx_results_old'` 95 var tableName string 96 require.Errorf(t, pool.QueryRow(context.Background(), sql).Scan(&tableName), "no rows in result set") 97 } 98 99 func populateMigrationData(t *testing.T, ctx context.Context) []*pb.Transaction { 100 t.Helper() 101 102 txr, err := (&tmTypes.TxResult{}).Marshal() 103 require.NoError(t, err) 104 now := time.Now() 105 day := time.Hour * 24 106 txns := []txResult{ 107 { 108 height: 1, 109 index: 1, 110 createdAt: now, 111 txHash: "deadbeef01", 112 txResult: txr, 113 submitter: "TEST", 114 cmdType: "TEST", 115 }, 116 { 117 height: 2, 118 index: 1, 119 createdAt: now.Add(day), 120 txHash: "deadbeef02", 121 txResult: txr, 122 submitter: "TEST", 123 cmdType: "TEST", 124 }, 125 { 126 height: 3, 127 index: 1, 128 createdAt: now.Add(day * 2), 129 txHash: "deadbeef03", 130 txResult: txr, 131 submitter: "TEST", 132 cmdType: "TEST", 133 }, 134 { 135 height: 4, 136 index: 1, 137 createdAt: now.Add(day * 3), 138 txHash: "deadbeef04", 139 txResult: txr, 140 submitter: "TEST", 141 cmdType: "TEST", 142 }, 143 { 144 height: 5, 145 index: 1, 146 createdAt: now.Add(day * 4), 147 txHash: "deadbeef05", 148 txResult: txr, 149 submitter: "TEST", 150 cmdType: "TEST", 151 }, 152 { 153 height: 6, 154 index: 1, 155 createdAt: now.Add(day * 5), 156 txHash: "deadbeef06", 157 txResult: txr, 158 submitter: "TEST", 159 cmdType: "TEST", 160 }, 161 { 162 height: 7, 163 index: 1, 164 createdAt: now.Add(day * 6), 165 txHash: "deadbeef07", 166 txResult: txr, 167 submitter: "TEST", 168 cmdType: "TEST", 169 }, 170 { 171 height: 8, 172 index: 1, 173 createdAt: now.Add(day * 7), 174 txHash: "deadbeef08", 175 txResult: txr, 176 submitter: "TEST", 177 cmdType: "TEST", 178 }, 179 { 180 height: 9, 181 index: 1, 182 createdAt: now.Add(day * 8), 183 txHash: "deadbeef09", 184 txResult: txr, 185 submitter: "TEST", 186 cmdType: "TEST", 187 }, 188 { 189 height: 10, 190 index: 1, 191 createdAt: now.Add(day * 9), 192 txHash: "deadbeef10", 193 txResult: txr, 194 submitter: "TEST", 195 cmdType: "TEST", 196 }, 197 } 198 199 want := addTestTxResults(ctx, t, "tx_results_old", txns...) 200 201 return want 202 }