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 }