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