github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/lease/manager_expire_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package lease_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 corelease "github.com/juju/juju/core/lease" 15 coretesting "github.com/juju/juju/testing" 16 "github.com/juju/juju/worker/lease" 17 ) 18 19 type ExpireSuite struct { 20 testing.IsolationSuite 21 } 22 23 var _ = gc.Suite(&ExpireSuite{}) 24 25 func (s *ExpireSuite) TestStartup_ExpiryInPast(c *gc.C) { 26 fix := &Fixture{ 27 leases: map[string]corelease.Info{ 28 "redis": corelease.Info{Expiry: offset(-time.Second)}, 29 }, 30 expectCalls: []call{{ 31 method: "Refresh", 32 }, { 33 method: "ExpireLease", 34 args: []interface{}{"redis"}, 35 callback: func(leases map[string]corelease.Info) { 36 delete(leases, "redis") 37 }, 38 }}, 39 } 40 fix.RunTest(c, func(_ *lease.Manager, _ *coretesting.Clock) {}) 41 } 42 43 func (s *ExpireSuite) TestStartup_ExpiryInFuture(c *gc.C) { 44 fix := &Fixture{ 45 leases: map[string]corelease.Info{ 46 "redis": corelease.Info{Expiry: offset(time.Second)}, 47 }, 48 } 49 fix.RunTest(c, func(_ *lease.Manager, clock *coretesting.Clock) { 50 clock.Advance(almostSeconds(1)) 51 }) 52 } 53 54 func (s *ExpireSuite) TestStartup_ExpiryInFuture_TimePasses(c *gc.C) { 55 fix := &Fixture{ 56 leases: map[string]corelease.Info{ 57 "redis": corelease.Info{Expiry: offset(time.Second)}, 58 }, 59 expectCalls: []call{{ 60 method: "Refresh", 61 }, { 62 method: "ExpireLease", 63 args: []interface{}{"redis"}, 64 callback: func(leases map[string]corelease.Info) { 65 delete(leases, "redis") 66 }, 67 }}, 68 } 69 fix.RunTest(c, func(_ *lease.Manager, clock *coretesting.Clock) { 70 clock.Advance(time.Second) 71 }) 72 } 73 74 func (s *ExpireSuite) TestStartup_NoExpiry_NotLongEnough(c *gc.C) { 75 fix := &Fixture{} 76 fix.RunTest(c, func(_ *lease.Manager, clock *coretesting.Clock) { 77 clock.Advance(almostSeconds(3600)) 78 }) 79 } 80 81 func (s *ExpireSuite) TestStartup_NoExpiry_LongEnough(c *gc.C) { 82 fix := &Fixture{ 83 leases: map[string]corelease.Info{ 84 "goose": corelease.Info{Expiry: offset(3 * time.Hour)}, 85 }, 86 expectCalls: []call{{ 87 method: "Refresh", 88 callback: func(leases map[string]corelease.Info) { 89 leases["redis"] = corelease.Info{ 90 Expiry: offset(time.Minute), 91 } 92 }, 93 }, { 94 method: "ExpireLease", 95 args: []interface{}{"redis"}, 96 callback: func(leases map[string]corelease.Info) { 97 delete(leases, "redis") 98 }, 99 }}, 100 } 101 fix.RunTest(c, func(_ *lease.Manager, clock *coretesting.Clock) { 102 clock.Advance(time.Hour) 103 }) 104 } 105 106 func (s *ExpireSuite) TestExpire_ErrInvalid_Expired(c *gc.C) { 107 fix := &Fixture{ 108 leases: map[string]corelease.Info{ 109 "redis": corelease.Info{Expiry: offset(time.Second)}, 110 }, 111 expectCalls: []call{{ 112 method: "Refresh", 113 }, { 114 method: "ExpireLease", 115 args: []interface{}{"redis"}, 116 err: corelease.ErrInvalid, 117 callback: func(leases map[string]corelease.Info) { 118 delete(leases, "redis") 119 }, 120 }}, 121 } 122 fix.RunTest(c, func(_ *lease.Manager, clock *coretesting.Clock) { 123 clock.Advance(time.Second) 124 }) 125 } 126 127 func (s *ExpireSuite) TestExpire_ErrInvalid_Updated(c *gc.C) { 128 fix := &Fixture{ 129 leases: map[string]corelease.Info{ 130 "redis": corelease.Info{Expiry: offset(time.Second)}, 131 }, 132 expectCalls: []call{{ 133 method: "Refresh", 134 }, { 135 method: "ExpireLease", 136 args: []interface{}{"redis"}, 137 err: corelease.ErrInvalid, 138 callback: func(leases map[string]corelease.Info) { 139 leases["redis"] = corelease.Info{Expiry: offset(time.Minute)} 140 }, 141 }}, 142 } 143 fix.RunTest(c, func(_ *lease.Manager, clock *coretesting.Clock) { 144 clock.Advance(time.Second) 145 }) 146 } 147 148 func (s *ExpireSuite) TestExpire_OtherError(c *gc.C) { 149 fix := &Fixture{ 150 leases: map[string]corelease.Info{ 151 "redis": corelease.Info{Expiry: offset(time.Second)}, 152 }, 153 expectCalls: []call{{ 154 method: "Refresh", 155 }, { 156 method: "ExpireLease", 157 args: []interface{}{"redis"}, 158 err: errors.New("snarfblat hobalob"), 159 }}, 160 expectDirty: true, 161 } 162 fix.RunTest(c, func(manager *lease.Manager, clock *coretesting.Clock) { 163 clock.Advance(time.Second) 164 err := manager.Wait() 165 c.Check(err, gc.ErrorMatches, "snarfblat hobalob") 166 }) 167 } 168 169 func (s *ExpireSuite) TestClaim_ExpiryInFuture(c *gc.C) { 170 fix := &Fixture{ 171 expectCalls: []call{{ 172 method: "ClaimLease", 173 args: []interface{}{"redis", corelease.Request{"redis/0", time.Minute}}, 174 callback: func(leases map[string]corelease.Info) { 175 leases["redis"] = corelease.Info{ 176 Holder: "redis/0", 177 Expiry: offset(63 * time.Second), 178 } 179 }, 180 }}, 181 } 182 fix.RunTest(c, func(manager *lease.Manager, clock *coretesting.Clock) { 183 // Ask for a minute, actually get 63s. Don't expire early. 184 err := manager.Claim("redis", "redis/0", time.Minute) 185 c.Assert(err, jc.ErrorIsNil) 186 clock.Advance(almostSeconds(63)) 187 }) 188 } 189 190 func (s *ExpireSuite) TestClaim_ExpiryInFuture_TimePasses(c *gc.C) { 191 fix := &Fixture{ 192 expectCalls: []call{{ 193 method: "ClaimLease", 194 args: []interface{}{"redis", corelease.Request{"redis/0", time.Minute}}, 195 callback: func(leases map[string]corelease.Info) { 196 leases["redis"] = corelease.Info{ 197 Holder: "redis/0", 198 Expiry: offset(63 * time.Second), 199 } 200 }, 201 }, { 202 method: "Refresh", 203 }, { 204 method: "ExpireLease", 205 args: []interface{}{"redis"}, 206 callback: func(leases map[string]corelease.Info) { 207 delete(leases, "redis") 208 }, 209 }}, 210 } 211 fix.RunTest(c, func(manager *lease.Manager, clock *coretesting.Clock) { 212 // Ask for a minute, actually get 63s. Expire on time. 213 err := manager.Claim("redis", "redis/0", time.Minute) 214 c.Assert(err, jc.ErrorIsNil) 215 clock.Advance(63 * time.Second) 216 }) 217 } 218 219 func (s *ExpireSuite) TestExtend_ExpiryInFuture(c *gc.C) { 220 fix := &Fixture{ 221 leases: map[string]corelease.Info{ 222 "redis": corelease.Info{ 223 Holder: "redis/0", 224 Expiry: offset(time.Second), 225 }, 226 }, 227 expectCalls: []call{{ 228 method: "ExtendLease", 229 args: []interface{}{"redis", corelease.Request{"redis/0", time.Minute}}, 230 callback: func(leases map[string]corelease.Info) { 231 leases["redis"] = corelease.Info{ 232 Holder: "redis/0", 233 Expiry: offset(63 * time.Second), 234 } 235 }, 236 }}, 237 } 238 fix.RunTest(c, func(manager *lease.Manager, clock *coretesting.Clock) { 239 // Ask for a minute, actually get 63s. Don't expire early. 240 err := manager.Claim("redis", "redis/0", time.Minute) 241 c.Assert(err, jc.ErrorIsNil) 242 clock.Advance(almostSeconds(63)) 243 }) 244 } 245 246 func (s *ExpireSuite) TestExtend_ExpiryInFuture_TimePasses(c *gc.C) { 247 fix := &Fixture{ 248 leases: map[string]corelease.Info{ 249 "redis": corelease.Info{ 250 Holder: "redis/0", 251 Expiry: offset(time.Second), 252 }, 253 }, 254 expectCalls: []call{{ 255 method: "ExtendLease", 256 args: []interface{}{"redis", corelease.Request{"redis/0", time.Minute}}, 257 callback: func(leases map[string]corelease.Info) { 258 leases["redis"] = corelease.Info{ 259 Holder: "redis/0", 260 Expiry: offset(63 * time.Second), 261 } 262 }, 263 }, { 264 method: "Refresh", 265 }, { 266 method: "ExpireLease", 267 args: []interface{}{"redis"}, 268 callback: func(leases map[string]corelease.Info) { 269 delete(leases, "redis") 270 }, 271 }}, 272 } 273 fix.RunTest(c, func(manager *lease.Manager, clock *coretesting.Clock) { 274 // Ask for a minute, actually get 63s. Expire on time. 275 err := manager.Claim("redis", "redis/0", time.Minute) 276 c.Assert(err, jc.ErrorIsNil) 277 clock.Advance(63 * time.Second) 278 }) 279 } 280 281 func (s *ExpireSuite) TestExpire_Multiple(c *gc.C) { 282 fix := &Fixture{ 283 leases: map[string]corelease.Info{ 284 "redis": corelease.Info{ 285 Holder: "redis/0", 286 Expiry: offset(time.Second), 287 }, 288 "store": corelease.Info{ 289 Holder: "store/3", 290 Expiry: offset(5 * time.Second), 291 }, 292 "tokumx": corelease.Info{ 293 Holder: "tokumx/5", 294 Expiry: offset(10 * time.Second), // will not expire. 295 }, 296 "ultron": corelease.Info{ 297 Holder: "ultron/7", 298 Expiry: offset(5 * time.Second), 299 }, 300 "vvvvvv": corelease.Info{ 301 Holder: "vvvvvv/2", 302 Expiry: offset(time.Second), // would expire, but errors first. 303 }, 304 }, 305 expectCalls: []call{{ 306 method: "Refresh", 307 }, { 308 method: "ExpireLease", 309 args: []interface{}{"redis"}, 310 callback: func(leases map[string]corelease.Info) { 311 delete(leases, "redis") 312 }, 313 }, { 314 method: "ExpireLease", 315 args: []interface{}{"store"}, 316 err: corelease.ErrInvalid, 317 callback: func(leases map[string]corelease.Info) { 318 delete(leases, "store") 319 }, 320 }, { 321 method: "ExpireLease", 322 args: []interface{}{"ultron"}, 323 err: errors.New("what is this?"), 324 }}, 325 expectDirty: true, 326 } 327 fix.RunTest(c, func(manager *lease.Manager, clock *coretesting.Clock) { 328 clock.Advance(5 * time.Second) 329 err := manager.Wait() 330 c.Check(err, gc.ErrorMatches, "what is this\\?") 331 }) 332 }