github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/lease/client_operation_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 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/core/lease" 13 ) 14 15 // ClientOperationSuite verifies behaviour when claiming, extending, and expiring leases. 16 type ClientOperationSuite struct { 17 FixtureSuite 18 } 19 20 var _ = gc.Suite(&ClientOperationSuite{}) 21 22 func (s *ClientOperationSuite) TestClaimLease(c *gc.C) { 23 fix := s.EasyFixture(c) 24 25 leaseDuration := time.Minute 26 err := fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 27 c.Assert(err, jc.ErrorIsNil) 28 29 // The lease is claimed, for an exact duration. 30 c.Check("name", fix.Holder(), "holder") 31 exactExpiry := fix.Zero.Add(leaseDuration) 32 c.Check("name", fix.Expiry(), exactExpiry) 33 } 34 35 func (s *ClientOperationSuite) TestClaimMultipleLeases(c *gc.C) { 36 fix := s.EasyFixture(c) 37 38 err := fix.Client.ClaimLease("short", lease.Request{"holder", time.Second}) 39 c.Assert(err, jc.ErrorIsNil) 40 err = fix.Client.ClaimLease("medium", lease.Request{"grasper", time.Minute}) 41 c.Assert(err, jc.ErrorIsNil) 42 err = fix.Client.ClaimLease("long", lease.Request{"clutcher", time.Hour}) 43 c.Assert(err, jc.ErrorIsNil) 44 45 check := func(name, holder string, duration time.Duration) { 46 c.Check(name, fix.Holder(), holder) 47 expiry := fix.Zero.Add(duration) 48 c.Check(name, fix.Expiry(), expiry) 49 } 50 check("short", "holder", time.Second) 51 check("medium", "grasper", time.Minute) 52 check("long", "clutcher", time.Hour) 53 } 54 55 func (s *ClientOperationSuite) TestCannotClaimLeaseTwice(c *gc.C) { 56 fix := s.EasyFixture(c) 57 58 leaseDuration := time.Minute 59 err := fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 60 c.Assert(err, jc.ErrorIsNil) 61 62 // The lease is claimed and cannot be claimed again... 63 err = fix.Client.ClaimLease("name", lease.Request{"other-holder", leaseDuration}) 64 c.Check(err, gc.Equals, lease.ErrInvalid) 65 66 // ...not even for the same holder... 67 err = fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 68 c.Check(err, gc.Equals, lease.ErrInvalid) 69 70 // ...not even when the lease has expired. 71 fix.Clock.Advance(time.Hour) 72 err = fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 73 c.Check(err, gc.Equals, lease.ErrInvalid) 74 } 75 76 func (s *ClientOperationSuite) TestExtendLease(c *gc.C) { 77 fix := s.EasyFixture(c) 78 err := fix.Client.ClaimLease("name", lease.Request{"holder", time.Second}) 79 c.Assert(err, jc.ErrorIsNil) 80 81 leaseDuration := time.Minute 82 err = fix.Client.ExtendLease("name", lease.Request{"holder", leaseDuration}) 83 c.Assert(err, jc.ErrorIsNil) 84 85 // The lease is extended, *to* (not by) the exact duration requested. 86 c.Check("name", fix.Holder(), "holder") 87 exactExpiry := fix.Zero.Add(leaseDuration) 88 c.Check("name", fix.Expiry(), exactExpiry) 89 } 90 91 func (s *ClientOperationSuite) TestCanExtendStaleLease(c *gc.C) { 92 fix := s.EasyFixture(c) 93 err := fix.Client.ClaimLease("name", lease.Request{"holder", time.Second}) 94 c.Assert(err, jc.ErrorIsNil) 95 96 // Advance the clock past lease expiry time, then extend. 97 fix.Clock.Advance(time.Minute) 98 extendTime := fix.Clock.Now() 99 leaseDuration := time.Minute 100 err = fix.Client.ExtendLease("name", lease.Request{"holder", leaseDuration}) 101 c.Assert(err, jc.ErrorIsNil) 102 103 // The lease is extended fine, *to* (not by) the exact duration requested. 104 c.Check("name", fix.Holder(), "holder") 105 exactExpiry := extendTime.Add(leaseDuration) 106 c.Check("name", fix.Expiry(), exactExpiry) 107 } 108 109 func (s *ClientOperationSuite) TestExtendLeaseCannotChangeHolder(c *gc.C) { 110 fix := s.EasyFixture(c) 111 err := fix.Client.ClaimLease("name", lease.Request{"holder", time.Second}) 112 c.Assert(err, jc.ErrorIsNil) 113 114 leaseDuration := time.Minute 115 err = fix.Client.ExtendLease("name", lease.Request{"other-holder", leaseDuration}) 116 c.Assert(err, gc.Equals, lease.ErrInvalid) 117 } 118 119 func (s *ClientOperationSuite) TestExtendLeaseCannotShortenLease(c *gc.C) { 120 fix := s.EasyFixture(c) 121 leaseDuration := time.Minute 122 err := fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 123 c.Assert(err, jc.ErrorIsNil) 124 125 // A non-extension will succeed -- we can still honour all guarantees 126 // implied by a nil error... 127 err = fix.Client.ExtendLease("name", lease.Request{"holder", time.Second}) 128 c.Assert(err, jc.ErrorIsNil) 129 130 // ...but we can't make it any shorter, lest we fail to honour the 131 // guarantees implied by the original lease. 132 c.Check("name", fix.Holder(), "holder") 133 exactExpiry := fix.Zero.Add(leaseDuration) 134 c.Check("name", fix.Expiry(), exactExpiry) 135 } 136 137 func (s *ClientOperationSuite) TestCannotExpireLeaseBeforeExpiry(c *gc.C) { 138 fix := s.EasyFixture(c) 139 leaseDuration := time.Minute 140 err := fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 141 c.Assert(err, jc.ErrorIsNil) 142 143 // It can't be expired until after the duration has elapsed. 144 fix.Clock.Advance(leaseDuration) 145 err = fix.Client.ExpireLease("name") 146 c.Assert(err, gc.Equals, lease.ErrInvalid) 147 } 148 149 func (s *ClientOperationSuite) TestExpireLeaseAfterExpiry(c *gc.C) { 150 fix := s.EasyFixture(c) 151 leaseDuration := time.Minute 152 err := fix.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 153 c.Assert(err, jc.ErrorIsNil) 154 155 // It can be expired as soon as the duration has elapsed. 156 fix.Clock.Advance(leaseDuration + time.Nanosecond) 157 err = fix.Client.ExpireLease("name") 158 c.Assert(err, jc.ErrorIsNil) 159 c.Check("name", fix.Holder(), "") 160 } 161 162 func (s *ClientOperationSuite) TestCannotExpireUnheldLease(c *gc.C) { 163 fix := s.EasyFixture(c) 164 err := fix.Client.ExpireLease("name") 165 c.Assert(err, gc.Equals, lease.ErrInvalid) 166 }