github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/meterstatus/isolated_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package meterstatus_test 5 6 import ( 7 "fmt" 8 "path" 9 "time" 10 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/utils/clock" 14 "github.com/juju/utils/fslock" 15 gc "gopkg.in/check.v1" 16 17 coretesting "github.com/juju/juju/testing" 18 "github.com/juju/juju/worker" 19 "github.com/juju/juju/worker/meterstatus" 20 "github.com/juju/juju/worker/uniter/runner/context" 21 ) 22 23 const ( 24 AmberGracePeriod = time.Minute 25 RedGracePeriod = time.Minute * 5 26 ) 27 28 type IsolatedWorkerSuite struct { 29 coretesting.BaseSuite 30 31 stub *testing.Stub 32 33 dataDir string 34 lock *fslock.Lock 35 36 clk *coretesting.Clock 37 38 hookRan chan struct{} 39 triggersCreated chan struct{} 40 41 worker worker.Worker 42 } 43 44 var _ = gc.Suite(&IsolatedWorkerSuite{}) 45 46 func (s *IsolatedWorkerSuite) SetUpTest(c *gc.C) { 47 s.BaseSuite.SetUpTest(c) 48 s.stub = &testing.Stub{} 49 50 s.dataDir = c.MkDir() 51 52 s.hookRan = make(chan struct{}) 53 s.triggersCreated = make(chan struct{}) 54 55 triggerFactory := func(state meterstatus.WorkerState, status string, disconectedAt time.Time, clk clock.Clock, amber time.Duration, red time.Duration) (<-chan time.Time, <-chan time.Time) { 56 select { 57 case s.triggersCreated <- struct{}{}: 58 case <-time.After(coretesting.LongWait): 59 c.Fatalf("failed to signal trigger creation") 60 } 61 return meterstatus.GetTriggers(state, status, disconectedAt, clk, amber, red) 62 } 63 64 s.clk = coretesting.NewClock(time.Now()) 65 wrk, err := meterstatus.NewIsolatedStatusWorker( 66 meterstatus.IsolatedConfig{ 67 Runner: &stubRunner{stub: s.stub, ran: s.hookRan}, 68 StateFile: meterstatus.NewStateFile(path.Join(s.dataDir, "meter-status.yaml")), 69 Clock: s.clk, 70 AmberGracePeriod: AmberGracePeriod, 71 RedGracePeriod: RedGracePeriod, 72 TriggerFactory: triggerFactory, 73 }) 74 c.Assert(err, jc.ErrorIsNil) 75 c.Assert(wrk, gc.NotNil) 76 s.worker = wrk 77 } 78 79 func (s *IsolatedWorkerSuite) TearDownTest(c *gc.C) { 80 s.worker.Kill() 81 err := s.worker.Wait() 82 c.Assert(err, jc.ErrorIsNil) 83 } 84 85 func (s *IsolatedWorkerSuite) TestConfigValidation(c *gc.C) { 86 tests := []struct { 87 cfg meterstatus.IsolatedConfig 88 expected string 89 }{{ 90 cfg: meterstatus.IsolatedConfig{ 91 Runner: &stubRunner{stub: s.stub}, 92 StateFile: meterstatus.NewStateFile(path.Join(s.dataDir, "meter-status.yaml")), 93 }, 94 expected: "clock not provided", 95 }, { 96 cfg: meterstatus.IsolatedConfig{ 97 Clock: coretesting.NewClock(time.Now()), 98 StateFile: meterstatus.NewStateFile(path.Join(s.dataDir, "meter-status.yaml")), 99 }, 100 expected: "hook runner not provided", 101 }, { 102 cfg: meterstatus.IsolatedConfig{ 103 Clock: coretesting.NewClock(time.Now()), 104 Runner: &stubRunner{stub: s.stub}, 105 }, 106 expected: "state file not provided", 107 }} 108 for i, test := range tests { 109 c.Logf("running test %d", i) 110 err := test.cfg.Validate() 111 c.Assert(err, gc.ErrorMatches, test.expected) 112 } 113 } 114 115 func (s *IsolatedWorkerSuite) TestTriggering(c *gc.C) { 116 assertSignal(c, s.triggersCreated) 117 s.clk.Advance(AmberGracePeriod + time.Second) 118 assertSignal(c, s.hookRan) 119 s.clk.Advance(RedGracePeriod + time.Second) 120 assertSignal(c, s.hookRan) 121 122 s.stub.CheckCallNames(c, "RunHook", "RunHook") 123 } 124 125 // TestMissingHookError tests that errors caused by missing hooks do not stop the worker. 126 func (s *IsolatedWorkerSuite) TestMissingHookError(c *gc.C) { 127 s.stub.SetErrors(context.NewMissingHookError("meter-status-changed")) 128 129 assertSignal(c, s.triggersCreated) 130 s.clk.Advance(AmberGracePeriod + time.Second) 131 assertSignal(c, s.hookRan) 132 133 s.stub.CheckCallNames(c, "RunHook") 134 } 135 136 // TestRandomHookError tests that errors returned by hooks do not stop the worker. 137 func (s *IsolatedWorkerSuite) TestRandomHookError(c *gc.C) { 138 s.stub.SetErrors(fmt.Errorf("blah")) 139 140 assertSignal(c, s.triggersCreated) 141 s.clk.Advance(AmberGracePeriod + time.Second) 142 assertSignal(c, s.hookRan) 143 144 s.stub.CheckCallNames(c, "RunHook") 145 }