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  }