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