rpc/server: use httptest.Server for testing

Which allows to reuse it for websockets.
This commit is contained in:
Roman Khimov 2020-04-29 15:14:56 +03:00
parent 1b523be4b6
commit d275652b37
2 changed files with 23 additions and 22 deletions

View file

@ -2,6 +2,7 @@ package server
import ( import (
"net/http" "net/http"
"net/http/httptest"
"os" "os"
"testing" "testing"
@ -17,7 +18,7 @@ import (
"go.uber.org/zap/zaptest" "go.uber.org/zap/zaptest"
) )
func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, http.HandlerFunc) { func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *httptest.Server) {
var nBlocks uint32 var nBlocks uint32
net := config.ModeUnitTestNet net := config.ModeUnitTestNet
@ -55,9 +56,11 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, http.HandlerFu
server, err := network.NewServer(serverConfig, chain, logger) server, err := network.NewServer(serverConfig, chain, logger)
require.NoError(t, err) require.NoError(t, err)
rpcServer := New(chain, cfg.ApplicationConfiguration.RPC, server, logger) rpcServer := New(chain, cfg.ApplicationConfiguration.RPC, server, logger)
handler := http.HandlerFunc(rpcServer.handleHTTPRequest)
return chain, handler handler := http.HandlerFunc(rpcServer.handleHTTPRequest)
srv := httptest.NewServer(handler)
return chain, srv
} }
type FeerStub struct{} type FeerStub struct{}

View file

@ -32,7 +32,7 @@ import (
type executor struct { type executor struct {
chain *core.Blockchain chain *core.Blockchain
handler http.HandlerFunc httpSrv *httptest.Server
} }
const ( const (
@ -814,18 +814,18 @@ var rpcTestCases = map[string][]rpcTestCase{
} }
func TestRPC(t *testing.T) { func TestRPC(t *testing.T) {
chain, handler := initServerWithInMemoryChain(t) chain, httpSrv := initServerWithInMemoryChain(t)
defer chain.Close() defer chain.Close()
e := &executor{chain: chain, handler: handler} e := &executor{chain: chain, httpSrv: httpSrv}
for method, cases := range rpcTestCases { for method, cases := range rpcTestCases {
t.Run(method, func(t *testing.T) { t.Run(method, func(t *testing.T) {
rpc := `{"jsonrpc": "2.0", "id": 1, "method": "%s", "params": %s}` rpc := `{"jsonrpc": "2.0", "id": 1, "method": "%s", "params": %s}`
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
body := doRPCCall(fmt.Sprintf(rpc, method, tc.params), handler, t) body := doRPCCall(fmt.Sprintf(rpc, method, tc.params), httpSrv.URL, t)
result := checkErrGetResult(t, body, tc.fail) result := checkErrGetResult(t, body, tc.fail)
if tc.fail { if tc.fail {
return return
@ -849,7 +849,7 @@ func TestRPC(t *testing.T) {
rpc := `{"jsonrpc": "2.0", "id": 1, "method": "submitblock", "params": ["%s"]}` rpc := `{"jsonrpc": "2.0", "id": 1, "method": "submitblock", "params": ["%s"]}`
t.Run("empty", func(t *testing.T) { t.Run("empty", func(t *testing.T) {
s := newBlock(t, chain, 1) s := newBlock(t, chain, 1)
body := doRPCCall(fmt.Sprintf(rpc, s), handler, t) body := doRPCCall(fmt.Sprintf(rpc, s), httpSrv.URL, t)
checkErrGetResult(t, body, true) checkErrGetResult(t, body, true)
}) })
@ -867,13 +867,13 @@ func TestRPC(t *testing.T) {
t.Run("invalid height", func(t *testing.T) { t.Run("invalid height", func(t *testing.T) {
b := newBlock(t, chain, 2, newTx()) b := newBlock(t, chain, 2, newTx())
body := doRPCCall(fmt.Sprintf(rpc, encodeBlock(t, b)), handler, t) body := doRPCCall(fmt.Sprintf(rpc, encodeBlock(t, b)), httpSrv.URL, t)
checkErrGetResult(t, body, true) checkErrGetResult(t, body, true)
}) })
t.Run("positive", func(t *testing.T) { t.Run("positive", func(t *testing.T) {
b := newBlock(t, chain, 1, newTx()) b := newBlock(t, chain, 1, newTx())
body := doRPCCall(fmt.Sprintf(rpc, encodeBlock(t, b)), handler, t) body := doRPCCall(fmt.Sprintf(rpc, encodeBlock(t, b)), httpSrv.URL, t)
data := checkErrGetResult(t, body, false) data := checkErrGetResult(t, body, false)
var res bool var res bool
require.NoError(t, json.Unmarshal(data, &res)) require.NoError(t, json.Unmarshal(data, &res))
@ -885,7 +885,7 @@ func TestRPC(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[1].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s"]}"`, TXHash.StringLE()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s"]}"`, TXHash.StringLE())
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, httpSrv.URL, t)
result := checkErrGetResult(t, body, false) result := checkErrGetResult(t, body, false)
var res string var res string
err := json.Unmarshal(result, &res) err := json.Unmarshal(result, &res)
@ -897,7 +897,7 @@ func TestRPC(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[1].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 0]}"`, TXHash.StringLE()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 0]}"`, TXHash.StringLE())
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, httpSrv.URL, t)
result := checkErrGetResult(t, body, false) result := checkErrGetResult(t, body, false)
var res string var res string
err := json.Unmarshal(result, &res) err := json.Unmarshal(result, &res)
@ -909,7 +909,7 @@ func TestRPC(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[1].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, httpSrv.URL, t)
txOut := checkErrGetResult(t, body, false) txOut := checkErrGetResult(t, body, false)
actual := result.TransactionOutputRaw{} actual := result.TransactionOutputRaw{}
err := json.Unmarshal(txOut, &actual) err := json.Unmarshal(txOut, &actual)
@ -936,7 +936,7 @@ func TestRPC(t *testing.T) {
hdr := e.getHeader(testHeaderHash) hdr := e.getHeader(testHeaderHash)
runCase := func(t *testing.T, rpc string, expected, actual interface{}) { runCase := func(t *testing.T, rpc string, expected, actual interface{}) {
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, httpSrv.URL, t)
data := checkErrGetResult(t, body, false) data := checkErrGetResult(t, body, false)
require.NoError(t, json.Unmarshal(data, actual)) require.NoError(t, json.Unmarshal(data, actual))
require.Equal(t, expected, actual) require.Equal(t, expected, actual)
@ -984,7 +984,7 @@ func TestRPC(t *testing.T) {
tx := block.Transactions[3] tx := block.Transactions[3]
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "gettxout", "params": [%s, %d]}"`, rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "gettxout", "params": [%s, %d]}"`,
`"`+tx.Hash().StringLE()+`"`, 0) `"`+tx.Hash().StringLE()+`"`, 0)
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, httpSrv.URL, t)
res := checkErrGetResult(t, body, false) res := checkErrGetResult(t, body, false)
var txOut result.TransactionOutput var txOut result.TransactionOutput
@ -1010,7 +1010,7 @@ func TestRPC(t *testing.T) {
} }
rpc := `{"jsonrpc": "2.0", "id": 1, "method": "getrawmempool", "params": []}` rpc := `{"jsonrpc": "2.0", "id": 1, "method": "getrawmempool", "params": []}`
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, httpSrv.URL, t)
res := checkErrGetResult(t, body, false) res := checkErrGetResult(t, body, false)
var actual []util.Uint256 var actual []util.Uint256
@ -1082,12 +1082,10 @@ func checkErrGetResult(t *testing.T, body []byte, expectingFail bool) json.RawMe
return resp.Result return resp.Result
} }
func doRPCCall(rpcCall string, handler http.HandlerFunc, t *testing.T) []byte { func doRPCCall(rpcCall string, url string, t *testing.T) []byte {
req := httptest.NewRequest("POST", "http://0.0.0.0:20333/", strings.NewReader(rpcCall)) cl := http.Client{Timeout: time.Second}
req.Header.Set("Content-Type", "application/json") resp, err := cl.Post(url, "application/json", strings.NewReader(rpcCall))
w := httptest.NewRecorder() require.NoErrorf(t, err, "could not make a POST request")
handler(w, req)
resp := w.Result()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
assert.NoErrorf(t, err, "could not read response from the request: %s", rpcCall) assert.NoErrorf(t, err, "could not read response from the request: %s", rpcCall)
return bytes.TrimSpace(body) return bytes.TrimSpace(body)