github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/presence/pinger_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package presence_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/apiserver/presence"
    15  	"github.com/juju/juju/worker/workertest"
    16  )
    17  
    18  type WorkerSuite struct {
    19  	testing.IsolationSuite
    20  }
    21  
    22  var _ = gc.Suite(&WorkerSuite{})
    23  
    24  func (s *WorkerSuite) TestConfigValidateOkay(c *gc.C) {
    25  	err := validConfig().Validate()
    26  	c.Check(err, jc.ErrorIsNil)
    27  }
    28  
    29  func (s *WorkerSuite) TestConfigValidateMissingIdentity(c *gc.C) {
    30  	config := validConfig()
    31  	config.Identity = nil
    32  	checkInvalid(c, config, "nil Identity not valid")
    33  }
    34  
    35  func (s *WorkerSuite) TestConfigValidateMissingStart(c *gc.C) {
    36  	config := validConfig()
    37  	config.Start = nil
    38  	checkInvalid(c, config, "nil Start not valid")
    39  }
    40  
    41  func (s *WorkerSuite) TestConfigValidateMissingClock(c *gc.C) {
    42  	config := validConfig()
    43  	config.Clock = nil
    44  	checkInvalid(c, config, "nil Clock not valid")
    45  }
    46  
    47  func (s *WorkerSuite) TestConfigValidateMissingRetryDelay(c *gc.C) {
    48  	config := validConfig()
    49  	config.RetryDelay = 0
    50  	checkInvalid(c, config, `non-positive RetryDelay not valid`)
    51  }
    52  
    53  func (s *WorkerSuite) TestConfigValidateNegativeRetryDelay(c *gc.C) {
    54  	config := validConfig()
    55  	config.RetryDelay = -time.Minute
    56  	checkInvalid(c, config, `non-positive RetryDelay not valid`)
    57  }
    58  
    59  func (s *WorkerSuite) TestInitialSuccess(c *gc.C) {
    60  	fix := NewFixture()
    61  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
    62  		workertest.CleanKill(c, worker)
    63  		// Despite immediate kill, a pinger was still started.
    64  		context.WaitPinger()
    65  	})
    66  	stub.CheckCallNames(c, "Start")
    67  }
    68  
    69  func (s *WorkerSuite) TestInitialFailedStart(c *gc.C) {
    70  	// First start attempt fails.
    71  	fix := NewFixture(errors.New("zap"))
    72  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
    73  		workertest.CleanKill(c, worker)
    74  		// Despite immediate kill, we didn't exit until the
    75  		// second time through the loop.
    76  		context.WaitAlarms(2)
    77  	})
    78  	stub.CheckCallNames(c, "Start")
    79  }
    80  
    81  func (s *WorkerSuite) TestInitialRetryIsDelayed(c *gc.C) {
    82  	// First start attempt fails.
    83  	fix := NewFixture(errors.New("zap"))
    84  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
    85  		context.WaitAlarms(2)
    86  		// Now we know the worker is waiting to start the next
    87  		// pinger, advance *almost* far enough to trigger it.
    88  		context.AdvanceClock(almostFiveSeconds)
    89  		workertest.CheckAlive(c, worker)
    90  	})
    91  	stub.CheckCallNames(c, "Start")
    92  }
    93  
    94  func (s *WorkerSuite) TestInitialRetryIsNotDelayedTooMuch(c *gc.C) {
    95  	// First start attempt fails.
    96  	fix := NewFixture(errors.New("zap"))
    97  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
    98  		context.WaitAlarms(2)
    99  		// Now we know the worker is waiting to start the next
   100  		// pinger, advance *just* far enough to trigger it.
   101  		context.AdvanceClock(fiveSeconds)
   102  		context.WaitPinger()
   103  	})
   104  	stub.CheckCallNames(c, "Start", "Start")
   105  }
   106  
   107  func (s *WorkerSuite) TestFailedPingerRestartIsDelayed(c *gc.C) {
   108  	// First start succeeds; pinger will die with error when killed.
   109  	fix := NewFixture(nil, errors.New("zap"))
   110  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
   111  		context.WaitPinger().Kill()
   112  		context.WaitAlarms(2)
   113  		// Now we know the first pinger has been stopped, and
   114  		// the worker is waiting to start the next one, advance
   115  		// *almost* far enough to trigger it.
   116  		context.AdvanceClock(almostFiveSeconds)
   117  		workertest.CheckAlive(c, worker)
   118  	})
   119  	stub.CheckCallNames(c, "Start")
   120  }
   121  
   122  func (s *WorkerSuite) TestFailedPingerRestartIsNotDelayedTooMuch(c *gc.C) {
   123  	// First start succeeds; pinger will die with error when killed.
   124  	fix := NewFixture(nil, errors.New("zap"))
   125  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
   126  		context.WaitPinger().Kill()
   127  		context.WaitAlarms(2)
   128  		// Now we know the first pinger has been stopped, and
   129  		// the worker is waiting to start the next one, advance
   130  		// *just* far enough to trigger it.
   131  		context.AdvanceClock(fiveSeconds)
   132  		context.WaitPinger()
   133  	})
   134  	stub.CheckCallNames(c, "Start", "Start")
   135  }
   136  
   137  func (s *WorkerSuite) TestStoppedPingerRestartIsDelayed(c *gc.C) {
   138  	fix := NewFixture()
   139  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
   140  		context.WaitPinger().Kill()
   141  		context.WaitAlarms(2)
   142  		// Now we know the first pinger has been stopped (no
   143  		// error), and the worker is waiting to start the next
   144  		// one, advance *almost* far enough to trigger it.
   145  		context.AdvanceClock(almostFiveSeconds)
   146  		workertest.CheckAlive(c, worker)
   147  	})
   148  	stub.CheckCallNames(c, "Start")
   149  }
   150  
   151  func (s *WorkerSuite) TestStoppedPingerRestartIsNotDelayedTooMuch(c *gc.C) {
   152  	fix := NewFixture()
   153  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
   154  		context.WaitPinger().Kill()
   155  		context.WaitAlarms(2)
   156  		// Now we know the first pinger has been stopped (no
   157  		// error), and the worker is waiting to start the next
   158  		// one, advance *just* far enough to trigger it.
   159  		context.AdvanceClock(fiveSeconds)
   160  		context.WaitPinger()
   161  	})
   162  	stub.CheckCallNames(c, "Start", "Start")
   163  }
   164  
   165  func (s *WorkerSuite) TestManyRestarts(c *gc.C) {
   166  	fix := NewFixture()
   167  	stub := fix.Run(c, func(context Context, worker *presence.Worker) {
   168  		context.WaitAlarms(1)
   169  		for i := 0; i < 4; i++ {
   170  			context.WaitPinger().Kill()
   171  			context.WaitAlarms(1)
   172  			context.AdvanceClock(fiveSeconds)
   173  		}
   174  		workertest.CheckAlive(c, worker)
   175  	})
   176  	stub.CheckCallNames(c, "Start", "Start", "Start", "Start", "Start")
   177  }