Files
tendermint/rpc/client/mock/abci_test.go
M. J. Fromberger 5c1399d803 rpc: fix mock test cases (#7571)
In two cases, we check for the content of an error right after asserting that
no error occurs. Fix the sense of those checks.

In one case, we check that there is no error with the diagnostic "expected
error". It's not clear whether this means "an error was expected" (which is
what I believe) or "we got the expected error". However, given the way the mock
plumbing is set up, the first interpretation seems right.
2022-01-12 20:17:53 +00:00

204 lines
5.6 KiB
Go

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")},
DeliverTx: abci.ResponseDeliverTx{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.DeliverTx.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.DeliverTx)
assert.True(t, res.DeliverTx.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
}