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.

377 lines
9.5 KiB

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