diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2019-02-04 20:47:34 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-04 20:47:34 +0800 |
commit | 245f3146c26698193c4b479e7bc5825b058c444a (patch) | |
tree | c1196f7579e99e89e3e38cd2c7e442ef49a95731 /rpc/testdata | |
parent | ec3432bccbb058567c0ea3f1e6537460f1f0aa29 (diff) | |
download | go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.tar go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.tar.gz go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.tar.bz2 go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.tar.lz go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.tar.xz go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.tar.zst go-tangerine-245f3146c26698193c4b479e7bc5825b058c444a.zip |
rpc: implement full bi-directional communication (#18471)
New APIs added:
client.RegisterName(namespace, service) // makes service available to server
client.Notify(ctx, method, args...) // sends a notification
ClientFromContext(ctx) // to get a client in handler method
This is essentially a rewrite of the server-side code. JSON-RPC
processing code is now the same on both server and client side. Many
minor issues were fixed in the process and there is a new test suite for
JSON-RPC spec compliance (and non-compliance in some cases).
List of behavior changes:
- Method handlers are now called with a per-request context instead of a
per-connection context. The context is canceled right after the method
returns.
- Subscription error channels are always closed when the connection
ends. There is no need to also wait on the Notifier's Closed channel
to detect whether the subscription has ended.
- Client now omits "params" instead of sending "params": null when there
are no arguments to a call. The previous behavior was not compliant
with the spec. The server still accepts "params": null.
- Floating point numbers are allowed as "id". The spec doesn't allow
them, but we handle request "id" as json.RawMessage and guarantee that
the same number will be sent back.
- Logging is improved significantly. There is now a message at DEBUG
level for each RPC call served.
Diffstat (limited to 'rpc/testdata')
-rw-r--r-- | rpc/testdata/invalid-badid.js | 7 | ||||
-rw-r--r-- | rpc/testdata/invalid-batch.js | 14 | ||||
-rw-r--r-- | rpc/testdata/invalid-idonly.js | 7 | ||||
-rw-r--r-- | rpc/testdata/invalid-nonobj.js | 4 | ||||
-rw-r--r-- | rpc/testdata/invalid-syntax.json | 5 | ||||
-rw-r--r-- | rpc/testdata/reqresp-batch.js | 8 | ||||
-rw-r--r-- | rpc/testdata/reqresp-echo.js | 16 | ||||
-rw-r--r-- | rpc/testdata/reqresp-namedparam.js | 5 | ||||
-rw-r--r-- | rpc/testdata/reqresp-noargsrets.js | 4 | ||||
-rw-r--r-- | rpc/testdata/reqresp-nomethod.js | 4 | ||||
-rw-r--r-- | rpc/testdata/reqresp-noparam.js | 4 | ||||
-rw-r--r-- | rpc/testdata/reqresp-paramsnull.js | 4 | ||||
-rw-r--r-- | rpc/testdata/revcall.js | 6 | ||||
-rw-r--r-- | rpc/testdata/revcall2.js | 7 | ||||
-rw-r--r-- | rpc/testdata/subscription.js | 12 |
15 files changed, 107 insertions, 0 deletions
diff --git a/rpc/testdata/invalid-badid.js b/rpc/testdata/invalid-badid.js new file mode 100644 index 000000000..2202b8ccd --- /dev/null +++ b/rpc/testdata/invalid-badid.js @@ -0,0 +1,7 @@ +// This test checks processing of messages with invalid ID. + +--> {"id":[],"method":"test_foo"} +<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}} + +--> {"id":{},"method":"test_foo"} +<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}} diff --git a/rpc/testdata/invalid-batch.js b/rpc/testdata/invalid-batch.js new file mode 100644 index 000000000..f470574fb --- /dev/null +++ b/rpc/testdata/invalid-batch.js @@ -0,0 +1,14 @@ +// This test checks the behavior of batches with invalid elements. +// Empty batches are not allowed. Batches may contain junk. + +--> [] +<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"empty batch"}} + +--> [1] +<-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}] + +--> [1,2,3] +<-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}] + +--> [{"jsonrpc":"2.0","id":1,"method":"test_echo","params":["foo",1]},55,{"jsonrpc":"2.0","id":2,"method":"unknown_method"},{"foo":"bar"}] +<-- [{"jsonrpc":"2.0","id":1,"result":{"String":"foo","Int":1,"Args":null}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"the method unknown_method does not exist/is not available"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}] diff --git a/rpc/testdata/invalid-idonly.js b/rpc/testdata/invalid-idonly.js new file mode 100644 index 000000000..79997bee3 --- /dev/null +++ b/rpc/testdata/invalid-idonly.js @@ -0,0 +1,7 @@ +// This test checks processing of messages that contain just the ID and nothing else. + +--> {"id":1} +<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}} + +--> {"jsonrpc":"2.0","id":1} +<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}} diff --git a/rpc/testdata/invalid-nonobj.js b/rpc/testdata/invalid-nonobj.js new file mode 100644 index 000000000..4b9f4d994 --- /dev/null +++ b/rpc/testdata/invalid-nonobj.js @@ -0,0 +1,4 @@ +// This test checks behavior for invalid requests. + +--> 1 +<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}} diff --git a/rpc/testdata/invalid-syntax.json b/rpc/testdata/invalid-syntax.json new file mode 100644 index 000000000..b19429960 --- /dev/null +++ b/rpc/testdata/invalid-syntax.json @@ -0,0 +1,5 @@ +// This test checks that an error is written for invalid JSON requests. + +--> 'f +<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32700,"message":"invalid character '\\'' looking for beginning of value"}} + diff --git a/rpc/testdata/reqresp-batch.js b/rpc/testdata/reqresp-batch.js new file mode 100644 index 000000000..977af7663 --- /dev/null +++ b/rpc/testdata/reqresp-batch.js @@ -0,0 +1,8 @@ +// There is no response for all-notification batches. + +--> [{"jsonrpc":"2.0","method":"test_echo","params":["x",99]}] + +// This test checks regular batch calls. + +--> [{"jsonrpc":"2.0","id":2,"method":"test_echo","params":[]}, {"jsonrpc":"2.0","id": 3,"method":"test_echo","params":["x",3]}] +<-- [{"jsonrpc":"2.0","id":2,"error":{"code":-32602,"message":"missing value for required argument 0"}},{"jsonrpc":"2.0","id":3,"result":{"String":"x","Int":3,"Args":null}}] diff --git a/rpc/testdata/reqresp-echo.js b/rpc/testdata/reqresp-echo.js new file mode 100644 index 000000000..7a9e90321 --- /dev/null +++ b/rpc/testdata/reqresp-echo.js @@ -0,0 +1,16 @@ +// This test calls the test_echo method. + +--> {"jsonrpc": "2.0", "id": 2, "method": "test_echo", "params": []} +<-- {"jsonrpc":"2.0","id":2,"error":{"code":-32602,"message":"missing value for required argument 0"}} + +--> {"jsonrpc": "2.0", "id": 2, "method": "test_echo", "params": ["x"]} +<-- {"jsonrpc":"2.0","id":2,"error":{"code":-32602,"message":"missing value for required argument 1"}} + +--> {"jsonrpc": "2.0", "id": 2, "method": "test_echo", "params": ["x", 3]} +<-- {"jsonrpc":"2.0","id":2,"result":{"String":"x","Int":3,"Args":null}} + +--> {"jsonrpc": "2.0", "id": 2, "method": "test_echo", "params": ["x", 3, {"S": "foo"}]} +<-- {"jsonrpc":"2.0","id":2,"result":{"String":"x","Int":3,"Args":{"S":"foo"}}} + +--> {"jsonrpc": "2.0", "id": 2, "method": "test_echoWithCtx", "params": ["x", 3, {"S": "foo"}]} +<-- {"jsonrpc":"2.0","id":2,"result":{"String":"x","Int":3,"Args":{"S":"foo"}}} diff --git a/rpc/testdata/reqresp-namedparam.js b/rpc/testdata/reqresp-namedparam.js new file mode 100644 index 000000000..9a9372b0a --- /dev/null +++ b/rpc/testdata/reqresp-namedparam.js @@ -0,0 +1,5 @@ +// This test checks that an error response is sent for calls +// with named parameters. + +--> {"jsonrpc":"2.0","method":"test_echo","params":{"int":23},"id":3} +<-- {"jsonrpc":"2.0","id":3,"error":{"code":-32602,"message":"non-array args"}} diff --git a/rpc/testdata/reqresp-noargsrets.js b/rpc/testdata/reqresp-noargsrets.js new file mode 100644 index 000000000..e61cc708b --- /dev/null +++ b/rpc/testdata/reqresp-noargsrets.js @@ -0,0 +1,4 @@ +// This test calls the test_noArgsRets method. + +--> {"jsonrpc": "2.0", "id": "foo", "method": "test_noArgsRets", "params": []} +<-- {"jsonrpc":"2.0","id":"foo","result":null} diff --git a/rpc/testdata/reqresp-nomethod.js b/rpc/testdata/reqresp-nomethod.js new file mode 100644 index 000000000..58ea6f307 --- /dev/null +++ b/rpc/testdata/reqresp-nomethod.js @@ -0,0 +1,4 @@ +// This test calls a method that doesn't exist. + +--> {"jsonrpc": "2.0", "id": 2, "method": "invalid_method", "params": [2, 3]} +<-- {"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"the method invalid_method does not exist/is not available"}} diff --git a/rpc/testdata/reqresp-noparam.js b/rpc/testdata/reqresp-noparam.js new file mode 100644 index 000000000..2edf486d9 --- /dev/null +++ b/rpc/testdata/reqresp-noparam.js @@ -0,0 +1,4 @@ +// This test checks that calls with no parameters work. + +--> {"jsonrpc":"2.0","method":"test_noArgsRets","id":3} +<-- {"jsonrpc":"2.0","id":3,"result":null} diff --git a/rpc/testdata/reqresp-paramsnull.js b/rpc/testdata/reqresp-paramsnull.js new file mode 100644 index 000000000..8a01bae1b --- /dev/null +++ b/rpc/testdata/reqresp-paramsnull.js @@ -0,0 +1,4 @@ +// This test checks that calls with "params":null work. + +--> {"jsonrpc":"2.0","method":"test_noArgsRets","params":null,"id":3} +<-- {"jsonrpc":"2.0","id":3,"result":null} diff --git a/rpc/testdata/revcall.js b/rpc/testdata/revcall.js new file mode 100644 index 000000000..695d9858f --- /dev/null +++ b/rpc/testdata/revcall.js @@ -0,0 +1,6 @@ +// This test checks reverse calls. + +--> {"jsonrpc":"2.0","id":2,"method":"test_callMeBack","params":["foo",[1]]} +<-- {"jsonrpc":"2.0","id":1,"method":"foo","params":[1]} +--> {"jsonrpc":"2.0","id":1,"result":"my result"} +<-- {"jsonrpc":"2.0","id":2,"result":"my result"} diff --git a/rpc/testdata/revcall2.js b/rpc/testdata/revcall2.js new file mode 100644 index 000000000..acab46551 --- /dev/null +++ b/rpc/testdata/revcall2.js @@ -0,0 +1,7 @@ +// This test checks reverse calls. + +--> {"jsonrpc":"2.0","id":2,"method":"test_callMeBackLater","params":["foo",[1]]} +<-- {"jsonrpc":"2.0","id":2,"result":null} +<-- {"jsonrpc":"2.0","id":1,"method":"foo","params":[1]} +--> {"jsonrpc":"2.0","id":1,"result":"my result"} + diff --git a/rpc/testdata/subscription.js b/rpc/testdata/subscription.js new file mode 100644 index 000000000..9f1007301 --- /dev/null +++ b/rpc/testdata/subscription.js @@ -0,0 +1,12 @@ +// This test checks basic subscription support. + +--> {"jsonrpc":"2.0","id":1,"method":"nftest_subscribe","params":["someSubscription",5,1]} +<-- {"jsonrpc":"2.0","id":1,"result":"0x1"} +<-- {"jsonrpc":"2.0","method":"nftest_subscription","params":{"subscription":"0x1","result":1}} +<-- {"jsonrpc":"2.0","method":"nftest_subscription","params":{"subscription":"0x1","result":2}} +<-- {"jsonrpc":"2.0","method":"nftest_subscription","params":{"subscription":"0x1","result":3}} +<-- {"jsonrpc":"2.0","method":"nftest_subscription","params":{"subscription":"0x1","result":4}} +<-- {"jsonrpc":"2.0","method":"nftest_subscription","params":{"subscription":"0x1","result":5}} + +--> {"jsonrpc":"2.0","id":2,"method":"nftest_echo","params":[11]} +<-- {"jsonrpc":"2.0","id":2,"result":11} |