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.

383 lines
9.6 KiB

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