github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 }