func (s *MachineSuite) TestWatchUnits(c *C) { // Start a watch on an empty machine; check no units reported. w := s.machine.WatchUnits() defer testing.AssertStop(c, w) wc := testing.NewLaxStringsWatcherC(c, s.State, w) wc.AssertChange() wc.AssertNoChange() // Change machine; no change. err := s.machine.SetProvisioned("cheese", "fake_nonce", nil) c.Assert(err, IsNil) wc.AssertNoChange() // Assign a unit (to a separate instance); change detected. mysql, err := s.State.AddService("mysql", s.AddTestingCharm(c, "mysql")) c.Assert(err, IsNil) mysql0, err := mysql.AddUnit() c.Assert(err, IsNil) machine, err := s.State.Machine(s.machine.Id()) c.Assert(err, IsNil) err = mysql0.AssignToMachine(machine) c.Assert(err, IsNil) wc.AssertChange("mysql/0") wc.AssertNoChange() // Change the unit; no change. err = mysql0.SetStatus(params.StatusStarted, "") c.Assert(err, IsNil) wc.AssertNoChange() // Assign another unit and make the first Dying; check both changes detected. mysql1, err := mysql.AddUnit() c.Assert(err, IsNil) err = mysql1.AssignToMachine(machine) c.Assert(err, IsNil) err = mysql0.Destroy() c.Assert(err, IsNil) wc.AssertChange("mysql/0", "mysql/1") wc.AssertNoChange() // Add a subordinate to the Alive unit; change detected. logging, err := s.State.AddService("logging", s.AddTestingCharm(c, "logging")) c.Assert(err, IsNil) eps, err := s.State.InferEndpoints([]string{"mysql", "logging"}) c.Assert(err, IsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, IsNil) mysqlru1, err := rel.Unit(mysql1) c.Assert(err, IsNil) err = mysqlru1.EnterScope(nil) c.Assert(err, IsNil) logging0, err := logging.Unit("logging/0") c.Assert(err, IsNil) wc.AssertChange("logging/0") wc.AssertNoChange() // Change the subordinate; no change. err = logging0.SetStatus(params.StatusStarted, "") c.Assert(err, IsNil) wc.AssertNoChange() // Make the Dying unit Dead; change detected. err = mysql0.EnsureDead() c.Assert(err, IsNil) wc.AssertChange("mysql/0") wc.AssertNoChange() // Stop watcher; check Changes chan closed. testing.AssertStop(c, w) wc.AssertClosed() // Start a fresh watcher; check all units reported. w = s.machine.WatchUnits() defer testing.AssertStop(c, w) wc = testing.NewLaxStringsWatcherC(c, s.State, w) wc.AssertChange("mysql/0", "mysql/1", "logging/0") wc.AssertNoChange() // Remove the Dead unit; no change. err = mysql0.Remove() c.Assert(err, IsNil) wc.AssertNoChange() // Destroy the subordinate; change detected. err = logging0.Destroy() c.Assert(err, IsNil) wc.AssertChange("logging/0") wc.AssertNoChange() // Unassign the principal; check subordinate departure also reported. err = mysql1.UnassignFromMachine() c.Assert(err, IsNil) wc.AssertChange("mysql/1", "logging/0") wc.AssertNoChange() }
func (s *UnitSuite) TestWatchSubordinates(c *C) { w := s.unit.WatchSubordinateUnits() defer testing.AssertStop(c, w) wc := testing.NewLaxStringsWatcherC(c, s.State, w) wc.AssertChange() wc.AssertNoChange() // Add a couple of subordinates, check change. subCharm := s.AddTestingCharm(c, "logging") var subUnits []*state.Unit for i := 0; i < 2; i++ { // Note: subordinate units can only be created as a side effect of a // principal entering scope; and a given principal can only have a // single subordinate unit of each service. name := "logging" + strconv.Itoa(i) subSvc, err := s.State.AddService(name, subCharm) c.Assert(err, IsNil) eps, err := s.State.InferEndpoints([]string{name, "wordpress"}) c.Assert(err, IsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, IsNil) ru, err := rel.Unit(s.unit) c.Assert(err, IsNil) err = ru.EnterScope(nil) c.Assert(err, IsNil) units, err := subSvc.AllUnits() c.Assert(err, IsNil) c.Assert(units, HasLen, 1) subUnits = append(subUnits, units[0]) } wc.AssertChange(subUnits[0].Name(), subUnits[1].Name()) wc.AssertNoChange() // Set one to Dying, check change. err := subUnits[0].Destroy() c.Assert(err, IsNil) wc.AssertChange(subUnits[0].Name()) wc.AssertNoChange() // Set both to Dead, and remove one; check change. err = subUnits[0].EnsureDead() c.Assert(err, IsNil) err = subUnits[1].EnsureDead() c.Assert(err, IsNil) err = subUnits[1].Remove() c.Assert(err, IsNil) wc.AssertChange(subUnits[0].Name(), subUnits[1].Name()) wc.AssertNoChange() // Stop watcher, check closed. testing.AssertStop(c, w) wc.AssertClosed() // Start a new watch, check Dead unit is reported. w = s.unit.WatchSubordinateUnits() defer testing.AssertStop(c, w) wc = testing.NewLaxStringsWatcherC(c, s.State, w) wc.AssertChange(subUnits[0].Name()) wc.AssertNoChange() // Remove the leftover, check no change. err = subUnits[0].Remove() c.Assert(err, IsNil) wc.AssertNoChange() }