From a8b77359dfb9c630291279ecb03c198d26e6012e Mon Sep 17 00:00:00 2001 From: Emmanuel Odeke Date: Sat, 28 Oct 2017 15:24:35 -0700 Subject: [PATCH] rpc/lib/server: separate out Notifications test Addressing feedback from @ebuchman --- rpc/lib/server/handlers_test.go | 62 ++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/rpc/lib/server/handlers_test.go b/rpc/lib/server/handlers_test.go index 16467558b..2260f73d3 100644 --- a/rpc/lib/server/handlers_test.go +++ b/rpc/lib/server/handlers_test.go @@ -10,16 +10,14 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" rs "github.com/tendermint/tendermint/rpc/lib/server" types "github.com/tendermint/tendermint/rpc/lib/types" "github.com/tendermint/tmlibs/log" ) -// Ensure that nefarious/unintended inputs to `params` -// do not crash our RPC handlers. -// See Issue https://github.com/tendermint/tendermint/issues/708. -func TestRPCParams(t *testing.T) { +func testMux() *http.ServeMux { funcMap := map[string]*rs.RPCFunc{ "c": rs.NewRPCFunc(func(s string, i int) (string, error) { return "foo", nil }, "s,i"), } @@ -28,25 +26,31 @@ func TestRPCParams(t *testing.T) { logger := log.NewTMLogger(buf) rs.RegisterRPCFuncs(mux, funcMap, logger) + return mux +} + +func statusOK(code int) bool { return code >= 200 && code <= 299 } + +// Ensure that nefarious/unintended inputs to `params` +// do not crash our RPC handlers. +// See Issue https://github.com/tendermint/tendermint/issues/708. +func TestRPCParams(t *testing.T) { + mux := testMux() tests := []struct { - payload string - wantErr string - notification bool + payload string + wantErr string }{ - {`{"jsonrpc": "2.0"}`, "", true}, // The server SHOULD NOT respond to a notification according to JSONRPC Section 4.1. - {`{"jsonrpc": "2.0", "id": "0"}`, "Method not found", false}, - {`{"jsonrpc": "2.0", "method": "y", "id": "0"}`, "Method not found", false}, - {`{"jsonrpc": "2.0", "method": "c", "id": "0", "params": null}`, "", false}, - {`{"method": "c", "id": "0", "params": {}}`, "", false}, - {`{"method": "c", "id": "0", "params": a}`, "invalid character", false}, - {`{"method": "c", "id": "0", "params": ["a", 10]}`, "", false}, - {`{"method": "c", "id": "0", "params": ["a"]}`, "got 1", false}, - {`{"method": "c", "id": "0", "params": ["a", "b"]}`, "of type int", false}, - {`{"method": "c", "id": "0", "params": [1, 1]}`, "of type string", false}, + {`{"jsonrpc": "2.0", "id": "0"}`, "Method not found"}, + {`{"jsonrpc": "2.0", "method": "y", "id": "0"}`, "Method not found"}, + {`{"jsonrpc": "2.0", "method": "c", "id": "0", "params": null}`, ""}, + {`{"method": "c", "id": "0", "params": {}}`, ""}, + {`{"method": "c", "id": "0", "params": a}`, "invalid character"}, + {`{"method": "c", "id": "0", "params": ["a", 10]}`, ""}, + {`{"method": "c", "id": "0", "params": ["a"]}`, "got 1"}, + {`{"method": "c", "id": "0", "params": ["a", "b"]}`, "of type int"}, + {`{"method": "c", "id": "0", "params": [1, 1]}`, "of type string"}, } - statusOK := func(code int) bool { return code >= 200 && code <= 299 } - for i, tt := range tests { req, _ := http.NewRequest("POST", "http://localhost/", strings.NewReader(tt.payload)) rec := httptest.NewRecorder() @@ -60,11 +64,6 @@ func TestRPCParams(t *testing.T) { continue } - if tt.notification { - assert.Equal(t, len(blob), 0, "#%d: a notification SHOULD NOT be responded to by the server", i) - continue - } - recv := new(types.RPCResponse) assert.Nil(t, json.Unmarshal(blob, recv), "#%d: expecting successful parsing of an RPCResponse:\nblob: %s", i, blob) assert.NotEqual(t, recv, new(types.RPCResponse), "#%d: not expecting a blank RPCResponse", i) @@ -78,3 +77,18 @@ func TestRPCParams(t *testing.T) { } } } + +func TestRPCNotification(t *testing.T) { + mux := testMux() + body := strings.NewReader(`{"jsonrpc": "2.0"}`) + req, _ := http.NewRequest("POST", "http://localhost/", body) + rec := httptest.NewRecorder() + mux.ServeHTTP(rec, req) + res := rec.Result() + + // Always expecting back a JSONRPCResponse + require.True(t, statusOK(res.StatusCode), "should always return 2XX") + blob, err := ioutil.ReadAll(res.Body) + require.Nil(t, err, "reading from the body should not give back an error") + require.Equal(t, len(blob), 0, "a notification SHOULD NOT be responded to by the server") +}