github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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/errors" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/utils/clock" 14 gc "gopkg.in/check.v1" 15 "gopkg.in/juju/names.v2" 16 17 "github.com/juju/juju/agent" 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" 22 "github.com/juju/juju/worker/singular" 23 ) 24 25 type fixture struct { 26 testing.Stub 27 } 28 29 func newFixture(c *gc.C, errs ...error) *fixture { 30 fix := &fixture{} 31 fix.Stub.SetErrors(errs...) 32 return fix 33 } 34 35 type testFunc func(*singular.FlagWorker, *testing.Clock, func()) 36 37 func (fix *fixture) Run(c *gc.C, test testFunc) { 38 facade := newStubFacade(&fix.Stub) 39 clock := testing.NewClock(time.Now()) 40 flagWorker, err := singular.NewFlagWorker(singular.FlagConfig{ 41 Facade: facade, 42 Clock: clock, 43 Duration: time.Minute, 44 }) 45 c.Assert(err, jc.ErrorIsNil) 46 47 done := make(chan struct{}) 48 go func() { 49 defer close(done) 50 defer worker.Stop(flagWorker) 51 defer facade.unblock() 52 test(flagWorker, clock, facade.unblock) 53 }() 54 select { 55 case <-done: 56 case <-time.After(coretesting.LongWait): 57 c.Fatalf("test timed out") 58 } 59 } 60 61 func (fix *fixture) CheckClaimWait(c *gc.C) { 62 fix.CheckCalls(c, []testing.StubCall{{ 63 FuncName: "Claim", 64 Args: []interface{}{time.Minute}, 65 }, { 66 FuncName: "Wait", 67 }}) 68 } 69 70 func (fix *fixture) CheckClaims(c *gc.C, count int) { 71 expect := make([]testing.StubCall, count) 72 for i := 0; i < count; i++ { 73 expect[i] = testing.StubCall{ 74 FuncName: "Claim", 75 Args: []interface{}{time.Minute}, 76 } 77 } 78 fix.CheckCalls(c, expect) 79 } 80 81 type stubFacade struct { 82 stub *testing.Stub 83 mu sync.Mutex 84 block chan struct{} 85 } 86 87 func newStubFacade(stub *testing.Stub) *stubFacade { 88 return &stubFacade{ 89 stub: stub, 90 block: make(chan struct{}), 91 } 92 } 93 94 func (facade *stubFacade) unblock() { 95 facade.mu.Lock() 96 defer facade.mu.Unlock() 97 select { 98 case <-facade.block: 99 default: 100 close(facade.block) 101 } 102 } 103 104 func (facade *stubFacade) Claim(duration time.Duration) error { 105 facade.stub.AddCall("Claim", duration) 106 return facade.stub.NextErr() 107 } 108 109 func (facade *stubFacade) Wait() error { 110 facade.stub.AddCall("Wait") 111 <-facade.block 112 return facade.stub.NextErr() 113 } 114 115 var errClaimDenied = errors.Trace(lease.ErrClaimDenied) 116 117 type mockAgent struct { 118 agent.Agent 119 wrongKind bool 120 } 121 122 func (mock *mockAgent) CurrentConfig() agent.Config { 123 return &mockAgentConfig{wrongKind: mock.wrongKind} 124 } 125 126 type mockAgentConfig struct { 127 agent.Config 128 wrongKind bool 129 } 130 131 func (mock *mockAgentConfig) Tag() names.Tag { 132 if mock.wrongKind { 133 return names.NewUnitTag("foo/1") 134 } 135 return names.NewMachineTag("123") 136 } 137 138 type fakeClock struct { 139 clock.Clock 140 } 141 142 type fakeFacade struct { 143 singular.Facade 144 } 145 146 type fakeWorker struct { 147 worker.Worker 148 } 149 150 type fakeAPICaller struct { 151 base.APICaller 152 }