github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/state/lease/client_persistence_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 "gopkg.in/mgo.v2/bson" 12 13 "github.com/juju/juju/state/lease" 14 ) 15 16 // ClientPersistenceSuite checks that the operations really affect the DB in 17 // the expected way. 18 type ClientPersistenceSuite struct { 19 FixtureSuite 20 } 21 22 var _ = gc.Suite(&ClientPersistenceSuite{}) 23 24 func (s *ClientPersistenceSuite) TestNewClientInvalidClockDoc(c *gc.C) { 25 config := lease.ClientConfig{ 26 Id: "client", 27 Namespace: "namespace", 28 Collection: "collection", 29 Mongo: NewMongo(s.db), 30 Clock: lease.SystemClock{}, 31 } 32 dbKey := "clock#namespace#" 33 err := s.db.C("collection").Insert(bson.M{"_id": dbKey}) 34 c.Assert(err, jc.ErrorIsNil) 35 36 client, err := lease.NewClient(config) 37 c.Check(client, gc.IsNil) 38 c.Check(err, gc.ErrorMatches, `corrupt clock document: invalid type ""`) 39 } 40 41 func (s *ClientPersistenceSuite) TestNewClientInvalidLeaseDoc(c *gc.C) { 42 config := lease.ClientConfig{ 43 Id: "client", 44 Namespace: "namespace", 45 Collection: "collection", 46 Mongo: NewMongo(s.db), 47 Clock: lease.SystemClock{}, 48 } 49 err := s.db.C("collection").Insert(bson.M{ 50 "_id": "snagglepuss", 51 "type": "lease", 52 "namespace": "namespace", 53 }) 54 c.Assert(err, jc.ErrorIsNil) 55 56 client, err := lease.NewClient(config) 57 c.Check(client, gc.IsNil) 58 c.Check(err, gc.ErrorMatches, `corrupt lease document "snagglepuss": inconsistent _id`) 59 } 60 61 func (s *ClientPersistenceSuite) TestNewClientMissingClockDoc(c *gc.C) { 62 // The database starts out empty, so just creating the fixture is enough 63 // to test this code path. 64 s.EasyFixture(c) 65 } 66 67 func (s *ClientPersistenceSuite) TestNewClientExtantClockDoc(c *gc.C) { 68 // Empty database: new Client creates clock doc. 69 s.EasyFixture(c) 70 71 // Clock doc exists; new Client created successfully. 72 s.EasyFixture(c) 73 } 74 75 func (s *ClientPersistenceSuite) TestClaimLease(c *gc.C) { 76 fix1 := s.EasyFixture(c) 77 leaseDuration := time.Minute 78 err := fix1.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 79 c.Assert(err, jc.ErrorIsNil) 80 81 // Same client id, same clock, new instance: sees exact same lease. 82 fix2 := s.EasyFixture(c) 83 c.Check("name", fix2.Holder(), "holder") 84 exactExpiry := fix1.Zero.Add(leaseDuration) 85 c.Check("name", fix2.Expiry(), exactExpiry) 86 } 87 88 func (s *ClientPersistenceSuite) TestExtendLease(c *gc.C) { 89 fix1 := s.EasyFixture(c) 90 err := fix1.Client.ClaimLease("name", lease.Request{"holder", time.Second}) 91 c.Assert(err, jc.ErrorIsNil) 92 leaseDuration := time.Minute 93 err = fix1.Client.ExtendLease("name", lease.Request{"holder", leaseDuration}) 94 c.Assert(err, jc.ErrorIsNil) 95 96 // Same client id, same clock, new instance: sees exact same lease. 97 fix2 := s.EasyFixture(c) 98 c.Check("name", fix2.Holder(), "holder") 99 exactExpiry := fix1.Zero.Add(leaseDuration) 100 c.Check("name", fix2.Expiry(), exactExpiry) 101 } 102 103 func (s *ClientPersistenceSuite) TestExpireLease(c *gc.C) { 104 fix1 := s.EasyFixture(c) 105 leaseDuration := time.Minute 106 err := fix1.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 107 c.Assert(err, jc.ErrorIsNil) 108 fix1.Clock.Advance(leaseDuration + time.Nanosecond) 109 err = fix1.Client.ExpireLease("name") 110 c.Assert(err, jc.ErrorIsNil) 111 112 // Same client id, same clock, new instance: sees no lease. 113 fix2 := s.EasyFixture(c) 114 c.Check("name", fix2.Holder(), "") 115 } 116 117 func (s *ClientPersistenceSuite) TestNamespaceIsolation(c *gc.C) { 118 fix1 := s.EasyFixture(c) 119 leaseDuration := time.Minute 120 err := fix1.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 121 c.Assert(err, jc.ErrorIsNil) 122 123 // Same client id, same clock, different namespace: sees no lease. 124 fix2 := s.NewFixture(c, FixtureParams{ 125 Namespace: "different-namespace", 126 }) 127 c.Check("name", fix2.Holder(), "") 128 } 129 130 func (s *ClientPersistenceSuite) TestTimezoneChanges(c *gc.C) { 131 fix1 := s.EasyFixture(c) 132 leaseDuration := time.Minute 133 err := fix1.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 134 c.Assert(err, jc.ErrorIsNil) 135 136 // Same client can come up in a different timezone and still work correctly. 137 fix2 := s.NewFixture(c, FixtureParams{ 138 ClockStart: fix1.Zero.In(time.FixedZone("somewhere", -1234)), 139 }) 140 c.Check("name", fix2.Holder(), "holder") 141 exactExpiry := fix2.Zero.Add(leaseDuration) 142 c.Check("name", fix2.Expiry(), exactExpiry) 143 } 144 145 func (s *ClientPersistenceSuite) TestTimezoneIsolation(c *gc.C) { 146 fix1 := s.EasyFixture(c) 147 leaseDuration := time.Minute 148 err := fix1.Client.ClaimLease("name", lease.Request{"holder", leaseDuration}) 149 c.Assert(err, jc.ErrorIsNil) 150 151 // Different client *and* different timezone; but clock agrees perfectly, 152 // so we still see no skew. 153 fix2 := s.NewFixture(c, FixtureParams{ 154 Id: "remote-client", 155 ClockStart: fix1.Zero.UTC(), 156 }) 157 c.Check("name", fix2.Holder(), "holder") 158 exactExpiry := fix1.Zero.Add(leaseDuration).UTC() 159 c.Check("name", fix2.Expiry(), exactExpiry) 160 }