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