github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/lease/fixture_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/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	corelease "github.com/juju/juju/core/lease"
    14  	coretesting "github.com/juju/juju/testing"
    15  	"github.com/juju/juju/worker/lease"
    16  )
    17  
    18  const (
    19  	defaultMaxSleep = time.Hour
    20  	almostOneSecond = time.Second - time.Nanosecond
    21  )
    22  
    23  var (
    24  	defaultClockStart time.Time
    25  )
    26  
    27  func init() {
    28  	// We pick a time with a comfortable h:m:s component but:
    29  	//  (1) past the int32 unix epoch limit;
    30  	//  (2) at a 5ns offset to make sure we're not discarding precision;
    31  	//  (3) in a weird time zone.
    32  	value := "2073-03-03T01:00:00.000000005-08:40"
    33  	var err error
    34  	defaultClockStart, err = time.Parse(time.RFC3339Nano, value)
    35  	if err != nil {
    36  		panic(err)
    37  	}
    38  }
    39  
    40  // offset returns the result of defaultClockStart.Add(d); it exists to make
    41  // expiry tests easier to write.
    42  func offset(d time.Duration) time.Time {
    43  	return defaultClockStart.Add(d)
    44  }
    45  
    46  // almostSeconds returns a duration smaller than the supplied number of
    47  // seconds by one nanosecond.
    48  func almostSeconds(seconds int) time.Duration {
    49  	if seconds < 1 {
    50  		panic("unexpected")
    51  	}
    52  	return (time.Second * time.Duration(seconds)) - time.Nanosecond
    53  }
    54  
    55  // Fixture allows us to test a *lease.Manager with a usefully-mocked
    56  // clock.Clock and corelease.Client.
    57  type Fixture struct {
    58  
    59  	// leases contains the leases the corelease.Client should report when the
    60  	// test starts up.
    61  	leases map[string]corelease.Info
    62  
    63  	// expectCalls contains the calls that should be made to the corelease.Client
    64  	// in the course of a test. By specifying a callback you can cause the
    65  	// reported leases to change.
    66  	expectCalls []call
    67  
    68  	// expectDirty should be set for tests that purposefully abuse the manager
    69  	// to the extent that it returns an error on Wait(); tests that don't set
    70  	// this flag will check that the manager's shutdown error is nil.
    71  	expectDirty bool
    72  }
    73  
    74  // RunTest sets up a Manager and a Clock and passes them into the supplied
    75  // test function. The manager will be cleaned up afterwards.
    76  func (fix *Fixture) RunTest(c *gc.C, test func(*lease.Manager, *testing.Clock)) {
    77  	clock := testing.NewClock(defaultClockStart)
    78  	client := NewClient(fix.leases, fix.expectCalls)
    79  	manager, err := lease.NewManager(lease.ManagerConfig{
    80  		Clock:     clock,
    81  		Client:    client,
    82  		Secretary: Secretary{},
    83  		MaxSleep:  defaultMaxSleep,
    84  	})
    85  	c.Assert(err, jc.ErrorIsNil)
    86  	defer func() {
    87  		// Dirty tests will probably have stopped the manager anyway, but no
    88  		// sense leaving them around if things aren't exactly as we expect.
    89  		manager.Kill()
    90  		err := manager.Wait()
    91  		if !fix.expectDirty {
    92  			c.Check(err, jc.ErrorIsNil)
    93  		}
    94  	}()
    95  	defer client.Wait(c)
    96  	waitAlarms(c, clock, 1)
    97  	test(manager, clock)
    98  }
    99  
   100  func waitAlarms(c *gc.C, clock *testing.Clock, count int) {
   101  	timeout := time.After(coretesting.LongWait)
   102  	for i := 0; i < count; i++ {
   103  		select {
   104  		case <-clock.Alarms():
   105  		case <-timeout:
   106  			c.Fatalf("timed out waiting for %dth alarm set", i)
   107  		}
   108  	}
   109  }