github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/apiserver/pinger_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiserver_test 5 6 import ( 7 "time" 8 9 "github.com/juju/loggo" 10 gitjujutesting "github.com/juju/testing" 11 "github.com/juju/utils" 12 gc "launchpad.net/gocheck" 13 14 "github.com/juju/juju/juju/testing" 15 "github.com/juju/juju/rpc" 16 "github.com/juju/juju/state/api" 17 "github.com/juju/juju/state/apiserver" 18 coretesting "github.com/juju/juju/testing" 19 ) 20 21 type stateSuite struct { 22 testing.JujuConnSuite 23 } 24 25 var _ = gc.Suite(&stateSuite{}) 26 27 var testPingPeriod = 100 * time.Millisecond 28 29 func (s *stateSuite) TestConnectionBrokenDetection(c *gc.C) { 30 s.PatchValue(&api.PingPeriod, testPingPeriod) 31 32 st, _ := s.OpenAPIAsNewMachine(c) 33 34 // Connection still alive 35 select { 36 case <-time.After(testPingPeriod): 37 case <-st.Broken(): 38 c.Fatalf("connection should be alive still") 39 } 40 41 // Close the connection and see if we detect this 42 go st.Close() 43 44 // Check it's detected 45 select { 46 case <-time.After(testPingPeriod + time.Second): 47 c.Fatalf("connection not closed as expected") 48 case <-st.Broken(): 49 return 50 } 51 } 52 53 func (s *stateSuite) TestPing(c *gc.C) { 54 tw := &loggo.TestWriter{} 55 c.Assert(loggo.RegisterWriter("ping-tester", tw, loggo.DEBUG), gc.IsNil) 56 defer loggo.RemoveWriter("ping-tester") 57 58 st, _ := s.OpenAPIAsNewMachine(c) 59 err := st.Ping() 60 c.Assert(err, gc.IsNil) 61 err = st.Close() 62 c.Assert(err, gc.IsNil) 63 err = st.Ping() 64 c.Assert(err, gc.Equals, rpc.ErrShutdown) 65 66 // Make sure that ping messages have not been logged. 67 for _, m := range tw.Log { 68 c.Logf("checking %q", m.Message) 69 c.Check(m.Message, gc.Not(gc.Matches), ".*Ping.*") 70 } 71 } 72 73 func (s *stateSuite) TestClientNoNeedToPing(c *gc.C) { 74 s.PatchValue(apiserver.MaxClientPingInterval, time.Duration(0)) 75 st, err := api.Open(s.APIInfo(c), api.DefaultDialOpts()) 76 c.Assert(err, gc.IsNil) 77 time.Sleep(coretesting.ShortWait) 78 err = st.Ping() 79 c.Assert(err, gc.IsNil) 80 } 81 82 func (s *stateSuite) TestAgentConnectionShutsDownWithNoPing(c *gc.C) { 83 s.PatchValue(apiserver.MaxClientPingInterval, time.Duration(0)) 84 st, _ := s.OpenAPIAsNewMachine(c) 85 time.Sleep(coretesting.ShortWait) 86 err := st.Ping() 87 c.Assert(err, gc.ErrorMatches, "connection is shut down") 88 } 89 90 func (s *stateSuite) TestAgentConnectionDelaysShutdownWithPing(c *gc.C) { 91 // We have to be careful, because Login can take 25ms, so we ping 92 // immediately after connecting. 93 s.PatchValue(apiserver.MaxClientPingInterval, 50*time.Millisecond) 94 st, _ := s.OpenAPIAsNewMachine(c) 95 err := st.Ping() 96 c.Assert(err, gc.IsNil) 97 // As long as we don't wait too long, the connection stays open 98 for i := 0; i < 10; i++ { 99 time.Sleep(10 * time.Millisecond) 100 err = st.Ping() 101 c.Assert(err, gc.IsNil) 102 } 103 // However, once we stop pinging for too long, the connection dies 104 time.Sleep(75 * time.Millisecond) 105 err = st.Ping() 106 c.Assert(err, gc.ErrorMatches, "connection is shut down") 107 } 108 109 type mongoPingerSuite struct { 110 testing.JujuConnSuite 111 } 112 113 var _ = gc.Suite(&mongoPingerSuite{}) 114 115 func (s *mongoPingerSuite) SetUpTest(c *gc.C) { 116 // We need to set the ping interval before the server is started. 117 s.PatchValue(apiserver.MongoPingInterval, coretesting.ShortWait) 118 s.JujuConnSuite.SetUpTest(c) 119 } 120 121 func (s *mongoPingerSuite) TestAgentConnectionsShutDownWhenStateDies(c *gc.C) { 122 s.PatchValue(apiserver.MongoPingInterval, coretesting.ShortWait) 123 st, _ := s.OpenAPIAsNewMachine(c) 124 err := st.Ping() 125 c.Assert(err, gc.IsNil) 126 gitjujutesting.MgoServer.Destroy() 127 128 attempt := utils.AttemptStrategy{ 129 Total: coretesting.LongWait, 130 Delay: coretesting.ShortWait, 131 } 132 for a := attempt.Start(); a.Next(); { 133 if err := st.Ping(); err != nil { 134 c.Assert(err, gc.ErrorMatches, "connection is shut down") 135 return 136 } 137 } 138 c.Fatalf("timed out waiting for API server to die") 139 }