cosmos-sdk/store/streaming/streaming_test.go
Aaron Craelius 5c90246b3f
feat(log): remove core dependency and update core interface to be dependency free (#21045)
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
Co-authored-by: Julien Robert <julien@rbrt.fr>
2024-07-26 11:00:27 +00:00

179 lines
4.7 KiB
Go

package streaming
import (
"context"
"fmt"
"os"
"runtime"
"testing"
"time"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
)
type PluginTestSuite struct {
suite.Suite
loggerCtx MockContext
workDir string
finalizeBlockReq abci.FinalizeBlockRequest
finalizeBlockRes abci.FinalizeBlockResponse
commitRes abci.CommitResponse
changeSet []*storetypes.StoreKVPair
}
func (s *PluginTestSuite) SetupTest() {
if runtime.GOOS != "linux" {
s.T().Skip("only run on linux")
}
path, err := os.Getwd()
if err != nil {
s.T().Fail()
}
s.workDir = path
pluginVersion := "abci"
// to write data to files, replace stdout/stdout => file/file
pluginPath := fmt.Sprintf("%s/abci/examples/stdout/stdout", s.workDir)
if err := os.Setenv(GetPluginEnvKey(pluginVersion), pluginPath); err != nil {
s.T().Fail()
}
raw, err := NewStreamingPlugin(pluginVersion, "trace")
require.NoError(s.T(), err, "load", "streaming", "unexpected error")
abciListener, ok := raw.(storetypes.ABCIListener)
require.True(s.T(), ok, "should pass type check")
header := cmtproto.Header{Height: 1, Time: time.Now()}
logger := log.NewNopLogger()
streamingService := storetypes.StreamingManager{
ABCIListeners: []storetypes.ABCIListener{abciListener},
StopNodeOnErr: true,
}
s.loggerCtx = NewMockContext(header, logger, streamingService)
// test abci message types
s.finalizeBlockReq = abci.FinalizeBlockRequest{
Height: s.loggerCtx.BlockHeight(),
Txs: [][]byte{{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}},
Misbehavior: []abci.Misbehavior{},
Hash: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DecidedLastCommit: abci.CommitInfo{},
}
s.finalizeBlockRes = abci.FinalizeBlockResponse{
Events: []abci.Event{},
ConsensusParamUpdates: &cmtproto.ConsensusParams{},
ValidatorUpdates: []abci.ValidatorUpdate{},
TxResults: []*abci.ExecTxResult{{
Events: []abci.Event{},
Code: 1,
Codespace: "mockCodeSpace",
Data: []byte{5, 6, 7, 8},
GasUsed: 2,
GasWanted: 3,
Info: "mockInfo",
Log: "mockLog",
}},
}
s.commitRes = abci.CommitResponse{}
// test store kv pair types
for range [2000]int{} {
s.changeSet = append(s.changeSet, &storetypes.StoreKVPair{
StoreKey: "mockStore",
Delete: false,
Key: []byte{1, 2, 3},
Value: []byte{3, 2, 1},
})
}
}
func TestPluginTestSuite(t *testing.T) {
suite.Run(t, new(PluginTestSuite))
}
func (s *PluginTestSuite) TestABCIGRPCPlugin() {
s.T().Run("Should successfully load streaming", func(t *testing.T) {
abciListeners := s.loggerCtx.StreamingManager().ABCIListeners
for _, abciListener := range abciListeners {
for i := range [50]int{} {
err := abciListener.ListenFinalizeBlock(s.loggerCtx, s.finalizeBlockReq, s.finalizeBlockRes)
assert.NoError(t, err, "ListenEndBlock")
err = abciListener.ListenCommit(s.loggerCtx, s.commitRes, s.changeSet)
assert.NoError(t, err, "ListenCommit")
s.updateHeight(int64(i + 1))
}
}
})
}
func (s *PluginTestSuite) updateHeight(n int64) {
header := s.loggerCtx.BlockHeader()
header.Height = n
s.loggerCtx = NewMockContext(header, s.loggerCtx.Logger(), s.loggerCtx.StreamingManager())
}
var (
_ context.Context = MockContext{}
_ storetypes.Context = MockContext{}
)
type MockContext struct {
baseCtx context.Context
header cmtproto.Header
logger log.Logger
streamingManager storetypes.StreamingManager
}
func (m MockContext) BlockHeight() int64 { return m.header.Height }
func (m MockContext) Logger() log.Logger { return m.logger }
func (m MockContext) StreamingManager() storetypes.StreamingManager { return m.streamingManager }
func (m MockContext) BlockHeader() cmtproto.Header {
msg := proto.Clone(&m.header).(*cmtproto.Header)
return *msg
}
func NewMockContext(header cmtproto.Header, logger log.Logger, sm storetypes.StreamingManager) MockContext {
header.Time = header.Time.UTC()
return MockContext{
baseCtx: context.Background(),
header: header,
logger: logger,
streamingManager: sm,
}
}
func (m MockContext) Deadline() (deadline time.Time, ok bool) {
return m.baseCtx.Deadline()
}
func (m MockContext) Done() <-chan struct{} {
return m.baseCtx.Done()
}
func (m MockContext) Err() error {
return m.baseCtx.Err()
}
func (m MockContext) Value(key any) any {
return m.baseCtx.Value(key)
}