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