OSDN Git Service

libgo: Update to weekly.2011-11-01.
[pf3gnuchains/gcc-fork.git] / libgo / go / rpc / jsonrpc / all_test.go
1 // Copyright 2010 The Go Authors.  All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package jsonrpc
6
7 import (
8         "fmt"
9         "io"
10         "json"
11         "net"
12         "os"
13         "rpc"
14         "testing"
15 )
16
17 type Args struct {
18         A, B int
19 }
20
21 type Reply struct {
22         C int
23 }
24
25 type Arith int
26
27 func (t *Arith) Add(args *Args, reply *Reply) os.Error {
28         reply.C = args.A + args.B
29         return nil
30 }
31
32 func (t *Arith) Mul(args *Args, reply *Reply) os.Error {
33         reply.C = args.A * args.B
34         return nil
35 }
36
37 func (t *Arith) Div(args *Args, reply *Reply) os.Error {
38         if args.B == 0 {
39                 return os.NewError("divide by zero")
40         }
41         reply.C = args.A / args.B
42         return nil
43 }
44
45 func (t *Arith) Error(args *Args, reply *Reply) os.Error {
46         panic("ERROR")
47 }
48
49 func init() {
50         rpc.Register(new(Arith))
51 }
52
53 func TestServer(t *testing.T) {
54         type addResp struct {
55                 Id     interface{} `json:"id"`
56                 Result Reply       `json:"result"`
57                 Error  interface{} `json:"error"`
58         }
59
60         cli, srv := net.Pipe()
61         defer cli.Close()
62         go ServeConn(srv)
63         dec := json.NewDecoder(cli)
64
65         // Send hand-coded requests to server, parse responses.
66         for i := 0; i < 10; i++ {
67                 fmt.Fprintf(cli, `{"method": "Arith.Add", "id": "\u%04d", "params": [{"A": %d, "B": %d}]}`, i, i, i+1)
68                 var resp addResp
69                 err := dec.Decode(&resp)
70                 if err != nil {
71                         t.Fatalf("Decode: %s", err)
72                 }
73                 if resp.Error != nil {
74                         t.Fatalf("resp.Error: %s", resp.Error)
75                 }
76                 if resp.Id.(string) != string(i) {
77                         t.Fatalf("resp: bad id %q want %q", resp.Id.(string), string(i))
78                 }
79                 if resp.Result.C != 2*i+1 {
80                         t.Fatalf("resp: bad result: %d+%d=%d", i, i+1, resp.Result.C)
81                 }
82         }
83
84         fmt.Fprintf(cli, "{}\n")
85         var resp addResp
86         if err := dec.Decode(&resp); err != nil {
87                 t.Fatalf("Decode after empty: %s", err)
88         }
89         if resp.Error == nil {
90                 t.Fatalf("Expected error, got nil")
91         }
92 }
93
94 func TestClient(t *testing.T) {
95         // Assume server is okay (TestServer is above).
96         // Test client against server.
97         cli, srv := net.Pipe()
98         go ServeConn(srv)
99
100         client := NewClient(cli)
101         defer client.Close()
102
103         // Synchronous calls
104         args := &Args{7, 8}
105         reply := new(Reply)
106         err := client.Call("Arith.Add", args, reply)
107         if err != nil {
108                 t.Errorf("Add: expected no error but got string %q", err.String())
109         }
110         if reply.C != args.A+args.B {
111                 t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
112         }
113
114         args = &Args{7, 8}
115         reply = new(Reply)
116         err = client.Call("Arith.Mul", args, reply)
117         if err != nil {
118                 t.Errorf("Mul: expected no error but got string %q", err.String())
119         }
120         if reply.C != args.A*args.B {
121                 t.Errorf("Mul: expected %d got %d", reply.C, args.A*args.B)
122         }
123
124         // Out of order.
125         args = &Args{7, 8}
126         mulReply := new(Reply)
127         mulCall := client.Go("Arith.Mul", args, mulReply, nil)
128         addReply := new(Reply)
129         addCall := client.Go("Arith.Add", args, addReply, nil)
130
131         addCall = <-addCall.Done
132         if addCall.Error != nil {
133                 t.Errorf("Add: expected no error but got string %q", addCall.Error.String())
134         }
135         if addReply.C != args.A+args.B {
136                 t.Errorf("Add: expected %d got %d", addReply.C, args.A+args.B)
137         }
138
139         mulCall = <-mulCall.Done
140         if mulCall.Error != nil {
141                 t.Errorf("Mul: expected no error but got string %q", mulCall.Error.String())
142         }
143         if mulReply.C != args.A*args.B {
144                 t.Errorf("Mul: expected %d got %d", mulReply.C, args.A*args.B)
145         }
146
147         // Error test
148         args = &Args{7, 0}
149         reply = new(Reply)
150         err = client.Call("Arith.Div", args, reply)
151         // expect an error: zero divide
152         if err == nil {
153                 t.Error("Div: expected error")
154         } else if err.String() != "divide by zero" {
155                 t.Error("Div: expected divide by zero error; got", err)
156         }
157 }
158
159 func TestMalformedInput(t *testing.T) {
160         cli, srv := net.Pipe()
161         go cli.Write([]byte(`{id:1}`)) // invalid json
162         ServeConn(srv)                 // must return, not loop
163 }
164
165 func TestUnexpectedError(t *testing.T) {
166         cli, srv := myPipe()
167         go cli.PipeWriter.CloseWithError(os.NewError("unexpected error!")) // reader will get this error
168         ServeConn(srv)                                                     // must return, not loop
169 }
170
171 // Copied from package net.
172 func myPipe() (*pipe, *pipe) {
173         r1, w1 := io.Pipe()
174         r2, w2 := io.Pipe()
175
176         return &pipe{r1, w2}, &pipe{r2, w1}
177 }
178
179 type pipe struct {
180         *io.PipeReader
181         *io.PipeWriter
182 }
183
184 type pipeAddr int
185
186 func (pipeAddr) Network() string {
187         return "pipe"
188 }
189
190 func (pipeAddr) String() string {
191         return "pipe"
192 }
193
194 func (p *pipe) Close() os.Error {
195         err := p.PipeReader.Close()
196         err1 := p.PipeWriter.Close()
197         if err == nil {
198                 err = err1
199         }
200         return err
201 }
202
203 func (p *pipe) LocalAddr() net.Addr {
204         return pipeAddr(0)
205 }
206
207 func (p *pipe) RemoteAddr() net.Addr {
208         return pipeAddr(0)
209 }
210
211 func (p *pipe) SetTimeout(nsec int64) os.Error {
212         return os.NewError("net.Pipe does not support timeouts")
213 }
214
215 func (p *pipe) SetReadTimeout(nsec int64) os.Error {
216         return os.NewError("net.Pipe does not support timeouts")
217 }
218
219 func (p *pipe) SetWriteTimeout(nsec int64) os.Error {
220         return os.NewError("net.Pipe does not support timeouts")
221 }