github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/core/watcher/watchertest/notify.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package watchertest 5 6 import ( 7 "time" 8 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 tomb "gopkg.in/tomb.v2" 12 13 "github.com/juju/juju/core/watcher" 14 "github.com/juju/juju/testing" 15 ) 16 17 type MockNotifyWatcher struct { 18 tomb tomb.Tomb 19 ch <-chan struct{} 20 } 21 22 func NewMockNotifyWatcher(ch <-chan struct{}) *MockNotifyWatcher { 23 w := &MockNotifyWatcher{ch: ch} 24 w.tomb.Go(func() error { 25 <-w.tomb.Dying() 26 return tomb.ErrDying 27 }) 28 return w 29 } 30 31 func (w *MockNotifyWatcher) Changes() watcher.NotifyChannel { 32 return watcher.NotifyChannel(w.ch) 33 } 34 35 func (w *MockNotifyWatcher) Stop() error { 36 w.Kill() 37 return w.Wait() 38 } 39 40 func (w *MockNotifyWatcher) Kill() { 41 w.tomb.Kill(nil) 42 } 43 44 // KillErr can be used to kill the worker with 45 // an error, to simulate a failing watcher. 46 func (w *MockNotifyWatcher) KillErr(err error) { 47 w.tomb.Kill(err) 48 } 49 50 func (w *MockNotifyWatcher) Err() error { 51 return w.tomb.Err() 52 } 53 54 func (w *MockNotifyWatcher) Wait() error { 55 return w.tomb.Wait() 56 } 57 58 func NewNotifyWatcherC(c *gc.C, watcher watcher.NotifyWatcher, preAssert func()) NotifyWatcherC { 59 if preAssert == nil { 60 preAssert = func() {} 61 } 62 return NotifyWatcherC{ 63 C: c, 64 Watcher: watcher, 65 PreAssert: preAssert, 66 } 67 } 68 69 type NotifyWatcherC struct { 70 *gc.C 71 Watcher watcher.NotifyWatcher 72 PreAssert func() 73 } 74 75 // AssertOneChange fails if no change is sent before a long time has passed; or 76 // if, subsequent to that, any further change is sent before a short time has 77 // passed. 78 func (c NotifyWatcherC) AssertOneChange() { 79 c.PreAssert() 80 select { 81 case _, ok := <-c.Watcher.Changes(): 82 c.Assert(ok, jc.IsTrue) 83 case <-time.After(testing.LongWait): 84 c.Fatalf("watcher did not send change") 85 } 86 c.AssertNoChange() 87 } 88 89 // AssertNoChange fails if it manages to read a value from Changes before a 90 // short time has passed. 91 func (c NotifyWatcherC) AssertNoChange() { 92 c.PreAssert() 93 select { 94 case _, ok := <-c.Watcher.Changes(): 95 c.Fatalf("watcher sent unexpected change: (_, %v)", ok) 96 case <-time.After(testing.ShortWait): 97 } 98 } 99 100 // AssertStops Kills the watcher and asserts (1) that Wait completes without 101 // error before a long time has passed; and (2) that Changes remains open but 102 // no values are being sent. 103 func (c NotifyWatcherC) AssertStops() { 104 c.Watcher.Kill() 105 wait := make(chan error) 106 go func() { 107 c.PreAssert() 108 wait <- c.Watcher.Wait() 109 }() 110 select { 111 case <-time.After(testing.LongWait): 112 c.Fatalf("watcher never stopped") 113 case err := <-wait: 114 c.Assert(err, jc.ErrorIsNil) 115 } 116 117 c.PreAssert() 118 select { 119 case _, ok := <-c.Watcher.Changes(): 120 c.Fatalf("watcher sent unexpected change: (_, %v)", ok) 121 default: 122 } 123 }