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.

304 lines
6.0 KiB

  1. package rpc
  2. import (
  3. "bytes"
  4. crand "crypto/rand"
  5. "math/rand"
  6. "net/http"
  7. "os/exec"
  8. "testing"
  9. "time"
  10. client "github.com/tendermint/go-rpc/client"
  11. server "github.com/tendermint/go-rpc/server"
  12. types "github.com/tendermint/go-rpc/types"
  13. wire "github.com/tendermint/go-wire"
  14. )
  15. // Client and Server should work over tcp or unix sockets
  16. const (
  17. tcpAddr = "tcp://0.0.0.0:46657"
  18. unixSocket = "/tmp/go-rpc.sock"
  19. unixAddr = "unix:///tmp/go-rpc.sock"
  20. websocketEndpoint = "/websocket/endpoint"
  21. )
  22. // Define a type for results and register concrete versions
  23. type Result interface{}
  24. type ResultStatus struct {
  25. Value string
  26. }
  27. type ResultBytes struct {
  28. Value []byte
  29. }
  30. var _ = wire.RegisterInterface(
  31. struct{ Result }{},
  32. wire.ConcreteType{&ResultStatus{}, 0x1},
  33. wire.ConcreteType{&ResultBytes{}, 0x2},
  34. )
  35. // Define some routes
  36. var Routes = map[string]*server.RPCFunc{
  37. "status": server.NewRPCFunc(StatusResult, "arg"),
  38. "status_ws": server.NewWSRPCFunc(StatusWSResult, "arg"),
  39. "bytes": server.NewRPCFunc(BytesResult, "arg"),
  40. }
  41. // an rpc function
  42. func StatusResult(v string) (Result, error) {
  43. return &ResultStatus{v}, nil
  44. }
  45. func StatusWSResult(wsCtx types.WSRPCContext, v string) (Result, error) {
  46. return &ResultStatus{v}, nil
  47. }
  48. func BytesResult(v []byte) (Result, error) {
  49. return &ResultBytes{v}, nil
  50. }
  51. // launch unix and tcp servers
  52. func init() {
  53. cmd := exec.Command("rm", "-f", unixSocket)
  54. err := cmd.Start()
  55. if err != nil {
  56. panic(err)
  57. }
  58. err = cmd.Wait()
  59. mux := http.NewServeMux()
  60. server.RegisterRPCFuncs(mux, Routes)
  61. wm := server.NewWebsocketManager(Routes, nil)
  62. mux.HandleFunc(websocketEndpoint, wm.WebsocketHandler)
  63. go func() {
  64. _, err := server.StartHTTPServer(tcpAddr, mux)
  65. if err != nil {
  66. panic(err)
  67. }
  68. }()
  69. mux2 := http.NewServeMux()
  70. server.RegisterRPCFuncs(mux2, Routes)
  71. wm = server.NewWebsocketManager(Routes, nil)
  72. mux2.HandleFunc(websocketEndpoint, wm.WebsocketHandler)
  73. go func() {
  74. _, err := server.StartHTTPServer(unixAddr, mux2)
  75. if err != nil {
  76. panic(err)
  77. }
  78. }()
  79. // wait for servers to start
  80. time.Sleep(time.Second * 2)
  81. }
  82. func testURI(t *testing.T, cl *client.URIClient) {
  83. val := "acbd"
  84. params := map[string]interface{}{
  85. "arg": val,
  86. }
  87. var result Result
  88. _, err := cl.Call("status", params, &result)
  89. if err != nil {
  90. t.Fatal(err)
  91. }
  92. got := result.(*ResultStatus).Value
  93. if got != val {
  94. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  95. }
  96. }
  97. func testJSONRPC(t *testing.T, cl *client.JSONRPCClient) {
  98. val := "acbd"
  99. params := map[string]interface{}{
  100. "arg": val,
  101. }
  102. var result Result
  103. _, err := cl.Call("status", params, &result)
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. got := result.(*ResultStatus).Value
  108. if got != val {
  109. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  110. }
  111. }
  112. func testWS(t *testing.T, cl *client.WSClient) {
  113. val := "acbd"
  114. params := map[string]interface{}{
  115. "arg": val,
  116. }
  117. err := cl.WriteJSON(types.RPCRequest{
  118. JSONRPC: "2.0",
  119. ID: "",
  120. Method: "status",
  121. Params: params,
  122. })
  123. if err != nil {
  124. t.Fatal(err)
  125. }
  126. select {
  127. case msg := <-cl.ResultsCh:
  128. result := new(Result)
  129. wire.ReadJSONPtr(result, msg, &err)
  130. if err != nil {
  131. t.Fatal(err)
  132. }
  133. got := (*result).(*ResultStatus).Value
  134. if got != val {
  135. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  136. }
  137. case err := <-cl.ErrorsCh:
  138. t.Fatal(err)
  139. }
  140. }
  141. //-------------
  142. func TestURI_TCP(t *testing.T) {
  143. cl := client.NewURIClient(tcpAddr)
  144. testURI(t, cl)
  145. }
  146. func TestURI_UNIX(t *testing.T) {
  147. cl := client.NewURIClient(unixAddr)
  148. testURI(t, cl)
  149. }
  150. func TestJSONRPC_TCP(t *testing.T) {
  151. cl := client.NewJSONRPCClient(tcpAddr)
  152. testJSONRPC(t, cl)
  153. }
  154. func TestJSONRPC_UNIX(t *testing.T) {
  155. cl := client.NewJSONRPCClient(unixAddr)
  156. testJSONRPC(t, cl)
  157. }
  158. func TestWS_TCP(t *testing.T) {
  159. cl := client.NewWSClient(tcpAddr, websocketEndpoint)
  160. _, err := cl.Start()
  161. if err != nil {
  162. t.Fatal(err)
  163. }
  164. testWS(t, cl)
  165. }
  166. func TestWS_UNIX(t *testing.T) {
  167. cl := client.NewWSClient(unixAddr, websocketEndpoint)
  168. _, err := cl.Start()
  169. if err != nil {
  170. t.Fatal(err)
  171. }
  172. testWS(t, cl)
  173. }
  174. func TestHexStringArg(t *testing.T) {
  175. cl := client.NewURIClient(tcpAddr)
  176. // should NOT be handled as hex
  177. val := "0xabc"
  178. params := map[string]interface{}{
  179. "arg": val,
  180. }
  181. var result Result
  182. _, err := cl.Call("status", params, &result)
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. got := result.(*ResultStatus).Value
  187. if got != val {
  188. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  189. }
  190. }
  191. func TestQuotedStringArg(t *testing.T) {
  192. cl := client.NewURIClient(tcpAddr)
  193. // should NOT be unquoted
  194. val := "\"abc\""
  195. params := map[string]interface{}{
  196. "arg": val,
  197. }
  198. var result Result
  199. _, err := cl.Call("status", params, &result)
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. got := result.(*ResultStatus).Value
  204. if got != val {
  205. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  206. }
  207. }
  208. func randBytes(t *testing.T) []byte {
  209. n := rand.Intn(10) + 2
  210. buf := make([]byte, n)
  211. _, err := crand.Read(buf)
  212. if err != nil {
  213. t.Fatal(err)
  214. }
  215. return bytes.Replace(buf, []byte("="), []byte{100}, -1)
  216. }
  217. func TestByteSliceViaJSONRPC(t *testing.T) {
  218. cl := client.NewJSONRPCClient(unixAddr)
  219. val := randBytes(t)
  220. params := map[string]interface{}{
  221. "arg": val,
  222. }
  223. var result Result
  224. _, err := cl.Call("bytes", params, &result)
  225. if err != nil {
  226. t.Fatal(err)
  227. }
  228. got := result.(*ResultBytes).Value
  229. if bytes.Compare(got, val) != 0 {
  230. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  231. }
  232. }
  233. func TestWSNewWSRPCFunc(t *testing.T) {
  234. cl := client.NewWSClient(unixAddr, websocketEndpoint)
  235. _, err := cl.Start()
  236. if err != nil {
  237. t.Fatal(err)
  238. }
  239. defer cl.Stop()
  240. val := "acbd"
  241. params := map[string]interface{}{
  242. "arg": val,
  243. }
  244. err = cl.WriteJSON(types.RPCRequest{
  245. JSONRPC: "2.0",
  246. ID: "",
  247. Method: "status_ws",
  248. Params: params,
  249. })
  250. if err != nil {
  251. t.Fatal(err)
  252. }
  253. select {
  254. case msg := <-cl.ResultsCh:
  255. result := new(Result)
  256. wire.ReadJSONPtr(result, msg, &err)
  257. if err != nil {
  258. t.Fatal(err)
  259. }
  260. got := (*result).(*ResultStatus).Value
  261. if got != val {
  262. t.Fatalf("Got: %v .... Expected: %v \n", got, val)
  263. }
  264. case err := <-cl.ErrorsCh:
  265. t.Fatal(err)
  266. }
  267. }