class SubordinateRelationHookContextTest(HookContextTestBase): @inlineCallbacks def setUp(self): yield super(SubordinateRelationHookContextTest, self).setUp() relation = yield self._build_relation() self.context = DepartedRelationHookContext( self.client, self.unit.unit_name, self.unit.internal_id, relation.relation_name, relation.internal_relation_id) @inlineCallbacks def _build_relation(self): mysql_ep = RelationEndpoint("mysql", "juju-info", "juju-info", "server", "global") logging_ep = RelationEndpoint("logging", "juju-info", "juju-info", "client", "container") mysql, my_units = yield self.get_service_and_units_by_charm_name( "mysql", 1) self.assertFalse((yield mysql.is_subordinate())) log, log_units = yield self.get_service_and_units_by_charm_name( "logging") self.assertTrue((yield log.is_subordinate())) # add the relationship so we can create units with containers relation_state, service_states = (yield self.relation_manager.add_relation_state( mysql_ep, logging_ep)) log, log_units = yield self.get_service_and_units_by_charm_name( "logging", containers=my_units) self.assertTrue((yield log.is_subordinate())) for lu in log_units: self.assertTrue((yield lu.is_subordinate())) self.mu1 = my_units[0] self.lu1 = log_units[0] self.mystate = pick_attr(service_states, relation_role="server") self.logstate = pick_attr(service_states, relation_role="client") yield self.mystate.add_unit_state(self.mu1) self.log_unit_relation = yield self.logstate.add_unit_state(self.lu1) self.my_unit_relation = yield self.mystate.add_unit_state(self.mu1) self.unit = self.lu1 self.container_unit = self.mu1 self.service = log self.relation_state = relation_state returnValue(self.logstate) def get_unit_settings_path(self, relation, unit, container=None): container_info = "" if container: container_info = "%s/" % container.internal_id unit_relation_path = "/relations/%s/%ssettings/%s" % ( relation.internal_id, container_info, unit.internal_id) return unit_relation_path @inlineCallbacks def test_get_departed_members(self): """Related units cannot be retrieved.""" members = yield self.context.get_members() self.assertEqual(members, []) # Add a new member and refetch yield self.add_related_service_unit(self.mysql_states) members2 = yield self.context.get_members() # There should be no change in the retrieved members. self.assertEqual(members2, []) @inlineCallbacks def test_get_self(self): """Own settings can be retrieved.""" settings_path = self.get_unit_settings_path( self.relation_state, self.unit, self.container_unit) self.client.set(settings_path, yaml.dump({"hello": "world"})) data = yield self.context.get(None) self.assertEquals(data, {"hello": "world"}) def get_context(self, service_relation, unit_relation, unit, change_type, unit_name): change = RelationChange( service_relation.relation_ident, change_type, unit_name) return RelationHookContext( self.client, unit_relation, change, unit_name=unit.unit_name) @inlineCallbacks def test_get_members_subordinate_context(self): context = self.get_context(self.logstate, self.log_unit_relation, self.lu1, "joined", "logging/0") self.assertEquals((yield context.get_members()), ["mysql/1"]) context = self.get_context(self.mystate, self.my_unit_relation, self.mu1, "joined", "mysql/1") self.assertEquals((yield context.get_members()), ["logging/0"]) @inlineCallbacks def test_get_settings_path(self): @inlineCallbacks def verify_settings_path(service_relation, unit_relation, unit, expected): sp = yield unit_relation.get_settings_path() self.assertEquals(sp, expected) context = self.get_context(service_relation, unit_relation, unit, "joined", "") sp2 = yield context.get_settings_path(unit.internal_id) self.assertEquals(sp2, expected) yield verify_settings_path(self.mystate, self.my_unit_relation, self.mu1, "/relations/relation-0000000001/" "unit-0000000002/settings/unit-0000000002") yield verify_settings_path(self.logstate, self.log_unit_relation, self.lu1, "/relations/relation-0000000001/" "unit-0000000002/settings/unit-0000000003")
class DepartedRelationHookContextTest( HookContextTestBase, CommonHookContextTestsMixin): @inlineCallbacks def setUp(self): yield super(DepartedRelationHookContextTest, self).setUp() self.service = self.wordpress_states["service"] self.unit = self.wordpress_states["unit"] relation = self.wordpress_states["service_relation"] self.context = DepartedRelationHookContext( self.client, self.unit.unit_name, self.unit.internal_id, relation.relation_name, relation.internal_relation_id) @inlineCallbacks def test_get_members(self): """Related units cannot be retrieved.""" members = yield self.context.get_members() self.assertEqual(members, []) # Add a new member and refetch yield self.add_related_service_unit(self.mysql_states) members2 = yield self.context.get_members() # There should be no change in the retrieved members. self.assertEqual(members2, []) @inlineCallbacks def test_get_self(self): """Own settings can be retrieved.""" self.client.set(self.get_unit_settings_path(self.wordpress_states), yaml.dump({"hello": "world"})) data = yield self.context.get(None) self.assertEquals(data, {"hello": "world"}) @inlineCallbacks def test_get_self_by_name(self): """Own settings can be retrieved by name.""" self.client.set(self.get_unit_settings_path(self.wordpress_states), yaml.dump({"hello": "world"})) data = yield self.context.get("wordpress/0") self.assertEquals(data, {"hello": "world"}) @inlineCallbacks def test_get_other(self): """Other unit settings cannot be retrieved.""" e = yield self.assertFailure( self.context.get("mysql/0"), RelationBrokenContextError) self.assertEquals( str(e), "Cannot access other units in broken relation") @inlineCallbacks def test_get_value_self(self): """Own settings can be retrieved.""" self.client.set(self.get_unit_settings_path(self.wordpress_states), yaml.dump({"hello": "world"})) self.assertEquals( (yield self.context.get_value("wordpress/0", "hello")), "world") self.assertEquals( (yield self.context.get_value("wordpress/0", "goodbye")), "") @inlineCallbacks def test_get_value_other(self): """Other unit settings cannot be retrieved.""" e = yield self.assertFailure( self.context.get_value("mysql/0", "anything"), RelationBrokenContextError) self.assertEquals( str(e), "Cannot access other units in broken relation") @inlineCallbacks def test_set(self): """Own settings cannot be changed.""" e = yield self.assertFailure( self.context.set({"anything": "anything"}), RelationBrokenContextError) self.assertEquals( str(e), "Cannot change settings in broken relation") @inlineCallbacks def test_set_value(self): """Own settings cannot be changed.""" e = yield self.assertFailure( self.context.set_value("anything", "anything"), RelationBrokenContextError) self.assertEquals( str(e), "Cannot change settings in broken relation") @inlineCallbacks def test_delete_value(self): """Own settings cannot be changed.""" e = yield self.assertFailure( self.context.delete_value("anything"), RelationBrokenContextError) self.assertEquals( str(e), "Cannot change settings in broken relation") @inlineCallbacks def test_has_read(self): """We can tell whether settings have been read""" self.assertFalse(self.context.has_read("wordpress/0")) self.assertFalse(self.context.has_read("mysql/0")) yield self.context.get(None) self.assertTrue(self.context.has_read("wordpress/0")) self.assertFalse(self.context.has_read("mysql/0")) yield self.assertFailure( self.context.get_value("mysql/0", "anything"), RelationBrokenContextError) self.assertTrue(self.context.has_read("wordpress/0")) self.assertFalse(self.context.has_read("mysql/0")) @inlineCallbacks def test_relation_ident(self): """Verify relation ident and enumerate other relations for context.""" self.assertEqual(self.context.relation_ident, "database:0") self.assertEqual((yield self.context.get_relation_idents(None)), ["database:0"])