github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/core/watcher/watchertest/relationunits.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 "github.com/juju/collections/set" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/core/watcher" 14 "github.com/juju/juju/testing" 15 ) 16 17 // NewRelationUnitsWatcherC returns a RelationUnitsWatcherC that 18 // checks for aggressive event coalescence. 19 func NewRelationUnitsWatcherC(c *gc.C, w watcher.RelationUnitsWatcher) RelationUnitsWatcherC { 20 return RelationUnitsWatcherC{ 21 C: c, 22 Watcher: w, 23 settingsVersions: make(map[string]int64), 24 appSettingsVersions: make(map[string]int64), 25 } 26 } 27 28 type RelationUnitsWatcherC struct { 29 *gc.C 30 Watcher watcher.RelationUnitsWatcher 31 PreAssert func() 32 settingsVersions map[string]int64 33 appSettingsVersions map[string]int64 34 } 35 36 func (c RelationUnitsWatcherC) AssertNoChange() { 37 select { 38 case actual, ok := <-c.Watcher.Changes(): 39 c.Fatalf("watcher sent unexpected change: (%#v, %v)", actual, ok) 40 case <-time.After(testing.ShortWait): 41 } 42 } 43 44 // AssertChange asserts the given changes was reported by the watcher, 45 // but does not assume there are no following changes. 46 func (c RelationUnitsWatcherC) AssertChange(changed []string, appChanged []string, departed []string) { 47 // Get all items in changed in a map for easy lookup. 48 changedNames := set.NewStrings(changed...) 49 appChangedNames := set.NewStrings(appChanged...) 50 timeout := time.After(testing.LongWait) 51 select { 52 case actual, ok := <-c.Watcher.Changes(): 53 c.Logf("got change %v", actual) 54 c.Assert(ok, jc.IsTrue) 55 c.Check(actual.Changed, gc.HasLen, len(changed)) 56 c.Check(actual.AppChanged, gc.HasLen, len(appChanged)) 57 // Because the versions can change, we only need to make sure 58 // the keys match, not the contents (UnitSettings == txnRevno). 59 for k, settings := range actual.Changed { 60 c.Check(changedNames.Contains(k), jc.IsTrue) 61 oldVer, ok := c.settingsVersions[k] 62 if !ok { 63 // This is the first time we see this unit, so 64 // save the settings version for later. 65 c.settingsVersions[k] = settings.Version 66 } else { 67 // Already seen; make sure the version increased. 68 c.Assert(settings.Version, jc.GreaterThan, oldVer, 69 gc.Commentf("expected unit settings to increase got %d had %d", 70 settings.Version, oldVer)) 71 } 72 } 73 for k, version := range actual.AppChanged { 74 c.Assert(appChangedNames.Contains(k), jc.IsTrue) 75 oldVer, ok := c.appSettingsVersions[k] 76 if ok { 77 // Make sure if we've seen this setting before, it has been updated 78 c.Assert(version, jc.GreaterThan, oldVer, 79 gc.Commentf("expected app settings to increase got %d had %d", 80 version, oldVer)) 81 } 82 c.appSettingsVersions[k] = version 83 } 84 c.Assert(actual.Departed, jc.SameContents, departed) 85 case <-timeout: 86 c.Fatalf("watcher did not send change") 87 } 88 } 89 90 // AssertStops Kills the watcher and asserts (1) that Wait completes without 91 // error before a long time has passed; and (2) that Changes remains open but 92 // no values are being sent. 93 func (c RelationUnitsWatcherC) AssertStops() { 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 change, ok := <-c.Watcher.Changes(): 108 c.Fatalf("watcher sent unexpected change: (%#v, %v)", change, ok) 109 default: 110 } 111 }