func (s *ContextRelationSuite) TestNonMemberCaching(c *C) {
	unit, err := s.svc.AddUnit()
	c.Assert(err, IsNil)
	ru, err := s.rel.Unit(unit)
	c.Assert(err, IsNil)
	err = ru.EnterScope(map[string]interface{}{"blib": "blob"})
	c.Assert(err, IsNil)
	settings, err := ru.Settings()
	c.Assert(err, IsNil)
	settings.Set("ping", "pong")
	_, err = settings.Write()
	c.Assert(err, IsNil)
	ctx := uniter.NewContextRelation(s.ru, nil)

	// Check that settings are read from state.
	m, err := ctx.ReadSettings("u/1")
	c.Assert(err, IsNil)
	expect := settings.Map()
	c.Assert(m, DeepEquals, expect)

	// Check that changes to state do not affect the obtained settings...
	settings.Set("ping", "pow")
	_, err = settings.Write()
	c.Assert(err, IsNil)
	m, err = ctx.ReadSettings("u/1")
	c.Assert(err, IsNil)
	c.Assert(m, DeepEquals, expect)

	// ...until the caches are cleared.
	ctx.ClearCache()
	c.Assert(err, IsNil)
	m, err = ctx.ReadSettings("u/1")
	c.Assert(err, IsNil)
	c.Assert(m["ping"], Equals, "pow")
}
Beispiel #2
0
func (s *HookContextSuite) AddContextRelation(c *C, name string) {
	ep := state.Endpoint{
		s.service.Name(), "ifce", name, state.RolePeer, charm.ScopeGlobal,
	}
	rel, err := s.State.AddRelation(ep)
	c.Assert(err, IsNil)
	ru, err := rel.Unit(s.unit)
	c.Assert(err, IsNil)
	s.relunits[rel.Id()] = ru
	err = ru.EnterScope(map[string]interface{}{"relation-name": name})
	c.Assert(err, IsNil)
	s.relctxs[rel.Id()] = uniter.NewContextRelation(ru, nil)
}
func (s *HookContextSuite) AddContextRelation(c *C, name string) {
	_, err := s.State.AddService(name, s.relch)
	c.Assert(err, IsNil)
	eps, err := s.State.InferEndpoints([]string{"u", name})
	c.Assert(err, IsNil)
	rel, err := s.State.AddRelation(eps...)
	c.Assert(err, IsNil)
	ru, err := rel.Unit(s.unit)
	c.Assert(err, IsNil)
	s.relunits[rel.Id()] = ru
	err = ru.EnterScope(map[string]interface{}{"relation-name": name})
	c.Assert(err, IsNil)
	s.relctxs[rel.Id()] = uniter.NewContextRelation(ru, nil)
}
func (s *ContextRelationSuite) TestMemberCaching(c *C) {
	unit, err := s.svc.AddUnit()
	c.Assert(err, IsNil)
	ru, err := s.rel.Unit(unit)
	c.Assert(err, IsNil)
	err = ru.EnterScope(map[string]interface{}{"blib": "blob"})
	c.Assert(err, IsNil)
	settings, err := ru.Settings()
	c.Assert(err, IsNil)
	settings.Set("ping", "pong")
	_, err = settings.Write()
	c.Assert(err, IsNil)
	ctx := uniter.NewContextRelation(s.ru, map[string]int64{"u/1": 0})

	// Check that uncached settings are read from state.
	m, err := ctx.ReadSettings("u/1")
	c.Assert(err, IsNil)
	expect := settings.Map()
	c.Assert(m, DeepEquals, expect)

	// Check that changes to state do not affect the cached settings.
	settings.Set("ping", "pow")
	_, err = settings.Write()
	c.Assert(err, IsNil)
	m, err = ctx.ReadSettings("u/1")
	c.Assert(err, IsNil)
	c.Assert(m, DeepEquals, expect)

	// Check that ClearCache spares the members cache.
	ctx.ClearCache()
	m, err = ctx.ReadSettings("u/1")
	c.Assert(err, IsNil)
	c.Assert(m, DeepEquals, expect)

	// 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, IsNil)
	c.Assert(m, DeepEquals, map[string]interface{}{"entirely": "different"})
}
func (s *ContextRelationSuite) TestChangeMembers(c *C) {
	ctx := uniter.NewContextRelation(s.ru, nil)
	c.Assert(ctx.UnitNames(), 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(), DeepEquals, []string{"u/2", "u/4"})
	assertSettings := func(unit string, expect map[string]interface{}) {
		actual, err := ctx.ReadSettings(unit)
		c.Assert(err, IsNil)
		c.Assert(actual, DeepEquals, expect)
	}
	assertSettings("u/2", map[string]interface{}{"baz": 2})
	assertSettings("u/4", map[string]interface{}{"qux": 4})

	// Send a second update; check that members are only added, not removed.
	ctx.UpdateMembers(uniter.SettingsMap{
		"u/1": {"foo": 1},
		"u/2": nil,
		"u/3": {"bar": 3},
	})
	c.Assert(ctx.UnitNames(), DeepEquals, []string{"u/1", "u/2", "u/3", "u/4"})

	// Check that all settings remain cached, including u/2's (which lacked
	// new settings data in the second update).
	assertSettings("u/1", map[string]interface{}{"foo": 1})
	assertSettings("u/2", map[string]interface{}{"baz": 2})
	assertSettings("u/3", map[string]interface{}{"bar": 3})
	assertSettings("u/4", map[string]interface{}{"qux": 4})

	// Delete a member, and check that it is no longer a member...
	ctx.DeleteMember("u/2")
	c.Assert(ctx.UnitNames(), DeepEquals, []string{"u/1", "u/3", "u/4"})

	// ...and that its settings are no longer cached.
	_, err := ctx.ReadSettings("u/2")
	c.Assert(err, ErrorMatches, `cannot read settings for unit "u/2" in relation "u:ring": settings not found`)
}
func (s *ContextRelationSuite) TestSettings(c *C) {
	ctx := uniter.NewContextRelation(s.ru, nil)

	// Change Settings, then clear cache without writing.
	node, err := ctx.Settings()
	c.Assert(err, IsNil)
	expect := node.Map()
	node.Set("change", "exciting")
	ctx.ClearCache()

	// Check that the change is not cached...
	node, err = ctx.Settings()
	c.Assert(err, IsNil)
	c.Assert(node.Map(), DeepEquals, expect)

	// ...and not written to state.
	settings, err := s.ru.ReadSettings("u/0")
	c.Assert(err, IsNil)
	c.Assert(settings, DeepEquals, expect)

	// Change again, write settings, and clear caches.
	node.Set("change", "exciting")
	err = ctx.WriteSettings()
	c.Assert(err, IsNil)
	ctx.ClearCache()

	// Check that the change is reflected in Settings...
	expect["change"] = "exciting"
	node, err = ctx.Settings()
	c.Assert(err, IsNil)
	c.Assert(node.Map(), DeepEquals, expect)

	// ...and was written to state.
	settings, err = s.ru.ReadSettings("u/0")
	c.Assert(err, IsNil)
	c.Assert(settings, DeepEquals, expect)
}