aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/rpc/server_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/rpc/server_test.go')
-rw-r--r--libgo/go/rpc/server_test.go91
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
}