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  }