github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/resumer/resumer_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package resumer_test 5 6 import ( 7 "errors" 8 "time" 9 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/resumer" 16 "github.com/juju/juju/worker/workertest" 17 ) 18 19 type ResumerSuite struct { 20 testing.IsolationSuite 21 } 22 23 var _ = gc.Suite(&ResumerSuite{}) 24 25 func (*ResumerSuite) TestImmediateFailure(c *gc.C) { 26 fix := newFixture(errors.New("zap")) 27 stub := fix.Run(c, func(_ *testing.Clock, worker *resumer.Resumer) { 28 err := workertest.CheckKilled(c, worker) 29 c.Check(err, gc.ErrorMatches, "cannot resume transactions: zap") 30 }) 31 stub.CheckCallNames(c, "ResumeTransactions") 32 } 33 34 func (*ResumerSuite) TestWaitsToResume(c *gc.C) { 35 fix := newFixture(nil, errors.New("unexpected")) 36 stub := fix.Run(c, func(clock *testing.Clock, worker *resumer.Resumer) { 37 waitAlarms(c, clock, 2) 38 clock.Advance(time.Hour - time.Nanosecond) 39 workertest.CheckAlive(c, worker) 40 workertest.CleanKill(c, worker) 41 }) 42 stub.CheckCallNames(c, "ResumeTransactions") 43 } 44 45 func (*ResumerSuite) TestResumesAfterWait(c *gc.C) { 46 fix := newFixture(nil, nil, errors.New("unexpected")) 47 stub := fix.Run(c, func(clock *testing.Clock, worker *resumer.Resumer) { 48 waitAlarms(c, clock, 2) 49 clock.Advance(time.Hour) 50 waitAlarms(c, clock, 1) 51 workertest.CleanKill(c, worker) 52 }) 53 stub.CheckCallNames(c, "ResumeTransactions", "ResumeTransactions") 54 } 55 56 func (*ResumerSuite) TestSeveralResumes(c *gc.C) { 57 fix := newFixture(nil, nil, nil, errors.New("unexpected")) 58 stub := fix.Run(c, func(clock *testing.Clock, worker *resumer.Resumer) { 59 waitAlarms(c, clock, 2) 60 clock.Advance(time.Hour) 61 waitAlarms(c, clock, 1) 62 clock.Advance(time.Hour) 63 waitAlarms(c, clock, 1) 64 workertest.CleanKill(c, worker) 65 }) 66 stub.CheckCallNames(c, "ResumeTransactions", "ResumeTransactions", "ResumeTransactions") 67 } 68 69 func newFixture(errs ...error) *fixture { 70 return &fixture{errors: errs} 71 } 72 73 type fixture struct { 74 errors []error 75 } 76 77 type TestFunc func(*testing.Clock, *resumer.Resumer) 78 79 func (fix fixture) Run(c *gc.C, test TestFunc) *testing.Stub { 80 81 stub := &testing.Stub{} 82 stub.SetErrors(fix.errors...) 83 clock := testing.NewClock(time.Now()) 84 facade := newMockFacade(stub) 85 86 worker, err := resumer.NewResumer(resumer.Config{ 87 Facade: facade, 88 Interval: time.Hour, 89 Clock: clock, 90 }) 91 c.Assert(err, jc.ErrorIsNil) 92 defer workertest.DirtyKill(c, worker) 93 94 test(clock, worker) 95 return stub 96 } 97 98 func newMockFacade(stub *testing.Stub) *mockFacade { 99 return &mockFacade{stub: stub} 100 } 101 102 type mockFacade struct { 103 stub *testing.Stub 104 } 105 106 func (mock *mockFacade) ResumeTransactions() error { 107 mock.stub.AddCall("ResumeTransactions") 108 return mock.stub.NextErr() 109 } 110 111 func waitAlarms(c *gc.C, clock *testing.Clock, count int) { 112 timeout := time.After(coretesting.LongWait) 113 for i := 0; i < count; i++ { 114 select { 115 case <-clock.Alarms(): 116 case <-timeout: 117 c.Fatalf("timed out waiting for alarm %d", i) 118 } 119 } 120 }