cosmos-sdk/indexer/postgres/tests/postgres_test.go
2024-09-12 12:30:50 +00:00

102 lines
2.7 KiB
Go

package tests
import (
"context"
"os"
"strings"
"testing"
embeddedpostgres "github.com/fergusstrange/embedded-postgres"
"github.com/hashicorp/consul/sdk/freeport"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/stretchr/testify/require"
"cosmossdk.io/indexer/postgres"
"cosmossdk.io/schema/addressutil"
"cosmossdk.io/schema/indexer"
indexertesting "cosmossdk.io/schema/testing"
"cosmossdk.io/schema/testing/appdatasim"
"cosmossdk.io/schema/testing/statesim"
)
func TestPostgresIndexer(t *testing.T) {
t.Run("RetainDeletions", func(t *testing.T) {
testPostgresIndexer(t, true)
})
t.Run("NoRetainDeletions", func(t *testing.T) {
testPostgresIndexer(t, false)
})
}
func testPostgresIndexer(t *testing.T, retainDeletions bool) {
t.Helper()
tempDir, err := os.MkdirTemp("", "postgres-indexer-test")
require.NoError(t, err)
dbPort := freeport.GetOne(t)
pgConfig := embeddedpostgres.DefaultConfig().
Port(uint32(dbPort)).
DataPath(tempDir)
dbUrl := pgConfig.GetConnectionURL()
pg := embeddedpostgres.NewDatabase(pgConfig)
require.NoError(t, pg.Start())
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(func() {
cancel()
require.NoError(t, pg.Stop())
err := os.RemoveAll(tempDir)
require.NoError(t, err)
})
cfg, err := postgresConfigToIndexerConfig(postgres.Config{
DatabaseURL: dbUrl,
DisableRetainDeletions: !retainDeletions,
})
require.NoError(t, err)
debugLog := &strings.Builder{}
pgIndexer, err := postgres.StartIndexer(indexer.InitParams{
Config: cfg,
Context: ctx,
Logger: &prettyLogger{debugLog},
AddressCodec: addressutil.HexAddressCodec{},
})
require.NoError(t, err)
sim, err := appdatasim.NewSimulator(appdatasim.Options{
Listener: pgIndexer.Listener,
AppSchema: indexertesting.ExampleAppSchema,
StateSimOptions: statesim.Options{
CanRetainDeletions: retainDeletions,
},
})
require.NoError(t, err)
blockDataGen := sim.BlockDataGenN(10, 100)
numBlocks := 200
if testing.Short() {
numBlocks = 10
}
for i := 0; i < numBlocks; i++ {
// using Example generates a deterministic data set based
// on a seed so that regression tests can be created OR rapid.Check can
// be used for fully random property-based testing
blockData := blockDataGen.Example(i)
// process the generated block data with the simulator which will also
// send it to the indexer
require.NoError(t, sim.ProcessBlockData(blockData), debugLog.String())
// compare the expected state in the simulator to the actual state in the indexer and expect the diff to be empty
require.Empty(t, appdatasim.DiffAppData(sim, pgIndexer.View), debugLog.String())
// reset the debug log after each successful block so that it doesn't get too long when debugging
debugLog.Reset()
}
}