diff --git a/config.yaml b/config.yaml index b00c2f5..d556998 100644 --- a/config.yaml +++ b/config.yaml @@ -90,3 +90,7 @@ options: default: "multicast" description: | Two supported modes are multicast (udp) or unicast (udpu) + debug: + default: False + type: boolean + description: Enable debug logging diff --git a/hooks/hooks.py b/hooks/hooks.py index ca284c0..2771b50 100755 --- a/hooks/hooks.py +++ b/hooks/hooks.py @@ -127,6 +127,7 @@ def get_corosync_conf(): 'ip_version': ip_version, 'ha_nodes': get_ha_nodes(), 'transport': get_transport(), + 'debug': config('debug'), } if None not in conf.itervalues(): return conf @@ -144,6 +145,7 @@ def get_corosync_conf(): 'ip_version': ip_version, 'ha_nodes': get_ha_nodes(), 'transport': get_transport(), + 'debug': config('debug'), } if config('prefer-ipv6'): diff --git a/templates/corosync.conf b/templates/corosync.conf index 02670f8..b41c65c 100644 --- a/templates/corosync.conf +++ b/templates/corosync.conf @@ -84,9 +84,9 @@ logging { to_logfile: no to_syslog: yes syslog_facility: daemon - debug: off + debug: {% if debug %}on{% else %}off{% endif %} logger_subsys { subsys: QUORUM - debug: off + debug: {% if debug %}on{% else %}off{% endif %} } } diff --git a/unit_tests/test_hacluster_hooks.py b/unit_tests/test_hacluster_hooks.py index 2f8affb..a932396 100644 --- a/unit_tests/test_hacluster_hooks.py +++ b/unit_tests/test_hacluster_hooks.py @@ -1,10 +1,26 @@ +from __future__ import print_function + import mock +import os +import re +import shutil +import tempfile import unittest with mock.patch('charmhelpers.core.hookenv.config'): import hooks as hacluster_hooks +def local_log(msg, level='INFO'): + print('[{}] {}'.format(level, msg)) + + +def write_file(path, content, *args, **kwargs): + with open(path, 'w') as f: + f.write(content) + f.flush() + + class SwiftContextTestCase(unittest.TestCase): @mock.patch('hooks.config') @@ -17,3 +33,59 @@ class SwiftContextTestCase(unittest.TestCase): mock_config.return_value = 'hafu' self.assertRaises(ValueError, hacluster_hooks.get_transport) + + +@mock.patch('hooks.log', local_log) +@mock.patch('hooks.write_file', write_file) +class TestCorosyncConf(unittest.TestCase): + + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + hacluster_hooks.COROSYNC_CONF = os.path.join(self.tmpdir, + 'corosync.conf') + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + def test_debug_on(self): + self.check_debug(True) + + def test_debug_off(self): + self.check_debug(False) + + @mock.patch('hooks.relation_get') + @mock.patch('hooks.related_units') + @mock.patch('hooks.relation_ids') + @mock.patch('hacluster.get_network_address') + @mock.patch('hooks.config') + def check_debug(self, enabled, mock_config, get_network_address, + relation_ids, related_units, relation_get): + cfg = {'debug': enabled, + 'prefer-ipv6': False, + 'corosync_transport': 'udpu', + 'corosync_mcastaddr': 'corosync_mcastaddr'} + + def c(k): + return cfg.get(k) + + mock_config.side_effect = c + get_network_address.return_value = "127.0.0.1" + relation_ids.return_value = ['foo:1'] + related_units.return_value = ['unit-machine-0'] + relation_get.return_value = 'iface' + + hacluster_hooks.get_ha_nodes = mock.MagicMock() + conf = hacluster_hooks.get_corosync_conf() + self.assertEqual(conf['debug'], enabled) + + self.assertTrue(hacluster_hooks.emit_corosync_conf()) + + with open(hacluster_hooks.COROSYNC_CONF) as fd: + content = fd.read() + if enabled: + pattern = 'debug: on\n' + else: + pattern = 'debug: off\n' + + matches = re.findall(pattern, content, re.M) + self.assertEqual(len(matches), 2, str(matches))