github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/trusty/haproxy/hooks/tests/test_config_changed_hooks.py (about) 1 import sys 2 import base64 3 import os 4 5 from testtools import TestCase 6 from mock import patch, call 7 8 import hooks 9 from utils_for_tests import patch_open 10 11 12 class ConfigChangedTest(TestCase): 13 14 def setUp(self): 15 super(ConfigChangedTest, self).setUp() 16 self.config_get = self.patch_hook("config_get") 17 self.config_get().changed.return_value = False 18 self.get_service_ports = self.patch_hook("get_service_ports") 19 self.get_listen_stanzas = self.patch_hook("get_listen_stanzas") 20 self.create_haproxy_globals = self.patch_hook( 21 "create_haproxy_globals") 22 self.create_haproxy_defaults = self.patch_hook( 23 "create_haproxy_defaults") 24 self.remove_services = self.patch_hook("remove_services") 25 self.create_services = self.patch_hook("create_services") 26 self.load_services = self.patch_hook("load_services") 27 self.construct_haproxy_config = self.patch_hook( 28 "construct_haproxy_config") 29 self.service_haproxy = self.patch_hook( 30 "service_haproxy") 31 self.update_sysctl = self.patch_hook( 32 "update_sysctl") 33 self.update_ssl_cert = self.patch_hook( 34 "update_ssl_cert") 35 self.notify_website = self.patch_hook("notify_website") 36 self.notify_peer = self.patch_hook("notify_peer") 37 self.write_metrics_cronjob = self.patch_hook("write_metrics_cronjob") 38 self.log = self.patch_hook("log") 39 sys_exit = patch.object(sys, "exit") 40 self.sys_exit = sys_exit.start() 41 self.addCleanup(sys_exit.stop) 42 43 def patch_hook(self, hook_name): 44 mock_controller = patch.object(hooks, hook_name) 45 mock = mock_controller.start() 46 self.addCleanup(mock_controller.stop) 47 return mock 48 49 def test_config_changed_notify_website_changed_stanzas(self): 50 self.service_haproxy.return_value = True 51 self.get_listen_stanzas.side_effect = ( 52 (('foo.internal', '1.2.3.4', 123),), 53 (('foo.internal', '1.2.3.4', 123), 54 ('bar.internal', '1.2.3.5', 234),)) 55 56 hooks.config_changed() 57 58 self.notify_website.assert_called_once_with() 59 self.notify_peer.assert_called_once_with() 60 61 def test_config_changed_no_notify_website_not_changed(self): 62 self.service_haproxy.return_value = True 63 self.get_listen_stanzas.side_effect = ( 64 (('foo.internal', '1.2.3.4', 123),), 65 (('foo.internal', '1.2.3.4', 123),)) 66 67 hooks.config_changed() 68 69 self.notify_website.assert_not_called() 70 self.notify_peer.assert_not_called() 71 72 def test_config_changed_no_notify_website_failed_check(self): 73 self.service_haproxy.return_value = False 74 self.get_listen_stanzas.side_effect = ( 75 (('foo.internal', '1.2.3.4', 123),), 76 (('foo.internal', '1.2.3.4', 123), 77 ('bar.internal', '1.2.3.5', 234),)) 78 79 hooks.config_changed() 80 81 self.notify_website.assert_not_called() 82 self.notify_peer.assert_not_called() 83 self.log.assert_called_once_with( 84 "HAProxy configuration check failed, exiting.") 85 self.sys_exit.assert_called_once_with(1) 86 87 def test_config_changed_notify_reverseproxy(self): 88 """ 89 If the ssl_cert config value changes, the reverseproxy relations get 90 updated. 91 """ 92 config_data = self.config_get() 93 config_data.changed.return_value = True 94 _notify_reverseproxy = self.patch_hook("_notify_reverseproxy") 95 service_restart = self.patch_hook('service_restart') 96 97 hooks.config_changed() 98 self.assertIn(call('ssl_cert'), config_data.changed.mock_calls) 99 _notify_reverseproxy.assert_called_once_with() 100 service_restart.assert_called_once_with('rsyslog') 101 102 def test_config_changed_restart_rsyslog(self): 103 """ 104 If the gloabl_log or source config value changes, rsyslog is 105 restarted 106 """ 107 config_data = self.config_get() 108 called = [] 109 110 def changed(a): 111 if a in called or a == 'ssl_cert': 112 return False 113 called.append(a) 114 return True 115 116 config_data.changed.side_effect = changed 117 service_restart = self.patch_hook('service_restart') 118 119 hooks.config_changed() 120 self.assertIn(call('global_log'), config_data.changed.mock_calls) 121 service_restart.assert_called_once_with('rsyslog') 122 hooks.config_changed() 123 self.assertIn(call('source'), config_data.changed.mock_calls) 124 service_restart.assert_called_with('rsyslog') 125 126 127 class HelpersTest(TestCase): 128 def test_constructs_haproxy_config(self): 129 with patch_open() as (mock_open, mock_file): 130 hooks.construct_haproxy_config('foo-globals', 'foo-defaults', 131 'foo-monitoring', 'foo-services') 132 133 mock_file.write.assert_called_with( 134 'foo-globals\n\n' 135 'foo-defaults\n\n' 136 'foo-monitoring\n\n' 137 'foo-services\n\n' 138 ) 139 mock_open.assert_called_with(hooks.default_haproxy_config, 'w') 140 141 def test_constructs_nothing_if_globals_is_none(self): 142 with patch_open() as (mock_open, mock_file): 143 hooks.construct_haproxy_config(None, 'foo-defaults', 144 'foo-monitoring', 'foo-services') 145 146 self.assertFalse(mock_open.called) 147 self.assertFalse(mock_file.called) 148 149 def test_constructs_nothing_if_defaults_is_none(self): 150 with patch_open() as (mock_open, mock_file): 151 hooks.construct_haproxy_config('foo-globals', None, 152 'foo-monitoring', 'foo-services') 153 154 self.assertFalse(mock_open.called) 155 self.assertFalse(mock_file.called) 156 157 def test_constructs_haproxy_config_without_optionals(self): 158 with patch_open() as (mock_open, mock_file): 159 hooks.construct_haproxy_config('foo-globals', 'foo-defaults') 160 161 mock_file.write.assert_called_with( 162 'foo-globals\n\n' 163 'foo-defaults\n\n' 164 ) 165 mock_open.assert_called_with(hooks.default_haproxy_config, 'w') 166 167 def test_update_ssl_cert_custom_certificate(self): 168 config_data = { 169 "ssl_cert": base64.b64encode("cert-data\n"), 170 "ssl_key": base64.b64encode("key-data\n")} 171 with patch("hooks.log"): 172 with patch("hooks.write_ssl_pem") as write_ssl_pem_mock: 173 hooks.update_ssl_cert(config_data) 174 default_pem_path = os.path.join( 175 hooks.default_haproxy_lib_dir, "default.pem") 176 write_ssl_pem_mock.assert_called_with( 177 default_pem_path, "cert-data\nkey-data\n") 178 179 def test_update_ssl_cert_selfsigned(self): 180 config_data = {"ssl_cert": "SELFSIGNED"} 181 with patch("hooks.log"): 182 with patch("hooks.get_selfsigned_cert") as selfsigned_mock: 183 selfsigned_mock.return_value = "data" 184 with patch("hooks.write_ssl_pem") as write_ssl_pem_mock: 185 hooks.update_ssl_cert(config_data) 186 default_pem_path = os.path.join( 187 hooks.default_haproxy_lib_dir, "default.pem") 188 write_ssl_pem_mock.assert_called_with( 189 default_pem_path, "data")