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.

382 lines
9.7 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. crand "crypto/rand"
  5. "fmt"
  6. "math/rand"
  7. "testing"
  8. "time"
  9. abci "github.com/tendermint/abci/types"
  10. . "github.com/tendermint/go-common"
  11. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  12. "github.com/tendermint/tendermint/types"
  13. )
  14. //--------------------------------------------------------------------------------
  15. // Test the HTTP client
  16. // These tests assume the dummy app
  17. //--------------------------------------------------------------------------------
  18. //--------------------------------------------------------------------------------
  19. // status
  20. func TestURIStatus(t *testing.T) {
  21. tmResult := new(ctypes.TMResult)
  22. _, err := clientURI.Call("status", map[string]interface{}{}, tmResult)
  23. if err != nil {
  24. panic(err)
  25. }
  26. testStatus(t, tmResult)
  27. }
  28. func TestJSONStatus(t *testing.T) {
  29. tmResult := new(ctypes.TMResult)
  30. _, err := clientJSON.Call("status", []interface{}{}, tmResult)
  31. if err != nil {
  32. panic(err)
  33. }
  34. testStatus(t, tmResult)
  35. }
  36. func testStatus(t *testing.T, statusI interface{}) {
  37. tmRes := statusI.(*ctypes.TMResult)
  38. status := (*tmRes).(*ctypes.ResultStatus)
  39. if status.NodeInfo.Network != chainID {
  40. panic(Fmt("ChainID mismatch: got %s expected %s",
  41. status.NodeInfo.Network, chainID))
  42. }
  43. }
  44. //--------------------------------------------------------------------------------
  45. // broadcast tx sync
  46. // random bytes (excluding byte('='))
  47. func randBytes() []byte {
  48. n := rand.Intn(10) + 2
  49. buf := make([]byte, n)
  50. _, err := crand.Read(buf)
  51. if err != nil {
  52. panic(err)
  53. }
  54. return bytes.Replace(buf, []byte("="), []byte{100}, -1)
  55. }
  56. func TestURIBroadcastTxSync(t *testing.T) {
  57. config.Set("block_size", 0)
  58. defer config.Set("block_size", -1)
  59. tmResult := new(ctypes.TMResult)
  60. tx := randBytes()
  61. _, err := clientURI.Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, tmResult)
  62. if err != nil {
  63. panic(err)
  64. }
  65. testBroadcastTxSync(t, tmResult, tx)
  66. }
  67. func TestJSONBroadcastTxSync(t *testing.T) {
  68. config.Set("block_size", 0)
  69. defer config.Set("block_size", -1)
  70. tmResult := new(ctypes.TMResult)
  71. tx := randBytes()
  72. _, err := clientJSON.Call("broadcast_tx_sync", []interface{}{tx}, tmResult)
  73. if err != nil {
  74. panic(err)
  75. }
  76. testBroadcastTxSync(t, tmResult, tx)
  77. }
  78. func testBroadcastTxSync(t *testing.T, resI interface{}, tx []byte) {
  79. tmRes := resI.(*ctypes.TMResult)
  80. res := (*tmRes).(*ctypes.ResultBroadcastTx)
  81. if res.Code != abci.CodeType_OK {
  82. panic(Fmt("BroadcastTxSync got non-zero exit code: %v. %X; %s", res.Code, res.Data, res.Log))
  83. }
  84. mem := node.MempoolReactor().Mempool
  85. if mem.Size() != 1 {
  86. panic(Fmt("Mempool size should have been 1. Got %d", mem.Size()))
  87. }
  88. txs := mem.Reap(1)
  89. if !bytes.Equal(txs[0], tx) {
  90. panic(Fmt("Tx in mempool does not match test tx. Got %X, expected %X", txs[0], tx))
  91. }
  92. mem.Flush()
  93. }
  94. //--------------------------------------------------------------------------------
  95. // query
  96. func testTxKV() ([]byte, []byte, []byte) {
  97. k := randBytes()
  98. v := randBytes()
  99. return k, v, []byte(Fmt("%s=%s", k, v))
  100. }
  101. func sendTx() ([]byte, []byte) {
  102. tmResult := new(ctypes.TMResult)
  103. k, v, tx := testTxKV()
  104. _, err := clientJSON.Call("broadcast_tx_commit", []interface{}{tx}, tmResult)
  105. if err != nil {
  106. panic(err)
  107. }
  108. fmt.Println("SENT TX", tx)
  109. fmt.Printf("SENT TX %X\n", tx)
  110. fmt.Printf("k %X; v %X", k, v)
  111. return k, v
  112. }
  113. func TestURIABCIQuery(t *testing.T) {
  114. k, v := sendTx()
  115. time.Sleep(time.Second)
  116. tmResult := new(ctypes.TMResult)
  117. _, err := clientURI.Call("abci_query", map[string]interface{}{"path": "", "data": k, "prove": false}, tmResult)
  118. if err != nil {
  119. panic(err)
  120. }
  121. testABCIQuery(t, tmResult, v)
  122. }
  123. func TestJSONABCIQuery(t *testing.T) {
  124. k, v := sendTx()
  125. tmResult := new(ctypes.TMResult)
  126. _, err := clientJSON.Call("abci_query", []interface{}{"", k, false}, tmResult)
  127. if err != nil {
  128. panic(err)
  129. }
  130. testABCIQuery(t, tmResult, v)
  131. }
  132. func testABCIQuery(t *testing.T, statusI interface{}, value []byte) {
  133. tmRes := statusI.(*ctypes.TMResult)
  134. resQuery := (*tmRes).(*ctypes.ResultABCIQuery)
  135. if !resQuery.Response.Code.IsOK() {
  136. panic(Fmt("Query returned an err: %v", resQuery))
  137. }
  138. // XXX: specific to value returned by the dummy
  139. if len(resQuery.Response.Value) == 0 {
  140. panic(Fmt("Query error. Found no value"))
  141. }
  142. }
  143. //--------------------------------------------------------------------------------
  144. // broadcast tx commit
  145. func TestURIBroadcastTxCommit(t *testing.T) {
  146. tmResult := new(ctypes.TMResult)
  147. tx := randBytes()
  148. _, err := clientURI.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
  149. if err != nil {
  150. panic(err)
  151. }
  152. testBroadcastTxCommit(t, tmResult, tx)
  153. }
  154. func TestJSONBroadcastTxCommit(t *testing.T) {
  155. tmResult := new(ctypes.TMResult)
  156. tx := randBytes()
  157. _, err := clientJSON.Call("broadcast_tx_commit", []interface{}{tx}, tmResult)
  158. if err != nil {
  159. panic(err)
  160. }
  161. testBroadcastTxCommit(t, tmResult, tx)
  162. }
  163. func testBroadcastTxCommit(t *testing.T, resI interface{}, tx []byte) {
  164. tmRes := resI.(*ctypes.TMResult)
  165. res := (*tmRes).(*ctypes.ResultBroadcastTxCommit)
  166. checkTx := res.CheckTx
  167. if checkTx.Code != abci.CodeType_OK {
  168. panic(Fmt("BroadcastTxCommit got non-zero exit code from CheckTx: %v. %X; %s", checkTx.Code, checkTx.Data, checkTx.Log))
  169. }
  170. deliverTx := res.DeliverTx
  171. if deliverTx.Code != abci.CodeType_OK {
  172. panic(Fmt("BroadcastTxCommit got non-zero exit code from CheckTx: %v. %X; %s", deliverTx.Code, deliverTx.Data, deliverTx.Log))
  173. }
  174. mem := node.MempoolReactor().Mempool
  175. if mem.Size() != 0 {
  176. panic(Fmt("Mempool size should have been 0. Got %d", mem.Size()))
  177. }
  178. // TODO: find tx in block
  179. }
  180. //--------------------------------------------------------------------------------
  181. // Test the websocket service
  182. var wsTyp = "JSONRPC"
  183. // make a simple connection to the server
  184. func TestWSConnect(t *testing.T) {
  185. wsc := newWSClient(t)
  186. wsc.Stop()
  187. }
  188. // receive a new block message
  189. func TestWSNewBlock(t *testing.T) {
  190. wsc := newWSClient(t)
  191. eid := types.EventStringNewBlock()
  192. subscribe(t, wsc, eid)
  193. defer func() {
  194. unsubscribe(t, wsc, eid)
  195. wsc.Stop()
  196. }()
  197. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
  198. fmt.Println("Check:", b)
  199. return nil
  200. })
  201. }
  202. // receive a few new block messages in a row, with increasing height
  203. func TestWSBlockchainGrowth(t *testing.T) {
  204. if testing.Short() {
  205. t.Skip("skipping test in short mode.")
  206. }
  207. wsc := newWSClient(t)
  208. eid := types.EventStringNewBlock()
  209. subscribe(t, wsc, eid)
  210. defer func() {
  211. unsubscribe(t, wsc, eid)
  212. wsc.Stop()
  213. }()
  214. // listen for NewBlock, ensure height increases by 1
  215. var initBlockN int
  216. for i := 0; i < 3; i++ {
  217. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, eventData interface{}) error {
  218. block := eventData.(types.EventDataNewBlock).Block
  219. if i == 0 {
  220. initBlockN = block.Header.Height
  221. } else {
  222. if block.Header.Height != initBlockN+i {
  223. return fmt.Errorf("Expected block %d, got block %d", initBlockN+i, block.Header.Height)
  224. }
  225. }
  226. return nil
  227. })
  228. }
  229. }
  230. func TestWSTxEvent(t *testing.T) {
  231. wsc := newWSClient(t)
  232. tx := randBytes()
  233. // listen for the tx I am about to submit
  234. eid := types.EventStringTx(types.Tx(tx))
  235. subscribe(t, wsc, eid)
  236. defer func() {
  237. unsubscribe(t, wsc, eid)
  238. wsc.Stop()
  239. }()
  240. // send an tx
  241. tmResult := new(ctypes.TMResult)
  242. _, err := clientJSON.Call("broadcast_tx_sync", []interface{}{tx}, tmResult)
  243. if err != nil {
  244. t.Fatal("Error submitting event")
  245. }
  246. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
  247. evt, ok := b.(types.EventDataTx)
  248. if !ok {
  249. t.Fatal("Got wrong event type", b)
  250. }
  251. if bytes.Compare([]byte(evt.Tx), tx) != 0 {
  252. t.Error("Event returned different tx")
  253. }
  254. if evt.Code != abci.CodeType_OK {
  255. t.Error("Event returned tx error code", evt.Code)
  256. }
  257. return nil
  258. })
  259. }
  260. /* TODO: this with dummy app..
  261. func TestWSDoubleFire(t *testing.T) {
  262. if testing.Short() {
  263. t.Skip("skipping test in short mode.")
  264. }
  265. con := newWSCon(t)
  266. eid := types.EventStringAccInput(user[0].Address)
  267. subscribe(t, con, eid)
  268. defer func() {
  269. unsubscribe(t, con, eid)
  270. con.Close()
  271. }()
  272. amt := int64(100)
  273. toAddr := user[1].Address
  274. // broadcast the transaction, wait to hear about it
  275. waitForEvent(t, con, eid, true, func() {
  276. tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
  277. broadcastTx(t, wsTyp, tx)
  278. }, func(eid string, b []byte) error {
  279. return nil
  280. })
  281. // but make sure we don't hear about it twice
  282. waitForEvent(t, con, eid, false, func() {
  283. }, func(eid string, b []byte) error {
  284. return nil
  285. })
  286. }*/
  287. //--------------------------------------------------------------------------------
  288. // unsafe_set_config
  289. var stringVal = "my string"
  290. var intVal = 987654321
  291. var boolVal = true
  292. // don't change these
  293. var testCasesUnsafeSetConfig = [][]string{
  294. []string{"string", "key1", stringVal},
  295. []string{"int", "key2", fmt.Sprintf("%v", intVal)},
  296. []string{"bool", "key3", fmt.Sprintf("%v", boolVal)},
  297. }
  298. func TestURIUnsafeSetConfig(t *testing.T) {
  299. for _, testCase := range testCasesUnsafeSetConfig {
  300. tmResult := new(ctypes.TMResult)
  301. _, err := clientURI.Call("unsafe_set_config", map[string]interface{}{
  302. "type": testCase[0],
  303. "key": testCase[1],
  304. "value": testCase[2],
  305. }, tmResult)
  306. if err != nil {
  307. panic(err)
  308. }
  309. }
  310. testUnsafeSetConfig(t)
  311. }
  312. func TestJSONUnsafeSetConfig(t *testing.T) {
  313. for _, testCase := range testCasesUnsafeSetConfig {
  314. tmResult := new(ctypes.TMResult)
  315. _, err := clientJSON.Call("unsafe_set_config", []interface{}{testCase[0], testCase[1], testCase[2]}, tmResult)
  316. if err != nil {
  317. panic(err)
  318. }
  319. }
  320. testUnsafeSetConfig(t)
  321. }
  322. func testUnsafeSetConfig(t *testing.T) {
  323. s := config.GetString("key1")
  324. if s != stringVal {
  325. panic(Fmt("got %v, expected %v", s, stringVal))
  326. }
  327. i := config.GetInt("key2")
  328. if i != intVal {
  329. panic(Fmt("got %v, expected %v", i, intVal))
  330. }
  331. b := config.GetBool("key3")
  332. if b != boolVal {
  333. panic(Fmt("got %v, expected %v", b, boolVal))
  334. }
  335. }