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