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