github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/cleaner/cleaner_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cleaner_test 5 6 import ( 7 "errors" 8 stdtesting "testing" 9 "time" 10 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/api/watcher" 15 coretesting "github.com/juju/juju/testing" 16 "github.com/juju/juju/worker" 17 "github.com/juju/juju/worker/cleaner" 18 ) 19 20 func TestPackage(t *stdtesting.T) { 21 gc.TestingT(t) 22 } 23 24 type CleanerSuite struct { 25 coretesting.BaseSuite 26 mockState *cleanerMock 27 } 28 29 var _ = gc.Suite(&CleanerSuite{}) 30 31 var _ worker.NotifyWatchHandler = (*cleaner.Cleaner)(nil) 32 33 func (s *CleanerSuite) SetUpTest(c *gc.C) { 34 s.BaseSuite.SetUpTest(c) 35 s.mockState = &cleanerMock{ 36 calls: make(chan string), 37 } 38 s.mockState.watcher = newMockNotifyWatcher(nil) 39 } 40 41 func (s *CleanerSuite) AssertReceived(c *gc.C, expect string) { 42 select { 43 case call := <-s.mockState.calls: 44 c.Assert(call, gc.Matches, expect) 45 case <-time.After(coretesting.LongWait): 46 c.Fatalf("Timed out waiting for %s", expect) 47 } 48 } 49 50 func (s *CleanerSuite) AssertEmpty(c *gc.C) { 51 select { 52 case call, ok := <-s.mockState.calls: 53 c.Fatalf("Unexpected %s (ok: %v)", call, ok) 54 case <-time.After(coretesting.ShortWait): 55 } 56 } 57 58 func (s *CleanerSuite) TestCleaner(c *gc.C) { 59 cln := cleaner.NewCleaner(s.mockState) 60 defer func() { c.Assert(worker.Stop(cln), jc.ErrorIsNil) }() 61 62 s.AssertReceived(c, "WatchCleanups") 63 s.AssertReceived(c, "Cleanup") 64 65 s.mockState.watcher.Change() 66 s.AssertReceived(c, "Cleanup") 67 } 68 69 func (s *CleanerSuite) TestWatchCleanupsError(c *gc.C) { 70 s.mockState.err = []error{errors.New("hello")} 71 cln := cleaner.NewCleaner(s.mockState) 72 73 s.AssertReceived(c, "WatchCleanups") 74 s.AssertEmpty(c) 75 err := worker.Stop(cln) 76 c.Assert(err, gc.ErrorMatches, "hello") 77 } 78 79 func (s *CleanerSuite) TestCleanupError(c *gc.C) { 80 s.mockState.err = []error{nil, errors.New("hello")} 81 cln := cleaner.NewCleaner(s.mockState) 82 83 s.AssertReceived(c, "WatchCleanups") 84 s.AssertReceived(c, "Cleanup") 85 err := worker.Stop(cln) 86 c.Assert(err, jc.ErrorIsNil) 87 log := c.GetTestLog() 88 c.Assert(log, jc.Contains, "ERROR juju.worker.cleaner cannot cleanup state: hello") 89 } 90 91 // cleanerMock is used to check the 92 // calls of Cleanup() and WatchCleanups() 93 type cleanerMock struct { 94 watcher *mockNotifyWatcher 95 calls chan string 96 err []error 97 } 98 99 func (m *cleanerMock) getError() (e error) { 100 if len(m.err) > 0 { 101 e = m.err[0] 102 m.err = m.err[1:] 103 } 104 return 105 } 106 107 func (m *cleanerMock) Cleanup() error { 108 m.calls <- "Cleanup" 109 return m.getError() 110 } 111 112 func (m *cleanerMock) WatchCleanups() (watcher.NotifyWatcher, error) { 113 m.calls <- "WatchCleanups" 114 return m.watcher, m.getError() 115 } 116 117 var _ cleaner.StateCleaner = (*cleanerMock)(nil) 118 119 type mockNotifyWatcher struct { 120 watcher.NotifyWatcher 121 122 err error 123 changes chan struct{} 124 } 125 126 func newMockNotifyWatcher(err error) *mockNotifyWatcher { 127 m := &mockNotifyWatcher{ 128 changes: make(chan struct{}, 1), 129 err: err, 130 } 131 m.Change() 132 return m 133 } 134 135 func (m *mockNotifyWatcher) Err() error { 136 return m.err 137 } 138 139 func (m *mockNotifyWatcher) Changes() <-chan struct{} { 140 if m.err != nil { 141 close(m.changes) 142 } 143 return m.changes 144 } 145 146 func (m *mockNotifyWatcher) Stop() error { 147 return m.err 148 } 149 150 func (m *mockNotifyWatcher) Change() { 151 m.changes <- struct{}{} 152 }