github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/watcher_test.go (about)

     1  // Copyright 2019 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"time"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/state"
    13  	"github.com/juju/juju/state/testing"
    14  	coretesting "github.com/juju/juju/testing"
    15  )
    16  
    17  var _ = gc.Suite(&watcherSuite{})
    18  
    19  type watcherSuite struct {
    20  	ConnSuite
    21  }
    22  
    23  func (s *watcherSuite) TestEntityWatcherEventsNonExistent(c *gc.C) {
    24  	// Just watching a document should not trigger an event
    25  	c.Logf("starting watcher for %q %q", "machines", "2")
    26  	w := state.NewEntityWatcher(s.State, "machines", "2")
    27  	wc := testing.NewNotifyWatcherC(c, w)
    28  	wc.AssertOneChange()
    29  }
    30  
    31  func (s *watcherSuite) TestEntityWatcherFirstEvent(c *gc.C) {
    32  	m, err := s.State.AddMachine(state.UbuntuBase("18.04"), state.JobHostUnits)
    33  	c.Assert(err, jc.ErrorIsNil)
    34  	// Send the Machine creation event before we start our watcher
    35  	w := m.Watch()
    36  
    37  	// This code is essentially what's in NewNotifyWatcherC.AssertOneChange()
    38  	// but we allow for an optional second event. The 2 events are:
    39  	// - initial watcher event
    40  	// - machine created event
    41  	// Due to mixed use of wall clock and test clock in the various bits
    42  	// of infrastructure, we can't guarantee that the watcher fires after
    43  	// the machine created event arrives, which means that event sometimes
    44  	// arrives separately and would fail the test.
    45  	eventCount := 0
    46  loop:
    47  	for {
    48  		select {
    49  		case _, ok := <-w.Changes():
    50  			c.Logf("got change")
    51  			c.Assert(ok, jc.IsTrue)
    52  			eventCount++
    53  			if eventCount > 2 {
    54  				c.Fatalf("watcher sent unexpected change")
    55  			}
    56  		case <-time.After(coretesting.ShortWait):
    57  			if eventCount > 0 {
    58  				break loop
    59  			}
    60  		case <-time.After(coretesting.LongWait):
    61  			c.Fatalf("watcher did not send change")
    62  			break loop
    63  		}
    64  	}
    65  }
    66  
    67  func (s *watcherSuite) TestLegacyActionNotificationWatcher(c *gc.C) {
    68  	dummy := s.AddTestingApplication(c, "dummy", s.AddTestingCharm(c, "dummy"))
    69  	unit, err := dummy.AddUnit(state.AddUnitParams{})
    70  	c.Assert(err, jc.ErrorIsNil)
    71  
    72  	w := state.NewActionNotificationWatcher(s.State, true, unit)
    73  	wc := testing.NewStringsWatcherC(c, w)
    74  	wc.AssertChange()
    75  
    76  	operationID, err := s.Model.EnqueueOperation("a test", 1)
    77  	c.Assert(err, jc.ErrorIsNil)
    78  	action, err := s.Model.AddAction(unit, operationID, "snapshot", nil, nil, nil)
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	wc.AssertChange(action.Id())
    81  
    82  	_, err = action.Cancel()
    83  	c.Assert(err, jc.ErrorIsNil)
    84  	wc.AssertNoChange()
    85  }