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  }