ethergo/listener/suite_test.go
package listener_test
import (
"context"
"fmt"
"math/big"
"os"
"testing"
"time"
"github.com/brianvoe/gofakeit/v6"
"github.com/ipfs/go-log"
common_base "github.com/synapsecns/sanguine/core/dbcommon"
"github.com/synapsecns/sanguine/ethergo/examples/contracttests"
"github.com/synapsecns/sanguine/ethergo/examples/contracttests/counter"
"github.com/synapsecns/sanguine/ethergo/listener"
db2 "github.com/synapsecns/sanguine/ethergo/listener/db"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"github.com/Flaque/filet"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/suite"
"github.com/synapsecns/sanguine/core/metrics"
"github.com/synapsecns/sanguine/core/testsuite"
"github.com/synapsecns/sanguine/ethergo/backends"
"github.com/synapsecns/sanguine/ethergo/backends/geth"
"gorm.io/driver/sqlite"
)
const chainID = 10
type ListenerTestSuite struct {
*testsuite.TestSuite
manager *contracttests.DeployManager
backend backends.SimulatedTestBackend
store db2.ChainListenerDB
metrics metrics.Handler
counter *counter.CounterRef
}
func NewListenerSuite(tb testing.TB) *ListenerTestSuite {
tb.Helper()
return &ListenerTestSuite{
TestSuite: testsuite.NewTestSuite(tb),
}
}
func TestListenerSuite(t *testing.T) {
suite.Run(t, NewListenerSuite(t))
}
func (l *ListenerTestSuite) SetupTest() {
l.TestSuite.SetupTest()
l.manager = contracttests.NewDeployManager(l.T())
l.backend = geth.NewEmbeddedBackendForChainID(l.GetTestContext(), l.T(), big.NewInt(chainID))
var err error
l.metrics = metrics.NewNullHandler()
l.store, err = NewSqliteStore(l.GetTestContext(), filet.TmpDir(l.T(), ""), l.metrics)
l.Require().NoError(err)
_, l.counter = l.manager.GetCounter(l.GetTestContext(), l.backend)
}
func (l *ListenerTestSuite) TestGetMetadataNoStore() {
deployBlock, err := l.counter.DeployBlock(&bind.CallOpts{Context: l.GetTestContext()})
l.NoError(err)
// nothing stored, should use start block
cl := listener.NewTestChainListener(listener.TestChainListenerArgs{
Address: l.counter.Address(),
InitialBlock: deployBlock.Uint64(),
Client: l.backend,
Store: l.store,
Handler: l.metrics,
})
startBlock, myChainID, err := cl.GetMetadata(l.GetTestContext())
l.NoError(err)
l.Equal(myChainID, uint64(chainID))
l.Equal(startBlock, deployBlock.Uint64())
}
func (l *ListenerTestSuite) TestStartBlock() {
cl := listener.NewTestChainListener(listener.TestChainListenerArgs{
Address: l.counter.Address(),
Client: l.backend,
Store: l.store,
Handler: l.metrics,
})
deployBlock, err := l.counter.DeployBlock(&bind.CallOpts{Context: l.GetTestContext()})
l.NoError(err)
expectedLastIndexed := deployBlock.Uint64() + 10
err = l.store.PutLatestBlock(l.GetTestContext(), chainID, expectedLastIndexed)
l.NoError(err)
startBlock, cid, err := cl.GetMetadata(l.GetTestContext())
l.NoError(err)
l.Equal(cid, uint64(chainID))
l.Equal(startBlock, expectedLastIndexed)
}
func (l *ListenerTestSuite) TestListen() {
}
// NewSqliteStore creates a new sqlite data store.
func NewSqliteStore(parentCtx context.Context, dbPath string, handler metrics.Handler) (_ *db2.Store, err error) {
logger := log.Logger("sqlite-store")
logger.Debugf("creating sqlite store at %s", dbPath)
ctx, span := handler.Tracer().Start(parentCtx, "start-sqlite")
defer func() {
metrics.EndSpanWithErr(span, err)
}()
// create the directory to the store if it doesn't exist
err = os.MkdirAll(dbPath, os.ModePerm)
if err != nil {
return nil, fmt.Errorf("could not create sqlite store")
}
logger.Warnf("submitter database is at %s/synapse.db", dbPath)
namingStrategy := schema.NamingStrategy{
TablePrefix: fmt.Sprintf("test%d_%d_", gofakeit.Int64(), time.Now().Unix()),
}
gdb, err := gorm.Open(sqlite.Open(fmt.Sprintf("%s/%s", dbPath, "synapse.db")), &gorm.Config{
DisableForeignKeyConstraintWhenMigrating: true,
Logger: common_base.GetGormLogger(logger),
FullSaveAssociations: true,
SkipDefaultTransaction: true,
NamingStrategy: namingStrategy,
})
if err != nil {
return nil, fmt.Errorf("could not connect to db %s: %w", dbPath, err)
}
err = gdb.AutoMigrate(&db2.LastIndexed{})
if err != nil {
return nil, fmt.Errorf("could not migrate models: %w", err)
}
handler.AddGormCallbacks(gdb)
err = gdb.WithContext(ctx).AutoMigrate(db2.GetAllModels()...)
if err != nil {
return nil, fmt.Errorf("could not migrate models: %w", err)
}
return db2.NewChainListenerStore(gdb, handler), nil
}