Start writing test scaffold to test server
This commit is contained in:
parent
f93947f3ab
commit
1f31fbeea8
120
mock/app.go
Normal file
120
mock/app.go
Normal file
@ -0,0 +1,120 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// NewApp creates a simple mock kvstore app for testing.
|
||||
// It should work similar to a real app.
|
||||
// Make sure rootDir is empty before running the test,
|
||||
// in order to guarantee consistent results
|
||||
func NewApp(logger log.Logger, rootDir string) (abci.Application, error) {
|
||||
db, err := dbm.NewGoLevelDB("mock", rootDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Capabilities key to access the main KVStore.
|
||||
capKeyMainStore := sdk.NewKVStoreKey("main")
|
||||
|
||||
// Create BaseApp.
|
||||
baseApp := bam.NewBaseApp("kvstore", logger, db)
|
||||
|
||||
// Set mounts for BaseApp's MultiStore.
|
||||
baseApp.MountStoresIAVL(capKeyMainStore)
|
||||
|
||||
// Set Tx decoder
|
||||
baseApp.SetTxDecoder(decodeTx)
|
||||
|
||||
baseApp.SetInitChainer(InitChainer(capKeyMainStore))
|
||||
|
||||
// Set a handler Route.
|
||||
baseApp.Router().AddRoute("kvstore", KVStoreHandler(capKeyMainStore))
|
||||
|
||||
// Load latest version.
|
||||
if err := baseApp.LoadLatestVersion(capKeyMainStore); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return baseApp, nil
|
||||
}
|
||||
|
||||
// KVStoreHandler is a simple handler that takes kvstoreTx and writes
|
||||
// them to the db
|
||||
func KVStoreHandler(storeKey sdk.StoreKey) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
dTx, ok := msg.(kvstoreTx)
|
||||
if !ok {
|
||||
panic("KVStoreHandler should only receive kvstoreTx")
|
||||
}
|
||||
|
||||
// tx is already unmarshalled
|
||||
key := dTx.key
|
||||
value := dTx.value
|
||||
|
||||
store := ctx.KVStore(storeKey)
|
||||
store.Set(key, value)
|
||||
|
||||
return sdk.Result{
|
||||
Code: 0,
|
||||
Log: fmt.Sprintf("set %s=%s", key, value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type KV struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type GenesisJSON struct {
|
||||
Values []KV `json:"values"`
|
||||
}
|
||||
|
||||
// InitChainer returns a function that can initialize the chain
|
||||
// with key/value pairs
|
||||
func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain {
|
||||
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
stateJSON := req.AppStateBytes
|
||||
|
||||
genesisState := new(GenesisJSON)
|
||||
err := json.Unmarshal(stateJSON, genesisState)
|
||||
if err != nil {
|
||||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
|
||||
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
for _, val := range genesisState.Values {
|
||||
store := ctx.KVStore(key)
|
||||
store.Set([]byte(val.Key), []byte(val.Value))
|
||||
}
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
}
|
||||
|
||||
// GenInitOptions can be passed into InitCmd,
|
||||
// returns a static string of a few key-values that can be parsed
|
||||
// by InitChainer
|
||||
func GenInitOptions(args []string) (json.RawMessage, error) {
|
||||
opts := []byte(`{
|
||||
"values": [
|
||||
{
|
||||
"key": "hello",
|
||||
"value": "goodbye"
|
||||
},
|
||||
{
|
||||
"key": "foo",
|
||||
"value": "bar"
|
||||
}
|
||||
]
|
||||
}`)
|
||||
return opts, nil
|
||||
}
|
||||
27
mock/helpers.go
Normal file
27
mock/helpers.go
Normal file
@ -0,0 +1,27 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
)
|
||||
|
||||
// SetupApp returns an application as well as a clean-up function
|
||||
// to be used to quickly setup a test case with an app
|
||||
func SetupApp() (abci.Application, func(), error) {
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).
|
||||
With("module", "mock")
|
||||
rootDir, err := ioutil.TempDir("mock-sdk", "")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
os.RemoveAll(rootDir)
|
||||
}
|
||||
|
||||
app, err := NewApp(logger, rootDir)
|
||||
return app, cleanup, err
|
||||
}
|
||||
76
mock/tx.go
Normal file
76
mock/tx.go
Normal file
@ -0,0 +1,76 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
// An sdk.Tx which is its own sdk.Msg.
|
||||
type kvstoreTx struct {
|
||||
key []byte
|
||||
value []byte
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) Get(key interface{}) (value interface{}) {
|
||||
switch k := key.(type) {
|
||||
case string:
|
||||
switch k {
|
||||
case "key":
|
||||
return tx.key
|
||||
case "value":
|
||||
return tx.value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) Type() string {
|
||||
return "kvstore"
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) GetMsg() sdk.Msg {
|
||||
return tx
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) GetSignBytes() []byte {
|
||||
return tx.bytes
|
||||
}
|
||||
|
||||
// Should the app be calling this? Or only handlers?
|
||||
func (tx kvstoreTx) ValidateBasic() sdk.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) GetSigners() []crypto.Address {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) GetSignatures() []sdk.StdSignature {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx kvstoreTx) GetFeePayer() crypto.Address {
|
||||
return nil
|
||||
}
|
||||
|
||||
// takes raw transaction bytes and decodes them into an sdk.Tx. An sdk.Tx has
|
||||
// all the signatures and can be used to authenticate.
|
||||
func decodeTx(txBytes []byte) (sdk.Tx, sdk.Error) {
|
||||
var tx sdk.Tx
|
||||
|
||||
split := bytes.Split(txBytes, []byte("="))
|
||||
if len(split) == 1 {
|
||||
k := split[0]
|
||||
tx = kvstoreTx{k, k, txBytes}
|
||||
} else if len(split) == 2 {
|
||||
k, v := split[0], split[1]
|
||||
tx = kvstoreTx{k, v, txBytes}
|
||||
} else {
|
||||
return nil, sdk.ErrTxParse("too many =")
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
@ -62,10 +62,6 @@ func GenerateCoinKey() (crypto.Address, string, error) {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// debug
|
||||
bz, err := json.Marshal(info.PubKey)
|
||||
fmt.Printf("PubKey: %s\n", string(bz))
|
||||
|
||||
addr := info.PubKey.Address()
|
||||
return addr, secret, nil
|
||||
}
|
||||
|
||||
7
server/init_test.go
Normal file
7
server/init_test.go
Normal file
@ -0,0 +1,7 @@
|
||||
package server
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
|
||||
}
|
||||
15
server/start_test.go
Normal file
15
server/start_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStart(t *testing.T) {
|
||||
// app, cleanup, err := mock.SetupApp()
|
||||
// if cleanup != nil {
|
||||
// defer cleanup()
|
||||
// }
|
||||
|
||||
// require.NoError(t, err)
|
||||
// // TODO: init and start
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user