synapsecns/sanguine

View on GitHub
ethergo/listener/suite_test.go

Summary

Maintainability
A
35 mins
Test Coverage
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
}