func TestNonPointerRequest(t *testing.T) { c, s := net.Pipe() defer c.Close() registry := birpc.NewRegistry() registry.RegisterService(NonPointerRequest{}) server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry) server_err := make(chan error) go func() { server_err <- server.Serve() }() io.WriteString(c, `{"id": "42", "fn": "NonPointerRequest.NonPointer", "args": 13}`+"\n") var reply LowLevelReply dec := json.NewDecoder(c) if err := dec.Decode(&reply); err != nil && err != io.EOF { t.Fatalf("decode failed: %s", err) } t.Logf("reply msg: %#v", reply) if reply.Error != nil { t.Fatalf("unexpected error response: %v", reply.Error) } if string(reply.Result) != `13` { t.Fatalf("got wrong answer: %v", reply.Result) } c.Close() err := <-server_err if err != io.EOF { t.Fatalf("unexpected error from ServeCodec: %v", err) } }
func TestUnmarshalArgsError(t *testing.T) { c, s := net.Pipe() defer c.Close() registry := birpc.NewRegistry() registry.RegisterService(WordLength{}) server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry) server_err := make(chan error) go func() { server_err <- server.Serve() }() const REQ = `{"id": "42", "fn": "WordLength.Len", "args": "evil"}` + "\n" io.WriteString(c, REQ) var reply LowLevelReply dec := json.NewDecoder(c) if err := dec.Decode(&reply); err != nil && err != io.EOF { t.Fatalf("decode failed: %s", err) } t.Logf("reply msg: %#v", reply) if reply.Error == nil { t.Fatalf("expected an error") } if reply.Result != nil { t.Fatalf("got unexpected result: %v", reply.Result) } c.Close() err := <-server_err if err != io.EOF { t.Fatalf("unexpected error from ServeCodec: %v", err) } }
func main() { prog := path.Base(os.Args[0]) log.SetFlags(0) log.SetPrefix(prog + ": ") flag.Usage = Usage flag.Parse() if flag.NArg() > 0 { Usage() os.Exit(1) } log.Printf("Serving at http://%s:%d/", *host, *port) chat := Chat{} chat.broadcast = topic.New() chat.registry = birpc.NewRegistry() chat.registry.RegisterService(&chat) defer close(chat.broadcast.Broadcast) upgrader := websocket.Upgrader{} serve := func(w http.ResponseWriter, req *http.Request) { ws, err := upgrader.Upgrade(w, req, nil) if err != nil { log.Println(err) return } endpoint := wetsock.NewEndpoint(chat.registry, ws) messages := make(chan interface{}, 10) chat.broadcast.Register(messages) go func() { defer chat.broadcast.Unregister(messages) for i := range messages { msg := i.(Outgoing) // Fire-and-forget. // TODO use .Notify when it exists _ = endpoint.Go("Chat.Message", msg, nil, nil) } // broadcast topic kicked us out for being too slow; // probably a hung TCP connection. let client // re-establish. log.Printf("Kicking slow client: %v", ws.RemoteAddr()) ws.Close() }() if err := endpoint.Serve(); err != nil { log.Printf("websocket error from %v: %v", ws.RemoteAddr(), err) } } http.HandleFunc("/sock", serve) http.Handle("/", http.HandlerFunc(index)) addr := fmt.Sprintf("%s:%d", *host, *port) err := http.ListenAndServe(addr, nil) if err != nil { log.Fatal(err) } }
func TestRegisterBadMultiReturn(t *testing.T) { registry := birpc.NewRegistry() testPanic( t, func() { registry.RegisterService(MultiReturn{}) }, "birpc.RegisterService: method birpc_test.MultiReturn.MultiReturn must return error", ) }
func TestRegisterBadNonPointerReply(t *testing.T) { registry := birpc.NewRegistry() testPanic( t, func() { registry.RegisterService(NonPointerReply{}) }, "birpc.RegisterService: method birpc_test.NonPointerReply.NonPointer reply argument must be a pointer type", ) }
func TestRegisterBadTooFewArguments(t *testing.T) { registry := birpc.NewRegistry() testPanic( t, func() { registry.RegisterService(TooFewArguments{}) }, "birpc.RegisterService: method birpc_test.TooFewArguments.TooFew is missing request/reply arguments", ) }
func TestServerError(t *testing.T) { c, s := net.Pipe() defer c.Close() registry := birpc.NewRegistry() registry.RegisterService(Failing{}) server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry) server_err := make(chan error) go func() { server_err <- server.Serve() }() const REQ = `{"id": "42", "fn": "Failing.Fail", "args": {}}` + "\n" io.WriteString(c, REQ) var reply LowLevelReply dec := json.NewDecoder(c) if err := dec.Decode(&reply); err != nil && err != io.EOF { t.Fatalf("decode failed: %s", err) } t.Logf("reply msg: %#v", reply) if reply.Error == nil { t.Fatalf("expected an error") } if g, e := reply.Error.Msg, "intentional"; g != e { t.Fatalf("unexpected error response: %q != %q", g, e) } if reply.Result != nil { t.Fatalf("got unexpected result: %v", reply.Result) } c.Close() err := <-server_err if err != io.EOF { t.Fatalf("unexpected error from ServeCodec: %v", err) } }
func TestFillArgsError(t *testing.T) { c, s := net.Pipe() defer c.Close() registry := birpc.NewRegistry() // just need anything with >2 parameters registry.RegisterService(&EndpointPeer{}) jsonCodec := jsonmsg.NewCodec(s) codec := BadFillArgsCodec{jsonCodec} server := birpc.NewEndpoint(codec, registry) server_err := make(chan error) go func() { server_err <- server.Serve() }() io.WriteString(c, `{"id":"42","fn":"EndpointPeer.Poke","args":{}}`) var reply LowLevelReply dec := json.NewDecoder(c) if err := dec.Decode(&reply); err != nil && err != io.EOF { t.Fatalf("decode failed: %s", err) } t.Logf("reply msg: %#v", reply) if reply.Error == nil { t.Fatalf("expected an error") } if reply.Result != nil { t.Fatalf("got unexpected result: %v", reply.Result) } c.Close() err := <-server_err if err != io.EOF { t.Fatalf("unexpected error from ServeCodec: %v", err) } }
func TestServerEndpointArg(t *testing.T) { peer := &EndpointPeer{} registry := birpc.NewRegistry() registry.RegisterService(peer) c, s := net.Pipe() defer c.Close() server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry) server_err := make(chan error) go func() { server_err <- server.Serve() }() io.WriteString(c, `{"id":"42","fn":"EndpointPeer.Poke","args":{}}`) var reply LowLevelReply dec := json.NewDecoder(c) if err := dec.Decode(&reply); err != nil && err != io.EOF { t.Fatalf("decode failed: %s", err) } t.Logf("reply msg: %#v", reply) if reply.Error != nil { t.Fatalf("unexpected error response: %v", reply.Error) } c.Close() err := <-server_err if err != io.EOF { t.Fatalf("unexpected error from ServeCodec: %v", err) } if peer.seen == nil { t.Fatalf("peer never saw a birpc.Endpoint") } }
func makeRegistry() *birpc.Registry { r := birpc.NewRegistry() r.RegisterService(WordLength{}) return r }