Consolidate test doubles

- Migrate various mocks of core namespaces to shared version in `fakes` pkg
- Err on the side of making test doubles less sophisticated
- Don't pull over mocks of namespaces that are only used in example code
This commit is contained in:
Rob Mulholand
2018-11-03 13:49:23 -05:00
committed by Ian Norden
parent 5fe6394406
commit ba071ef13f
46 changed files with 640 additions and 893 deletions
+50 -35
View File
@@ -7,14 +7,16 @@ import (
)
type MockBlockRepository struct {
createOrUpdateBlockCallCount int
createOrUpdateBlockCalled bool
createOrUpdateBlockPassedBlock core.Block
createOrUpdateBlockReturnInt int64
createOrUpdateBlockPassedBlockNumbers []int64
createOrUpdateBlockReturnErr error
createOrUpdateBlockReturnInt int64
missingBlockNumbersCalled bool
missingBlockNumbersPassedStartingBlockNumber int64
missingBlockNumbersPassedEndingBlockNumber int64
missingBlockNumbersPassedNodeId string
missingBlockNumbersPassedStartingBlockNumber int64
missingBlockNumbersReturnArray []int64
setBlockStatusCalled bool
setBlockStatusPassedChainHead int64
@@ -22,65 +24,78 @@ type MockBlockRepository struct {
func NewMockBlockRepository() *MockBlockRepository {
return &MockBlockRepository{
createOrUpdateBlockCallCount: 0,
createOrUpdateBlockCalled: false,
createOrUpdateBlockPassedBlock: core.Block{},
createOrUpdateBlockReturnInt: 0,
createOrUpdateBlockPassedBlockNumbers: nil,
createOrUpdateBlockReturnErr: nil,
createOrUpdateBlockReturnInt: 0,
missingBlockNumbersCalled: false,
missingBlockNumbersPassedStartingBlockNumber: 0,
missingBlockNumbersPassedEndingBlockNumber: 0,
missingBlockNumbersPassedNodeId: "",
missingBlockNumbersPassedStartingBlockNumber: 0,
missingBlockNumbersReturnArray: nil,
setBlockStatusCalled: false,
setBlockStatusPassedChainHead: 0,
}
}
func (mbr *MockBlockRepository) SetCreateOrUpdateBlockReturnVals(i int64, err error) {
mbr.createOrUpdateBlockReturnInt = i
mbr.createOrUpdateBlockReturnErr = err
func (repository *MockBlockRepository) SetCreateOrUpdateBlockReturnVals(i int64, err error) {
repository.createOrUpdateBlockReturnInt = i
repository.createOrUpdateBlockReturnErr = err
}
func (mbr *MockBlockRepository) SetMissingBlockNumbersReturnArray(returnArray []int64) {
mbr.missingBlockNumbersReturnArray = returnArray
func (repository *MockBlockRepository) SetMissingBlockNumbersReturnArray(returnArray []int64) {
repository.missingBlockNumbersReturnArray = returnArray
}
func (mbr *MockBlockRepository) CreateOrUpdateBlock(block core.Block) (int64, error) {
mbr.createOrUpdateBlockCalled = true
mbr.createOrUpdateBlockPassedBlock = block
return mbr.createOrUpdateBlockReturnInt, mbr.createOrUpdateBlockReturnErr
func (repository *MockBlockRepository) CreateOrUpdateBlock(block core.Block) (int64, error) {
repository.createOrUpdateBlockCallCount++
repository.createOrUpdateBlockCalled = true
repository.createOrUpdateBlockPassedBlock = block
repository.createOrUpdateBlockPassedBlockNumbers = append(repository.createOrUpdateBlockPassedBlockNumbers, block.Number)
return repository.createOrUpdateBlockReturnInt, repository.createOrUpdateBlockReturnErr
}
func (mbr *MockBlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
panic("implement me")
func (repository *MockBlockRepository) GetBlock(blockNumber int64) (core.Block, error) {
return core.Block{Number: blockNumber}, nil
}
func (mbr *MockBlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64, nodeId string) []int64 {
mbr.missingBlockNumbersCalled = true
mbr.missingBlockNumbersPassedStartingBlockNumber = startingBlockNumber
mbr.missingBlockNumbersPassedEndingBlockNumber = endingBlockNumber
mbr.missingBlockNumbersPassedNodeId = nodeId
return mbr.missingBlockNumbersReturnArray
func (repository *MockBlockRepository) MissingBlockNumbers(startingBlockNumber int64, endingBlockNumber int64, nodeId string) []int64 {
repository.missingBlockNumbersCalled = true
repository.missingBlockNumbersPassedStartingBlockNumber = startingBlockNumber
repository.missingBlockNumbersPassedEndingBlockNumber = endingBlockNumber
repository.missingBlockNumbersPassedNodeId = nodeId
return repository.missingBlockNumbersReturnArray
}
func (mbr *MockBlockRepository) SetBlocksStatus(chainHead int64) {
mbr.setBlockStatusCalled = true
mbr.setBlockStatusPassedChainHead = chainHead
func (repository *MockBlockRepository) SetBlocksStatus(chainHead int64) {
repository.setBlockStatusCalled = true
repository.setBlockStatusPassedChainHead = chainHead
}
func (mbr *MockBlockRepository) AssertCreateOrUpdateBlockCalledWith(block core.Block) {
Expect(mbr.createOrUpdateBlockCalled).To(BeTrue())
Expect(mbr.createOrUpdateBlockPassedBlock).To(Equal(block))
func (repository *MockBlockRepository) AssertCreateOrUpdateBlockCallCountEquals(times int) {
Expect(repository.createOrUpdateBlockCallCount).To(Equal(times))
}
func (mbr *MockBlockRepository) AssertMissingBlockNumbersCalledWith(startingBlockNumber int64, endingBlockNumber int64, nodeId string) {
Expect(mbr.missingBlockNumbersCalled).To(BeTrue())
Expect(mbr.missingBlockNumbersPassedStartingBlockNumber).To(Equal(startingBlockNumber))
Expect(mbr.missingBlockNumbersPassedEndingBlockNumber).To(Equal(endingBlockNumber))
Expect(mbr.missingBlockNumbersPassedNodeId).To(Equal(nodeId))
func (repository *MockBlockRepository) AssertCreateOrUpdateBlocksCallCountAndBlockNumbersEquals(times int, blockNumbers []int64) {
Expect(repository.createOrUpdateBlockCallCount).To(Equal(times))
Expect(repository.createOrUpdateBlockPassedBlockNumbers).To(Equal(blockNumbers))
}
func (mbr *MockBlockRepository) AssertSetBlockStatusCalledWith(chainHead int64) {
Expect(mbr.setBlockStatusCalled).To(BeTrue())
Expect(mbr.setBlockStatusPassedChainHead).To(Equal(chainHead))
func (repository *MockBlockRepository) AssertCreateOrUpdateBlockCalledWith(block core.Block) {
Expect(repository.createOrUpdateBlockCalled).To(BeTrue())
Expect(repository.createOrUpdateBlockPassedBlock).To(Equal(block))
}
func (repository *MockBlockRepository) AssertMissingBlockNumbersCalledWith(startingBlockNumber int64, endingBlockNumber int64, nodeId string) {
Expect(repository.missingBlockNumbersCalled).To(BeTrue())
Expect(repository.missingBlockNumbersPassedStartingBlockNumber).To(Equal(startingBlockNumber))
Expect(repository.missingBlockNumbersPassedEndingBlockNumber).To(Equal(endingBlockNumber))
Expect(repository.missingBlockNumbersPassedNodeId).To(Equal(nodeId))
}
func (repository *MockBlockRepository) AssertSetBlockStatusCalledWith(chainHead int64) {
Expect(repository.setBlockStatusCalled).To(BeTrue())
Expect(repository.setBlockStatusPassedChainHead).To(Equal(chainHead))
}
+49 -63
View File
@@ -3,95 +3,81 @@ package fakes
import (
"math/big"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/core"
)
type MockBlockChain struct {
ContractReturnValue []byte
WasToldToStop bool
blocks map[int64]core.Block
blocksChannel chan core.Block
contractAttributes map[string]map[string]string
err error
headers map[int64]core.Header
logs map[string][]core.Log
node core.Node
fetchContractDataErr error
fetchContractDataPassedAbi string
fetchContractDataPassedAddress string
fetchContractDataPassedMethod string
fetchContractDataPassedMethodArg interface{}
fetchContractDataPassedResult interface{}
fetchContractDataPassedBlockNumber int64
getBlockByNumberErr error
lastBlock *big.Int
node core.Node
}
func NewMockBlockChain() *MockBlockChain {
return &MockBlockChain{
node: core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "Geth"},
}
}
func (blockChain *MockBlockChain) SetFetchContractDataErr(err error) {
blockChain.fetchContractDataErr = err
}
func (blockChain *MockBlockChain) SetLastBlock(blockNumber *big.Int) {
blockChain.lastBlock = blockNumber
}
func (blockChain *MockBlockChain) SetGetBlockByNumberErr(err error) {
blockChain.getBlockByNumberErr = err
}
func (blockChain *MockBlockChain) GetHeaderByNumber(blockNumber int64) (core.Header, error) {
return blockChain.headers[blockNumber], nil
return core.Header{BlockNumber: blockNumber}, nil
}
func (blockChain *MockBlockChain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
panic("implement me")
blockChain.fetchContractDataPassedAbi = abiJSON
blockChain.fetchContractDataPassedAddress = address
blockChain.fetchContractDataPassedMethod = method
blockChain.fetchContractDataPassedMethodArg = methodArg
blockChain.fetchContractDataPassedResult = result
blockChain.fetchContractDataPassedBlockNumber = blockNumber
return blockChain.fetchContractDataErr
}
func (blockChain *MockBlockChain) CallContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
return blockChain.ContractReturnValue, nil
return []byte{}, nil
}
func (blockChain *MockBlockChain) LastBlock() *big.Int {
var max int64
for blockNumber := range blockChain.blocks {
if blockNumber > max {
max = blockNumber
}
}
return big.NewInt(max)
return blockChain.lastBlock
}
func (blockChain *MockBlockChain) GetLogs(contract core.Contract, startingBlock *big.Int, endingBlock *big.Int) ([]core.Log, error) {
return blockChain.logs[contract.Hash], nil
return []core.Log{}, nil
}
func (blockChain *MockBlockChain) Node() core.Node {
return blockChain.node
}
func NewMockBlockChain(err error) *MockBlockChain {
return &MockBlockChain{
blocks: make(map[int64]core.Block),
logs: make(map[string][]core.Log),
contractAttributes: make(map[string]map[string]string),
node: core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "Geth"},
err: err,
}
}
func NewMockBlockChainWithBlocks(blocks []core.Block) *MockBlockChain {
blockNumberToBlocks := make(map[int64]core.Block)
for _, block := range blocks {
blockNumberToBlocks[block.Number] = block
}
return &MockBlockChain{
blocks: blockNumberToBlocks,
}
}
func NewMockBlockChainWithHeaders(headers []core.Header) *MockBlockChain {
// need to create blocks and headers so that LastBlock() will work in the mock
// no reason to implement LastBlock() separately for headers since it checks
// the last header in the Node's DB already
memoryBlocks := make(map[int64]core.Block)
memoryHeaders := make(map[int64]core.Header)
for _, header := range headers {
memoryBlocks[header.BlockNumber] = core.Block{Number: header.BlockNumber}
memoryHeaders[header.BlockNumber] = header
}
return &MockBlockChain{
blocks: memoryBlocks,
headers: memoryHeaders,
}
}
func (blockChain *MockBlockChain) GetBlockByNumber(blockNumber int64) (core.Block, error) {
if blockChain.err != nil {
return core.Block{}, blockChain.err
}
return blockChain.blocks[blockNumber], nil
return core.Block{Number: blockNumber}, blockChain.getBlockByNumberErr
}
func (blockChain *MockBlockChain) AddBlock(block core.Block) {
blockChain.blocks[block.Number] = block
blockChain.blocksChannel <- block
// TODO: handle methodArg being nil (can't match nil to nil in Gomega)
func (blockChain *MockBlockChain) AssertFetchContractDataCalledWith(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) {
Expect(blockChain.fetchContractDataPassedAbi).To(Equal(abiJSON))
Expect(blockChain.fetchContractDataPassedAddress).To(Equal(address))
Expect(blockChain.fetchContractDataPassedMethod).To(Equal(method))
Expect(blockChain.fetchContractDataPassedResult).To(Equal(result))
Expect(blockChain.fetchContractDataPassedBlockNumber).To(Equal(blockNumber))
}
@@ -5,11 +5,12 @@ import (
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/gomega"
)
type MockClient struct {
type MockEthClient struct {
callContractErr error
callContractPassedContext context.Context
callContractPassedMsg ethereum.CallMsg
@@ -27,10 +28,14 @@ type MockClient struct {
filterLogsPassedContext context.Context
filterLogsPassedQuery ethereum.FilterQuery
filterLogsReturnLogs []types.Log
transactionReceipts map[string]*types.Receipt
err error
transactionSenderErr error
transactionReceiptErr error
}
func NewMockClient() *MockClient {
return &MockClient{
func NewMockEthClient() *MockEthClient {
return &MockEthClient{
callContractErr: nil,
callContractPassedContext: nil,
callContractPassedMsg: ethereum.CallMsg{},
@@ -48,83 +53,110 @@ func NewMockClient() *MockClient {
filterLogsPassedContext: nil,
filterLogsPassedQuery: ethereum.FilterQuery{},
filterLogsReturnLogs: nil,
transactionReceipts: make(map[string]*types.Receipt),
err: nil,
}
}
func (client *MockClient) SetCallContractErr(err error) {
func (client *MockEthClient) SetCallContractErr(err error) {
client.callContractErr = err
}
func (client *MockClient) SetCallContractReturnBytes(returnBytes []byte) {
func (client *MockEthClient) SetCallContractReturnBytes(returnBytes []byte) {
client.callContractReturnBytes = returnBytes
}
func (client *MockClient) SetBlockByNumberErr(err error) {
func (client *MockEthClient) SetBlockByNumberErr(err error) {
client.blockByNumberErr = err
}
func (client *MockClient) SetBlockByNumberReturnBlock(block *types.Block) {
func (client *MockEthClient) SetBlockByNumberReturnBlock(block *types.Block) {
client.blockByNumberReturnBlock = block
}
func (client *MockClient) SetHeaderByNumberErr(err error) {
func (client *MockEthClient) SetHeaderByNumberErr(err error) {
client.headerByNumberErr = err
}
func (client *MockClient) SetHeaderByNumberReturnHeader(header *types.Header) {
func (client *MockEthClient) SetHeaderByNumberReturnHeader(header *types.Header) {
client.headerByNumberReturnHeader = header
}
func (client *MockClient) SetFilterLogsErr(err error) {
func (client *MockEthClient) SetFilterLogsErr(err error) {
client.filterLogsErr = err
}
func (client *MockClient) SetFilterLogsReturnLogs(logs []types.Log) {
func (client *MockEthClient) SetFilterLogsReturnLogs(logs []types.Log) {
client.filterLogsReturnLogs = logs
}
func (client *MockClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
func (client *MockEthClient) SetTransactionReceiptErr(err error) {
client.transactionReceiptErr = err
}
func (client *MockEthClient) SetTransactionReceipts(receipts []*types.Receipt) {
for _, receipt := range receipts {
client.transactionReceipts[receipt.TxHash.Hex()] = receipt
}
}
func (client *MockEthClient) SetTransactionSenderErr(err error) {
client.transactionSenderErr = err
}
func (client *MockEthClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
client.callContractPassedContext = ctx
client.callContractPassedMsg = msg
client.callContractPassedNumber = blockNumber
return client.callContractReturnBytes, client.callContractErr
}
func (client *MockClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
func (client *MockEthClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
client.blockByNumberPassedContext = ctx
client.blockByNumberPassedNumber = number
return client.blockByNumberReturnBlock, client.blockByNumberErr
}
func (client *MockClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
func (client *MockEthClient) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
client.headerByNumberPassedContext = ctx
client.headerByNumberPassedNumber = number
return client.headerByNumberReturnHeader, client.headerByNumberErr
}
func (client *MockClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
func (client *MockEthClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
client.filterLogsPassedContext = ctx
client.filterLogsPassedQuery = q
return client.filterLogsReturnLogs, client.filterLogsErr
}
func (client *MockClient) AssertCallContractCalledWith(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) {
func (client *MockEthClient) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
return common.HexToAddress("0x123"), client.transactionSenderErr
}
func (client *MockEthClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
if gasUsed, ok := client.transactionReceipts[txHash.Hex()]; ok {
return gasUsed, client.transactionReceiptErr
}
return &types.Receipt{GasUsed: uint64(0)}, client.transactionReceiptErr
}
func (client *MockEthClient) AssertCallContractCalledWith(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) {
Expect(client.callContractPassedContext).To(Equal(ctx))
Expect(client.callContractPassedMsg).To(Equal(msg))
Expect(client.callContractPassedNumber).To(Equal(blockNumber))
}
func (client *MockClient) AssertBlockByNumberCalledWith(ctx context.Context, number *big.Int) {
func (client *MockEthClient) AssertBlockByNumberCalledWith(ctx context.Context, number *big.Int) {
Expect(client.blockByNumberPassedContext).To(Equal(ctx))
Expect(client.blockByNumberPassedNumber).To(Equal(number))
}
func (client *MockClient) AssertHeaderByNumberCalledWith(ctx context.Context, number *big.Int) {
func (client *MockEthClient) AssertHeaderByNumberCalledWith(ctx context.Context, number *big.Int) {
Expect(client.headerByNumberPassedContext).To(Equal(ctx))
Expect(client.headerByNumberPassedNumber).To(Equal(number))
}
func (client *MockClient) AssertFilterLogsCalledWith(ctx context.Context, q ethereum.FilterQuery) {
func (client *MockEthClient) AssertFilterLogsCalledWith(ctx context.Context, q ethereum.FilterQuery) {
Expect(client.filterLogsPassedContext).To(Equal(ctx))
Expect(client.filterLogsPassedQuery).To(Equal(q))
}
+40
View File
@@ -0,0 +1,40 @@
package fakes
import (
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/core"
)
type MockHeaderRepository struct {
createOrUpdateBlockNumbersCallCount int
createOrUpdateBlockNumbersPassedBlockNumbers []int64
missingBlockNumbers []int64
}
func NewMockHeaderRepository() *MockHeaderRepository {
return &MockHeaderRepository{}
}
func (repository *MockHeaderRepository) SetMissingBlockNumbers(blockNumbers []int64) {
repository.missingBlockNumbers = blockNumbers
}
func (repository *MockHeaderRepository) CreateOrUpdateHeader(header core.Header) (int64, error) {
repository.createOrUpdateBlockNumbersCallCount++
repository.createOrUpdateBlockNumbersPassedBlockNumbers = append(repository.createOrUpdateBlockNumbersPassedBlockNumbers, header.BlockNumber)
return 0, nil
}
func (*MockHeaderRepository) GetHeader(blockNumber int64) (core.Header, error) {
return core.Header{BlockNumber: blockNumber}, nil
}
func (repository *MockHeaderRepository) MissingBlockNumbers(startingBlockNumber, endingBlockNumber int64, nodeID string) []int64 {
return repository.missingBlockNumbers
}
func (repository *MockHeaderRepository) AssertCreateOrUpdateHeaderCallCountAndPassedBlockNumbers(times int, blockNumbers []int64) {
Expect(repository.createOrUpdateBlockNumbersCallCount).To(Equal(times))
Expect(repository.createOrUpdateBlockNumbersPassedBlockNumbers).To(Equal(blockNumbers))
}
+73
View File
@@ -0,0 +1,73 @@
package fakes
import (
"context"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/p2p"
"github.com/vulcanize/vulcanizedb/pkg/core"
)
type MockRpcClient struct {
ipcPath string
nodeType core.NodeType
}
func NewMockRpcClient() *MockRpcClient {
return &MockRpcClient{}
}
func (client *MockRpcClient) SetNodeType(nodeType core.NodeType) {
client.nodeType = nodeType
}
func (client *MockRpcClient) SetIpcPath(ipcPath string) {
client.ipcPath = ipcPath
}
func (*MockRpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
switch method {
case "admin_nodeInfo":
if p, ok := result.(*p2p.NodeInfo); ok {
p.ID = "enode://GethNode@172.17.0.1:30303"
p.Name = "Geth/v1.7"
}
case "eth_getBlockByNumber":
if p, ok := result.(*types.Header); ok {
*p = types.Header{}
}
case "parity_versionInfo":
if p, ok := result.(*core.ParityNodeInfo); ok {
*p = core.ParityNodeInfo{
Track: "",
ParityVersion: core.ParityVersion{
Major: 1,
Minor: 2,
Patch: 3,
},
Hash: "",
}
}
case "parity_enode":
if p, ok := result.(*string); ok {
*p = "enode://ParityNode@172.17.0.1:30303"
}
case "net_version":
if p, ok := result.(*string); ok {
*p = "1234"
}
}
return nil
}
func (client *MockRpcClient) IpcPath() string {
return client.ipcPath
}
func (client *MockRpcClient) SupportedModules() (map[string]string, error) {
result := make(map[string]string)
if client.nodeType == core.GETH {
result["admin"] = "ok"
}
return result, nil
}