func (s *machineSuite) TestWatchUnits(c *gc.C) { w, err := s.apiMachine.WatchUnits() c.Assert(err, gc.IsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) // Initial event. wc.AssertChange("wordpress/0") wc.AssertNoChange() // Change something other than the life cycle and make sure it's // not detected. err = s.machines[0].SetPassword("foo") c.Assert(err, gc.ErrorMatches, "password is only 3 bytes long, and is not a valid Agent password") wc.AssertNoChange() err = s.machines[0].SetPassword("foo-12345678901234567890") c.Assert(err, gc.IsNil) wc.AssertNoChange() // Unassign unit 0 from the machine and check it's detected. err = s.units[0].UnassignFromMachine() c.Assert(err, gc.IsNil) wc.AssertChange("wordpress/0") wc.AssertNoChange() statetesting.AssertStop(c, w) wc.AssertClosed() }
func (s *deployerSuite) TestWatchUnits(c *gc.C) { machine, err := s.st.Machine(s.machine.Tag()) c.Assert(err, gc.IsNil) w, err := machine.WatchUnits() c.Assert(err, gc.IsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) // Initial event. wc.AssertChange("mysql/0", "logging/0") wc.AssertNoChange() // Change something other than the lifecycle and make sure it's // not detected. err = s.subordinate.SetPassword("foo") c.Assert(err, gc.ErrorMatches, "password is only 3 bytes long, and is not a valid Agent password") wc.AssertNoChange() err = s.subordinate.SetPassword("foo-12345678901234567890") c.Assert(err, gc.IsNil) wc.AssertNoChange() // Make the subordinate dead and check it's detected. err = s.subordinate.EnsureDead() c.Assert(err, gc.IsNil) wc.AssertChange("logging/0") wc.AssertNoChange() statetesting.AssertStop(c, w) wc.AssertClosed() }
func (s *watcherSuite) TestStringsWatcherStopsWithPendingSend(c *gc.C) { // Call the Deployer facade's WatchUnits for machine-0. var results params.StringsWatchResults args := params.Entities{Entities: []params.Entity{{Tag: s.rawMachine.Tag()}}} err := s.stateAPI.Call("Deployer", "", "WatchUnits", args, &results) c.Assert(err, gc.IsNil) c.Assert(results.Results, gc.HasLen, 1) result := results.Results[0] c.Assert(result.Error, gc.IsNil) // Start a StringsWatcher and check the initial event. w := watcher.NewStringsWatcher(s.stateAPI, result) wc := statetesting.NewStringsWatcherC(c, s.State, w) // Create a service, deploy a unit of it on the machine. mysql := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql")) principal, err := mysql.AddUnit() c.Assert(err, gc.IsNil) err = principal.AssignToMachine(s.rawMachine) c.Assert(err, gc.IsNil) // Ensure the initial event is delivered. Then test the watcher // can be stopped cleanly without reading the pending change. s.BackingState.StartSync() statetesting.AssertCanStopWhenSending(c, w) wc.AssertClosed() }
func (s *withoutStateServerSuite) TestWatchEnvironMachines(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) got, err := s.provisioner.WatchEnvironMachines() c.Assert(err, gc.IsNil) want := params.StringsWatchResult{ StringsWatcherId: "1", Changes: []string{"0", "1", "2", "3", "4"}, } c.Assert(got.StringsWatcherId, gc.Equals, want.StringsWatcherId) c.Assert(got.Changes, jc.SameContents, want.Changes) // Verify the resources were registered and stop them when done. c.Assert(s.resources.Count(), gc.Equals, 1) resource := s.resources.Get("1") defer statetesting.AssertStop(c, resource) // Check that the Watch has consumed the initial event ("returned" // in the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher)) wc.AssertNoChange() // Make sure WatchEnvironMachines fails with a machine agent login. anAuthorizer := s.authorizer anAuthorizer.MachineAgent = true anAuthorizer.EnvironManager = false aProvisioner, err := provisioner.NewProvisionerAPI(s.State, s.resources, anAuthorizer) c.Assert(err, gc.IsNil) result, err := aProvisioner.WatchEnvironMachines() c.Assert(err, gc.ErrorMatches, "permission denied") c.Assert(result, gc.DeepEquals, params.StringsWatchResult{}) }
func (s *firewallerSuite) TestWatchUnits(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) args := addFakeEntities(params.Entities{Entities: []params.Entity{ {Tag: s.machines[0].Tag()}, {Tag: s.service.Tag()}, {Tag: s.units[0].Tag()}, }}) result, err := s.firewaller.WatchUnits(args) c.Assert(err, gc.IsNil) c.Assert(result, jc.DeepEquals, params.StringsWatchResults{ Results: []params.StringsWatchResult{ {Changes: []string{"wordpress/0"}, StringsWatcherId: "1"}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.NotFoundError("machine 42")}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) // Verify the resource was registered and stop when done c.Assert(s.resources.Count(), gc.Equals, 1) c.Assert(result.Results[0].StringsWatcherId, gc.Equals, "1") resource := s.resources.Get("1") defer statetesting.AssertStop(c, resource) // Check that the Watch has consumed the initial event ("returned" in // the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher)) wc.AssertNoChange() }
func (s *deployerSuite) TestWatchUnits(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) args := params.Entities{Entities: []params.Entity{ {Tag: "machine-1"}, {Tag: "machine-0"}, {Tag: "machine-42"}, }} result, err := s.deployer.WatchUnits(args) c.Assert(err, gc.IsNil) sort.Strings(result.Results[0].Changes) c.Assert(result, gc.DeepEquals, params.StringsWatchResults{ Results: []params.StringsWatchResult{ {Changes: []string{"logging/0", "mysql/0"}, StringsWatcherId: "1"}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) // Verify the resource was registered and stop when done c.Assert(s.resources.Count(), gc.Equals, 1) c.Assert(result.Results[0].StringsWatcherId, gc.Equals, "1") resource := s.resources.Get("1") defer statetesting.AssertStop(c, resource) // Check that the Watch has consumed the initial event ("returned" in // the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher)) wc.AssertNoChange() }
func (s *serviceSuite) TestWatchRelations(c *gc.C) { w, err := s.apiService.WatchRelations() c.Assert(err, gc.IsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) // Initial event. wc.AssertChange() wc.AssertNoChange() // Change something other than the lifecycle and make sure it's // not detected. err = s.wordpressService.SetExposed() c.Assert(err, gc.IsNil) wc.AssertNoChange() // Add another service and relate it to wordpress, // check it's detected. s.addMachineServiceCharmAndUnit(c, "mysql") rel := s.addRelation(c, "wordpress", "mysql") wc.AssertChange(rel.String()) // Destroy the relation and check it's detected. err = rel.Destroy() c.Assert(err, gc.IsNil) wc.AssertChange(rel.String()) wc.AssertNoChange() statetesting.AssertStop(c, w) wc.AssertClosed() }
func (s *provisionerSuite) TestWatchEnvironMachines(c *gc.C) { w, err := s.provisioner.WatchEnvironMachines() c.Assert(err, gc.IsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) // Initial event. wc.AssertChange(s.machine.Id()) // Add another 2 machines make sure they are detected. otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) otherMachine, err = s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) wc.AssertChange("1", "2") // Change the lifecycle of last machine. err = otherMachine.EnsureDead() c.Assert(err, gc.IsNil) wc.AssertChange("2") // Add a container and make sure it's not detected. template := state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, } _, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) c.Assert(err, gc.IsNil) wc.AssertNoChange() statetesting.AssertStop(c, w) wc.AssertClosed() }
func (s *watcherSuite) TestWatchUnitsKeepsEvents(c *gc.C) { // Create two services, relate them, and add one unit to each - a // principal and a subordinate. mysql := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql")) logging := s.AddTestingService(c, "logging", s.AddTestingCharm(c, "logging")) eps, err := s.State.InferEndpoints([]string{"mysql", "logging"}) c.Assert(err, gc.IsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, gc.IsNil) principal, err := mysql.AddUnit() c.Assert(err, gc.IsNil) err = principal.AssignToMachine(s.rawMachine) c.Assert(err, gc.IsNil) relUnit, err := rel.Unit(principal) c.Assert(err, gc.IsNil) err = relUnit.EnterScope(nil) c.Assert(err, gc.IsNil) subordinate, err := logging.Unit("logging/0") c.Assert(err, gc.IsNil) // Call the Deployer facade's WatchUnits for machine-0. var results params.StringsWatchResults args := params.Entities{Entities: []params.Entity{{Tag: s.rawMachine.Tag()}}} err = s.stateAPI.Call("Deployer", "", "WatchUnits", args, &results) c.Assert(err, gc.IsNil) c.Assert(results.Results, gc.HasLen, 1) result := results.Results[0] c.Assert(result.Error, gc.IsNil) // Start a StringsWatcher and check the initial event. w := watcher.NewStringsWatcher(s.stateAPI, result) wc := statetesting.NewStringsWatcherC(c, s.State, w) wc.AssertChange("mysql/0", "logging/0") wc.AssertNoChange() // Now, without reading any changes advance the lifecycle of both // units, inducing an update server-side after each two changes to // ensure they're reported as separate events over the API. err = subordinate.EnsureDead() c.Assert(err, gc.IsNil) s.BackingState.StartSync() err = subordinate.Remove() c.Assert(err, gc.IsNil) err = principal.EnsureDead() c.Assert(err, gc.IsNil) s.BackingState.StartSync() // Expect these changes as 2 separate events, so that // nothing gets lost. wc.AssertChange("logging/0") wc.AssertChange("mysql/0") wc.AssertNoChange() statetesting.AssertStop(c, w) wc.AssertClosed() }
func (s *withoutStateServerSuite) TestWatchAllContainers(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) args := params.WatchContainers{Params: []params.WatchContainer{ {MachineTag: s.machines[0].Tag()}, {MachineTag: s.machines[1].Tag()}, {MachineTag: "machine-42"}, {MachineTag: "unit-foo-0"}, {MachineTag: "service-bar"}, }} result, err := s.provisioner.WatchAllContainers(args) c.Assert(err, gc.IsNil) c.Assert(result, gc.DeepEquals, params.StringsWatchResults{ Results: []params.StringsWatchResult{ {StringsWatcherId: "1", Changes: []string{}}, {StringsWatcherId: "2", Changes: []string{}}, {Error: apiservertesting.NotFoundError("machine 42")}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) // Verify the resources were registered and stop them when done. c.Assert(s.resources.Count(), gc.Equals, 2) m0Watcher := s.resources.Get("1") defer statetesting.AssertStop(c, m0Watcher) m1Watcher := s.resources.Get("2") defer statetesting.AssertStop(c, m1Watcher) // Check that the Watch has consumed the initial event ("returned" // in the Watch call) wc0 := statetesting.NewStringsWatcherC(c, s.State, m0Watcher.(state.StringsWatcher)) wc0.AssertNoChange() wc1 := statetesting.NewStringsWatcherC(c, s.State, m1Watcher.(state.StringsWatcher)) wc1.AssertNoChange() }
func (s *ServiceSuite) TestWatchUnitsLifecycle(c *gc.C) { // Empty initial event when no units. w := s.mysql.WatchUnits() defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChange() wc.AssertNoChange() // Create one unit, check one change. quick, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) wc.AssertChange(quick.Name()) wc.AssertNoChange() // Destroy that unit (short-circuited to removal), check one change. err = quick.Destroy() c.Assert(err, gc.IsNil) wc.AssertChange(quick.Name()) wc.AssertNoChange() // Create another, check one change. slow, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) wc.AssertChange(slow.Name()) wc.AssertNoChange() // Change unit itself, no change. preventUnitDestroyRemove(c, slow) wc.AssertNoChange() // Make unit Dying, change detected. err = slow.Destroy() c.Assert(err, gc.IsNil) wc.AssertChange(slow.Name()) wc.AssertNoChange() // Make unit Dead, change detected. err = slow.EnsureDead() c.Assert(err, gc.IsNil) wc.AssertChange(slow.Name()) wc.AssertNoChange() // Remove unit, final change not detected. err = slow.Remove() c.Assert(err, gc.IsNil) wc.AssertNoChange() }
func (s *ServiceSuite) TestWatchUnitsBulkEvents(c *gc.C) { // Alive unit... alive, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) // Dying unit... dying, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) preventUnitDestroyRemove(c, dying) err = dying.Destroy() c.Assert(err, gc.IsNil) // Dead unit... dead, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) preventUnitDestroyRemove(c, dead) err = dead.Destroy() c.Assert(err, gc.IsNil) err = dead.EnsureDead() c.Assert(err, gc.IsNil) // Gone unit. gone, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) err = gone.Destroy() c.Assert(err, gc.IsNil) // All except gone unit are reported in initial event. w := s.mysql.WatchUnits() defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChange(alive.Name(), dying.Name(), dead.Name()) wc.AssertNoChange() // Remove them all; alive/dying changes reported; dead never mentioned again. err = alive.Destroy() c.Assert(err, gc.IsNil) err = dying.EnsureDead() c.Assert(err, gc.IsNil) err = dying.Remove() c.Assert(err, gc.IsNil) err = dead.Remove() c.Assert(err, gc.IsNil) wc.AssertChange(alive.Name(), dying.Name()) wc.AssertNoChange() }
func (s *uniterSuite) assertOneStringsWatcher(c *gc.C, result params.StringsWatchResults, err error) { c.Assert(err, gc.IsNil) c.Assert(result.Results, gc.HasLen, 3) c.Assert(result.Results[0].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) c.Assert(result.Results[1].StringsWatcherId, gc.Equals, "1") c.Assert(result.Results[1].Changes, gc.NotNil) c.Assert(result.Results[1].Error, gc.IsNil) c.Assert(result.Results[2].Error, gc.DeepEquals, apiservertesting.ErrUnauthorized) // Verify the resource was registered and stop when done c.Assert(s.resources.Count(), gc.Equals, 1) resource := s.resources.Get("1") defer statetesting.AssertStop(c, resource) // Check that the Watch has consumed the initial event ("returned" in // the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher)) wc.AssertNoChange() }
func (s *firewallerSuite) TestWatchEnvironMachines(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) got, err := s.firewaller.WatchEnvironMachines() c.Assert(err, gc.IsNil) want := params.StringsWatchResult{ StringsWatcherId: "1", Changes: []string{"0", "1", "2"}, } c.Assert(got.StringsWatcherId, gc.Equals, want.StringsWatcherId) c.Assert(got.Changes, jc.SameContents, want.Changes) // Verify the resources were registered and stop them when done. c.Assert(s.resources.Count(), gc.Equals, 1) resource := s.resources.Get("1") defer statetesting.AssertStop(c, resource) // Check that the Watch has consumed the initial event ("returned" // in the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher)) wc.AssertNoChange() }
func (s *provisionerSuite) TestWatchContainers(c *gc.C) { apiMachine, err := s.provisioner.Machine(s.machine.Tag()) c.Assert(err, gc.IsNil) // Add one LXC container. template := state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) c.Assert(err, gc.IsNil) w, err := apiMachine.WatchContainers(instance.LXC) c.Assert(err, gc.IsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) // Initial event. wc.AssertChange(container.Id()) // Change something other than the containers and make sure it's // not detected. err = apiMachine.SetStatus(params.StatusStarted, "not really", nil) c.Assert(err, gc.IsNil) wc.AssertNoChange() // Add a KVM container and make sure it's not detected. container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.KVM) c.Assert(err, gc.IsNil) wc.AssertNoChange() // Add another LXC container and make sure it's detected. container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) c.Assert(err, gc.IsNil) wc.AssertChange(container.Id()) statetesting.AssertStop(c, w) wc.AssertClosed() }
func (s *ServiceSuite) TestWatchRelations(c *gc.C) { // TODO(fwereade) split this test up a bit. w := s.mysql.WatchRelations() defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChange() wc.AssertNoChange() // Add a relation; check change. mysqlep, err := s.mysql.Endpoint("server") c.Assert(err, gc.IsNil) wpch := s.AddTestingCharm(c, "wordpress") wpi := 0 addRelation := func() *state.Relation { name := fmt.Sprintf("wp%d", wpi) wpi++ wp := s.AddTestingService(c, name, wpch) wpep, err := wp.Endpoint("db") c.Assert(err, gc.IsNil) rel, err := s.State.AddRelation(mysqlep, wpep) c.Assert(err, gc.IsNil) return rel } rel0 := addRelation() wc.AssertChange(rel0.String()) wc.AssertNoChange() // Add another relation; check change. rel1 := addRelation() wc.AssertChange(rel1.String()) wc.AssertNoChange() // Destroy a relation; check change. err = rel0.Destroy() c.Assert(err, gc.IsNil) wc.AssertChange(rel0.String()) wc.AssertNoChange() // Stop watcher; check change chan is closed. testing.AssertStop(c, w) wc.AssertClosed() // Add a new relation; start a new watcher; check initial event. rel2 := addRelation() w = s.mysql.WatchRelations() defer testing.AssertStop(c, w) wc = testing.NewStringsWatcherC(c, s.State, w) wc.AssertChange(rel1.String(), rel2.String()) wc.AssertNoChange() // Add a unit to the new relation; check no change. unit, err := s.mysql.AddUnit() c.Assert(err, gc.IsNil) ru2, err := rel2.Unit(unit) c.Assert(err, gc.IsNil) err = ru2.EnterScope(nil) c.Assert(err, gc.IsNil) wc.AssertNoChange() // Destroy the relation with the unit in scope, and add another; check // changes. err = rel2.Destroy() c.Assert(err, gc.IsNil) rel3 := addRelation() wc.AssertChange(rel2.String(), rel3.String()) wc.AssertNoChange() // Leave scope, destroying the relation, and check that change as well. err = ru2.LeaveScope() c.Assert(err, gc.IsNil) wc.AssertChange(rel2.String()) wc.AssertNoChange() }
func (s *UnitSuite) TestWatchSubordinates(c *gc.C) { w := s.unit.WatchSubordinateUnits() defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(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 := s.AddTestingService(c, name, subCharm) eps, err := s.State.InferEndpoints([]string{name, "wordpress"}) c.Assert(err, gc.IsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, gc.IsNil) ru, err := rel.Unit(s.unit) c.Assert(err, gc.IsNil) err = ru.EnterScope(nil) c.Assert(err, gc.IsNil) units, err := subSvc.AllUnits() c.Assert(err, gc.IsNil) c.Assert(units, gc.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, gc.IsNil) wc.AssertChange(subUnits[0].Name()) wc.AssertNoChange() // Set both to Dead, and remove one; check change. err = subUnits[0].EnsureDead() c.Assert(err, gc.IsNil) err = subUnits[1].EnsureDead() c.Assert(err, gc.IsNil) err = subUnits[1].Remove() c.Assert(err, gc.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.NewStringsWatcherC(c, s.State, w) wc.AssertChange(subUnits[0].Name()) wc.AssertNoChange() // Remove the leftover, check no change. err = subUnits[0].Remove() c.Assert(err, gc.IsNil) wc.AssertNoChange() }