aboutsummaryrefslogtreecommitdiffstats
path: root/rpc/server_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'rpc/server_test.go')
-rw-r--r--rpc/server_test.go198
1 files changed, 39 insertions, 159 deletions
diff --git a/rpc/server_test.go b/rpc/server_test.go
index c60db38df..de47e1afd 100644
--- a/rpc/server_test.go
+++ b/rpc/server_test.go
@@ -18,10 +18,9 @@ package rpc
import (
"encoding/json"
- "fmt"
+ "net"
"reflect"
"testing"
- "time"
"golang.org/x/net/context"
)
@@ -69,10 +68,6 @@ func (s *Service) Subscription(ctx context.Context) (Subscription, error) {
return nil, nil
}
-func (s *Service) SubsriptionWithArgs(ctx context.Context, a, b int) (Subscription, error) {
- return nil, nil
-}
-
func TestServerRegisterName(t *testing.T) {
server := NewServer()
service := new(Service)
@@ -94,182 +89,67 @@ func TestServerRegisterName(t *testing.T) {
t.Errorf("Expected 4 callbacks for service 'calc', got %d", len(svc.callbacks))
}
- if len(svc.subscriptions) != 2 {
- t.Errorf("Expected 2 subscriptions for service 'calc', got %d", len(svc.subscriptions))
+ if len(svc.subscriptions) != 1 {
+ t.Errorf("Expected 1 subscription for service 'calc', got %d", len(svc.subscriptions))
}
}
-// dummy codec used for testing RPC method execution
-type ServerTestCodec struct {
- counter int
- input []byte
- output string
- closer chan interface{}
-}
-
-func (c *ServerTestCodec) ReadRequestHeaders() ([]rpcRequest, bool, RPCError) {
- c.counter += 1
+func testServerMethodExecution(t *testing.T, method string) {
+ server := NewServer()
+ service := new(Service)
- if c.counter == 1 {
- var req JSONRequest
- json.Unmarshal(c.input, &req)
- return []rpcRequest{rpcRequest{id: *req.Id, isPubSub: false, service: "test", method: req.Method, params: req.Payload}}, false, nil
+ if err := server.RegisterName("test", service); err != nil {
+ t.Fatalf("%v", err)
}
- // requests are executes in parallel, wait a bit before returning an error so that the previous request has time to
- // be executed
- timer := time.NewTimer(time.Duration(2) * time.Second)
- <-timer.C
+ stringArg := "string arg"
+ intArg := 1122
+ argsArg := &Args{"abcde"}
+ params := []interface{}{stringArg, intArg, argsArg}
- return nil, false, &invalidRequestError{"connection closed"}
-}
+ request := map[string]interface{}{
+ "id": 12345,
+ "method": "test_" + method,
+ "version": "2.0",
+ "params": params,
+ }
-func (c *ServerTestCodec) ParseRequestArguments(argTypes []reflect.Type, payload interface{}) ([]reflect.Value, RPCError) {
+ clientConn, serverConn := net.Pipe()
+ defer clientConn.Close()
- args, _ := payload.(json.RawMessage)
+ go server.ServeCodec(NewJSONCodec(serverConn), OptionMethodInvocation)
- argValues := make([]reflect.Value, len(argTypes))
- params := make([]interface{}, len(argTypes))
+ out := json.NewEncoder(clientConn)
+ in := json.NewDecoder(clientConn)
- n, err := countArguments(args)
- if err != nil {
- return nil, &invalidParamsError{err.Error()}
+ if err := out.Encode(request); err != nil {
+ t.Fatal(err)
}
- if n != len(argTypes) {
- return nil, &invalidParamsError{fmt.Sprintf("insufficient params, want %d have %d", len(argTypes), n)}
+ response := JSONSuccessResponse{Result: &Result{}}
+ if err := in.Decode(&response); err != nil {
+ t.Fatal(err)
}
- for i, t := range argTypes {
- if t.Kind() == reflect.Ptr {
- // values must be pointers for the Unmarshal method, reflect.
- // Dereference otherwise reflect.New would create **SomeType
- argValues[i] = reflect.New(t.Elem())
- params[i] = argValues[i].Interface()
-
- // when not specified blockNumbers are by default latest (-1)
- if blockNumber, ok := params[i].(*BlockNumber); ok {
- *blockNumber = BlockNumber(-1)
- }
- } else {
- argValues[i] = reflect.New(t)
- params[i] = argValues[i].Interface()
-
- // when not specified blockNumbers are by default latest (-1)
- if blockNumber, ok := params[i].(*BlockNumber); ok {
- *blockNumber = BlockNumber(-1)
- }
+ if result, ok := response.Result.(*Result); ok {
+ if result.String != stringArg {
+ t.Errorf("expected %s, got : %s\n", stringArg, result.String)
}
- }
-
- if err := json.Unmarshal(args, &params); err != nil {
- return nil, &invalidParamsError{err.Error()}
- }
-
- // Convert pointers back to values where necessary
- for i, a := range argValues {
- if a.Kind() != argTypes[i].Kind() {
- argValues[i] = reflect.Indirect(argValues[i])
+ if result.Int != intArg {
+ t.Errorf("expected %d, got %d\n", intArg, result.Int)
}
- }
-
- return argValues, nil
-}
-
-func (c *ServerTestCodec) CreateResponse(id int64, reply interface{}) interface{} {
- return &JSONSuccessResponse{Version: jsonRPCVersion, Id: id, Result: reply}
-}
-
-func (c *ServerTestCodec) CreateErrorResponse(id *int64, err RPCError) interface{} {
- return &JSONErrResponse{Version: jsonRPCVersion, Id: id, Error: JSONError{Code: err.Code(), Message: err.Error()}}
-}
-
-func (c *ServerTestCodec) CreateErrorResponseWithInfo(id *int64, err RPCError, info interface{}) interface{} {
- return &JSONErrResponse{Version: jsonRPCVersion, Id: id,
- Error: JSONError{Code: err.Code(), Message: err.Error(), Data: info}}
-}
-
-func (c *ServerTestCodec) CreateNotification(subid string, event interface{}) interface{} {
- return &jsonNotification{Version: jsonRPCVersion, Method: notificationMethod,
- Params: jsonSubscription{Subscription: subid, Result: event}}
-}
-
-func (c *ServerTestCodec) Write(msg interface{}) error {
- if len(c.output) == 0 { // only capture first response
- if o, err := json.Marshal(msg); err != nil {
- return err
- } else {
- c.output = string(o)
+ if !reflect.DeepEqual(result.Args, argsArg) {
+ t.Errorf("expected %v, got %v\n", argsArg, result)
}
+ } else {
+ t.Fatalf("invalid response: expected *Result - got: %T", response.Result)
}
-
- return nil
-}
-
-func (c *ServerTestCodec) Close() {
- close(c.closer)
-}
-
-func (c *ServerTestCodec) Closed() <-chan interface{} {
- return c.closer
}
func TestServerMethodExecution(t *testing.T) {
- server := NewServer()
- service := new(Service)
-
- if err := server.RegisterName("test", service); err != nil {
- t.Fatalf("%v", err)
- }
-
- id := int64(12345)
- req := JSONRequest{
- Method: "echo",
- Version: "2.0",
- Id: &id,
- }
- args := []interface{}{"string arg", 1122, &Args{"qwerty"}}
- req.Payload, _ = json.Marshal(&args)
-
- input, _ := json.Marshal(&req)
- codec := &ServerTestCodec{input: input, closer: make(chan interface{})}
- go server.ServeCodec(codec, OptionMethodInvocation)
-
- <-codec.closer
-
- expected := `{"jsonrpc":"2.0","id":12345,"result":{"String":"string arg","Int":1122,"Args":{"S":"qwerty"}}}`
-
- if expected != codec.output {
- t.Fatalf("expected %s, got %s\n", expected, codec.output)
- }
+ testServerMethodExecution(t, "echo")
}
func TestServerMethodWithCtx(t *testing.T) {
- server := NewServer()
- service := new(Service)
-
- if err := server.RegisterName("test", service); err != nil {
- t.Fatalf("%v", err)
- }
-
- id := int64(12345)
- req := JSONRequest{
- Method: "echoWithCtx",
- Version: "2.0",
- Id: &id,
- }
- args := []interface{}{"string arg", 1122, &Args{"qwerty"}}
- req.Payload, _ = json.Marshal(&args)
-
- input, _ := json.Marshal(&req)
- codec := &ServerTestCodec{input: input, closer: make(chan interface{})}
- go server.ServeCodec(codec, OptionMethodInvocation)
-
- <-codec.closer
-
- expected := `{"jsonrpc":"2.0","id":12345,"result":{"String":"string arg","Int":1122,"Args":{"S":"qwerty"}}}`
-
- if expected != codec.output {
- t.Fatalf("expected %s, got %s\n", expected, codec.output)
- }
+ testServerMethodExecution(t, "echoWithCtx")
}