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 }