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.

388 lines
9.9 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": 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{}{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.ResultBroadcastTxCommit)
  172. checkTx := res.CheckTx
  173. if checkTx.Code != tmsp.CodeType_OK {
  174. panic(Fmt("BroadcastTxCommit got non-zero exit code from CheckTx: %v. %X; %s", checkTx.Code, checkTx.Data, checkTx.Log))
  175. }
  176. appendTx := res.AppendTx
  177. if appendTx.Code != tmsp.CodeType_OK {
  178. panic(Fmt("BroadcastTxCommit got non-zero exit code from CheckTx: %v. %X; %s", appendTx.Code, appendTx.Data, appendTx.Log))
  179. }
  180. mem := node.MempoolReactor().Mempool
  181. if mem.Size() != 0 {
  182. panic(Fmt("Mempool size should have been 0. Got %d", mem.Size()))
  183. }
  184. // TODO: find tx in block
  185. }
  186. //--------------------------------------------------------------------------------
  187. // Test the websocket service
  188. var wsTyp = "JSONRPC"
  189. // make a simple connection to the server
  190. func TestWSConnect(t *testing.T) {
  191. wsc := newWSClient(t)
  192. wsc.Stop()
  193. }
  194. // receive a new block message
  195. func TestWSNewBlock(t *testing.T) {
  196. wsc := newWSClient(t)
  197. eid := types.EventStringNewBlock()
  198. subscribe(t, wsc, eid)
  199. defer func() {
  200. unsubscribe(t, wsc, eid)
  201. wsc.Stop()
  202. }()
  203. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
  204. fmt.Println("Check:", b)
  205. return nil
  206. })
  207. }
  208. // receive a few new block messages in a row, with increasing height
  209. func TestWSBlockchainGrowth(t *testing.T) {
  210. if testing.Short() {
  211. t.Skip("skipping test in short mode.")
  212. }
  213. wsc := newWSClient(t)
  214. eid := types.EventStringNewBlock()
  215. subscribe(t, wsc, eid)
  216. defer func() {
  217. unsubscribe(t, wsc, eid)
  218. wsc.Stop()
  219. }()
  220. // listen for NewBlock, ensure height increases by 1
  221. var initBlockN int
  222. for i := 0; i < 3; i++ {
  223. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, eventData interface{}) error {
  224. block := eventData.(types.EventDataNewBlock).Block
  225. if i == 0 {
  226. initBlockN = block.Header.Height
  227. } else {
  228. if block.Header.Height != initBlockN+i {
  229. return fmt.Errorf("Expected block %d, got block %d", initBlockN+i, block.Header.Height)
  230. }
  231. }
  232. return nil
  233. })
  234. }
  235. }
  236. func TestWSTxEvent(t *testing.T) {
  237. wsc := newWSClient(t)
  238. tx := randBytes()
  239. // listen for the tx I am about to submit
  240. eid := types.EventStringTx(types.Tx(tx))
  241. subscribe(t, wsc, eid)
  242. defer func() {
  243. unsubscribe(t, wsc, eid)
  244. wsc.Stop()
  245. }()
  246. // send an tx
  247. tmResult := new(ctypes.TMResult)
  248. _, err := clientJSON.Call("broadcast_tx_sync", []interface{}{tx}, tmResult)
  249. if err != nil {
  250. t.Fatal("Error submitting event")
  251. }
  252. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
  253. evt, ok := b.(types.EventDataTx)
  254. if !ok {
  255. t.Fatal("Got wrong event type", b)
  256. }
  257. if bytes.Compare([]byte(evt.Tx), tx) != 0 {
  258. t.Error("Event returned different tx")
  259. }
  260. if evt.Code != tmsp.CodeType_OK {
  261. t.Error("Event returned tx error code", evt.Code)
  262. }
  263. return nil
  264. })
  265. }
  266. /* TODO: this with dummy app..
  267. func TestWSDoubleFire(t *testing.T) {
  268. if testing.Short() {
  269. t.Skip("skipping test in short mode.")
  270. }
  271. con := newWSCon(t)
  272. eid := types.EventStringAccInput(user[0].Address)
  273. subscribe(t, con, eid)
  274. defer func() {
  275. unsubscribe(t, con, eid)
  276. con.Close()
  277. }()
  278. amt := int64(100)
  279. toAddr := user[1].Address
  280. // broadcast the transaction, wait to hear about it
  281. waitForEvent(t, con, eid, true, func() {
  282. tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
  283. broadcastTx(t, wsTyp, tx)
  284. }, func(eid string, b []byte) error {
  285. return nil
  286. })
  287. // but make sure we don't hear about it twice
  288. waitForEvent(t, con, eid, false, func() {
  289. }, func(eid string, b []byte) error {
  290. return nil
  291. })
  292. }*/
  293. //--------------------------------------------------------------------------------
  294. // unsafe_set_config
  295. var stringVal = "my string"
  296. var intVal = 987654321
  297. var boolVal = true
  298. // don't change these
  299. var testCasesUnsafeSetConfig = [][]string{
  300. []string{"string", "key1", stringVal},
  301. []string{"int", "key2", fmt.Sprintf("%v", intVal)},
  302. []string{"bool", "key3", fmt.Sprintf("%v", boolVal)},
  303. }
  304. func TestURIUnsafeSetConfig(t *testing.T) {
  305. for _, testCase := range testCasesUnsafeSetConfig {
  306. tmResult := new(ctypes.TMResult)
  307. _, err := clientURI.Call("unsafe_set_config", map[string]interface{}{
  308. "type": testCase[0],
  309. "key": testCase[1],
  310. "value": testCase[2],
  311. }, tmResult)
  312. if err != nil {
  313. panic(err)
  314. }
  315. }
  316. testUnsafeSetConfig(t)
  317. }
  318. func TestJSONUnsafeSetConfig(t *testing.T) {
  319. for _, testCase := range testCasesUnsafeSetConfig {
  320. tmResult := new(ctypes.TMResult)
  321. _, err := clientJSON.Call("unsafe_set_config", []interface{}{testCase[0], testCase[1], testCase[2]}, tmResult)
  322. if err != nil {
  323. panic(err)
  324. }
  325. }
  326. testUnsafeSetConfig(t)
  327. }
  328. func testUnsafeSetConfig(t *testing.T) {
  329. s := config.GetString("key1")
  330. if s != stringVal {
  331. panic(Fmt("got %v, expected %v", s, stringVal))
  332. }
  333. i := config.GetInt("key2")
  334. if i != intVal {
  335. panic(Fmt("got %v, expected %v", i, intVal))
  336. }
  337. b := config.GetBool("key3")
  338. if b != boolVal {
  339. panic(Fmt("got %v, expected %v", b, boolVal))
  340. }
  341. }