diff options
Diffstat (limited to 'libgo/go/rpc/server_test.go')
-rw-r--r-- | libgo/go/rpc/server_test.go | 91 |
1 files changed, 87 insertions, 4 deletions
diff --git a/libgo/go/rpc/server_test.go b/libgo/go/rpc/server_test.go index cfff0c9..e7bbfbe 100644 --- a/libgo/go/rpc/server_test.go +++ b/libgo/go/rpc/server_test.go @@ -7,6 +7,7 @@ package rpc import ( "fmt" "http/httptest" + "io" "log" "net" "os" @@ -18,6 +19,7 @@ import ( ) var ( + newServer *Server serverAddr, newServerAddr string httpServerAddr string once, newOnce, httpOnce sync.Once @@ -52,7 +54,7 @@ func (t *Arith) Mul(args *Args, reply *Reply) os.Error { func (t *Arith) Div(args Args, reply *Reply) os.Error { if args.B == 0 { - return os.ErrorString("divide by zero") + return os.NewError("divide by zero") } reply.C = args.A / args.B return nil @@ -93,15 +95,15 @@ func startServer() { } func startNewServer() { - s := NewServer() - s.Register(new(Arith)) + newServer = NewServer() + newServer.Register(new(Arith)) var l net.Listener l, newServerAddr = listenTCP() log.Println("NewServer test RPC server listening on", newServerAddr) go Accept(l) - s.HandleHTTP(newHttpPath, "/bar") + newServer.HandleHTTP(newHttpPath, "/bar") httpOnce.Do(startHttpServer) } @@ -264,6 +266,85 @@ func testHTTPRPC(t *testing.T, path string) { } } +// CodecEmulator provides a client-like api and a ServerCodec interface. +// Can be used to test ServeRequest. +type CodecEmulator struct { + server *Server + serviceMethod string + args *Args + reply *Reply + err os.Error +} + +func (codec *CodecEmulator) Call(serviceMethod string, args *Args, reply *Reply) os.Error { + codec.serviceMethod = serviceMethod + codec.args = args + codec.reply = reply + codec.err = nil + var serverError os.Error + if codec.server == nil { + serverError = ServeRequest(codec) + } else { + serverError = codec.server.ServeRequest(codec) + } + if codec.err == nil && serverError != nil { + codec.err = serverError + } + return codec.err +} + +func (codec *CodecEmulator) ReadRequestHeader(req *Request) os.Error { + req.ServiceMethod = codec.serviceMethod + req.Seq = 0 + return nil +} + +func (codec *CodecEmulator) ReadRequestBody(argv interface{}) os.Error { + if codec.args == nil { + return io.ErrUnexpectedEOF + } + *(argv.(*Args)) = *codec.args + return nil +} + +func (codec *CodecEmulator) WriteResponse(resp *Response, reply interface{}) os.Error { + if resp.Error != "" { + codec.err = os.NewError(resp.Error) + } + *codec.reply = *(reply.(*Reply)) + return nil +} + +func (codec *CodecEmulator) Close() os.Error { + return nil +} + +func TestServeRequest(t *testing.T) { + once.Do(startServer) + testServeRequest(t, nil) + newOnce.Do(startNewServer) + testServeRequest(t, newServer) +} + +func testServeRequest(t *testing.T, server *Server) { + client := CodecEmulator{server: server} + + args := &Args{7, 8} + reply := new(Reply) + err := client.Call("Arith.Add", args, reply) + if err != nil { + t.Errorf("Add: expected no error but got string %q", err.String()) + } + if reply.C != args.A+args.B { + t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B) + } + + err = client.Call("Arith.Add", nil, reply) + if err == nil { + t.Errorf("expected error calling Arith.Add with nil arg") + } +} + type ReplyNotPointer int type ArgNotPublic int type ReplyNotPublic int @@ -360,6 +441,7 @@ func countMallocs(dial func() (*Client, os.Error), t *testing.T) uint64 { } args := &Args{7, 8} reply := new(Reply) + runtime.UpdateMemStats() mallocs := 0 - runtime.MemStats.Mallocs const count = 100 for i := 0; i < count; i++ { @@ -371,6 +453,7 @@ func countMallocs(dial func() (*Client, os.Error), t *testing.T) uint64 { t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B) } } + runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs return mallocs / count } |