func (st *State) Watch() *multiwatcher.Watcher { st.mu.Lock() if st.allManager == nil { st.allManager = multiwatcher.NewStoreManager(newAllWatcherStateBacking(st)) } st.mu.Unlock() return multiwatcher.NewWatcher(st.allManager) }
// StateWatcher tests the integration of the state watcher // with the state-based backing. Most of the logic is tested elsewhere - // this just tests end-to-end. func (s *storeManagerStateSuite) TestStateWatcher(c *C) { m0, err := s.State.AddMachine("series", JobManageEnviron) c.Assert(err, IsNil) c.Assert(m0.Id(), Equals, "0") m1, err := s.State.AddMachine("series", JobHostUnits) c.Assert(err, IsNil) c.Assert(m1.Id(), Equals, "1") b := newAllWatcherStateBacking(s.State) aw := multiwatcher.NewStoreManager(b) defer aw.Stop() w := multiwatcher.NewWatcher(aw) s.State.StartSync() checkNext(c, w, b, []params.Delta{{ Entity: ¶ms.MachineInfo{ Id: "0", Status: params.StatusPending, }, }, { Entity: ¶ms.MachineInfo{ Id: "1", Status: params.StatusPending, }, }}, "") // Make some changes to the state. err = m0.SetProvisioned("i-0", "bootstrap_nonce", nil) c.Assert(err, IsNil) err = m1.Destroy() c.Assert(err, IsNil) err = m1.EnsureDead() c.Assert(err, IsNil) err = m1.Remove() c.Assert(err, IsNil) m2, err := s.State.AddMachine("series", JobManageEnviron) c.Assert(err, IsNil) c.Assert(m2.Id(), Equals, "2") s.State.StartSync() // Check that we see the changes happen within a // reasonable time. var deltas []params.Delta for { d, err := getNext(c, w, 100*time.Millisecond) if err == errTimeout { break } c.Assert(err, IsNil) deltas = append(deltas, d...) } checkDeltasEqual(c, b, deltas, []params.Delta{{ Removed: true, Entity: ¶ms.MachineInfo{ Id: "1", Status: params.StatusPending, }, }, { Entity: ¶ms.MachineInfo{ Id: "2", Status: params.StatusPending, }, }, { Entity: ¶ms.MachineInfo{ Id: "0", InstanceId: "i-0", Status: params.StatusPending, }, }}) err = w.Stop() c.Assert(err, IsNil) _, err = w.Next() c.Assert(err, ErrorMatches, "state watcher was stopped") }