func (s *HookContextSuite) AddContextRelation(c *gc.C, name string) { s.AddTestingService(c, name, s.relch) eps, err := s.State.InferEndpoints([]string{"u", name}) 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) s.relunits[rel.Id()] = ru err = ru.EnterScope(map[string]interface{}{"relation-name": name}) c.Assert(err, gc.IsNil) s.apiUnit, err = s.uniter.Unit(s.unit.Tag()) c.Assert(err, gc.IsNil) apiRel, err := s.uniter.Relation(rel.Tag()) c.Assert(err, gc.IsNil) apiRelUnit, err := apiRel.Unit(s.apiUnit) c.Assert(err, gc.IsNil) s.relctxs[rel.Id()] = uniter.NewContextRelation(apiRelUnit, nil) }
func (s *ContextRelationSuite) TestMemberCaching(c *gc.C) { unit, err := s.svc.AddUnit() c.Assert(err, gc.IsNil) ru, err := s.rel.Unit(unit) c.Assert(err, gc.IsNil) err = ru.EnterScope(map[string]interface{}{"blib": "blob"}) c.Assert(err, gc.IsNil) settings, err := ru.Settings() c.Assert(err, gc.IsNil) settings.Set("ping", "pong") _, err = settings.Write() c.Assert(err, gc.IsNil) ctx := uniter.NewContextRelation(s.apiRelUnit, map[string]int64{"u/1": 0}) // Check that uncached settings are read from state. m, err := ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) expectMap := settings.Map() expectSettings := convertMap(expectMap) c.Assert(m, gc.DeepEquals, expectSettings) // Check that changes to state do not affect the cached settings. settings.Set("ping", "pow") _, err = settings.Write() c.Assert(err, gc.IsNil) m, err = ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, expectSettings) // Check that ClearCache spares the members cache. ctx.ClearCache() m, err = ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, expectSettings) // Check that updating the context overwrites the cached settings, and // that the contents of state are ignored. ctx.UpdateMembers(uniter.SettingsMap{"u/1": {"entirely": "different"}}) m, err = ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, params.RelationSettings{"entirely": "different"}) }
func (s *ContextRelationSuite) TestChangeMembers(c *gc.C) { ctx := uniter.NewContextRelation(s.apiRelUnit, nil) c.Assert(ctx.UnitNames(), gc.HasLen, 0) // Check the units and settings after a simple update. ctx.UpdateMembers(uniter.SettingsMap{ "u/2": {"baz": "2"}, "u/4": {"qux": "4"}, }) c.Assert(ctx.UnitNames(), gc.DeepEquals, []string{"u/2", "u/4"}) assertSettings := func(unit string, expect params.RelationSettings) { actual, err := ctx.ReadSettings(unit) c.Assert(err, gc.IsNil) c.Assert(actual, gc.DeepEquals, expect) } assertSettings("u/2", params.RelationSettings{"baz": "2"}) assertSettings("u/4", params.RelationSettings{"qux": "4"}) // Send a second update; check that members are only added, not removed. ctx.UpdateMembers(uniter.SettingsMap{ "u/1": {"foo": "1"}, "u/2": {"abc": "2"}, "u/3": {"bar": "3"}, }) c.Assert(ctx.UnitNames(), gc.DeepEquals, []string{"u/1", "u/2", "u/3", "u/4"}) // Check that all settings remain cached. assertSettings("u/1", params.RelationSettings{"foo": "1"}) assertSettings("u/2", params.RelationSettings{"abc": "2"}) assertSettings("u/3", params.RelationSettings{"bar": "3"}) assertSettings("u/4", params.RelationSettings{"qux": "4"}) // Delete a member, and check that it is no longer a member... ctx.DeleteMember("u/2") c.Assert(ctx.UnitNames(), gc.DeepEquals, []string{"u/1", "u/3", "u/4"}) // ...and that its settings are no longer cached. _, err := ctx.ReadSettings("u/2") c.Assert(err, gc.ErrorMatches, "cannot read settings for unit \"u/2\" in relation \"u:ring\": settings not found") }
func (s *ContextRelationSuite) TestSettings(c *gc.C) { ctx := uniter.NewContextRelation(s.apiRelUnit, nil) // Change Settings, then clear cache without writing. node, err := ctx.Settings() c.Assert(err, gc.IsNil) expectSettings := node.Map() expectMap := convertSettings(expectSettings) node.Set("change", "exciting") ctx.ClearCache() // Check that the change is not cached... node, err = ctx.Settings() c.Assert(err, gc.IsNil) c.Assert(node.Map(), gc.DeepEquals, expectSettings) // ...and not written to state. settings, err := s.ru.ReadSettings("u/0") c.Assert(err, gc.IsNil) c.Assert(settings, gc.DeepEquals, expectMap) // Change again, write settings, and clear caches. node.Set("change", "exciting") err = ctx.WriteSettings() c.Assert(err, gc.IsNil) ctx.ClearCache() // Check that the change is reflected in Settings... expectSettings["change"] = "exciting" expectMap["change"] = expectSettings["change"] node, err = ctx.Settings() c.Assert(err, gc.IsNil) c.Assert(node.Map(), gc.DeepEquals, expectSettings) // ...and was written to state. settings, err = s.ru.ReadSettings("u/0") c.Assert(err, gc.IsNil) c.Assert(settings, gc.DeepEquals, expectMap) }
func (s *ContextRelationSuite) TestNonMemberCaching(c *gc.C) { unit, err := s.svc.AddUnit() c.Assert(err, gc.IsNil) ru, err := s.rel.Unit(unit) c.Assert(err, gc.IsNil) err = ru.EnterScope(map[string]interface{}{"blib": "blob"}) c.Assert(err, gc.IsNil) settings, err := ru.Settings() c.Assert(err, gc.IsNil) settings.Set("ping", "pong") _, err = settings.Write() c.Assert(err, gc.IsNil) ctx := uniter.NewContextRelation(s.apiRelUnit, nil) // Check that settings are read from state. m, err := ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) expectMap := settings.Map() expectSettings := convertMap(expectMap) c.Assert(m, gc.DeepEquals, expectSettings) // Check that changes to state do not affect the obtained settings... settings.Set("ping", "pow") _, err = settings.Write() c.Assert(err, gc.IsNil) m, err = ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, expectSettings) // ...until the caches are cleared. ctx.ClearCache() c.Assert(err, gc.IsNil) m, err = ctx.ReadSettings("u/1") c.Assert(err, gc.IsNil) c.Assert(m["ping"], gc.Equals, "pow") }