github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/statushistorypruner/worker_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package statushistorypruner_test 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 coretesting "github.com/juju/juju/testing" 14 "github.com/juju/juju/worker" 15 "github.com/juju/juju/worker/statushistorypruner" 16 ) 17 18 type statusHistoryPrunerSuite struct { 19 coretesting.BaseSuite 20 } 21 22 var _ = gc.Suite(&statusHistoryPrunerSuite{}) 23 24 func (s *statusHistoryPrunerSuite) TestWorkerCallsPrune(c *gc.C) { 25 fakeTimer := newMockTimer(coretesting.LongWait) 26 27 fakeTimerFunc := func(d time.Duration) worker.PeriodicTimer { 28 // construction of timer should be with 0 because we intend it to 29 // run once before waiting. 30 c.Assert(d, gc.Equals, 0*time.Nanosecond) 31 return fakeTimer 32 } 33 facade := newFakeFacade() 34 conf := statushistorypruner.Config{ 35 Facade: facade, 36 MaxLogsPerEntity: 3, 37 PruneInterval: coretesting.ShortWait, 38 NewTimer: fakeTimerFunc, 39 } 40 41 pruner, err := statushistorypruner.New(conf) 42 c.Check(err, jc.ErrorIsNil) 43 s.AddCleanup(func(*gc.C) { 44 c.Assert(worker.Stop(pruner), jc.ErrorIsNil) 45 }) 46 47 err = fakeTimer.fire() 48 c.Check(err, jc.ErrorIsNil) 49 50 var passedLogs int 51 select { 52 case passedLogs = <-facade.passedMaxLogs: 53 case <-time.After(coretesting.LongWait): 54 c.Fatal("timed out waiting for passed logs to pruner") 55 } 56 c.Assert(passedLogs, gc.Equals, 3) 57 58 // Reset will have been called with the actual PruneInterval 59 var period time.Duration 60 select { 61 case period = <-fakeTimer.period: 62 case <-time.After(coretesting.LongWait): 63 c.Fatal("timed out waiting for period reset by pruner") 64 } 65 c.Assert(period, gc.Equals, coretesting.ShortWait) 66 } 67 68 func (s *statusHistoryPrunerSuite) TestWorkerWontCallPruneBeforeFiringTimer(c *gc.C) { 69 fakeTimer := newMockTimer(coretesting.LongWait) 70 71 fakeTimerFunc := func(d time.Duration) worker.PeriodicTimer { 72 // construction of timer should be with 0 because we intend it to 73 // run once before waiting. 74 c.Assert(d, gc.Equals, 0*time.Nanosecond) 75 return fakeTimer 76 } 77 facade := newFakeFacade() 78 conf := statushistorypruner.Config{ 79 Facade: facade, 80 MaxLogsPerEntity: 3, 81 PruneInterval: coretesting.ShortWait, 82 NewTimer: fakeTimerFunc, 83 } 84 85 pruner, err := statushistorypruner.New(conf) 86 c.Check(err, jc.ErrorIsNil) 87 s.AddCleanup(func(*gc.C) { 88 c.Assert(worker.Stop(pruner), jc.ErrorIsNil) 89 }) 90 91 select { 92 case <-facade.passedMaxLogs: 93 c.Fatal("called before firing timer.") 94 case <-time.After(coretesting.LongWait): 95 } 96 } 97 98 type mockTimer struct { 99 period chan time.Duration 100 c chan time.Time 101 } 102 103 func (t *mockTimer) Reset(d time.Duration) bool { 104 select { 105 case t.period <- d: 106 case <-time.After(coretesting.LongWait): 107 panic("timed out waiting for timer to reset") 108 } 109 return true 110 } 111 112 func (t *mockTimer) CountDown() <-chan time.Time { 113 return t.c 114 } 115 116 func (t *mockTimer) fire() error { 117 select { 118 case t.c <- time.Time{}: 119 case <-time.After(coretesting.LongWait): 120 return errors.New("timed out waiting for pruner to run") 121 } 122 return nil 123 } 124 125 func newMockTimer(d time.Duration) *mockTimer { 126 return &mockTimer{period: make(chan time.Duration, 1), 127 c: make(chan time.Time), 128 } 129 } 130 131 type fakeFacade struct { 132 passedMaxLogs chan int 133 } 134 135 func newFakeFacade() *fakeFacade { 136 return &fakeFacade{ 137 passedMaxLogs: make(chan int, 1), 138 } 139 } 140 141 // Prune implements Facade 142 func (f *fakeFacade) Prune(maxLogs int) error { 143 select { 144 case f.passedMaxLogs <- maxLogs: 145 case <-time.After(coretesting.LongWait): 146 return errors.New("timed out waiting for facade call Prune to run") 147 } 148 return nil 149 }