Merge pull request #612 from cosmos/rigel/cool-tests

Basecoin cool fix / upgrade tests
This commit is contained in:
Ethan Buchman 2018-03-13 13:46:19 +01:00 committed by GitHub
commit ee0b396bad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 161 additions and 137 deletions

View File

@ -1,12 +0,0 @@
*.swp
*.swo
vendor
build
app/data
### Vagrant ###
.vagrant/
*.box
*.log
vagrant

View File

@ -81,14 +81,14 @@ func MakeCodec() *wire.Codec {
const msgTypeSend = 0x1 const msgTypeSend = 0x1
const msgTypeIssue = 0x2 const msgTypeIssue = 0x2
const msgTypeWhatCool = 0x3 const msgTypeQuiz = 0x3
const msgTypeSetWhatCool = 0x4 const msgTypeSetTrend = 0x4
var _ = oldwire.RegisterInterface( var _ = oldwire.RegisterInterface(
struct{ sdk.Msg }{}, struct{ sdk.Msg }{},
oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend},
oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue},
oldwire.ConcreteType{cool.WhatCoolMsg{}, msgTypeWhatCool}, oldwire.ConcreteType{cool.QuizMsg{}, msgTypeQuiz},
oldwire.ConcreteType{cool.SetWhatCoolMsg{}, msgTypeSetWhatCool}, oldwire.ConcreteType{cool.SetTrendMsg{}, msgTypeSetTrend},
) )
const accTypeApp = 0x1 const accTypeApp = 0x1

View File

@ -23,6 +23,8 @@ import (
// Construct some global addrs and txs for tests. // Construct some global addrs and txs for tests.
var ( var (
chainID = "" // TODO
priv1 = crypto.GenPrivKeyEd25519() priv1 = crypto.GenPrivKeyEd25519()
addr1 = priv1.PubKey().Address() addr1 = priv1.PubKey().Address()
addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() addr2 = crypto.GenPrivKeyEd25519().PubKey().Address()
@ -33,19 +35,29 @@ var (
Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)},
} }
whatCoolMsg1 = cool.WhatCoolMsg{ quizMsg1 = cool.QuizMsg{
Sender: addr1, Sender: addr1,
CoolerThanCool: "icecold", CoolAnswer: "icecold",
} }
whatCoolMsg2 = cool.WhatCoolMsg{ quizMsg2 = cool.QuizMsg{
Sender: addr1, Sender: addr1,
CoolerThanCool: "icecold", CoolAnswer: "badvibesonly",
} }
setWhatCoolMsg = cool.SetWhatCoolMsg{ setTrendMsg1 = cool.SetTrendMsg{
Sender: addr1, Sender: addr1,
WhatCool: "goodbye", Cool: "icecold",
}
setTrendMsg2 = cool.SetTrendMsg{
Sender: addr1,
Cool: "badvibesonly",
}
setTrendMsg3 = cool.SetTrendMsg{
Sender: addr1,
Cool: "warmandkind",
} }
) )
@ -64,11 +76,10 @@ func TestMsgs(t *testing.T) {
msg sdk.Msg msg sdk.Msg
}{ }{
{sendMsg}, {sendMsg},
{whatCoolMsg1}, {quizMsg1},
{setWhatCoolMsg}, {setTrendMsg1},
} }
chainID := ""
sequences := []int64{0} sequences := []int64{0}
for i, m := range msgs { for i, m := range msgs {
sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, m.msg)) sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, m.msg))
@ -168,7 +179,6 @@ func TestSendMsgWithAccounts(t *testing.T) {
assert.Equal(t, acc1, res1) assert.Equal(t, acc1, res1)
// Sign the tx // Sign the tx
chainID := "" // TODO: InitChain should get the ChainID
sequences := []int64{0} sequences := []int64{0}
sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, sendMsg)) sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, sendMsg))
tx := sdk.NewStdTx(sendMsg, []sdk.StdSignature{{ tx := sdk.NewStdTx(sendMsg, []sdk.StdSignature{{
@ -209,56 +219,83 @@ func TestSendMsgWithAccounts(t *testing.T) {
assert.Equal(t, sdk.CodeOK, res.Code, res.Log) assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
} }
//func TestWhatCoolMsg(t *testing.T) { func TestQuizMsg(t *testing.T) {
//bapp := newBasecoinApp() bapp := newBasecoinApp()
//// Construct genesis state // Construct genesis state
//// Construct some genesis bytes to reflect basecoin/types/AppAccount // Construct some genesis bytes to reflect basecoin/types/AppAccount
//// Give 77 foocoin to the first key coins := sdk.Coins{}
//coins, err := sdk.ParseCoins("1icecold") baseAcc := auth.BaseAccount{
//require.Nil(t, err) Address: addr1,
//baseAcc := auth.BaseAccount{ Coins: coins,
//Address: addr1, }
//Coins: coins, acc1 := &types.AppAccount{baseAcc, "foobart"}
//}
//acc1 := &types.AppAccount{baseAcc, "foobart"}
//// Construct genesis state // Construct genesis state
//genesisState := types.GenesisState{ genesisState := types.GenesisState{
//Accounts: []*types.GenesisAccount{ Accounts: []*types.GenesisAccount{
//types.NewGenesisAccount(acc1), types.NewGenesisAccount(acc1),
//}, },
//} }
//stateBytes, err := json.MarshalIndent(genesisState, "", "\t") stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
//require.Nil(t, err) require.Nil(t, err)
//// Initialize the chain (nil) // Initialize the chain (nil)
//vals := []abci.Validator{} vals := []abci.Validator{}
//bapp.InitChain(abci.RequestInitChain{vals, stateBytes}) bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
//bapp.Commit() bapp.Commit()
//// A checkTx context (true) // A checkTx context (true)
//ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{})
//res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1)
//assert.Equal(t, acc1, res1) assert.Equal(t, acc1, res1)
//// Sign the tx // Set the trend, submit a really cool quiz and check for reward
//tx := sdk.NewStdTx(whatCoolMsg1, []sdk.StdSignature{{ SignCheckDeliver(t, bapp, setTrendMsg1, 0, true)
//PubKey: priv1.PubKey(), SignCheckDeliver(t, bapp, quizMsg1, 1, true)
//Signature: priv1.Sign(whatCoolMsg1.GetSignBytes()), CheckBalance(t, bapp, "69icecold")
//}}) SignCheckDeliver(t, bapp, quizMsg2, 2, true) // result without reward
CheckBalance(t, bapp, "69icecold")
SignCheckDeliver(t, bapp, quizMsg1, 3, true)
CheckBalance(t, bapp, "138icecold")
SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend
SignCheckDeliver(t, bapp, quizMsg1, 5, true) // the same answer will nolonger do!
CheckBalance(t, bapp, "138icecold")
SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again
CheckBalance(t, bapp, "69badvibesonly,138icecold")
SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool
//// Run a Check }
//res := bapp.Check(tx)
//assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
//// Simulate a Block func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq int64, expPass bool) {
//bapp.BeginBlock(abci.RequestBeginBlock{})
//res = bapp.Deliver(tx)
//assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
//// Check balances // Sign the tx
//ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) tx := sdk.NewStdTx(msg, []sdk.StdSignature{{
//res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) PubKey: priv1.PubKey(),
//assert.Equal(t, "70icecold", fmt.Sprintf("%v", res2.GetCoins())) Signature: priv1.Sign(sdk.StdSignBytes(chainID, []int64{seq}, msg)),
//} Sequence: seq,
}})
// Run a Check
res := bapp.Check(tx)
if expPass {
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
} else {
require.NotEqual(t, sdk.CodeOK, res.Code, res.Log)
}
// Simulate a Block
bapp.BeginBlock(abci.RequestBeginBlock{})
res = bapp.Deliver(tx)
if expPass {
require.Equal(t, sdk.CodeOK, res.Code, res.Log)
} else {
require.NotEqual(t, sdk.CodeOK, res.Code, res.Log)
}
}
func CheckBalance(t *testing.T, bapp *BasecoinApp, balExpected string) {
ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{})
res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1)
assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins()))
}

View File

@ -58,11 +58,11 @@ func main() {
)...) )...)
basecliCmd.AddCommand( basecliCmd.AddCommand(
client.PostCommands( client.PostCommands(
coolcmd.WhatCoolTxCmd(cdc), coolcmd.QuizTxCmd(cdc),
)...) )...)
basecliCmd.AddCommand( basecliCmd.AddCommand(
client.PostCommands( client.PostCommands(
coolcmd.SetWhatCoolTxCmd(cdc), coolcmd.SetTrendTxCmd(cdc),
)...) )...)
// add proxy, version and key info // add proxy, version and key info

View File

@ -12,10 +12,10 @@ import (
"github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool"
) )
// what cool transaction // take the coolness quiz transaction
func WhatCoolTxCmd(cdc *wire.Codec) *cobra.Command { func QuizTxCmd(cdc *wire.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "whatcool [answer]", Use: "cool [answer]",
Short: "What's cooler than being cool?", Short: "What's cooler than being cool?",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 || len(args[0]) == 0 { if len(args) != 1 || len(args[0]) == 0 {
@ -29,7 +29,7 @@ func WhatCoolTxCmd(cdc *wire.Codec) *cobra.Command {
} }
// create the message // create the message
msg := cool.NewWhatCoolMsg(from, args[0]) msg := cool.NewQuizMsg(from, args[0])
// build and sign the transaction, then broadcast to Tendermint // build and sign the transaction, then broadcast to Tendermint
res, err := builder.SignBuildBroadcast(msg, cdc) res, err := builder.SignBuildBroadcast(msg, cdc)
@ -43,10 +43,10 @@ func WhatCoolTxCmd(cdc *wire.Codec) *cobra.Command {
} }
} }
// set what cool transaction // set a new cool trend transaction
func SetWhatCoolTxCmd(cdc *wire.Codec) *cobra.Command { func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "setwhatcool [answer]", Use: "setcool [answer]",
Short: "You're so cool, tell us what is cool!", Short: "You're so cool, tell us what is cool!",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 || len(args[0]) == 0 { if len(args) != 1 || len(args[0]) == 0 {
@ -60,7 +60,7 @@ func SetWhatCoolTxCmd(cdc *wire.Codec) *cobra.Command {
} }
// create the message // create the message
msg := cool.NewSetWhatCoolMsg(from, args[0]) msg := cool.NewSetTrendMsg(from, args[0])
// build and sign the transaction, then broadcast to Tendermint // build and sign the transaction, then broadcast to Tendermint
res, err := builder.SignBuildBroadcast(msg, cdc) res, err := builder.SignBuildBroadcast(msg, cdc)

View File

@ -22,10 +22,10 @@ import (
func NewHandler(ck bank.CoinKeeper, cm Mapper) sdk.Handler { func NewHandler(ck bank.CoinKeeper, cm Mapper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) { switch msg := msg.(type) {
case SetWhatCoolMsg: case SetTrendMsg:
return handleSetWhatCoolMsg(ctx, cm, msg) return handleSetTrendMsg(ctx, cm, msg)
case WhatCoolMsg: case QuizMsg:
return handleWhatCoolMsg(ctx, ck, cm, msg) return handleQuizMsg(ctx, ck, cm, msg)
default: default:
errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name()) errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name())
return sdk.ErrUnknownRequest(errMsg).Result() return sdk.ErrUnknownRequest(errMsg).Result()
@ -33,20 +33,19 @@ func NewHandler(ck bank.CoinKeeper, cm Mapper) sdk.Handler {
} }
} }
// Handle WhatCoolMsg This is the engine of your module // Handle QuizMsg This is the engine of your module
func handleSetWhatCoolMsg(ctx sdk.Context, cm Mapper, msg SetWhatCoolMsg) sdk.Result { func handleSetTrendMsg(ctx sdk.Context, cm Mapper, msg SetTrendMsg) sdk.Result {
cm.SetWhatCool(ctx, msg.WhatCool) cm.SetTrend(ctx, msg.Cool)
return sdk.Result{} return sdk.Result{}
} }
// Handle WhatCoolMsg This is the engine of your module // Handle QuizMsg This is the engine of your module
func handleWhatCoolMsg(ctx sdk.Context, ck bank.CoinKeeper, cm Mapper, msg WhatCoolMsg) sdk.Result { func handleQuizMsg(ctx sdk.Context, ck bank.CoinKeeper, cm Mapper, msg QuizMsg) sdk.Result {
whatsCool := cm.GetWhatCool(ctx) currentTrend := cm.GetTrend(ctx)
if msg.CoolerThanCool == whatsCool { if msg.CoolAnswer == currentTrend {
bonusCoins := sdk.Coins{{currentTrend, 69}}
bonusCoins := sdk.Coins{{whatsCool, 69}}
_, err := ck.AddCoins(ctx, msg.Sender, bonusCoins) _, err := ck.AddCoins(ctx, msg.Sender, bonusCoins)
if err != nil { if err != nil {
return err.Result() return err.Result()

View File

@ -13,18 +13,18 @@ func NewMapper(key sdk.StoreKey) Mapper {
return Mapper{key} return Mapper{key}
} }
// Key to knowing whats cool // Key to knowing the trend on the streets!
var whatCoolKey = []byte("WhatsCoolKey") var trendKey = []byte("TrendKey")
// Implements sdk.AccountMapper. // Implements sdk.AccountMapper.
func (am Mapper) GetWhatCool(ctx sdk.Context) string { func (am Mapper) GetTrend(ctx sdk.Context) string {
store := ctx.KVStore(am.key) store := ctx.KVStore(am.key)
bz := store.Get(whatCoolKey) bz := store.Get(trendKey)
return string(bz) return string(bz)
} }
// Implements sdk.AccountMapper. // Implements sdk.AccountMapper.
func (am Mapper) SetWhatCool(ctx sdk.Context, whatscool string) { func (am Mapper) SetTrend(ctx sdk.Context, newTrend string) {
store := ctx.KVStore(am.key) store := ctx.KVStore(am.key)
store.Set(whatCoolKey, []byte(whatscool)) store.Set(trendKey, []byte(newTrend))
} }

View File

@ -10,46 +10,46 @@ import (
// A really cool msg type, these fields are can be entirely arbitrary and // A really cool msg type, these fields are can be entirely arbitrary and
// custom to your message // custom to your message
type SetWhatCoolMsg struct { type SetTrendMsg struct {
Sender sdk.Address Sender sdk.Address
WhatCool string Cool string
} }
// New cool message // New cool message
func NewSetWhatCoolMsg(sender sdk.Address, whatcool string) SetWhatCoolMsg { func NewSetTrendMsg(sender sdk.Address, cool string) SetTrendMsg {
return SetWhatCoolMsg{ return SetTrendMsg{
Sender: sender, Sender: sender,
WhatCool: whatcool, Cool: cool,
} }
} }
// enforce the msg type at compile time // enforce the msg type at compile time
var _ sdk.Msg = SetWhatCoolMsg{} var _ sdk.Msg = SetTrendMsg{}
// nolint // nolint
func (msg SetWhatCoolMsg) Type() string { return "cool" } func (msg SetTrendMsg) Type() string { return "cool" }
func (msg SetWhatCoolMsg) Get(key interface{}) (value interface{}) { return nil } func (msg SetTrendMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg SetWhatCoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } func (msg SetTrendMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg SetWhatCoolMsg) String() string { func (msg SetTrendMsg) String() string {
return fmt.Sprintf("SetWhatCoolMsg{Sender: %v, WhatCool: %v}", msg.Sender, msg.WhatCool) return fmt.Sprintf("SetTrendMsg{Sender: %v, Cool: %v}", msg.Sender, msg.Cool)
} }
// Validate Basic is used to quickly disqualify obviously invalid messages quickly // Validate Basic is used to quickly disqualify obviously invalid messages quickly
func (msg SetWhatCoolMsg) ValidateBasic() sdk.Error { func (msg SetTrendMsg) ValidateBasic() sdk.Error {
if len(msg.Sender) == 0 { if len(msg.Sender) == 0 {
return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("") return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("")
} }
if strings.Contains(msg.WhatCool, "hot") { if strings.Contains(msg.Cool, "hot") {
return sdk.ErrUnauthorized("").Trace("hot is not cool") return sdk.ErrUnauthorized("").Trace("hot is not cool")
} }
if strings.Contains(msg.WhatCool, "warm") { if strings.Contains(msg.Cool, "warm") {
return sdk.ErrUnauthorized("").Trace("warm is not very cool") return sdk.ErrUnauthorized("").Trace("warm is not very cool")
} }
return nil return nil
} }
// Get the bytes for the message signer to sign on // Get the bytes for the message signer to sign on
func (msg SetWhatCoolMsg) GetSignBytes() []byte { func (msg SetTrendMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg) b, err := json.Marshal(msg)
if err != nil { if err != nil {
panic(err) panic(err)
@ -59,34 +59,34 @@ func (msg SetWhatCoolMsg) GetSignBytes() []byte {
//_______________________________________________________________________ //_______________________________________________________________________
// A really cool msg type, these fields are can be entirely arbitrary and // A message type to quiz how cool you are. these fields are can be entirely
// custom to your message // arbitrary and custom to your message
type WhatCoolMsg struct { type QuizMsg struct {
Sender sdk.Address Sender sdk.Address
CoolerThanCool string CoolAnswer string
} }
// New cool message // New cool message
func NewWhatCoolMsg(sender sdk.Address, coolerthancool string) WhatCoolMsg { func NewQuizMsg(sender sdk.Address, coolerthancool string) QuizMsg {
return WhatCoolMsg{ return QuizMsg{
Sender: sender, Sender: sender,
CoolerThanCool: coolerthancool, CoolAnswer: coolerthancool,
} }
} }
// enforce the msg type at compile time // enforce the msg type at compile time
var _ sdk.Msg = WhatCoolMsg{} var _ sdk.Msg = QuizMsg{}
// nolint // nolint
func (msg WhatCoolMsg) Type() string { return "cool" } func (msg QuizMsg) Type() string { return "cool" }
func (msg WhatCoolMsg) Get(key interface{}) (value interface{}) { return nil } func (msg QuizMsg) Get(key interface{}) (value interface{}) { return nil }
func (msg WhatCoolMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } func (msg QuizMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} }
func (msg WhatCoolMsg) String() string { func (msg QuizMsg) String() string {
return fmt.Sprintf("WhatCoolMsg{Sender: %v, CoolerThanCool: %v}", msg.Sender, msg.CoolerThanCool) return fmt.Sprintf("QuizMsg{Sender: %v, CoolAnswer: %v}", msg.Sender, msg.CoolAnswer)
} }
// Validate Basic is used to quickly disqualify obviously invalid messages quickly // Validate Basic is used to quickly disqualify obviously invalid messages quickly
func (msg WhatCoolMsg) ValidateBasic() sdk.Error { func (msg QuizMsg) ValidateBasic() sdk.Error {
if len(msg.Sender) == 0 { if len(msg.Sender) == 0 {
return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("") return sdk.ErrUnrecognizedAddress(msg.Sender).Trace("")
} }
@ -94,7 +94,7 @@ func (msg WhatCoolMsg) ValidateBasic() sdk.Error {
} }
// Get the bytes for the message signer to sign on // Get the bytes for the message signer to sign on
func (msg WhatCoolMsg) GetSignBytes() []byte { func (msg QuizMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg) b, err := json.Marshal(msg)
if err != nil { if err != nil {
panic(err) panic(err)