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 (
|
2010-06-28 16:05:54 -07:00
|
|
|
"fmt"
|
2009-12-15 15:40:16 -08:00
|
|
|
"http"
|
|
|
|
|
"log"
|
|
|
|
|
"net"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
2010-08-06 06:14:41 +10:00
|
|
|
"sync"
|
2009-12-15 15:40:16 -08:00
|
|
|
"testing"
|
2009-07-13 12:58:14 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var serverAddr string
|
2009-07-14 20:47:39 -07:00
|
|
|
var httpServerAddr string
|
2010-08-06 06:14:41 +10:00
|
|
|
var once sync.Once
|
2009-07-13 12:58:14 -07:00
|
|
|
|
|
|
|
|
const second = 1e9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Args struct {
|
2009-12-15 15:40:16 -08:00
|
|
|
A, B int
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Reply struct {
|
2009-12-15 15:40:16 -08:00
|
|
|
C int
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Arith int
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Add(args *Args, reply *Reply) os.Error {
|
2009-12-15 15:40:16 -08:00
|
|
|
reply.C = args.A + args.B
|
|
|
|
|
return nil
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Mul(args *Args, reply *Reply) os.Error {
|
2009-12-15 15:40:16 -08:00
|
|
|
reply.C = args.A * args.B
|
|
|
|
|
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
|
|
|
}
|
2009-12-15 15:40:16 -08:00
|
|
|
reply.C = args.A / args.B
|
|
|
|
|
return nil
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
2010-06-28 16:05:54 -07:00
|
|
|
func (t *Arith) String(args *Args, reply *string) os.Error {
|
|
|
|
|
*reply = fmt.Sprintf("%d+%d=%d", args.A, args.B, args.A+args.B)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Arith) Scan(args *string, reply *Reply) (err os.Error) {
|
|
|
|
|
_, err = fmt.Sscan(*args, &reply.C)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-13 12:58:14 -07:00
|
|
|
func (t *Arith) Error(args *Args, reply *Reply) os.Error {
|
2010-03-24 16:46:53 -07:00
|
|
|
panic("ERROR")
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func startServer() {
|
2009-12-15 15:40:16 -08:00
|
|
|
Register(new(Arith))
|
2009-07-14 20:47:39 -07:00
|
|
|
|
2010-06-21 13:05:38 -07:00
|
|
|
l, e := net.Listen("tcp", "127.0.0.1:0") // any available address
|
2009-07-13 12:58:14 -07:00
|
|
|
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-12-15 15:40:16 -08:00
|
|
|
serverAddr = l.Addr().String()
|
log: new interface
New logging interface simplifies and generalizes.
1) Loggers now have only one output.
2) log.Stdout, Stderr, Crash and friends are gone.
Logging is now always to standard error by default.
3) log.Panic* replaces log.Crash*.
4) Exiting and panicking are not part of the logger's state; instead
the functions Exit* and Panic* simply call Exit or panic after
printing.
5) There is now one 'standard logger'. Instead of calling Stderr,
use Print etc. There are now triples, by analogy with fmt:
Print, Println, Printf
What was log.Stderr is now best represented by log.Println,
since there are now separate Print and Println functions
(and methods).
6) New functions SetOutput, SetFlags, and SetPrefix allow global
editing of the standard logger's properties. This is new
functionality. For instance, one can call
log.SetFlags(log.Lshortfile|log.Ltime|log.Lmicroseconds)
to get all logging output to show file name, line number, and
time stamp.
In short, for most purposes
log.Stderr -> log.Println or log.Print
log.Stderrf -> log.Printf
log.Crash -> log.Panicln or log.Panic
log.Crashf -> log.Panicf
log.Exit -> log.Exitln or log.Exit
log.Exitf -> log.Exitf (no change)
This has a slight breakage: since loggers now write only to one
output, existing calls to log.New() need to delete the second argument.
Also, custom loggers with exit or panic properties will need to be
reworked.
All package code updated to new interface.
The test has been reworked somewhat.
The old interface will be removed after the new release.
For now, its elements are marked 'deprecated' in their comments.
Fixes #1184.
R=rsc
CC=golang-dev
https://golang.org/cl/2419042
2010-10-12 12:59:18 -07:00
|
|
|
log.Println("Test RPC server listening on", serverAddr)
|
2009-12-15 15:40:16 -08:00
|
|
|
go Accept(l)
|
2009-07-14 20:47:39 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
HandleHTTP()
|
2010-06-21 13:05:38 -07:00
|
|
|
l, e = net.Listen("tcp", "127.0.0.1:0") // any available address
|
2009-07-14 20:47:39 -07:00
|
|
|
if e != nil {
|
log: new interface
New logging interface simplifies and generalizes.
1) Loggers now have only one output.
2) log.Stdout, Stderr, Crash and friends are gone.
Logging is now always to standard error by default.
3) log.Panic* replaces log.Crash*.
4) Exiting and panicking are not part of the logger's state; instead
the functions Exit* and Panic* simply call Exit or panic after
printing.
5) There is now one 'standard logger'. Instead of calling Stderr,
use Print etc. There are now triples, by analogy with fmt:
Print, Println, Printf
What was log.Stderr is now best represented by log.Println,
since there are now separate Print and Println functions
(and methods).
6) New functions SetOutput, SetFlags, and SetPrefix allow global
editing of the standard logger's properties. This is new
functionality. For instance, one can call
log.SetFlags(log.Lshortfile|log.Ltime|log.Lmicroseconds)
to get all logging output to show file name, line number, and
time stamp.
In short, for most purposes
log.Stderr -> log.Println or log.Print
log.Stderrf -> log.Printf
log.Crash -> log.Panicln or log.Panic
log.Crashf -> log.Panicf
log.Exit -> log.Exitln or log.Exit
log.Exitf -> log.Exitf (no change)
This has a slight breakage: since loggers now write only to one
output, existing calls to log.New() need to delete the second argument.
Also, custom loggers with exit or panic properties will need to be
reworked.
All package code updated to new interface.
The test has been reworked somewhat.
The old interface will be removed after the new release.
For now, its elements are marked 'deprecated' in their comments.
Fixes #1184.
R=rsc
CC=golang-dev
https://golang.org/cl/2419042
2010-10-12 12:59:18 -07:00
|
|
|
log.Printf("net.Listen tcp :0: %v", e)
|
2009-12-15 15:40:16 -08:00
|
|
|
os.Exit(1)
|
2009-07-14 20:47:39 -07:00
|
|
|
}
|
2009-12-15 15:40:16 -08:00
|
|
|
httpServerAddr = l.Addr().String()
|
log: new interface
New logging interface simplifies and generalizes.
1) Loggers now have only one output.
2) log.Stdout, Stderr, Crash and friends are gone.
Logging is now always to standard error by default.
3) log.Panic* replaces log.Crash*.
4) Exiting and panicking are not part of the logger's state; instead
the functions Exit* and Panic* simply call Exit or panic after
printing.
5) There is now one 'standard logger'. Instead of calling Stderr,
use Print etc. There are now triples, by analogy with fmt:
Print, Println, Printf
What was log.Stderr is now best represented by log.Println,
since there are now separate Print and Println functions
(and methods).
6) New functions SetOutput, SetFlags, and SetPrefix allow global
editing of the standard logger's properties. This is new
functionality. For instance, one can call
log.SetFlags(log.Lshortfile|log.Ltime|log.Lmicroseconds)
to get all logging output to show file name, line number, and
time stamp.
In short, for most purposes
log.Stderr -> log.Println or log.Print
log.Stderrf -> log.Printf
log.Crash -> log.Panicln or log.Panic
log.Crashf -> log.Panicf
log.Exit -> log.Exitln or log.Exit
log.Exitf -> log.Exitf (no change)
This has a slight breakage: since loggers now write only to one
output, existing calls to log.New() need to delete the second argument.
Also, custom loggers with exit or panic properties will need to be
reworked.
All package code updated to new interface.
The test has been reworked somewhat.
The old interface will be removed after the new release.
For now, its elements are marked 'deprecated' in their comments.
Fixes #1184.
R=rsc
CC=golang-dev
https://golang.org/cl/2419042
2010-10-12 12:59:18 -07:00
|
|
|
log.Println("Test HTTP RPC server listening on", httpServerAddr)
|
2009-12-15 15:40:16 -08:00
|
|
|
go http.Serve(l, nil)
|
2009-07-13 12:58:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestRPC(t *testing.T) {
|
2009-12-15 15:40:16 -08:00
|
|
|
once.Do(startServer)
|
2009-07-13 12:58:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08: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-12-15 15:40:16 -08:00
|
|
|
args := &Args{7, 8}
|
|
|
|
|
reply := new(Reply)
|
|
|
|
|
err = client.Call("Arith.Add", args, reply)
|
2009-11-17 11:29:02 -08:00
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("Add: expected no error but got string %q", err.String())
|
|
|
|
|
}
|
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-12-15 15:40:16 -08:00
|
|
|
args = &Args{7, 8}
|
|
|
|
|
reply = new(Reply)
|
|
|
|
|
err = client.Call("Arith.Mul", args, reply)
|
2009-11-17 11:29:02 -08:00
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("Mul: expected no error but got string %q", err.String())
|
|
|
|
|
}
|
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-12-15 15:40:16 -08:00
|
|
|
args = &Args{7, 8}
|
|
|
|
|
mulReply := new(Reply)
|
|
|
|
|
mulCall := client.Go("Arith.Mul", args, mulReply, nil)
|
|
|
|
|
addReply := new(Reply)
|
|
|
|
|
addCall := client.Go("Arith.Add", args, addReply, nil)
|
2009-07-13 16:52:57 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
addCall = <-addCall.Done
|
2009-11-17 11:29:02 -08:00
|
|
|
if addCall.Error != nil {
|
|
|
|
|
t.Errorf("Add: expected no error but got string %q", addCall.Error.String())
|
|
|
|
|
}
|
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-12-15 15:40:16 -08:00
|
|
|
mulCall = <-mulCall.Done
|
2009-11-17 11:29:02 -08:00
|
|
|
if mulCall.Error != nil {
|
|
|
|
|
t.Errorf("Mul: expected no error but got string %q", mulCall.Error.String())
|
|
|
|
|
}
|
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-12-15 15:40:16 -08:00
|
|
|
args = &Args{7, 0}
|
|
|
|
|
reply = new(Reply)
|
|
|
|
|
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
|
|
|
}
|
2010-06-28 16:05:54 -07:00
|
|
|
|
|
|
|
|
// Non-struct argument
|
|
|
|
|
const Val = 12345
|
|
|
|
|
str := fmt.Sprint(Val)
|
|
|
|
|
reply = new(Reply)
|
|
|
|
|
err = client.Call("Arith.Scan", &str, reply)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("Scan: expected no error but got string %q", err.String())
|
|
|
|
|
} else if reply.C != Val {
|
|
|
|
|
t.Errorf("Scan: expected %d got %d", Val, reply.C)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Non-struct reply
|
|
|
|
|
args = &Args{27, 35}
|
|
|
|
|
str = ""
|
|
|
|
|
err = client.Call("Arith.String", args, &str)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("String: expected no error but got string %q", err.String())
|
|
|
|
|
}
|
|
|
|
|
expect := fmt.Sprintf("%d+%d=%d", args.A, args.B, args.A+args.B)
|
|
|
|
|
if str != expect {
|
|
|
|
|
t.Errorf("String: expected %s got %s", expect, str)
|
|
|
|
|
}
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-07-14 20:47:39 -07:00
|
|
|
func TestHTTPRPC(t *testing.T) {
|
2009-12-15 15:40:16 -08:00
|
|
|
once.Do(startServer)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
client, err := DialHTTP("tcp", httpServerAddr)
|
2009-07-14 20:47:39 -07:00
|
|
|
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-12-15 15:40:16 -08:00
|
|
|
args := &Args{7, 8}
|
|
|
|
|
reply := new(Reply)
|
|
|
|
|
err = client.Call("Arith.Add", args, reply)
|
2009-11-17 11:29:02 -08:00
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("Add: expected no error but got string %q", err.String())
|
|
|
|
|
}
|
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-12-15 15:40:16 -08:00
|
|
|
once.Do(startServer)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
conn, err := net.Dial("tcp", "", serverAddr)
|
2009-07-14 13:23:14 -07:00
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing:", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
client := NewClient(conn)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
args := &Args{7, 8}
|
|
|
|
|
reply := new(Reply)
|
|
|
|
|
err = client.Call("Unknown.Add", args, reply)
|
2009-07-14 13:23:14 -07:00
|
|
|
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) {
|
2009-12-15 15:40:16 -08:00
|
|
|
once.Do(startServer)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
conn, err := net.Dial("tcp", "", serverAddr)
|
2009-07-14 13:23:14 -07:00
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing:", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
client := NewClient(conn)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
args := &Args{7, 8}
|
|
|
|
|
reply := new(Reply)
|
|
|
|
|
err = client.Call("Arith.Unknown", args, reply)
|
2009-07-14 13:23:14 -07:00
|
|
|
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) {
|
2009-12-15 15:40:16 -08:00
|
|
|
once.Do(startServer)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
conn, err := net.Dial("tcp", "", serverAddr)
|
2009-07-14 13:23:14 -07:00
|
|
|
if err != nil {
|
2009-11-09 12:07:39 -08:00
|
|
|
t.Fatal("dialing:", err)
|
2009-07-14 13:23:14 -07:00
|
|
|
}
|
|
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
client := NewClient(conn)
|
2009-07-14 13:23:14 -07:00
|
|
|
|
2009-12-15 15:40:16 -08:00
|
|
|
reply := new(Reply)
|
|
|
|
|
err = client.Call("Arith.Add", reply, reply) // args, reply would be the correct thing to use
|
2009-07-14 13:23:14 -07:00
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|
2009-12-02 10:41:28 -08:00
|
|
|
|
2010-06-28 16:05:54 -07:00
|
|
|
type ArgNotPointer int
|
|
|
|
|
type ReplyNotPointer int
|
|
|
|
|
type ArgNotPublic int
|
|
|
|
|
type ReplyNotPublic int
|
2009-12-02 10:41:28 -08:00
|
|
|
type local struct{}
|
|
|
|
|
|
2010-06-28 16:05:54 -07:00
|
|
|
func (t *ArgNotPointer) ArgNotPointer(args Args, reply *Reply) os.Error {
|
2009-12-02 10:41:28 -08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-28 16:05:54 -07:00
|
|
|
func (t *ReplyNotPointer) ReplyNotPointer(args *Args, reply Reply) os.Error {
|
2009-12-02 10:41:28 -08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-28 16:05:54 -07:00
|
|
|
func (t *ArgNotPublic) ArgNotPublic(args *local, reply *Reply) os.Error {
|
2009-12-02 10:41:28 -08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-28 16:05:54 -07:00
|
|
|
func (t *ReplyNotPublic) ReplyNotPublic(args *Args, reply *local) os.Error {
|
2009-12-02 10:41:28 -08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check that registration handles lots of bad methods and a type with no suitable methods.
|
|
|
|
|
func TestRegistrationError(t *testing.T) {
|
2010-06-28 16:05:54 -07:00
|
|
|
err := Register(new(ArgNotPointer))
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Errorf("expected error registering ArgNotPointer")
|
|
|
|
|
}
|
|
|
|
|
err = Register(new(ReplyNotPointer))
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Errorf("expected error registering ReplyNotPointer")
|
|
|
|
|
}
|
|
|
|
|
err = Register(new(ArgNotPublic))
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Errorf("expected error registering ArgNotPublic")
|
|
|
|
|
}
|
|
|
|
|
err = Register(new(ReplyNotPublic))
|
2009-12-02 10:41:28 -08:00
|
|
|
if err == nil {
|
2010-06-28 16:05:54 -07:00
|
|
|
t.Errorf("expected error registering ReplyNotPublic")
|
2009-12-02 10:41:28 -08:00
|
|
|
}
|
|
|
|
|
}
|