110 lines
2.9 KiB
Go
110 lines
2.9 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)
|
|
})
|
|
|
|
debugLog := &strings.Builder{}
|
|
|
|
res, err := indexer.StartIndexing(indexer.IndexingOptions{
|
|
Config: indexer.IndexingConfig{
|
|
Target: map[string]indexer.Config{
|
|
"postgres": {
|
|
Type: "postgres",
|
|
Config: postgres.Config{
|
|
DatabaseURL: dbUrl,
|
|
DisableRetainDeletions: !retainDeletions,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Context: ctx,
|
|
Logger: &prettyLogger{debugLog},
|
|
AddressCodec: addressutil.HexAddressCodec{},
|
|
})
|
|
require.NoError(t, err)
|
|
require.NoError(t, err)
|
|
|
|
sim, err := appdatasim.NewSimulator(appdatasim.Options{
|
|
Listener: res.Listener,
|
|
AppSchema: indexertesting.ExampleAppSchema,
|
|
StateSimOptions: statesim.Options{
|
|
CanRetainDeletions: retainDeletions,
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
pgIndexerView := res.IndexerInfos["postgres"].View
|
|
require.NotNil(t, pgIndexerView)
|
|
|
|
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, pgIndexerView), debugLog.String())
|
|
|
|
// reset the debug log after each successful block so that it doesn't get too long when debugging
|
|
debugLog.Reset()
|
|
}
|
|
}
|