github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/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) NotifyWatcherC { 59 return NotifyWatcherC{ 60 C: c, 61 Watcher: watcher, 62 } 63 } 64 65 type NotifyWatcherC struct { 66 *gc.C 67 Watcher watcher.NotifyWatcher 68 } 69 70 // AssertOneChange fails if no change is sent before a long time has passed; or 71 // if, subsequent to that, any further change is sent before a short time has 72 // passed. 73 func (c NotifyWatcherC) AssertOneChange() { 74 select { 75 case _, ok := <-c.Watcher.Changes(): 76 c.Assert(ok, jc.IsTrue) 77 case <-time.After(testing.LongWait): 78 c.Fatalf("watcher did not send change") 79 } 80 c.AssertNoChange() 81 } 82 83 // AssertNoChange fails if it manages to read a value from Changes before a 84 // short time has passed. 85 func (c NotifyWatcherC) AssertNoChange() { 86 select { 87 case _, ok := <-c.Watcher.Changes(): 88 c.Fatalf("watcher sent unexpected change: (_, %v)", ok) 89 case <-time.After(testing.ShortWait): 90 } 91 } 92 93 func (c NotifyWatcherC) assertStops(changesClosed bool) { 94 c.Watcher.Kill() 95 wait := make(chan error) 96 go func() { 97 wait <- c.Watcher.Wait() 98 }() 99 select { 100 case <-time.After(testing.LongWait): 101 c.Fatalf("watcher never stopped") 102 case err := <-wait: 103 c.Assert(err, jc.ErrorIsNil) 104 } 105 106 select { 107 case _, ok := <-c.Watcher.Changes(): 108 if ok || !changesClosed { 109 c.Fatalf("watcher sent unexpected change: (_, %v)", ok) 110 } 111 default: 112 } 113 } 114 115 // AssertStops Kills the watcher and asserts (1) that Wait completes without 116 // error before a long time has passed; and (2) that Changes remains open but 117 // no values are being sent. 118 func (c NotifyWatcherC) AssertStops() { 119 c.assertStops(false) 120 } 121 122 // AssertKilled Kills the watcher and asserts that Wait completes without 123 // error before a long time has passed. 124 func (c NotifyWatcherC) AssertKilled() { 125 c.assertStops(true) 126 }