Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Testing] Refactor test helpers #797

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions consensus/e2e_tests/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package e2e_tests
import (
"context"
"fmt"
"github.com/pokt-network/pocket/internal/testutil/p2p"
"github.com/pokt-network/pocket/internal/testutil/persistence"
telemetry_testutil "github.com/pokt-network/pocket/internal/testutil/telemetry"
"os"
"reflect"
"sort"
Expand All @@ -13,7 +16,6 @@ import (
"github.com/golang/mock/gomock"
"github.com/pokt-network/pocket/consensus"
typesCons "github.com/pokt-network/pocket/consensus/types"
persistenceMocks "github.com/pokt-network/pocket/persistence/types/mocks"
"github.com/pokt-network/pocket/runtime"
"github.com/pokt-network/pocket/runtime/configs"
"github.com/pokt-network/pocket/runtime/defaults"
Expand Down Expand Up @@ -101,7 +103,7 @@ func CreateTestConsensusPocketNode(
bus modules.Bus,
eventsChannel modules.EventsChannel,
) *shared.Node {
persistenceMock := basePersistenceMock(t, eventsChannel, bus)
persistenceMock := persistence_testutil.PersistenceMockWithBlockStore(t, eventsChannel, bus)
bus.RegisterModule(persistenceMock)

consensusMod, err := consensus.Create(bus)
Expand All @@ -115,9 +117,9 @@ func CreateTestConsensusPocketNode(
runtimeMgr := (bus).GetRuntimeMgr()
// TODO(olshansky): At the moment we are using the same base mocks for all the tests,
// but note that they will need to be customized on a per test basis.
p2pMock := baseP2PMock(t, eventsChannel)
p2pMock := p2p_testutil.BaseP2PMock(t, eventsChannel)
utilityMock := baseUtilityMock(t, eventsChannel, runtimeMgr.GetGenesis(), consensusModule)
telemetryMock := baseTelemetryMock(t, eventsChannel)
telemetryMock := telemetry_testutil.MinimalTelemetryMock(t)
loggerMock := baseLoggerMock(t, eventsChannel)
rpcMock := baseRpcMock(t, eventsChannel)

Expand Down Expand Up @@ -548,21 +550,6 @@ func baseReplicaUtilityUnitOfWorkMock(t *testing.T, genesisState *genesis.Genesi
return utilityReplicaUnitOfWorkMock
}

func baseTelemetryMock(t *testing.T, _ modules.EventsChannel) *mockModules.MockTelemetryModule {
ctrl := gomock.NewController(t)
telemetryMock := mockModules.NewMockTelemetryModule(ctrl)
timeSeriesAgentMock := baseTelemetryTimeSeriesAgentMock(t)
eventMetricsAgentMock := baseTelemetryEventMetricsAgentMock(t)

telemetryMock.EXPECT().Start().Return(nil).AnyTimes()
telemetryMock.EXPECT().SetBus(gomock.Any()).Return().AnyTimes()
telemetryMock.EXPECT().GetTimeSeriesAgent().Return(timeSeriesAgentMock).AnyTimes()
telemetryMock.EXPECT().GetEventMetricsAgent().Return(eventMetricsAgentMock).AnyTimes()
telemetryMock.EXPECT().GetModuleName().Return(modules.TelemetryModuleName).AnyTimes()

return telemetryMock
}

func baseRpcMock(t *testing.T, _ modules.EventsChannel) *mockModules.MockRPCModule {
ctrl := gomock.NewController(t)
rpcMock := mockModules.NewMockRPCModule(ctrl)
Expand Down
96 changes: 96 additions & 0 deletions internal/testutil/bus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package testutil

import (
"github.com/golang/mock/gomock"
"github.com/pokt-network/pocket/p2p/providers/current_height_provider"
"github.com/pokt-network/pocket/p2p/providers/peerstore_provider"
"github.com/pokt-network/pocket/runtime"
"github.com/pokt-network/pocket/shared/messaging"
"github.com/regen-network/gocuke"

"github.com/pokt-network/pocket/shared/modules"
"github.com/pokt-network/pocket/shared/modules/mocks"
)

type BusEventHandler func(*messaging.PocketEnvelope)
type BusEventHandlerFactory func(t gocuke.TestingT, busMock *mock_modules.MockBus) BusEventHandler

// MinimalBusMock returns a bus mock with a module registry and minimal
// expectations registered to maximize re-usability.
func MinimalBusMock(
t gocuke.TestingT,
runtimeMgr modules.RuntimeMgr,
) *mock_modules.MockBus {
t.Helper()

ctrl := gomock.NewController(t)
busMock := mock_modules.NewMockBus(ctrl)
busMock.EXPECT().GetRuntimeMgr().Return(runtimeMgr).AnyTimes()
busMock.EXPECT().RegisterModule(gomock.Any()).DoAndReturn(func(m modules.Module) {
m.SetBus(busMock)
}).AnyTimes()

mockModulesRegistry := mock_modules.NewMockModulesRegistry(ctrl)

// TODO_THIS_COMMIT: refactor - this doesn't belong here
mockModulesRegistry.EXPECT().GetModule(peerstore_provider.ModuleName).Return(nil, runtime.ErrModuleNotRegistered(peerstore_provider.ModuleName)).AnyTimes()
mockModulesRegistry.EXPECT().GetModule(current_height_provider.ModuleName).Return(nil, runtime.ErrModuleNotRegistered(current_height_provider.ModuleName)).AnyTimes()

busMock.EXPECT().GetModulesRegistry().Return(mockModulesRegistry).AnyTimes()
return busMock
}

// BaseBusMock returns a base bus mock which will accept any event,
// passing it to the provided handler function, any number of times.
func BaseBusMock(
t gocuke.TestingT,
runtimeMgr modules.RuntimeMgr,
) *mock_modules.MockBus {
t.Helper()

return WithoutBusEventHandler(t, MinimalBusMock(t, runtimeMgr))
}

// BusMockWithEventHandler returns a base bus mock which will accept any event,
// any number of times, calling the `handler` returned from `handlerFactory`
// with the event as an argument.
func BusMockWithEventHandler(
t gocuke.TestingT,
runtimeMgr modules.RuntimeMgr,
handlerFactory BusEventHandlerFactory,
) *mock_modules.MockBus {
t.Helper()

busMock := MinimalBusMock(t, runtimeMgr)
return WithBusEventHandler(t, busMock, handlerFactory)
}

// WithBusEventHandler adds an expectation to a bus mock such that it will accept
// any event, any number of times, calling the `handler` returned from `handlerFactory`
// with the event as an argument.
func WithBusEventHandler(
t gocuke.TestingT,
busMock *mock_modules.MockBus,
handlerFactory BusEventHandlerFactory,
) *mock_modules.MockBus {
t.Helper()

if handlerFactory != nil {
handler := handlerFactory(t, busMock)
busMock.EXPECT().PublishEventToBus(gomock.Any()).Do(handler).AnyTimes()
}

return busMock
}

// WithoutBusEventHandler adds an expectation to a bus mock such that it will accept
// any event, any number of times.
func WithoutBusEventHandler(
t gocuke.TestingT,
busMock *mock_modules.MockBus,
) *mock_modules.MockBus {
t.Helper()

busMock.EXPECT().PublishEventToBus(gomock.Any()).AnyTimes()
return busMock
}
30 changes: 30 additions & 0 deletions internal/testutil/bus/bus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package bus_testutil

import (
"github.com/regen-network/gocuke"

"github.com/pokt-network/pocket/internal/testutil"
"github.com/pokt-network/pocket/internal/testutil/runtime"
"github.com/pokt-network/pocket/runtime/genesis"
"github.com/pokt-network/pocket/shared/crypto"
"github.com/pokt-network/pocket/shared/modules/mocks"
)

func NewBus(
t gocuke.TestingT,
privKey crypto.PrivateKey,
serviceURL string,
genesisState *genesis.GenesisState,
busEventHandlerFactory testutil.BusEventHandlerFactory,
) *mock_modules.MockBus {
t.Helper()

runtimeMgrMock := runtime_testutil.BaseRuntimeManagerMock(
t, privKey,
serviceURL,
genesisState,
)
busMock := testutil.BusMockWithEventHandler(t, runtimeMgrMock, busEventHandlerFactory)
busMock.EXPECT().GetRuntimeMgr().Return(runtimeMgrMock).AnyTimes()
return busMock
}
30 changes: 30 additions & 0 deletions internal/testutil/composition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package testutil

// PipeTwoToOne threads two values of any type (T and U) through a pipeline of
// functions and returns the result of any type (U). Each function in the pipeline
// takes two arguments of type T and U, and returns a value of type U.
//
// Applies each function in the pipeline to the current value of U and the
// constant value of T, effectively "threading" the initial U value through the
// pipeline of functions.
//
// Does *not* mutate the original U value. Instead, it operates on a reference
// to U, ensuring that value types (non-pointer types) are not mutated.
//
// Returns the final value of U after it has been threaded through all the functions in the pipeline.
//
// Usage:
//
// result := PipeTwo(initialT, initialU, func1, func2, func3)
//
// In this example, initialT and initialU are the initial values of T and U, and func1, func2, and func3
// are functions that take two arguments of type T and U and return a value of type U.
func PipeTwoToOne[T, U any](t T, u U, pipeline ...func(T, U) U) U {
// NB: don't mutate potential value type `u` (i.e. non-pointer)
uRef := u
for _, fn := range pipeline {
uRef = fn(t, uRef)
}

return u
}
24 changes: 24 additions & 0 deletions internal/testutil/consensus/mocks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package consensus_testutil

import (
"github.com/golang/mock/gomock"
"github.com/regen-network/gocuke"

"github.com/pokt-network/pocket/shared/modules"
"github.com/pokt-network/pocket/shared/modules/mocks"
)

// Consensus mock - only needed for validatorMap access
func BaseConsensusMock(t gocuke.TestingT, busMock *mock_modules.MockBus) *mock_modules.MockConsensusModule {
ctrl := gomock.NewController(t)
consensusMock := mock_modules.NewMockConsensusModule(ctrl)
consensusMock.EXPECT().CurrentHeight().Return(uint64(1)).AnyTimes()

consensusMock.EXPECT().GetBus().Return(busMock).AnyTimes()
consensusMock.EXPECT().SetBus(busMock).AnyTimes()
consensusMock.EXPECT().GetModuleName().Return(modules.ConsensusModuleName).AnyTimes()
busMock.EXPECT().GetConsensusModule().Return(consensusMock).AnyTimes()
//busMock.RegisterModule(consensusMock)

return consensusMock
}
Loading