Merge lp:~rogpeppe/juju-core/213-rpc-test-timeouts into lp:~juju/juju-core/trunk

Proposed by Roger Peppe
Status: Merged
Merged at revision: 888
Proposed branch: lp:~rogpeppe/juju-core/213-rpc-test-timeouts
Merge into: lp:~juju/juju-core/trunk
Diff against target: 157 lines (+34/-54)
2 files modified
rpc/rpc_test.go (+34/-15)
rpc/server.go (+0/-39)
To merge this branch: bzr merge lp:~rogpeppe/juju-core/213-rpc-test-timeouts
Reviewer Review Type Date Requested Status
The Go Language Gophers Pending
Review via email: mp+148162@code.launchpad.net

Description of the change

rpc: don't hang tests on failure

As suggested in previous CL.
Also delete Accept method, also suggested earlier
and not done.

https://codereview.appspot.com/7324046/

To post a comment you must log in.
Revision history for this message
Roger Peppe (rogpeppe) wrote :

Reviewers: mp+148162_code.launchpad.net,

Message:
Please take a look.

Description:
rpc: don't hang tests on failure

https://code.launchpad.net/~rogpeppe/juju-core/213-rpc-test-timeouts/+merge/148162

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/7324046/

Affected files:
   A [revision details]
   M rpc/rpc_test.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>

Index: rpc/rpc_test.go
=== modified file 'rpc/rpc_test.go'
--- rpc/rpc_test.go 2013-02-12 15:37:30 +0000
+++ rpc/rpc_test.go 2013-02-13 12:18:19 +0000
@@ -160,7 +160,7 @@
    }
   }
   client.Close()
- err := <-srvDone
+ err := chanReadError(c, srvDone, "server done")
   c.Assert(err, IsNil)
  }

@@ -211,29 +211,29 @@
   }

   client, srvDone := newRPCClientServer(c, root)
- call := func(id string, done chan<- bool) {
+ call := func(id string, done chan<- struct{}) {
    var r stringVal
    err := client.Call("DelayedMethods", id, "Delay", nil, &r)
    c.Check(err, IsNil)
    c.Check(r.Val, Equals, "return "+id)
- done <- true
+ done <- struct{}{}
   }
- done1 := make(chan bool)
- done2 := make(chan bool)
+ done1 := make(chan struct{})
+ done2 := make(chan struct{})
   go call("1", done1)
   go call("2", done2)

   // Check that both calls are running concurrently.
- <-ready1
- <-ready2
+ chanRead(c, ready1, "method 1 ready")
+ chanRead(c, ready2, "method 2 ready")

   // Let the requests complete.
   start1 <- "return 1"
   start2 <- "return 2"
- <-done1
- <-done2
+ chanRead(c, done1, "method 1 done")
+ chanRead(c, done2, "method 2 done")
   client.Close()
- err := <-srvDone
+ err := chanReadError(c, srvDone, "server done")
   c.Assert(err, IsNil)
  }

@@ -249,14 +249,14 @@
    },
   }
   client, srvDone := newRPCClientServer(c, root)
- done := make(chan bool)
+ done := make(chan struct{})
   go func() {
    var r stringVal
    err := client.Call("DelayedMethods", "1", "Delay", nil, &r)
    c.Check(err, FitsTypeOf, &net.OpError{})
- done <- true
+ done <- struct{}{}
   }()
- <-ready
+ chanRead(c, ready, "DelayedMethods.Delay ready")
   client.Close()
   select {
   case err := <-srvDone:
@@ -265,9 +265,28 @@
   case <-time.After(25 * time.Millisecond):
   }
   start <- "xxx"
- err := <-srvDone
+ err := chanReadError(c, srvDone, "server done")
   c.Check(err, IsNil)
- <-done
+ chanRead(c, done, "DelayedMethods.Delay done")
+}
+
+func chanRead(c *C, ch <-chan struct{}, what string) {
+ select {
+ case <-ch:
+ return
+ case <-time.After(3 * time.Second):
+ c.Fatalf("timeout on channel read %s", what)
+ }
+}
+
+func chanReadError(c *C, ch <-chan error, what string) error {
+ select {
+ case e := <-ch:
+ return e
+ case <-time.After(3 * time.Second):
+ c.Fatalf("timeout on channel read %s", what)
+ }
+ panic("unreachable")
  }

  // newRPCClientServer starts an RPC server serving a connection from a

Revision history for this message
Dimiter Naydenov (dimitern) wrote :
Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2013-02-13 16:40, Dimiter Naydenov wrote:
> LGTM
>
> https://codereview.appspot.com/7324046/
>

LGTM

I can confirm that it makes the tests fail quickly rather than hang
until the 5min timeout.

Of course, better if they didn't fail, but this is still an
improvement. :)

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (Cygwin)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlEbiyQACgkQJdeBCYSNAAPYNQCgu/8iZnXoGba5+RMHDdo3XQoE
PYEAnRco0W3eMPh1BunHCHQ/DjYulkvF
=oBYC
-----END PGP SIGNATURE-----

Revision history for this message
William Reade (fwereade) wrote :

LGTM, one suggestion

https://codereview.appspot.com/7324046/diff/2001/rpc/rpc_test.go
File rpc/rpc_test.go (right):

https://codereview.appspot.com/7324046/diff/2001/rpc/rpc_test.go#newcode277
rpc/rpc_test.go:277: case <-time.After(3 * time.Second):
Can we reasonably drop this to, say, half a second?

https://codereview.appspot.com/7324046/

Revision history for this message
Roger Peppe (rogpeppe) wrote :
Revision history for this message
Roger Peppe (rogpeppe) wrote :

*** Submitted:

rpc: don't hang tests on failure

As suggested in previous CL.
Also delete Accept method, also suggested earlier
and not done.

R=dimitern, fwereade
CC=
https://codereview.appspot.com/7324046

https://codereview.appspot.com/7324046/diff/2001/rpc/rpc_test.go
File rpc/rpc_test.go (right):

https://codereview.appspot.com/7324046/diff/2001/rpc/rpc_test.go#newcode277
rpc/rpc_test.go:277: case <-time.After(3 * time.Second):
On 2013/02/13 12:56:35, fwereade wrote:
> Can we reasonably drop this to, say, half a second?

why bother? the timeout only happens on test failure, and in that case 3
seconds isn't an issue.

https://codereview.appspot.com/7324046/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'rpc/rpc_test.go'
--- rpc/rpc_test.go 2013-02-12 15:37:30 +0000
+++ rpc/rpc_test.go 2013-02-13 13:05:28 +0000
@@ -160,7 +160,7 @@
160 }160 }
161 }161 }
162 client.Close()162 client.Close()
163 err := <-srvDone163 err := chanReadError(c, srvDone, "server done")
164 c.Assert(err, IsNil)164 c.Assert(err, IsNil)
165}165}
166166
@@ -211,29 +211,29 @@
211 }211 }
212212
213 client, srvDone := newRPCClientServer(c, root)213 client, srvDone := newRPCClientServer(c, root)
214 call := func(id string, done chan<- bool) {214 call := func(id string, done chan<- struct{}) {
215 var r stringVal215 var r stringVal
216 err := client.Call("DelayedMethods", id, "Delay", nil, &r)216 err := client.Call("DelayedMethods", id, "Delay", nil, &r)
217 c.Check(err, IsNil)217 c.Check(err, IsNil)
218 c.Check(r.Val, Equals, "return "+id)218 c.Check(r.Val, Equals, "return "+id)
219 done <- true219 done <- struct{}{}
220 }220 }
221 done1 := make(chan bool)221 done1 := make(chan struct{})
222 done2 := make(chan bool)222 done2 := make(chan struct{})
223 go call("1", done1)223 go call("1", done1)
224 go call("2", done2)224 go call("2", done2)
225225
226 // Check that both calls are running concurrently.226 // Check that both calls are running concurrently.
227 <-ready1227 chanRead(c, ready1, "method 1 ready")
228 <-ready2228 chanRead(c, ready2, "method 2 ready")
229229
230 // Let the requests complete.230 // Let the requests complete.
231 start1 <- "return 1"231 start1 <- "return 1"
232 start2 <- "return 2"232 start2 <- "return 2"
233 <-done1233 chanRead(c, done1, "method 1 done")
234 <-done2234 chanRead(c, done2, "method 2 done")
235 client.Close()235 client.Close()
236 err := <-srvDone236 err := chanReadError(c, srvDone, "server done")
237 c.Assert(err, IsNil)237 c.Assert(err, IsNil)
238}238}
239239
@@ -249,14 +249,14 @@
249 },249 },
250 }250 }
251 client, srvDone := newRPCClientServer(c, root)251 client, srvDone := newRPCClientServer(c, root)
252 done := make(chan bool)252 done := make(chan struct{})
253 go func() {253 go func() {
254 var r stringVal254 var r stringVal
255 err := client.Call("DelayedMethods", "1", "Delay", nil, &r)255 err := client.Call("DelayedMethods", "1", "Delay", nil, &r)
256 c.Check(err, FitsTypeOf, &net.OpError{})256 c.Check(err, FitsTypeOf, &net.OpError{})
257 done <- true257 done <- struct{}{}
258 }()258 }()
259 <-ready259 chanRead(c, ready, "DelayedMethods.Delay ready")
260 client.Close()260 client.Close()
261 select {261 select {
262 case err := <-srvDone:262 case err := <-srvDone:
@@ -265,9 +265,28 @@
265 case <-time.After(25 * time.Millisecond):265 case <-time.After(25 * time.Millisecond):
266 }266 }
267 start <- "xxx"267 start <- "xxx"
268 err := <-srvDone268 err := chanReadError(c, srvDone, "server done")
269 c.Check(err, IsNil)269 c.Check(err, IsNil)
270 <-done270 chanRead(c, done, "DelayedMethods.Delay done")
271}
272
273func chanRead(c *C, ch <-chan struct{}, what string) {
274 select {
275 case <-ch:
276 return
277 case <-time.After(3 * time.Second):
278 c.Fatalf("timeout on channel read %s", what)
279 }
280}
281
282func chanReadError(c *C, ch <-chan error, what string) error {
283 select {
284 case e := <-ch:
285 return e
286 case <-time.After(3 * time.Second):
287 c.Fatalf("timeout on channel read %s", what)
288 }
289 panic("unreachable")
271}290}
272291
273// newRPCClientServer starts an RPC server serving a connection from a292// newRPCClientServer starts an RPC server serving a connection from a
274293
=== modified file 'rpc/server.go'
--- rpc/server.go 2013-02-11 12:30:10 +0000
+++ rpc/server.go 2013-02-13 13:05:28 +0000
@@ -4,7 +4,6 @@
4 "fmt"4 "fmt"
5 "io"5 "io"
6 "launchpad.net/juju-core/log"6 "launchpad.net/juju-core/log"
7 "net"
8 "reflect"7 "reflect"
9 "sync"8 "sync"
10)9)
@@ -61,44 +60,6 @@
61 sending sync.Mutex60 sending sync.Mutex
62}61}
6362
64// Accept accepts connections on the listener and serves requests for
65// each incoming connection. The newRoot function is called
66// to create the root value for the connection before spawning
67// the goroutine to service the RPC requests; it may be nil,
68// in which case the original root value passed to NewServer
69// will be used. A codec is chosen for the connection by
70// calling newCodec.
71//
72// Accept blocks; the caller typically invokes it in
73// a go statement.
74func (srv *Server) Accept(l net.Listener,
75 newRoot func(net.Conn) (interface{}, error),
76 newCodec func(io.ReadWriteCloser) ServerCodec) error {
77 for {
78 c, err := l.Accept()
79 if err != nil {
80 return err
81 }
82 rootv := srv.root
83 if newRoot != nil {
84 root, err := newRoot(c)
85 if err != nil {
86 log.Printf("rpc: connection refused: %v", err)
87 c.Close()
88 continue
89 }
90 rootv = reflect.ValueOf(root)
91 }
92 go func() {
93 defer c.Close()
94 if err := srv.serve(rootv, newCodec(c)); err != nil {
95 log.Printf("rpc: ServeCodec error: %v", err)
96 }
97 }()
98 }
99 panic("unreachable")
100}
101
102// ServeCodec runs the server on a single connection. ServeCodec63// ServeCodec runs the server on a single connection. ServeCodec
103// blocks, serving the connection until the client hangs up. The caller64// blocks, serving the connection until the client hangs up. The caller
104// typically invokes ServeCodec in a go statement. The given65// typically invokes ServeCodec in a go statement. The given

Subscribers

People subscribed via source and target branches