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