diff --git a/hooks/swift_utils.py b/hooks/swift_utils.py index 0fcdd8f..b13208c 100644 --- a/hooks/swift_utils.py +++ b/hooks/swift_utils.py @@ -1,3 +1,4 @@ +import copy import os import pwd import shutil @@ -147,32 +148,55 @@ class SwiftProxyCharmException(Exception): class SwiftProxyClusterRPC(object): + """Provides cluster relation rpc dicts. + + Crucially, this ensures that any settings we don't use in any given call + are set to None, therefore removing them from the relation so they don't + get accidentally interpreted by the receiver as part of the request. + + NOTE: these are only intended to be used from cluster peer relations. + """ def __init__(self, version=1): self._version = version + + def template(self): # Everything must be None by default so it gets dropped from the # relation unless we want it to be set. - self.blanks = {1: {'trigger': None, - 'builder-broker': None, - 'stop-proxy-service': None, - 'stop-proxy-service-ack': None, - 'peers-only': None}} + templates = {1: {'trigger': None, + 'builder-broker': None, + 'stop-proxy-service': None, + 'stop-proxy-service-ack': None, + 'peers-only': None}} + return copy.deepcopy(templates[self._version]) def stop_proxy_request(self, peers_only=None): - rq = self.blanks[self._version] + """Request to stop peer proxy service. + + NOTE: leader action + """ + rq = self.template() rq['trigger'] = str(uuid.uuid4()) rq['stop-proxy-service'] = rq['trigger'] rq['peers-only'] = peers_only return rq def stop_proxy_ack(self, token): - rq = self.blanks[self._version] + """Ack that peer proxy service is stopped. + + NOTE: non-leader action + """ + rq = self.template() rq['trigger'] = str(uuid.uuid4()) rq['stop-proxy-service-ack'] = token return rq def sync_rings_request(self, broker_host): - rq = self.blanks[self._version] + """Request for peer to sync rings. + + NOTE: leader action + """ + rq = self.template() rq['trigger'] = str(uuid.uuid4()) rq['builder-broker'] = broker_host return rq diff --git a/unit_tests/test_swift_hooks.py b/unit_tests/test_swift_hooks.py index fb0c373..359d1ff 100644 --- a/unit_tests/test_swift_hooks.py +++ b/unit_tests/test_swift_hooks.py @@ -35,15 +35,15 @@ class SwiftHooksTestCase(unittest.TestCase): responses = [{'some-other-key': token1}] self.assertFalse(swift_hooks.all_peers_stopped(responses)) - responses = [{'stop-proxy-service-rsp': token1}, - {'stop-proxy-service-rsp': token2}] + responses = [{'stop-proxy-service-ack': token1}, + {'stop-proxy-service-ack': token2}] self.assertFalse(swift_hooks.all_peers_stopped(responses)) - responses = [{'stop-proxy-service-rsp': token1}, - {'stop-proxy-service-rsp': token1}] + responses = [{'stop-proxy-service-ack': token1}, + {'stop-proxy-service-ack': token1}] self.assertTrue(swift_hooks.all_peers_stopped(responses)) - responses = [{'stop-proxy-service-rsp': token1}, - {'stop-proxy-service-rsp': token1}, + responses = [{'stop-proxy-service-ack': token1}, + {'stop-proxy-service-ack': token1}, {'some-other-key': token1}] self.assertFalse(swift_hooks.all_peers_stopped(responses)) diff --git a/unit_tests/test_swift_utils.py b/unit_tests/test_swift_utils.py index 1b31e2a..fb956a7 100644 --- a/unit_tests/test_swift_utils.py +++ b/unit_tests/test_swift_utils.py @@ -66,3 +66,43 @@ class SwiftUtilsTestCase(unittest.TestCase): swift_utils.mark_www_rings_deleted() finally: shutil.rmtree(tmpdir) + + @mock.patch('swift_utils.uuid') + def test_cluster_rpc_stop_proxy_request(self, mock_uuid): + mock_uuid.uuid4.return_value = 'test-uuid' + rpc = swift_utils.SwiftProxyClusterRPC() + rq = rpc.stop_proxy_request(peers_only=True) + self.assertEqual({'trigger': 'test-uuid', + 'builder-broker': None, + 'peers-only': True, + 'stop-proxy-service': 'test-uuid', + 'stop-proxy-service-ack': None}, rq) + + rq = rpc.stop_proxy_request() + self.assertEqual({'trigger': 'test-uuid', + 'builder-broker': None, + 'peers-only': None, + 'stop-proxy-service': 'test-uuid', + 'stop-proxy-service-ack': None}, rq) + + @mock.patch('swift_utils.uuid') + def test_cluster_rpc_stop_proxy_ack(self, mock_uuid): + mock_uuid.uuid4.return_value = 'token2' + rpc = swift_utils.SwiftProxyClusterRPC() + rq = rpc.stop_proxy_ack('token1') + self.assertEqual({'trigger': 'token2', + 'builder-broker': None, + 'peers-only': None, + 'stop-proxy-service': None, + 'stop-proxy-service-ack': 'token1'}, rq) + + @mock.patch('swift_utils.uuid') + def test_cluster_rpc_sync_request(self, mock_uuid): + mock_uuid.uuid4.return_value = 'token1' + rpc = swift_utils.SwiftProxyClusterRPC() + rq = rpc.sync_rings_request('HostA') + self.assertEqual({'trigger': 'token1', + 'builder-broker': 'HostA', + 'peers-only': None, + 'stop-proxy-service': None, + 'stop-proxy-service-ack': None}, rq)