github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/charmrevision/worker_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package charmrevision_test 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 coretesting "github.com/juju/juju/testing" 15 "github.com/juju/juju/worker" 16 "github.com/juju/juju/worker/charmrevision" 17 ) 18 19 type WorkerSuite struct { 20 testing.IsolationSuite 21 } 22 23 var _ = gc.Suite(&WorkerSuite{}) 24 25 func (s *WorkerSuite) TestUpdatesImmediately(c *gc.C) { 26 fix := newFixture(time.Minute) 27 fix.cleanTest(c, func(_ worker.Worker) { 28 fix.waitCall(c) 29 fix.waitNoCall(c) 30 }) 31 fix.revisionUpdater.stub.CheckCallNames(c, "UpdateLatestRevisions") 32 } 33 34 func (s *WorkerSuite) TestNoMoreUpdatesUntilPeriod(c *gc.C) { 35 fix := newFixture(time.Minute) 36 fix.cleanTest(c, func(_ worker.Worker) { 37 fix.waitCall(c) 38 fix.clock.Advance(time.Minute - time.Nanosecond) 39 fix.waitNoCall(c) 40 }) 41 fix.revisionUpdater.stub.CheckCallNames(c, "UpdateLatestRevisions") 42 } 43 44 func (s *WorkerSuite) TestUpdatesAfterPeriod(c *gc.C) { 45 fix := newFixture(time.Minute) 46 fix.cleanTest(c, func(_ worker.Worker) { 47 fix.waitCall(c) 48 fix.clock.Advance(time.Minute) 49 fix.waitCall(c) 50 fix.waitNoCall(c) 51 }) 52 fix.revisionUpdater.stub.CheckCallNames(c, "UpdateLatestRevisions", "UpdateLatestRevisions") 53 } 54 55 func (s *WorkerSuite) TestImmediateUpdateError(c *gc.C) { 56 fix := newFixture(time.Minute) 57 fix.revisionUpdater.stub.SetErrors( 58 errors.New("no updates for you"), 59 ) 60 fix.dirtyTest(c, func(w worker.Worker) { 61 fix.waitCall(c) 62 c.Check(w.Wait(), gc.ErrorMatches, "no updates for you") 63 fix.waitNoCall(c) 64 }) 65 fix.revisionUpdater.stub.CheckCallNames(c, "UpdateLatestRevisions") 66 } 67 68 func (s *WorkerSuite) TestDelayedUpdateError(c *gc.C) { 69 fix := newFixture(time.Minute) 70 fix.revisionUpdater.stub.SetErrors( 71 nil, 72 errors.New("no more updates for you"), 73 ) 74 fix.dirtyTest(c, func(w worker.Worker) { 75 fix.waitCall(c) 76 fix.clock.Advance(time.Minute) 77 fix.waitCall(c) 78 c.Check(w.Wait(), gc.ErrorMatches, "no more updates for you") 79 fix.waitNoCall(c) 80 }) 81 fix.revisionUpdater.stub.CheckCallNames(c, "UpdateLatestRevisions", "UpdateLatestRevisions") 82 } 83 84 // workerFixture isolates a charmrevision worker for testing. 85 type workerFixture struct { 86 revisionUpdater mockRevisionUpdater 87 clock *coretesting.Clock 88 period time.Duration 89 } 90 91 func newFixture(period time.Duration) workerFixture { 92 return workerFixture{ 93 revisionUpdater: newMockRevisionUpdater(), 94 clock: coretesting.NewClock(time.Now()), 95 period: period, 96 } 97 } 98 99 type testFunc func(worker.Worker) 100 101 func (fix workerFixture) cleanTest(c *gc.C, test testFunc) { 102 fix.runTest(c, test, true) 103 } 104 105 func (fix workerFixture) dirtyTest(c *gc.C, test testFunc) { 106 fix.runTest(c, test, false) 107 } 108 109 func (fix workerFixture) runTest(c *gc.C, test testFunc, checkWaitErr bool) { 110 w, err := charmrevision.NewWorker(charmrevision.Config{ 111 RevisionUpdater: fix.revisionUpdater, 112 Clock: fix.clock, 113 Period: fix.period, 114 }) 115 c.Assert(err, jc.ErrorIsNil) 116 defer func() { 117 err := worker.Stop(w) 118 if checkWaitErr { 119 c.Check(err, jc.ErrorIsNil) 120 } 121 }() 122 test(w) 123 } 124 125 func (fix workerFixture) waitCall(c *gc.C) { 126 select { 127 case <-fix.revisionUpdater.calls: 128 case <-time.After(coretesting.LongWait): 129 c.Fatalf("timed out") 130 } 131 } 132 133 func (fix workerFixture) waitNoCall(c *gc.C) { 134 select { 135 case <-fix.revisionUpdater.calls: 136 c.Fatalf("unexpected revisionUpdater call") 137 case <-time.After(coretesting.ShortWait): 138 } 139 } 140 141 // mockRevisionUpdater records (and notifies of) calls made to UpdateLatestRevisions. 142 type mockRevisionUpdater struct { 143 stub *testing.Stub 144 calls chan struct{} 145 } 146 147 func newMockRevisionUpdater() mockRevisionUpdater { 148 return mockRevisionUpdater{ 149 stub: &testing.Stub{}, 150 calls: make(chan struct{}, 1000), 151 } 152 } 153 154 func (mock mockRevisionUpdater) UpdateLatestRevisions() error { 155 mock.stub.AddCall("UpdateLatestRevisions") 156 mock.calls <- struct{}{} 157 return mock.stub.NextErr() 158 }