You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

203 lines
5.6 KiB

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
}