github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/singular/fixture_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package singular_test 5 6 import ( 7 "sync" 8 "time" 9 10 "github.com/juju/clock" 11 "github.com/juju/clock/testclock" 12 "github.com/juju/errors" 13 "github.com/juju/testing" 14 jc "github.com/juju/testing/checkers" 15 gc "gopkg.in/check.v1" 16 "gopkg.in/juju/worker.v1" 17 18 "github.com/juju/juju/api/base" 19 "github.com/juju/juju/core/lease" 20 coretesting "github.com/juju/juju/testing" 21 "github.com/juju/juju/worker/singular" 22 ) 23 24 type fixture struct { 25 testing.Stub 26 } 27 28 func newFixture(c *gc.C, errs ...error) *fixture { 29 fix := &fixture{} 30 fix.Stub.SetErrors(errs...) 31 return fix 32 } 33 34 type testFunc func(*singular.FlagWorker, *testclock.Clock, func()) 35 36 func (fix *fixture) Run(c *gc.C, test testFunc) { 37 facade := newStubFacade(&fix.Stub) 38 clock := testclock.NewClock(time.Now()) 39 flagWorker, err := singular.NewFlagWorker(singular.FlagConfig{ 40 Facade: facade, 41 Clock: clock, 42 Duration: time.Minute, 43 }) 44 c.Assert(err, jc.ErrorIsNil) 45 46 done := make(chan struct{}) 47 go func() { 48 defer close(done) 49 defer worker.Stop(flagWorker) 50 defer facade.unblock() 51 test(flagWorker, clock, facade.unblock) 52 }() 53 select { 54 case <-done: 55 case <-time.After(coretesting.LongWait): 56 c.Fatalf("test timed out") 57 } 58 } 59 60 func (fix *fixture) CheckClaimWait(c *gc.C) { 61 fix.CheckCalls(c, []testing.StubCall{{ 62 FuncName: "Claim", 63 Args: []interface{}{time.Minute}, 64 }, { 65 FuncName: "Wait", 66 }}) 67 } 68 69 func (fix *fixture) CheckClaims(c *gc.C, count int) { 70 expect := make([]testing.StubCall, count) 71 for i := 0; i < count; i++ { 72 expect[i] = testing.StubCall{ 73 FuncName: "Claim", 74 Args: []interface{}{time.Minute}, 75 } 76 } 77 fix.CheckCalls(c, expect) 78 } 79 80 type stubFacade struct { 81 stub *testing.Stub 82 mu sync.Mutex 83 block chan struct{} 84 } 85 86 func newStubFacade(stub *testing.Stub) *stubFacade { 87 return &stubFacade{ 88 stub: stub, 89 block: make(chan struct{}), 90 } 91 } 92 93 func (facade *stubFacade) unblock() { 94 facade.mu.Lock() 95 defer facade.mu.Unlock() 96 select { 97 case <-facade.block: 98 default: 99 close(facade.block) 100 } 101 } 102 103 func (facade *stubFacade) Claim(duration time.Duration) error { 104 facade.stub.AddCall("Claim", duration) 105 return facade.stub.NextErr() 106 } 107 108 func (facade *stubFacade) Wait() error { 109 facade.stub.AddCall("Wait") 110 <-facade.block 111 return facade.stub.NextErr() 112 } 113 114 type stubWorker struct { 115 stub *testing.Stub 116 } 117 118 func newStubWorker(stub *testing.Stub) *stubWorker { 119 return &stubWorker{ 120 stub: stub, 121 } 122 } 123 124 func (w *stubWorker) Check() bool { 125 w.stub.MethodCall(w, "Check") 126 return true 127 } 128 129 func (w *stubWorker) Kill() { 130 w.stub.MethodCall(w, "Kill") 131 } 132 133 func (w *stubWorker) Wait() error { 134 w.stub.MethodCall(w, "Wait") 135 return w.stub.NextErr() 136 } 137 138 var errClaimDenied = errors.Trace(lease.ErrClaimDenied) 139 140 type fakeClock struct { 141 clock.Clock 142 } 143 144 type fakeFacade struct { 145 singular.Facade 146 } 147 148 type fakeWorker struct { 149 worker.Worker 150 } 151 152 type fakeAPICaller struct { 153 base.APICaller 154 }