func (s *provisionerSuite) TestWatchFilesystemAttachments(c *gc.C) { s.setupFilesystems(c) c.Assert(s.resources.Count(), gc.Equals, 0) args := params.Entities{Entities: []params.Entity{ {"machine-0"}, {s.State.ModelTag().String()}, {"environ-adb650da-b77b-4ee8-9cbb-d57a9a592847"}, {"machine-1"}, {"machine-42"}}, } result, err := s.api.WatchFilesystemAttachments(args) c.Assert(err, jc.ErrorIsNil) sort.Sort(byMachineAndEntity(result.Results[0].Changes)) sort.Sort(byMachineAndEntity(result.Results[1].Changes)) c.Assert(result, jc.DeepEquals, params.MachineStorageIdsWatchResults{ Results: []params.MachineStorageIdsWatchResult{ { MachineStorageIdsWatcherId: "1", Changes: []params.MachineStorageId{{ MachineTag: "machine-0", AttachmentTag: "filesystem-0-0", }}, }, { MachineStorageIdsWatcherId: "2", Changes: []params.MachineStorageId{{ MachineTag: "machine-0", AttachmentTag: "filesystem-1", }, { MachineTag: "machine-0", AttachmentTag: "filesystem-2", }, { MachineTag: "machine-2", AttachmentTag: "filesystem-3", }}, }, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) // Verify the resources were registered and stop them when done. c.Assert(s.resources.Count(), gc.Equals, 2) v0Watcher := s.resources.Get("1") defer statetesting.AssertStop(c, v0Watcher) v1Watcher := s.resources.Get("2") defer statetesting.AssertStop(c, v1Watcher) // Check that the Watch has consumed the initial events ("returned" in // the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, v0Watcher.(state.StringsWatcher)) wc.AssertNoChange() wc = statetesting.NewStringsWatcherC(c, s.State, v1Watcher.(state.StringsWatcher)) wc.AssertNoChange() }
func (s *InstancePollerSuite) TestWatchModelMachinesSuccess(c *gc.C) { // Add a couple of machines. s.st.SetMachineInfo(c, machineInfo{id: "2"}) s.st.SetMachineInfo(c, machineInfo{id: "1"}) expectedResult := params.StringsWatchResult{ Error: nil, StringsWatcherId: "1", Changes: []string{"1", "2"}, // initial event (sorted ids) } result, err := s.api.WatchModelMachines() c.Assert(err, jc.ErrorIsNil) c.Assert(result, jc.DeepEquals, expectedResult) // Verify the watcher resource was registered. c.Assert(s.resources.Count(), gc.Equals, 1) resource1 := s.resources.Get("1") defer func() { if resource1 != nil { statetesting.AssertStop(c, resource1) } }() // Check that the watcher has consumed the initial event wc1 := statetesting.NewStringsWatcherC(c, s.st, resource1.(state.StringsWatcher)) wc1.AssertNoChange() s.st.CheckCallNames(c, "WatchModelMachines") // Add another watcher to verify events coalescence. result, err = s.api.WatchModelMachines() c.Assert(err, jc.ErrorIsNil) expectedResult.StringsWatcherId = "2" c.Assert(result, jc.DeepEquals, expectedResult) s.st.CheckCallNames(c, "WatchModelMachines", "WatchModelMachines") c.Assert(s.resources.Count(), gc.Equals, 2) resource2 := s.resources.Get("2") defer statetesting.AssertStop(c, resource2) wc2 := statetesting.NewStringsWatcherC(c, s.st, resource2.(state.StringsWatcher)) wc2.AssertNoChange() // Remove machine 1, check it's reported. s.st.RemoveMachine(c, "1") wc1.AssertChangeInSingleEvent("1") // Make separate changes, check they're combined. s.st.SetMachineInfo(c, machineInfo{id: "2", life: state.Dying}) s.st.SetMachineInfo(c, machineInfo{id: "3"}) s.st.RemoveMachine(c, "42") // ignored wc1.AssertChangeInSingleEvent("2", "3") wc2.AssertChangeInSingleEvent("1", "2", "3") // Stop the first watcher and assert its changes chan is closed. c.Assert(resource1.Stop(), jc.ErrorIsNil) wc1.AssertClosed() resource1 = nil }
func (s *ActionSuite) TestUnitWatchActionNotifications(c *gc.C) { // get units unit1, err := s.State.Unit(s.unit.Name()) c.Assert(err, jc.ErrorIsNil) preventUnitDestroyRemove(c, unit1) unit2, err := s.State.Unit(s.unit2.Name()) c.Assert(err, jc.ErrorIsNil) preventUnitDestroyRemove(c, unit2) // queue some actions before starting the watcher fa1, err := unit1.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) fa2, err := unit1.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) // set up watcher on first unit w := unit1.WatchActionNotifications() defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.State, w) // make sure the previously pending actions are sent on the watcher expect := expectActionIds(fa1, fa2) wc.AssertChange(expect...) wc.AssertNoChange() // add watcher on unit2 w2 := unit2.WatchActionNotifications() defer statetesting.AssertStop(c, w2) wc2 := statetesting.NewStringsWatcherC(c, s.State, w2) wc2.AssertChange() wc2.AssertNoChange() // add action on unit2 and makes sure unit1 watcher doesn't trigger // and unit2 watcher does fa3, err := unit2.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) wc.AssertNoChange() expect2 := expectActionIds(fa3) wc2.AssertChange(expect2...) wc2.AssertNoChange() // add a couple actions on unit1 and make sure watcher sees events fa4, err := unit1.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) fa5, err := unit1.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) expect = expectActionIds(fa4, fa5) wc.AssertChange(expect...) wc.AssertNoChange() }
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().String()}, {Tag: s.service.Tag().String()}, {Tag: s.units[0].Tag().String()}, }}) 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 *AddresserSuite) TestWatchIPAddresses(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) s.st.addIPAddressWatcher("0.1.2.3", "0.1.2.4", "0.1.2.7") result, err := s.api.WatchIPAddresses() c.Assert(err, jc.ErrorIsNil) c.Assert(result, gc.DeepEquals, params.EntitiesWatchResult{ EntitiesWatcherId: "1", Changes: []string{ "ipaddress-00000000-1111-2222-3333-0123456789ab", "ipaddress-00000000-1111-2222-4444-0123456789ab", "ipaddress-00000000-1111-2222-7777-0123456789ab", }, Error: nil, }) // 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.st, 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, jc.ErrorIsNil) 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, jc.ErrorIsNil) 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, jc.ErrorIsNil) 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, jc.ErrorIsNil) wc.AssertChange(rel.String()) 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().String()}}} 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 *firewallerBaseSuite) testWatchModelMachines( c *gc.C, facade interface { WatchModelMachines() (params.StringsWatchResult, error) }, ) { c.Assert(s.resources.Count(), gc.Equals, 0) got, err := facade.WatchModelMachines() c.Assert(err, jc.ErrorIsNil) 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 *VolumeStateSuite) TestWatchMachineVolumeAttachments(c *gc.C) { service := s.setupMixedScopeStorageService(c, "block") addUnit := func() { u, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) err = s.State.AssignUnit(u, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) } addUnit() w := s.State.WatchMachineVolumeAttachments(names.NewMachineTag("0")) defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChangeInSingleEvent("0:0", "0:0/1", "0:0/2") // initial wc.AssertNoChange() addUnit() // no change, since we're only interested in the one machine. wc.AssertNoChange() err := s.State.DetachVolume(names.NewMachineTag("0"), names.NewVolumeTag("0")) c.Assert(err, jc.ErrorIsNil) wc.AssertChangeInSingleEvent("0:0") // dying wc.AssertNoChange() err = s.State.RemoveVolumeAttachment(names.NewMachineTag("0"), names.NewVolumeTag("0")) c.Assert(err, jc.ErrorIsNil) wc.AssertChangeInSingleEvent("0:0") // removed wc.AssertNoChange() // TODO(axw) respond to changes to the same machine when we support // dynamic storage and/or placement. }
func (s *VolumeStateSuite) TestWatchEnvironVolumeAttachments(c *gc.C) { service := s.setupMixedScopeStorageService(c, "block") addUnit := func() { u, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) err = s.State.AssignUnit(u, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) } addUnit() w := s.State.WatchEnvironVolumeAttachments() defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChangeInSingleEvent("0:0") // initial wc.AssertNoChange() addUnit() wc.AssertChangeInSingleEvent("1:3") wc.AssertNoChange() err := s.State.DetachVolume(names.NewMachineTag("0"), names.NewVolumeTag("0")) c.Assert(err, jc.ErrorIsNil) wc.AssertChangeInSingleEvent("0:0") // dying wc.AssertNoChange() err = s.State.RemoveVolumeAttachment(names.NewMachineTag("0"), names.NewVolumeTag("0")) c.Assert(err, jc.ErrorIsNil) wc.AssertChangeInSingleEvent("0:0") // removed wc.AssertNoChange() }
func (s *unitSuite) TestWatchActionNotifications(c *gc.C) { w, err := s.apiUnit.WatchActionNotifications() c.Assert(err, jc.ErrorIsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) // Initial event. wc.AssertChange() // Add a couple of actions and make sure the changes are detected. action, err := s.wordpressUnit.AddAction("fakeaction", map[string]interface{}{ "outfile": "foo.txt", }) c.Assert(err, jc.ErrorIsNil) wc.AssertChange(action.Id()) action, err = s.wordpressUnit.AddAction("fakeaction", map[string]interface{}{ "outfile": "foo.bz2", "compression": map[string]interface{}{ "kind": "bzip", "quality": float64(5.0), }, }) c.Assert(err, jc.ErrorIsNil) wc.AssertChange(action.Id()) 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 *PortsDocSuite) TestWatchPorts(c *gc.C) { w := s.State.WatchOpenedPorts() c.Assert(w, gc.NotNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.State, w) wc.AssertChange() wc.AssertNoChange() portRange := state.PortRange{ FromPort: 100, ToPort: 200, UnitName: s.unit1.Name(), Protocol: "TCP", } globalKey := state.PortsGlobalKey(s.machine.Id(), network.DefaultPublic) err := s.ports.OpenPorts(portRange) c.Assert(err, gc.IsNil) wc.AssertChange(globalKey) err = s.ports.Refresh() c.Assert(err, gc.IsNil) err = s.ports.ClosePorts(portRange) c.Assert(err, gc.IsNil) wc.AssertChange(globalKey) }
func (s *FilesystemStateSuite) TestWatchMachineFilesystemAttachments(c *gc.C) { service := s.setupMixedScopeStorageService(c, "filesystem") addUnit := func() { u, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) err = s.State.AssignUnit(u, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) } addUnit() w := s.State.WatchMachineFilesystemAttachments(names.NewMachineTag("0")) defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChangeInSingleEvent("0:0", "0:0/1", "0:0/2") // initial wc.AssertNoChange() addUnit() // no change, since we're only interested in the one machine. wc.AssertNoChange() // TODO(axw) respond to changes to the same machine when we support // dynamic storage and/or placement. // TODO(axw) respond to Dying/Dead when we have // the means to progress Filesystem lifecycle. }
func (s *deployerSuite) TestWatchUnits(c *gc.C) { // TODO(dfc) fix state.Machine to return a MachineTag machine, err := s.st.Machine(s.machine.Tag().(names.MachineTag)) 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 *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 *ActionSuite) TestWatchActionNotifications(c *gc.C) { svc := s.AddTestingService(c, "dummy2", s.charm) u, err := svc.AddUnit() c.Assert(err, jc.ErrorIsNil) w := u.WatchActionNotifications() defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.State, w) wc.AssertChange() wc.AssertNoChange() // add 3 actions fa1, err := u.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) fa2, err := u.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) fa3, err := u.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) // fail the middle one action, err := s.State.Action(fa2.Id()) c.Assert(err, jc.ErrorIsNil) _, err = action.Finish(state.ActionResults{Status: state.ActionFailed, Message: "die scum"}) c.Assert(err, jc.ErrorIsNil) // expect the first and last one in the watcher expect := expectActionIds(fa1, fa3) wc.AssertChange(expect...) wc.AssertNoChange() }
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().String()}}} 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 *ActionSuite) TestUnitWatchActionResults(c *gc.C) { unit1, err := s.State.Unit(s.unit.Name()) c.Assert(err, gc.IsNil) preventUnitDestroyRemove(c, unit1) unit2, err := s.State.Unit(s.unit2.Name()) c.Assert(err, gc.IsNil) preventUnitDestroyRemove(c, unit2) action0, err := unit1.AddAction("fakeaction", nil) c.Assert(err, gc.IsNil) action1, err := unit2.AddAction("fakeaction", nil) c.Assert(err, gc.IsNil) action2, err := unit1.AddAction("fakeaction", nil) c.Assert(err, gc.IsNil) err = action2.Finish(state.ActionResults{Status: state.ActionFailed}) c.Assert(err, gc.IsNil) err = action1.Finish(state.ActionResults{Status: state.ActionCompleted}) c.Assert(err, gc.IsNil) w1 := unit1.WatchActionResults() defer statetesting.AssertStop(c, w1) wc1 := statetesting.NewStringsWatcherC(c, s.State, w1) expect := expectActionResultIds(unit1, "1") wc1.AssertChange(expect...) wc1.AssertNoChange() w2 := unit2.WatchActionResults() defer statetesting.AssertStop(c, w2) wc2 := statetesting.NewStringsWatcherC(c, s.State, w2) expect = expectActionResultIds(unit2, "0") wc2.AssertChange(expect...) wc2.AssertNoChange() err = action0.Finish(state.ActionResults{Status: state.ActionCompleted}) c.Assert(err, gc.IsNil) expect = expectActionResultIds(unit1, "0") wc1.AssertChange(expect...) wc1.AssertNoChange() }
func (s *provisionerSuite) TestWatchVolumes(c *gc.C) { s.setupVolumes(c) s.factory.MakeMachine(c, nil) c.Assert(s.resources.Count(), gc.Equals, 0) args := params.Entities{Entities: []params.Entity{ {"machine-0"}, {s.State.ModelTag().String()}, {"environ-adb650da-b77b-4ee8-9cbb-d57a9a592847"}, {"machine-1"}, {"machine-42"}}, } result, err := s.api.WatchVolumes(args) c.Assert(err, jc.ErrorIsNil) sort.Strings(result.Results[1].Changes) c.Assert(result, jc.DeepEquals, params.StringsWatchResults{ Results: []params.StringsWatchResult{ {StringsWatcherId: "1", Changes: []string{"0/0"}}, {StringsWatcherId: "2", Changes: []string{"1", "2", "3", "4"}}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) // Verify the resources were registered and stop them when done. c.Assert(s.resources.Count(), gc.Equals, 2) v0Watcher := s.resources.Get("1") defer statetesting.AssertStop(c, v0Watcher) v1Watcher := s.resources.Get("2") defer statetesting.AssertStop(c, v1Watcher) // Check that the Watch has consumed the initial events ("returned" in // the Watch call) wc := statetesting.NewStringsWatcherC(c, s.State, v0Watcher.(state.StringsWatcher)) wc.AssertNoChange() wc = statetesting.NewStringsWatcherC(c, s.State, v1Watcher.(state.StringsWatcher)) wc.AssertNoChange() }
func (s *FilesystemStateSuite) TestWatchMachineFilesystemAttachments(c *gc.C) { service := s.setupMixedScopeStorageService(c, "filesystem") addUnit := func(to *state.Machine) (u *state.Unit, m *state.Machine) { var err error u, err = service.AddUnit() c.Assert(err, jc.ErrorIsNil) if to != nil { err = u.AssignToMachine(to) c.Assert(err, jc.ErrorIsNil) return u, to } err = s.State.AssignUnit(u, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) mid, err := u.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) m, err = s.State.Machine(mid) c.Assert(err, jc.ErrorIsNil) return u, m } _, m0 := addUnit(nil) w := s.State.WatchMachineFilesystemAttachments(names.NewMachineTag("0")) defer testing.AssertStop(c, w) wc := testing.NewStringsWatcherC(c, s.State, w) wc.AssertChangeInSingleEvent("0:0/1", "0:0/2") // initial wc.AssertNoChange() addUnit(nil) // no change, since we're only interested in the one machine. wc.AssertNoChange() err := s.State.DetachFilesystem(names.NewMachineTag("0"), names.NewFilesystemTag("0")) c.Assert(err, jc.ErrorIsNil) // no change, since we're only interested in attachments of // machine-scoped volumes. wc.AssertNoChange() err = s.State.DetachFilesystem(names.NewMachineTag("0"), names.NewFilesystemTag("0/1")) c.Assert(err, jc.ErrorIsNil) wc.AssertChangeInSingleEvent("0:0/1") // dying wc.AssertNoChange() err = s.State.RemoveFilesystemAttachment(names.NewMachineTag("0"), names.NewFilesystemTag("0/1")) c.Assert(err, jc.ErrorIsNil) wc.AssertChangeInSingleEvent("0:0/1") // removed wc.AssertNoChange() addUnit(m0) wc.AssertChangeInSingleEvent("0:0/7", "0:0/8") wc.AssertNoChange() }
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 *firewallerSuite) TestWatchOpenedPorts(c *gc.C) { c.Assert(s.resources.Count(), gc.Equals, 0) s.openPorts(c) expectChanges := []string{ "0:", // empty subnet is ok (until it can be made mandatory) "0:10.20.30.0/24", "2:", } fakeEnvTag := names.NewModelTag("deadbeef-deaf-face-feed-0123456789ab") args := addFakeEntities(params.Entities{Entities: []params.Entity{ {Tag: fakeEnvTag.String()}, {Tag: s.machines[0].Tag().String()}, {Tag: s.service.Tag().String()}, {Tag: s.units[0].Tag().String()}, }}) result, err := s.firewaller.WatchOpenedPorts(args) sort.Strings(result.Results[0].Changes) c.Assert(err, jc.ErrorIsNil) c.Assert(result, jc.DeepEquals, params.StringsWatchResults{ Results: []params.StringsWatchResult{ {Changes: expectChanges, StringsWatcherId: "1"}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {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 *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 *stateSuite) TestWatchOpenedPorts(c *gc.C) { // Open some ports. err := s.units[0].OpenPorts("tcp", 1234, 1400) c.Assert(err, jc.ErrorIsNil) err = s.units[2].OpenPort("udp", 4321) c.Assert(err, jc.ErrorIsNil) w, err := s.firewaller.WatchOpenedPorts() c.Assert(err, jc.ErrorIsNil) defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) expectChanges := []string{ "0:juju-public", "2:juju-public", } wc.AssertChangeInSingleEvent(expectChanges...) wc.AssertNoChange() // Close a port, make sure it's detected. err = s.units[2].ClosePort("udp", 4321) c.Assert(err, jc.ErrorIsNil) wc.AssertChange(expectChanges[1]) wc.AssertNoChange() // Close it again, no changes. err = s.units[2].ClosePort("udp", 4321) c.Assert(err, jc.ErrorIsNil) wc.AssertNoChange() // Close non-existing port, no changes. err = s.units[0].ClosePort("udp", 1234) c.Assert(err, jc.ErrorIsNil) wc.AssertNoChange() // Open another port range, ensure it's detected. err = s.units[1].OpenPorts("tcp", 8080, 8088) c.Assert(err, jc.ErrorIsNil) wc.AssertChange("1:juju-public") wc.AssertNoChange() statetesting.AssertStop(c, w) wc.AssertClosed() }
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 *ActionSuite) TestActionsWatcherEmitsInitialChanges(c *gc.C) { // LP-1391914 :: idPrefixWatcher fails watcher contract to send // initial Change event // // state/idPrefixWatcher does not send an initial event in response // to the first time Changes() is called if all of the pending // events are removed before the first consumption of Changes(). // The watcher contract specifies that the first call to Changes() // should always return at a minimum an empty change set to notify // clients of it's initial state // preamble svc := s.AddTestingService(c, "dummy3", s.charm) unit, err := svc.AddUnit() c.Assert(err, jc.ErrorIsNil) u, err := s.State.Unit(unit.Name()) c.Assert(err, jc.ErrorIsNil) preventUnitDestroyRemove(c, u) // queue up actions a1, err := u.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) a2, err := u.AddAction("snapshot", nil) c.Assert(err, jc.ErrorIsNil) // start watcher but don't consume Changes() yet w := u.WatchActionNotifications() defer statetesting.AssertStop(c, w) wc := statetesting.NewStringsWatcherC(c, s.State, w) // remove actions reason := "removed" _, err = a1.Finish(state.ActionResults{Status: state.ActionFailed, Message: reason}) c.Assert(err, jc.ErrorIsNil) _, err = a2.Finish(state.ActionResults{Status: state.ActionFailed, Message: reason}) c.Assert(err, jc.ErrorIsNil) // per contract, there should be at minimum an initial empty Change() result wc.AssertChangeMaybeIncluding(expectActionIds(a1, a2)...) wc.AssertNoChange() }