2009-07-13 12:58:14 -07:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package rpc
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"http";
|
|
|
|
|
"log";
|
|
|
|
|
"net";
|
2009-07-14 13:23:14 -07:00
|
|
|
"once";
|
2009-07-13 12:58:14 -07:00
|
|
|
"os";
|
2009-07-14 13:23:14 -07:00
|
|
|
"strings";
|
2009-07-13 12:58:14 -07:00
|
|
|
"testing";
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var serverAddr string
|
2009-07-14 20:47:39 -07:00
|
|
|
var httpServerAddr string
|
2009-07-13 12:58:14 -07:00
|
|
|
|
|
|
|
|
const second = 1e9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Args struct {
|
2009-10-07 11:55:06 -07:00
|
|
|
A, B int;
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Reply struct {
|
2009-10-07 11:55:06 -07:00
|
|
|
C int;
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Arith int
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Add(args *Args, reply *Reply) os.Error {
|
|
|
|
|
reply.C = args.A + args.B;
|
2009-10-07 11:55:06 -07:00
|
|
|
return nil;
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Mul(args *Args, reply *Reply) os.Error {
|
|
|
|
|
reply.C = args.A * args.B;
|
2009-10-07 11:55:06 -07:00
|
|
|
return nil;
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Div(args *Args, reply *Reply) os.Error {
|
|
|
|
|
if args.B == 0 {
|
2009-11-09 12:07:39 -08:00
|
|
|
return os.ErrorString("divide by zero")
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
reply.C = args.A / args.B;
|
2009-10-07 11:55:06 -07:00
|
|
|
return nil;
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Error(args *Args, reply *Reply) os.Error {
|
2009-11-09 12:07:39 -08:00
|
|
|
panicln("ERROR")
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func startServer() {
|
2009-07-27 17:25:41 -07:00
|
|
|
Register(new(Arith));
|
2009-07-14 20:47:39 -07:00
|
|
|
|
2009-07-13 12:58:14 -07:00
|
|
|
l, e := net.Listen("tcp", ":0"); // any available address
|
|
|
|
|
if e != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
log.Exitf("net.Listen tcp :0: %v", e)
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
2009-11-02 18:37:30 -08:00
|
|
|
serverAddr = l.Addr().String();
|
2009-07-13 12:58:14 -07:00
|
|
|
log.Stderr("Test RPC server listening on ", serverAddr);
|
2009-07-27 17:25:41 -07:00
|
|
|
go Accept(l);
|
2009-07-14 20:47:39 -07:00
|
|
|
|
|
|
|
|
HandleHTTP();
|
|
|
|
|
l, e = net.Listen("tcp", ":0"); // any available address
|
|
|
|
|
if e != nil {
|
|
|
|
|
log.Stderrf("net.Listen tcp :0: %v", e);
|
|
|
|
|
os.Exit(1);
|
|
|
|
|
}
|
2009-11-02 18:37:30 -08:00
|
|
|
httpServerAddr = l.Addr().String();
|
2009-07-14 20:47:39 -07:00
|
|
|
log.Stderr("Test HTTP RPC server listening on ", httpServerAddr);
|
|
|
|
|
go http.Serve(l, nil);
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRPC(t *testing.T) {
|
2009-07-14 13:23:14 -07:00
|
|
|
once.Do(startServer);
|
2009-07-13 12:58:14 -07:00
|
|
|
|
2009-07-14 20:47:39 -07:00
|
|
|
client, err := Dial("tcp", serverAddr);
|
2009-07-13 12:58:14 -07:00
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing", err)
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-07-13 16:52:57 -07:00
|
|
|
// Synchronous calls
|
2009-10-07 11:55:06 -07:00
|
|
|
args := &Args{7, 8};
|
2009-07-13 12:58:14 -07:00
|
|
|
reply := new(Reply);
|
2009-07-13 16:52:57 -07:00
|
|
|
err = client.Call("Arith.Add", args, reply);
|
2009-11-09 21:23:52 -08:00
|
|
|
if reply.C != args.A+args.B {
|
|
|
|
|
t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-10-07 11:55:06 -07:00
|
|
|
args = &Args{7, 8};
|
2009-07-13 12:58:14 -07:00
|
|
|
reply = new(Reply);
|
2009-07-13 16:52:57 -07:00
|
|
|
err = client.Call("Arith.Mul", args, reply);
|
2009-11-09 21:23:52 -08:00
|
|
|
if reply.C != args.A*args.B {
|
|
|
|
|
t.Errorf("Mul: expected %d got %d", reply.C, args.A*args.B)
|
2009-07-13 16:52:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Out of order.
|
2009-10-07 11:55:06 -07:00
|
|
|
args = &Args{7, 8};
|
2009-07-13 16:52:57 -07:00
|
|
|
mulReply := new(Reply);
|
2009-07-14 13:23:14 -07:00
|
|
|
mulCall := client.Go("Arith.Mul", args, mulReply, nil);
|
2009-07-13 16:52:57 -07:00
|
|
|
addReply := new(Reply);
|
2009-07-14 13:23:14 -07:00
|
|
|
addCall := client.Go("Arith.Add", args, addReply, nil);
|
2009-07-13 16:52:57 -07:00
|
|
|
|
|
|
|
|
<-addCall.Done;
|
2009-11-09 21:23:52 -08:00
|
|
|
if addReply.C != args.A+args.B {
|
|
|
|
|
t.Errorf("Add: expected %d got %d", addReply.C, args.A+args.B)
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-07-13 16:52:57 -07:00
|
|
|
<-mulCall.Done;
|
2009-11-09 21:23:52 -08:00
|
|
|
if mulReply.C != args.A*args.B {
|
|
|
|
|
t.Errorf("Mul: expected %d got %d", mulReply.C, args.A*args.B)
|
2009-07-13 16:52:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Error test
|
2009-10-07 11:55:06 -07:00
|
|
|
args = &Args{7, 0};
|
2009-07-13 12:58:14 -07:00
|
|
|
reply = new(Reply);
|
2009-07-13 16:52:57 -07:00
|
|
|
err = client.Call("Arith.Div", args, reply);
|
2009-07-13 12:58:14 -07:00
|
|
|
// expect an error: zero divide
|
2009-07-13 16:52:57 -07:00
|
|
|
if err == nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("Div: expected error")
|
2009-07-14 13:23:14 -07:00
|
|
|
} else if err.String() != "divide by zero" {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("Div: expected divide by zero error; got", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-14 20:47:39 -07:00
|
|
|
func TestHTTPRPC(t *testing.T) {
|
|
|
|
|
once.Do(startServer);
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-07-14 20:47:39 -07:00
|
|
|
client, err := DialHTTP("tcp", httpServerAddr);
|
|
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing", err)
|
2009-07-14 20:47:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Synchronous calls
|
2009-10-07 11:55:06 -07:00
|
|
|
args := &Args{7, 8};
|
2009-07-14 20:47:39 -07:00
|
|
|
reply := new(Reply);
|
|
|
|
|
err = client.Call("Arith.Add", args, reply);
|
2009-11-09 21:23:52 -08:00
|
|
|
if reply.C != args.A+args.B {
|
|
|
|
|
t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
|
2009-07-14 20:47:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestCheckUnknownService(t *testing.T) {
|
2009-07-14 13:23:14 -07:00
|
|
|
once.Do(startServer);
|
|
|
|
|
|
|
|
|
|
conn, err := net.Dial("tcp", "", serverAddr);
|
|
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing:", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client := NewClient(conn);
|
|
|
|
|
|
2009-10-07 11:55:06 -07:00
|
|
|
args := &Args{7, 8};
|
2009-07-14 13:23:14 -07:00
|
|
|
reply := new(Reply);
|
|
|
|
|
err = client.Call("Unknown.Add", args, reply);
|
|
|
|
|
if err == nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("expected error calling unknown service")
|
2009-07-14 13:23:14 -07:00
|
|
|
} else if strings.Index(err.String(), "service") < 0 {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("expected error about service; got", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestCheckUnknownMethod(t *testing.T) {
|
|
|
|
|
once.Do(startServer);
|
|
|
|
|
|
|
|
|
|
conn, err := net.Dial("tcp", "", serverAddr);
|
|
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing:", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client := NewClient(conn);
|
|
|
|
|
|
2009-10-07 11:55:06 -07:00
|
|
|
args := &Args{7, 8};
|
2009-07-14 13:23:14 -07:00
|
|
|
reply := new(Reply);
|
|
|
|
|
err = client.Call("Arith.Unknown", args, reply);
|
|
|
|
|
if err == nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("expected error calling unknown service")
|
2009-07-14 13:23:14 -07:00
|
|
|
} else if strings.Index(err.String(), "method") < 0 {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("expected error about method; got", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestCheckBadType(t *testing.T) {
|
|
|
|
|
once.Do(startServer);
|
|
|
|
|
|
|
|
|
|
conn, err := net.Dial("tcp", "", serverAddr);
|
|
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing:", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client := NewClient(conn);
|
|
|
|
|
|
|
|
|
|
reply := new(Reply);
|
|
|
|
|
err = client.Call("Arith.Add", reply, reply); // args, reply would be the correct thing to use
|
|
|
|
|
if err == nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("expected error calling Arith.Add with wrong arg type")
|
2009-07-14 13:23:14 -07:00
|
|
|
} else if strings.Index(err.String(), "type") < 0 {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Error("expected error about type; got", err)
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
}
|