- package mock_test
-
- import (
- "context"
- "errors"
- "fmt"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- "github.com/tendermint/tendermint/abci/example/kvstore"
- abci "github.com/tendermint/tendermint/abci/types"
- "github.com/tendermint/tendermint/libs/bytes"
- "github.com/tendermint/tendermint/rpc/client"
- "github.com/tendermint/tendermint/rpc/client/mock"
- "github.com/tendermint/tendermint/rpc/coretypes"
- "github.com/tendermint/tendermint/types"
- )
-
- func TestABCIMock(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- key, value := []byte("foo"), []byte("bar")
- height := int64(10)
- goodTx := types.Tx{0x01, 0xff}
- badTx := types.Tx{0x12, 0x21}
-
- m := mock.ABCIMock{
- Info: mock.Call{Error: errors.New("foobar")},
- Query: mock.Call{Response: abci.ResponseQuery{
- Key: key,
- Value: value,
- Height: height,
- }},
- // Broadcast commit depends on call
- BroadcastCommit: mock.Call{
- Args: goodTx,
- Response: &coretypes.ResultBroadcastTxCommit{
- CheckTx: abci.ResponseCheckTx{Data: bytes.HexBytes("stand")},
- TxResult: abci.ExecTxResult{Data: bytes.HexBytes("deliver")},
- },
- Error: errors.New("bad tx"),
- },
- Broadcast: mock.Call{Error: errors.New("must commit")},
- }
-
- // now, let's try to make some calls
- _, err := m.ABCIInfo(ctx)
- require.Error(t, err)
- assert.Equal(t, "foobar", err.Error())
-
- // query always returns the response
- _query, err := m.ABCIQueryWithOptions(ctx, "/", nil, client.ABCIQueryOptions{Prove: false})
- query := _query.Response
- require.NoError(t, err)
- require.NotNil(t, query)
- assert.EqualValues(t, key, query.Key)
- assert.EqualValues(t, value, query.Value)
- assert.Equal(t, height, query.Height)
-
- // non-commit calls always return errors
- _, err = m.BroadcastTxSync(ctx, goodTx)
- require.Error(t, err)
- assert.Equal(t, "must commit", err.Error())
- _, err = m.BroadcastTxAsync(ctx, goodTx)
- require.Error(t, err)
- assert.Equal(t, "must commit", err.Error())
-
- // commit depends on the input
- _, err = m.BroadcastTxCommit(ctx, badTx)
- require.Error(t, err)
- assert.Equal(t, "bad tx", err.Error())
- bres, err := m.BroadcastTxCommit(ctx, goodTx)
- require.NoError(t, err, "%+v", err)
- assert.EqualValues(t, 0, bres.CheckTx.Code)
- assert.EqualValues(t, "stand", bres.CheckTx.Data)
- assert.EqualValues(t, "deliver", bres.TxResult.Data)
- }
-
- func TestABCIRecorder(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- // This mock returns errors on everything but Query
- m := mock.ABCIMock{
- Info: mock.Call{Response: abci.ResponseInfo{
- Data: "data",
- Version: "v0.9.9",
- }},
- Query: mock.Call{Error: errors.New("query")},
- Broadcast: mock.Call{Error: errors.New("broadcast")},
- BroadcastCommit: mock.Call{Error: errors.New("broadcast_commit")},
- }
- r := mock.NewABCIRecorder(m)
-
- require.Equal(t, 0, len(r.Calls))
-
- _, err := r.ABCIInfo(ctx)
- assert.NoError(t, err, "expected no err on info")
-
- _, err = r.ABCIQueryWithOptions(
- ctx,
- "path",
- bytes.HexBytes("data"),
- client.ABCIQueryOptions{Prove: false},
- )
- assert.Error(t, err, "expected error on query")
- require.Equal(t, 2, len(r.Calls))
-
- info := r.Calls[0]
- assert.Equal(t, "abci_info", info.Name)
- assert.Nil(t, info.Error)
- assert.Nil(t, info.Args)
- require.NotNil(t, info.Response)
- ir, ok := info.Response.(*coretypes.ResultABCIInfo)
- require.True(t, ok)
- assert.Equal(t, "data", ir.Response.Data)
- assert.Equal(t, "v0.9.9", ir.Response.Version)
-
- query := r.Calls[1]
- assert.Equal(t, "abci_query", query.Name)
- assert.Nil(t, query.Response)
- require.NotNil(t, query.Error)
- assert.Equal(t, "query", query.Error.Error())
- require.NotNil(t, query.Args)
- qa, ok := query.Args.(mock.QueryArgs)
- require.True(t, ok)
- assert.Equal(t, "path", qa.Path)
- assert.EqualValues(t, "data", qa.Data)
- assert.False(t, qa.Prove)
-
- // now add some broadcasts (should all err)
- txs := []types.Tx{{1}, {2}, {3}}
- _, err = r.BroadcastTxCommit(ctx, txs[0])
- assert.Error(t, err, "expected err on broadcast")
- _, err = r.BroadcastTxSync(ctx, txs[1])
- assert.Error(t, err, "expected err on broadcast")
- _, err = r.BroadcastTxAsync(ctx, txs[2])
- assert.Error(t, err, "expected err on broadcast")
-
- require.Equal(t, 5, len(r.Calls))
-
- bc := r.Calls[2]
- assert.Equal(t, "broadcast_tx_commit", bc.Name)
- assert.Nil(t, bc.Response)
- require.NotNil(t, bc.Error)
- assert.EqualValues(t, bc.Args, txs[0])
-
- bs := r.Calls[3]
- assert.Equal(t, "broadcast_tx_sync", bs.Name)
- assert.Nil(t, bs.Response)
- require.NotNil(t, bs.Error)
- assert.EqualValues(t, bs.Args, txs[1])
-
- ba := r.Calls[4]
- assert.Equal(t, "broadcast_tx_async", ba.Name)
- assert.Nil(t, ba.Response)
- require.NotNil(t, ba.Error)
- assert.EqualValues(t, ba.Args, txs[2])
- }
-
- func TestABCIApp(t *testing.T) {
- app := kvstore.NewApplication()
- m := mock.ABCIApp{app}
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- // get some info
- info, err := m.ABCIInfo(ctx)
- require.NoError(t, err)
- assert.Equal(t, `{"size":0}`, info.Response.GetData())
-
- // add a key
- key, value := "foo", "bar"
- tx := fmt.Sprintf("%s=%s", key, value)
- res, err := m.BroadcastTxCommit(ctx, types.Tx(tx))
- require.NoError(t, err)
- assert.True(t, res.CheckTx.IsOK())
- require.NotNil(t, res.TxResult)
- assert.True(t, res.TxResult.IsOK())
-
- // commit
- // TODO: This may not be necessary in the future
- if res.Height == -1 {
- m.App.Commit()
- }
-
- // check the key
- _qres, err := m.ABCIQueryWithOptions(
- ctx,
- "/key",
- bytes.HexBytes(key),
- client.ABCIQueryOptions{Prove: true},
- )
- qres := _qres.Response
- require.NoError(t, err)
- assert.EqualValues(t, value, qres.Value)
-
- // XXX Check proof
- }
|