|
|
- package rpctest
-
- import (
- "bytes"
- crand "crypto/rand"
- "fmt"
- "math/rand"
- "testing"
- "time"
-
- . "github.com/tendermint/go-common"
- "github.com/tendermint/go-wire"
- ctypes "github.com/tendermint/tendermint/rpc/core/types"
- "github.com/tendermint/tendermint/types"
- "github.com/tendermint/tmsp/example/dummy"
- tmsp "github.com/tendermint/tmsp/types"
- )
-
- //--------------------------------------------------------------------------------
- // Test the HTTP client
- // These tests assume the dummy app
- //--------------------------------------------------------------------------------
-
- //--------------------------------------------------------------------------------
- // status
-
- func TestURIStatus(t *testing.T) {
- tmResult := new(ctypes.TMResult)
- _, err := clientURI.Call("status", map[string]interface{}{}, tmResult)
- if err != nil {
- panic(err)
- }
- testStatus(t, tmResult)
- }
-
- func TestJSONStatus(t *testing.T) {
- tmResult := new(ctypes.TMResult)
- _, err := clientJSON.Call("status", []interface{}{}, tmResult)
- if err != nil {
- panic(err)
- }
- testStatus(t, tmResult)
- }
-
- func testStatus(t *testing.T, statusI interface{}) {
- tmRes := statusI.(*ctypes.TMResult)
- status := (*tmRes).(*ctypes.ResultStatus)
- if status.NodeInfo.Network != chainID {
- panic(Fmt("ChainID mismatch: got %s expected %s",
- status.NodeInfo.Network, chainID))
- }
- }
-
- //--------------------------------------------------------------------------------
- // broadcast tx sync
-
- // random bytes (excluding byte('='))
- func randBytes() []byte {
- n := rand.Intn(10) + 2
- buf := make([]byte, n)
- _, err := crand.Read(buf)
- if err != nil {
- panic(err)
- }
- return bytes.Replace(buf, []byte("="), []byte{100}, -1)
- }
-
- func TestURIBroadcastTxSync(t *testing.T) {
- config.Set("block_size", 0)
- defer config.Set("block_size", -1)
- tmResult := new(ctypes.TMResult)
- tx := randBytes()
- _, err := clientURI.Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, tmResult)
- if err != nil {
- panic(err)
- }
- testBroadcastTxSync(t, tmResult, tx)
- }
-
- func TestJSONBroadcastTxSync(t *testing.T) {
- config.Set("block_size", 0)
- defer config.Set("block_size", -1)
- tmResult := new(ctypes.TMResult)
- tx := randBytes()
- _, err := clientJSON.Call("broadcast_tx_sync", []interface{}{tx}, tmResult)
- if err != nil {
- panic(err)
- }
- testBroadcastTxSync(t, tmResult, tx)
- }
-
- func testBroadcastTxSync(t *testing.T, resI interface{}, tx []byte) {
- tmRes := resI.(*ctypes.TMResult)
- res := (*tmRes).(*ctypes.ResultBroadcastTx)
- if res.Code != tmsp.CodeType_OK {
- panic(Fmt("BroadcastTxSync got non-zero exit code: %v. %X; %s", res.Code, res.Data, res.Log))
- }
- mem := node.MempoolReactor().Mempool
- if mem.Size() != 1 {
- panic(Fmt("Mempool size should have been 1. Got %d", mem.Size()))
- }
-
- txs := mem.Reap(1)
- if !bytes.Equal(txs[0], tx) {
- panic(Fmt("Tx in mempool does not match test tx. Got %X, expected %X", txs[0], tx))
- }
-
- mem.Flush()
- }
-
- //--------------------------------------------------------------------------------
- // query
-
- func testTxKV() ([]byte, []byte, []byte) {
- k := randBytes()
- v := randBytes()
- return k, v, []byte(Fmt("%s=%s", k, v))
- }
-
- func sendTx() ([]byte, []byte) {
- tmResult := new(ctypes.TMResult)
- k, v, tx := testTxKV()
- _, err := clientJSON.Call("broadcast_tx_commit", []interface{}{tx}, tmResult)
- if err != nil {
- panic(err)
- }
- fmt.Println("SENT TX", tx)
- fmt.Printf("SENT TX %X\n", tx)
- fmt.Printf("k %X; v %X", k, v)
- return k, v
- }
-
- func TestURITMSPQuery(t *testing.T) {
- k, v := sendTx()
- time.Sleep(time.Second)
- tmResult := new(ctypes.TMResult)
- _, err := clientURI.Call("tmsp_query", map[string]interface{}{"query": k}, tmResult)
- if err != nil {
- panic(err)
- }
- testTMSPQuery(t, tmResult, v)
- }
-
- func TestJSONTMSPQuery(t *testing.T) {
- k, v := sendTx()
- tmResult := new(ctypes.TMResult)
- _, err := clientJSON.Call("tmsp_query", []interface{}{k}, tmResult)
- if err != nil {
- panic(err)
- }
- testTMSPQuery(t, tmResult, v)
- }
-
- func testTMSPQuery(t *testing.T, statusI interface{}, value []byte) {
- tmRes := statusI.(*ctypes.TMResult)
- query := (*tmRes).(*ctypes.ResultTMSPQuery)
- if query.Result.IsErr() {
- panic(Fmt("Query returned an err: %v", query))
- }
-
- qResult := new(dummy.QueryResult)
- if err := wire.ReadJSONBytes(query.Result.Data, qResult); err != nil {
- t.Fatal(err)
- }
- // XXX: specific to value returned by the dummy
- if qResult.Exists != true {
- panic(Fmt("Query error. Expected to find 'exists=true'. Got: %v", qResult))
- }
- }
-
- //--------------------------------------------------------------------------------
- // broadcast tx commit
-
- func TestURIBroadcastTxCommit(t *testing.T) {
- tmResult := new(ctypes.TMResult)
- tx := randBytes()
- _, err := clientURI.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
- if err != nil {
- panic(err)
- }
- testBroadcastTxCommit(t, tmResult, tx)
- }
-
- func TestJSONBroadcastTxCommit(t *testing.T) {
- tmResult := new(ctypes.TMResult)
- tx := randBytes()
- _, err := clientJSON.Call("broadcast_tx_commit", []interface{}{tx}, tmResult)
- if err != nil {
- panic(err)
- }
- testBroadcastTxCommit(t, tmResult, tx)
- }
-
- func testBroadcastTxCommit(t *testing.T, resI interface{}, tx []byte) {
- tmRes := resI.(*ctypes.TMResult)
- res := (*tmRes).(*ctypes.ResultBroadcastTxCommit)
- checkTx := res.CheckTx
- if checkTx.Code != tmsp.CodeType_OK {
- panic(Fmt("BroadcastTxCommit got non-zero exit code from CheckTx: %v. %X; %s", checkTx.Code, checkTx.Data, checkTx.Log))
- }
- appendTx := res.AppendTx
- if appendTx.Code != tmsp.CodeType_OK {
- panic(Fmt("BroadcastTxCommit got non-zero exit code from CheckTx: %v. %X; %s", appendTx.Code, appendTx.Data, appendTx.Log))
- }
- mem := node.MempoolReactor().Mempool
- if mem.Size() != 0 {
- panic(Fmt("Mempool size should have been 0. Got %d", mem.Size()))
- }
-
- // TODO: find tx in block
- }
-
- //--------------------------------------------------------------------------------
- // Test the websocket service
-
- var wsTyp = "JSONRPC"
-
- // make a simple connection to the server
- func TestWSConnect(t *testing.T) {
- wsc := newWSClient(t)
- wsc.Stop()
- }
-
- // receive a new block message
- func TestWSNewBlock(t *testing.T) {
- wsc := newWSClient(t)
- eid := types.EventStringNewBlock()
- subscribe(t, wsc, eid)
- defer func() {
- unsubscribe(t, wsc, eid)
- wsc.Stop()
- }()
- waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
- fmt.Println("Check:", b)
- return nil
- })
- }
-
- // receive a few new block messages in a row, with increasing height
- func TestWSBlockchainGrowth(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- wsc := newWSClient(t)
- eid := types.EventStringNewBlock()
- subscribe(t, wsc, eid)
- defer func() {
- unsubscribe(t, wsc, eid)
- wsc.Stop()
- }()
-
- // listen for NewBlock, ensure height increases by 1
-
- var initBlockN int
- for i := 0; i < 3; i++ {
- waitForEvent(t, wsc, eid, true, func() {}, func(eid string, eventData interface{}) error {
- block := eventData.(types.EventDataNewBlock).Block
- if i == 0 {
- initBlockN = block.Header.Height
- } else {
- if block.Header.Height != initBlockN+i {
- return fmt.Errorf("Expected block %d, got block %d", initBlockN+i, block.Header.Height)
- }
- }
-
- return nil
- })
- }
- }
-
- func TestWSTxEvent(t *testing.T) {
- wsc := newWSClient(t)
- tx := randBytes()
-
- // listen for the tx I am about to submit
- eid := types.EventStringTx(types.Tx(tx))
- subscribe(t, wsc, eid)
- defer func() {
- unsubscribe(t, wsc, eid)
- wsc.Stop()
- }()
-
- // send an tx
- tmResult := new(ctypes.TMResult)
- _, err := clientJSON.Call("broadcast_tx_sync", []interface{}{tx}, tmResult)
- if err != nil {
- t.Fatal("Error submitting event")
- }
-
- waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
- evt, ok := b.(types.EventDataTx)
- if !ok {
- t.Fatal("Got wrong event type", b)
- }
- if bytes.Compare([]byte(evt.Tx), tx) != 0 {
- t.Error("Event returned different tx")
- }
- if evt.Code != tmsp.CodeType_OK {
- t.Error("Event returned tx error code", evt.Code)
- }
- return nil
- })
- }
-
- /* TODO: this with dummy app..
- func TestWSDoubleFire(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- con := newWSCon(t)
- eid := types.EventStringAccInput(user[0].Address)
- subscribe(t, con, eid)
- defer func() {
- unsubscribe(t, con, eid)
- con.Close()
- }()
- amt := int64(100)
- toAddr := user[1].Address
- // broadcast the transaction, wait to hear about it
- waitForEvent(t, con, eid, true, func() {
- tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
- broadcastTx(t, wsTyp, tx)
- }, func(eid string, b []byte) error {
- return nil
- })
- // but make sure we don't hear about it twice
- waitForEvent(t, con, eid, false, func() {
- }, func(eid string, b []byte) error {
- return nil
- })
- }*/
-
- //--------------------------------------------------------------------------------
- // unsafe_set_config
-
- var stringVal = "my string"
- var intVal = 987654321
- var boolVal = true
-
- // don't change these
- var testCasesUnsafeSetConfig = [][]string{
- []string{"string", "key1", stringVal},
- []string{"int", "key2", fmt.Sprintf("%v", intVal)},
- []string{"bool", "key3", fmt.Sprintf("%v", boolVal)},
- }
-
- func TestURIUnsafeSetConfig(t *testing.T) {
- for _, testCase := range testCasesUnsafeSetConfig {
- tmResult := new(ctypes.TMResult)
- _, err := clientURI.Call("unsafe_set_config", map[string]interface{}{
- "type": testCase[0],
- "key": testCase[1],
- "value": testCase[2],
- }, tmResult)
- if err != nil {
- panic(err)
- }
- }
- testUnsafeSetConfig(t)
- }
-
- func TestJSONUnsafeSetConfig(t *testing.T) {
- for _, testCase := range testCasesUnsafeSetConfig {
- tmResult := new(ctypes.TMResult)
- _, err := clientJSON.Call("unsafe_set_config", []interface{}{testCase[0], testCase[1], testCase[2]}, tmResult)
- if err != nil {
- panic(err)
- }
- }
- testUnsafeSetConfig(t)
- }
-
- func testUnsafeSetConfig(t *testing.T) {
- s := config.GetString("key1")
- if s != stringVal {
- panic(Fmt("got %v, expected %v", s, stringVal))
- }
-
- i := config.GetInt("key2")
- if i != intVal {
- panic(Fmt("got %v, expected %v", i, intVal))
- }
-
- b := config.GetBool("key3")
- if b != boolVal {
- panic(Fmt("got %v, expected %v", b, boolVal))
- }
- }
|