mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-04 02:52:07 +00:00
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.
204 lines
5.6 KiB
Go
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
|
|
}
|