2017-07-26 17:31:43 -07:00
|
|
|
package stack
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2017-07-27 07:40:17 -07:00
|
|
|
"github.com/tendermint/merkleeyes/iavl"
|
2017-07-26 17:31:43 -07:00
|
|
|
"github.com/tendermint/tmlibs/log"
|
|
|
|
|
2017-08-21 14:13:58 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk"
|
|
|
|
"github.com/cosmos/cosmos-sdk/state"
|
2017-07-26 17:31:43 -07:00
|
|
|
)
|
|
|
|
|
2017-07-27 07:40:17 -07:00
|
|
|
func makeState() state.SimpleDB {
|
|
|
|
// return state.NewMemKVStore()
|
|
|
|
|
|
|
|
return state.NewBonsai(iavl.NewIAVLTree(0, nil))
|
|
|
|
|
|
|
|
// tree with persistence....
|
|
|
|
// tmpDir, err := ioutil.TempDir("", "state-tests")
|
|
|
|
// if err != nil {
|
|
|
|
// panic(err)
|
|
|
|
// }
|
|
|
|
// db := dbm.NewDB("test-get-dbs", dbm.LevelDBBackendStr, tmpDir)
|
|
|
|
// persist := iavl.NewIAVLTree(500, db)
|
|
|
|
// return state.NewBonsai(persist)
|
|
|
|
}
|
|
|
|
|
2017-07-26 17:31:43 -07:00
|
|
|
func TestCheckpointer(t *testing.T) {
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
2017-07-30 14:26:25 -07:00
|
|
|
good := writerHand{name: "foo", key: []byte{1, 2}, value: []byte("bar")}
|
2017-07-26 17:31:43 -07:00
|
|
|
bad := FailHandler{Err: errors.New("no go")}
|
|
|
|
|
|
|
|
app := New(
|
|
|
|
Checkpoint{OnCheck: true},
|
2017-07-30 14:26:25 -07:00
|
|
|
writerMid{name: "bing", key: []byte{1, 2}, value: []byte("bang")},
|
2017-07-26 17:31:43 -07:00
|
|
|
Checkpoint{OnDeliver: true},
|
|
|
|
).Use(
|
|
|
|
NewDispatcher(
|
|
|
|
WrapHandler(good),
|
|
|
|
WrapHandler(bad),
|
|
|
|
))
|
|
|
|
|
2017-08-21 14:13:58 -07:00
|
|
|
sdk.TxMapper.RegisterImplementation(RawTx{}, good.Name(), byte(80))
|
2017-07-26 17:31:43 -07:00
|
|
|
|
|
|
|
mid := state.Model{
|
|
|
|
Key: []byte{'b', 'i', 'n', 'g', 0, 1, 2},
|
|
|
|
Value: []byte("bang"),
|
|
|
|
}
|
|
|
|
end := state.Model{
|
|
|
|
Key: []byte{'f', 'o', 'o', 0, 1, 2},
|
|
|
|
Value: []byte("bar"),
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
// tx to send down the line
|
2017-08-21 14:13:58 -07:00
|
|
|
tx sdk.Tx
|
2017-07-26 17:31:43 -07:00
|
|
|
// expect no error?
|
|
|
|
valid bool
|
|
|
|
// models to check afterwards
|
|
|
|
toGetCheck []state.Model
|
|
|
|
// models to check afterwards
|
|
|
|
toGetDeliver []state.Model
|
|
|
|
}{
|
|
|
|
// everything writen on success
|
|
|
|
{
|
|
|
|
tx: NewRawTx([]byte{45, 67}),
|
|
|
|
valid: true,
|
|
|
|
toGetCheck: []state.Model{mid, end},
|
|
|
|
toGetDeliver: []state.Model{mid, end},
|
|
|
|
},
|
|
|
|
// mostly reverted on failure
|
|
|
|
{
|
|
|
|
tx: NewFailTx(),
|
|
|
|
valid: false,
|
|
|
|
toGetCheck: []state.Model{},
|
|
|
|
toGetDeliver: []state.Model{mid},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range cases {
|
|
|
|
ctx := NewContext("foo", 100, log.NewNopLogger())
|
|
|
|
|
2017-07-27 07:40:17 -07:00
|
|
|
store := makeState()
|
2017-07-26 17:31:43 -07:00
|
|
|
_, err := app.CheckTx(ctx, store, tc.tx)
|
|
|
|
if tc.valid {
|
|
|
|
require.Nil(err, "%+v", err)
|
|
|
|
} else {
|
|
|
|
require.NotNil(err)
|
|
|
|
}
|
|
|
|
for _, m := range tc.toGetCheck {
|
|
|
|
val := store.Get(m.Key)
|
|
|
|
assert.EqualValues(m.Value, val, "%d: %#v", i, m)
|
|
|
|
}
|
|
|
|
|
2017-07-27 07:40:17 -07:00
|
|
|
store = makeState()
|
2017-07-26 17:31:43 -07:00
|
|
|
_, err = app.DeliverTx(ctx, store, tc.tx)
|
|
|
|
if tc.valid {
|
|
|
|
require.Nil(err, "%+v", err)
|
|
|
|
} else {
|
|
|
|
require.NotNil(err)
|
|
|
|
}
|
|
|
|
for _, m := range tc.toGetDeliver {
|
|
|
|
val := store.Get(m.Key)
|
|
|
|
assert.EqualValues(m.Value, val, "%d: %#v", i, m)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|