Only check for one unit for container scoped rels.

When checking goal state, only look for one unit to be available
when examining container scoped relations as a principle unit only
ever has a relation with a single unit of a given subordinate
application.

Change-Id: I02f34358060c98c0702d3d7b58d52427c2a0445a
Closes-Bug: #1801754
This commit is contained in:
Liam Young 2018-11-05 18:36:06 +00:00
parent b849530eb0
commit 32e4d822c1
2 changed files with 45 additions and 4 deletions

View File

@ -76,6 +76,7 @@ from charmhelpers.core.decorators import (
from charmhelpers.core.hookenv import (
atexit,
cached,
config,
expected_peer_units,
expected_related_units,
@ -84,6 +85,7 @@ from charmhelpers.core.hookenv import (
leader_set,
log,
local_unit,
metadata,
relation_get,
relation_set,
relation_id,
@ -2239,6 +2241,18 @@ def fernet_keys_rotate_and_sync(log_func=log):
level=INFO)
@cached
def container_scoped_relations():
'''Get all the container scoped relations'''
md = metadata()
relations = []
for relation_type in ('provides', 'requires', 'peers'):
for relation in md.get(relation_type, []):
if md[relation_type][relation].get('scope') == 'container':
relations.append(relation)
return relations
def is_expected_scale():
"""Query juju goal-state to determine whether our peer- and dependency-
relations are at the expected scale.
@ -2269,8 +2283,15 @@ def is_expected_scale():
for dep in deps:
if not dep[1]:
return False
if (len(related_units(relid=dep[1])) <
len(list(expected_related_units(reltype=dep[0])))):
# Goal state returns every unit even for container scoped
# relations but the charm only ever has a relation with
# the local unit.
if dep[0] in container_scoped_relations():
expected_count = 1
else:
expected_count = len(
list(expected_related_units(reltype=dep[0])))
if len(related_units(relid=dep[1])) < expected_count:
return False
except NotImplementedError:
return True

View File

@ -1310,13 +1310,16 @@ class TestKeystoneUtils(CharmTestCase):
mock_fernet_rotate.assert_called_once_with()
mock_key_leader_set.assert_called_once_with()
@patch.object(utils, 'container_scoped_relations')
@patch.object(utils, 'expected_related_units')
@patch.object(utils, 'expected_peer_units')
@patch.object(utils, 'related_units')
@patch.object(utils, 'expect_ha')
@patch.object(utils, 'relation_ids')
def test_is_expected_scale(self, relation_ids, expect_ha, related_units,
expected_peer_units, expected_related_units):
expected_peer_units, expected_related_units,
container_scoped_relations):
container_scoped_relations.return_value = ['ha']
relation_ids.return_value = ['FAKE_RID']
expect_ha.return_value = False
related_units.return_value = ['unit/0', 'unit/1', 'unit/2']
@ -1328,13 +1331,16 @@ class TestKeystoneUtils(CharmTestCase):
call(reltype='shared-db')])
related_units.assert_called_with(relid='FAKE_RID')
@patch.object(utils, 'container_scoped_relations')
@patch.object(utils, 'expected_related_units')
@patch.object(utils, 'expected_peer_units')
@patch.object(utils, 'related_units')
@patch.object(utils, 'expect_ha')
@patch.object(utils, 'relation_ids')
def test_is_expected_scale_ha(self, relation_ids, expect_ha, related_units,
expected_peer_units, expected_related_units):
expected_peer_units, expected_related_units,
container_scoped_relations):
container_scoped_relations.return_value = ['ha']
relation_ids.return_value = ['FAKE_RID']
expect_ha.return_value = True
related_units.return_value = ['unit/0', 'unit/1', 'unit/2']
@ -1381,3 +1387,17 @@ class TestKeystoneUtils(CharmTestCase):
expected_peer_units.side_effect = NotImplementedError
self.assertTrue(utils.is_expected_scale())
expected_related_units.assert_not_called()
@patch.object(utils, 'metadata')
def test_container_scoped_relations(self, metadata):
_metadata = {
'provides': {
'amqp': {'interface': 'rabbitmq'},
'identity-service': {'interface': 'keystone'},
'ha': {
'interface': 'hacluster',
'scope': 'container'}},
'peers': {
'cluster': {'interface': 'openstack-ha'}}}
metadata.return_value = _metadata
self.assertEqual(utils.container_scoped_relations(), ['ha'])