Merge lp:~yolanda.robla/charms/precise/keystone/unit_testing into lp:~openstack-charmers/charms/precise/keystone/icehouse
- Precise Pangolin (12.04)
- unit_testing
- Merge into icehouse
Proposed by
Yolanda Robla
Status: | Merged |
---|---|
Merged at revision: | 79 |
Proposed branch: | lp:~yolanda.robla/charms/precise/keystone/unit_testing |
Merge into: | lp:~openstack-charmers/charms/precise/keystone/icehouse |
Diff against target: |
653 lines (+579/-5) 3 files modified
unit_tests/test_keystone_contexts.py (+70/-0) unit_tests/test_keystone_hooks.py (+251/-5) unit_tests/test_keystone_utils.py (+258/-0) |
To merge this branch: | bzr merge lp:~yolanda.robla/charms/precise/keystone/unit_testing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Needs Fixing | ||
Review via email: mp+214009@code.launchpad.net |
Commit message
Description of the change
Added unit testing
To post a comment you must log in.
- 79. By Yolanda Robla
-
mocking extra calls
- 80. By Yolanda Robla
-
mocking keystone manager
- 81. By Yolanda Robla
-
fixing tests for latest changes
Revision history for this message
James Page (james-page) wrote : | # |
Looking better; one further comment - Mocks don't have an "assert_called()" method; this works because its a mock but actually fails to check anything - use :
self.
I see a few instances of this throughout the tests.
review:
Needs Fixing
- 82. By Yolanda Robla
-
changing assert_called
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'unit_tests/test_keystone_contexts.py' | |||
2 | --- unit_tests/test_keystone_contexts.py 1970-01-01 00:00:00 +0000 | |||
3 | +++ unit_tests/test_keystone_contexts.py 2014-04-04 12:26:02 +0000 | |||
4 | @@ -0,0 +1,70 @@ | |||
5 | 1 | import keystone_context as context | ||
6 | 2 | from mock import patch | ||
7 | 3 | |||
8 | 4 | with patch('charmhelpers.core.hookenv.config') as config: | ||
9 | 5 | config.return_value = 'keystone' | ||
10 | 6 | import keystone_utils as utils | ||
11 | 7 | |||
12 | 8 | from test_utils import ( | ||
13 | 9 | CharmTestCase | ||
14 | 10 | ) | ||
15 | 11 | |||
16 | 12 | TO_PATCH = [ | ||
17 | 13 | 'determine_apache_port', | ||
18 | 14 | 'determine_api_port', | ||
19 | 15 | ] | ||
20 | 16 | |||
21 | 17 | |||
22 | 18 | class TestKeystoneContexts(CharmTestCase): | ||
23 | 19 | |||
24 | 20 | def setUp(self): | ||
25 | 21 | super(TestKeystoneContexts, self).setUp(context, TO_PATCH) | ||
26 | 22 | |||
27 | 23 | @patch('charmhelpers.contrib.openstack.context.is_clustered') | ||
28 | 24 | @patch('charmhelpers.contrib.openstack.context.determine_apache_port') | ||
29 | 25 | @patch('charmhelpers.contrib.openstack.context.determine_api_port') | ||
30 | 26 | @patch('charmhelpers.contrib.openstack.context.unit_get') | ||
31 | 27 | @patch('charmhelpers.contrib.openstack.context.https') | ||
32 | 28 | def test_apache_ssl_context_service_enabled(self, mock_https, | ||
33 | 29 | mock_unit_get, | ||
34 | 30 | mock_determine_api_port, | ||
35 | 31 | mock_determine_apache_port, | ||
36 | 32 | mock_is_clustered): | ||
37 | 33 | mock_https.return_value = True | ||
38 | 34 | mock_unit_get.return_value = '1.2.3.4' | ||
39 | 35 | mock_determine_api_port.return_value = '12' | ||
40 | 36 | mock_determine_apache_port.return_value = '34' | ||
41 | 37 | mock_is_clustered.return_value = False | ||
42 | 38 | |||
43 | 39 | ctxt = context.ApacheSSLContext() | ||
44 | 40 | with patch.object(ctxt, 'enable_modules') as mock_enable_modules: | ||
45 | 41 | with patch.object(ctxt, 'configure_cert') as mock_configure_cert: | ||
46 | 42 | self.assertEquals(ctxt(), {'endpoints': [(34, 12)], | ||
47 | 43 | 'private_address': '1.2.3.4', | ||
48 | 44 | 'namespace': 'keystone'}) | ||
49 | 45 | self.assertTrue(mock_https.called) | ||
50 | 46 | mock_unit_get.assert_called_with('private-address') | ||
51 | 47 | |||
52 | 48 | @patch('charmhelpers.contrib.openstack.context.relation_ids') | ||
53 | 49 | @patch('charmhelpers.contrib.openstack.context.unit_get') | ||
54 | 50 | @patch('charmhelpers.contrib.openstack.context.related_units') | ||
55 | 51 | @patch('charmhelpers.contrib.openstack.context.relation_get') | ||
56 | 52 | @patch('charmhelpers.contrib.openstack.context.log') | ||
57 | 53 | @patch('__builtin__.open') | ||
58 | 54 | def test_haproxy_context_service_enabled(self, mock_open, mock_log, mock_relation_get, mock_related_units, | ||
59 | 55 | mock_unit_get, mock_relation_ids): | ||
60 | 56 | mock_relation_ids.return_value = ['identity-service:0',] | ||
61 | 57 | mock_unit_get.return_value = '1.2.3.4' | ||
62 | 58 | mock_relation_get.return_value = '10.0.0.0' | ||
63 | 59 | mock_related_units.return_value = ['unit/0',] | ||
64 | 60 | self.determine_apache_port.return_value = '34' | ||
65 | 61 | |||
66 | 62 | ctxt = context.HAProxyContext() | ||
67 | 63 | |||
68 | 64 | self.assertEquals(ctxt(), {'listen_ports': {'admin_port': 'keystone', 'public_port': 'keystone'}, | ||
69 | 65 | 'service_ports': {'admin-port': ['keystone', '34'], | ||
70 | 66 | 'public-port': ['keystone', '34']}, | ||
71 | 67 | 'units': {'keystone': '1.2.3.4', 'unit-0':'10.0.0.0'}}) | ||
72 | 68 | mock_unit_get.assert_called_with('private-address') | ||
73 | 69 | mock_relation_get.assert_called_with('private-address', rid='identity-service:0', unit='unit/0') | ||
74 | 70 | mock_open.assert_called_with('/etc/default/haproxy', 'w') | ||
75 | 0 | 71 | ||
76 | === modified file 'unit_tests/test_keystone_hooks.py' | |||
77 | --- unit_tests/test_keystone_hooks.py 2014-03-31 08:35:19 +0000 | |||
78 | +++ unit_tests/test_keystone_hooks.py 2014-04-04 12:26:02 +0000 | |||
79 | @@ -15,6 +15,7 @@ | |||
80 | 15 | utils.restart_map = MagicMock() | 15 | utils.restart_map = MagicMock() |
81 | 16 | 16 | ||
82 | 17 | import keystone_hooks as hooks | 17 | import keystone_hooks as hooks |
83 | 18 | from charmhelpers.contrib import unison | ||
84 | 18 | 19 | ||
85 | 19 | utils.register_configs = _reg | 20 | utils.register_configs = _reg |
86 | 20 | utils.restart_map = _map | 21 | utils.restart_map = _map |
87 | @@ -25,10 +26,14 @@ | |||
88 | 25 | 'config', | 26 | 'config', |
89 | 26 | 'is_relation_made', | 27 | 'is_relation_made', |
90 | 27 | 'log', | 28 | 'log', |
91 | 29 | 'filter_installed_packages', | ||
92 | 28 | 'relation_ids', | 30 | 'relation_ids', |
93 | 31 | 'relation_list', | ||
94 | 29 | 'relation_set', | 32 | 'relation_set', |
95 | 30 | 'relation_get', | 33 | 'relation_get', |
96 | 34 | 'related_units', | ||
97 | 31 | 'unit_get', | 35 | 'unit_get', |
98 | 36 | 'peer_echo', | ||
99 | 32 | # charmhelpers.core.host | 37 | # charmhelpers.core.host |
100 | 33 | 'apt_install', | 38 | 'apt_install', |
101 | 34 | 'apt_update', | 39 | 'apt_update', |
102 | @@ -41,11 +46,20 @@ | |||
103 | 41 | 'restart_map', | 46 | 'restart_map', |
104 | 42 | 'register_configs', | 47 | 'register_configs', |
105 | 43 | 'do_openstack_upgrade', | 48 | 'do_openstack_upgrade', |
106 | 49 | 'openstack_upgrade_available', | ||
107 | 50 | 'save_script_rc', | ||
108 | 44 | 'migrate_database', | 51 | 'migrate_database', |
109 | 52 | 'ensure_initial_admin', | ||
110 | 53 | 'add_service_to_keystone', | ||
111 | 54 | 'synchronize_ca', | ||
112 | 55 | 'get_hacluster_config', | ||
113 | 56 | 'is_leader', | ||
114 | 45 | # other | 57 | # other |
115 | 46 | 'check_call', | 58 | 'check_call', |
116 | 47 | 'execd_preinstall', | 59 | 'execd_preinstall', |
118 | 48 | 'mkdir' | 60 | 'mkdir', |
119 | 61 | 'os', | ||
120 | 62 | 'time', | ||
121 | 49 | ] | 63 | ] |
122 | 50 | 64 | ||
123 | 51 | 65 | ||
124 | @@ -54,7 +68,18 @@ | |||
125 | 54 | def setUp(self): | 68 | def setUp(self): |
126 | 55 | super(KeystoneRelationTests, self).setUp(hooks, TO_PATCH) | 69 | super(KeystoneRelationTests, self).setUp(hooks, TO_PATCH) |
127 | 56 | self.config.side_effect = self.test_config.get | 70 | self.config.side_effect = self.test_config.get |
128 | 71 | self.ssh_user = 'juju_keystone' | ||
129 | 57 | 72 | ||
130 | 73 | def test_install_hook(self): | ||
131 | 74 | repo = 'cloud:precise-grizzly' | ||
132 | 75 | self.test_config.set('openstack-origin', repo) | ||
133 | 76 | hooks.install() | ||
134 | 77 | self.configure_installation_source.assert_called_with(repo) | ||
135 | 78 | self.assertTrue(self.apt_update.called) | ||
136 | 79 | self.apt_install.assert_called_with(['haproxy', 'unison', 'python-keystoneclient', | ||
137 | 80 | 'uuid', 'python-mysqldb', 'openssl', 'apache2', | ||
138 | 81 | 'pwgen', 'keystone', 'python-psycopg2'], fatal=True) | ||
139 | 82 | self.assertTrue(self.execd_preinstall.called) | ||
140 | 58 | 83 | ||
141 | 59 | def test_db_joined(self): | 84 | def test_db_joined(self): |
142 | 60 | self.unit_get.return_value = 'keystone.foohost.com' | 85 | self.unit_get.return_value = 'keystone.foohost.com' |
143 | @@ -76,18 +101,20 @@ | |||
144 | 76 | 101 | ||
145 | 77 | with self.assertRaises(Exception) as context: | 102 | with self.assertRaises(Exception) as context: |
146 | 78 | hooks.db_joined() | 103 | hooks.db_joined() |
148 | 79 | self.assertEqual(context.exception.message, | 104 | self.assertEqual( |
149 | 105 | context.exception.message, | ||
150 | 80 | 'Attempting to associate a mysql database when there ' | 106 | 'Attempting to associate a mysql database when there ' |
152 | 81 | 'is already associated a postgresql one') | 107 | 'is already associated a postgresql one') |
153 | 82 | 108 | ||
154 | 83 | def test_postgresql_joined_with_db(self): | 109 | def test_postgresql_joined_with_db(self): |
155 | 84 | self.is_relation_made.return_value = True | 110 | self.is_relation_made.return_value = True |
156 | 85 | 111 | ||
157 | 86 | with self.assertRaises(Exception) as context: | 112 | with self.assertRaises(Exception) as context: |
158 | 87 | hooks.pgsql_db_joined() | 113 | hooks.pgsql_db_joined() |
160 | 88 | self.assertEqual(context.exception.message, | 114 | self.assertEqual( |
161 | 115 | context.exception.message, | ||
162 | 89 | 'Attempting to associate a postgresql database when there ' | 116 | 'Attempting to associate a postgresql database when there ' |
164 | 90 | 'is already associated a mysql one') | 117 | 'is already associated a mysql one') |
165 | 91 | 118 | ||
166 | 92 | @patch.object(hooks, 'CONFIGS') | 119 | @patch.object(hooks, 'CONFIGS') |
167 | 93 | def test_db_changed_missing_relation_data(self, configs): | 120 | def test_db_changed_missing_relation_data(self, configs): |
168 | @@ -118,3 +145,222 @@ | |||
169 | 118 | configs.complete_contexts.return_value = ['pgsql-db'] | 145 | configs.complete_contexts.return_value = ['pgsql-db'] |
170 | 119 | configs.write = MagicMock() | 146 | configs.write = MagicMock() |
171 | 120 | hooks.pgsql_db_changed() | 147 | hooks.pgsql_db_changed() |
172 | 148 | |||
173 | 149 | @patch.object(hooks, 'CONFIGS') | ||
174 | 150 | @patch.object(hooks, 'identity_changed') | ||
175 | 151 | def test_db_changed(self, identity_changed, configs): | ||
176 | 152 | self.relation_ids.return_value = ['identity-service:0'] | ||
177 | 153 | self.related_units.return_value = ['unit/0'] | ||
178 | 154 | |||
179 | 155 | self._shared_db_test(configs) | ||
180 | 156 | self.assertEquals([call('/etc/keystone/keystone.conf')], | ||
181 | 157 | configs.write.call_args_list) | ||
182 | 158 | self.migrate_database.assert_called_with() | ||
183 | 159 | self.assertTrue(self.ensure_initial_admin.called) | ||
184 | 160 | identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0') | ||
185 | 161 | |||
186 | 162 | @patch.object(hooks, 'CONFIGS') | ||
187 | 163 | @patch.object(hooks, 'identity_changed') | ||
188 | 164 | def test_postgresql_db_changed(self, identity_changed, configs): | ||
189 | 165 | self.relation_ids.return_value = ['identity-service:0'] | ||
190 | 166 | self.related_units.return_value = ['unit/0'] | ||
191 | 167 | |||
192 | 168 | self._postgresql_db_test(configs) | ||
193 | 169 | self.assertEquals([call('/etc/keystone/keystone.conf')], | ||
194 | 170 | configs.write.call_args_list) | ||
195 | 171 | self.migrate_database.assert_called_with() | ||
196 | 172 | self.assertTrue(self.ensure_initial_admin.called) | ||
197 | 173 | identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0') | ||
198 | 174 | |||
199 | 175 | @patch.object(unison, 'ensure_user') | ||
200 | 176 | @patch.object(unison, 'get_homedir') | ||
201 | 177 | @patch.object(hooks, 'CONFIGS') | ||
202 | 178 | @patch.object(hooks, 'identity_changed') | ||
203 | 179 | @patch.object(hooks, 'configure_https') | ||
204 | 180 | def test_config_changed_no_openstack_upgrade_leader(self, configure_https, identity_changed, configs, get_homedir, ensure_user): | ||
205 | 181 | self.openstack_upgrade_available.return_value = False | ||
206 | 182 | self.eligible_leader.return_value = True | ||
207 | 183 | self.relation_ids.return_value = ['identity-service:0'] | ||
208 | 184 | self.relation_list.return_value = ['unit/0'] | ||
209 | 185 | |||
210 | 186 | hooks.config_changed() | ||
211 | 187 | ensure_user.assert_called_with(user=self.ssh_user, group='keystone') | ||
212 | 188 | get_homedir.assert_called_with(self.ssh_user) | ||
213 | 189 | |||
214 | 190 | self.save_script_rc.assert_called_with() | ||
215 | 191 | configure_https.assert_called_with() | ||
216 | 192 | self.assertTrue(configs.write_all.called) | ||
217 | 193 | |||
218 | 194 | self.migrate_database.assert_called_with() | ||
219 | 195 | self.assertTrue(self.ensure_initial_admin.called) | ||
220 | 196 | self.log.assert_called_with('Firing identity_changed hook for all related services.') | ||
221 | 197 | identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0') | ||
222 | 198 | |||
223 | 199 | @patch.object(unison, 'ensure_user') | ||
224 | 200 | @patch.object(unison, 'get_homedir') | ||
225 | 201 | @patch.object(hooks, 'CONFIGS') | ||
226 | 202 | @patch.object(hooks, 'identity_changed') | ||
227 | 203 | @patch.object(hooks, 'configure_https') | ||
228 | 204 | def test_config_changed_no_openstack_upgrade_not_leader(self, configure_https, identity_changed, configs, get_homedir, ensure_user): | ||
229 | 205 | self.openstack_upgrade_available.return_value = False | ||
230 | 206 | self.eligible_leader.return_value = False | ||
231 | 207 | |||
232 | 208 | hooks.config_changed() | ||
233 | 209 | ensure_user.assert_called_with(user=self.ssh_user, group='keystone') | ||
234 | 210 | get_homedir.assert_called_with(self.ssh_user) | ||
235 | 211 | |||
236 | 212 | self.save_script_rc.assert_called_with() | ||
237 | 213 | configure_https.assert_called_with() | ||
238 | 214 | self.assertTrue(configs.write_all.called) | ||
239 | 215 | |||
240 | 216 | self.assertFalse(self.migrate_database.called) | ||
241 | 217 | self.assertFalse(self.ensure_initial_admin.called) | ||
242 | 218 | self.assertFalse(identity_changed.called) | ||
243 | 219 | |||
244 | 220 | @patch.object(unison, 'ensure_user') | ||
245 | 221 | @patch.object(unison, 'get_homedir') | ||
246 | 222 | @patch.object(hooks, 'CONFIGS') | ||
247 | 223 | @patch.object(hooks, 'identity_changed') | ||
248 | 224 | @patch.object(hooks, 'configure_https') | ||
249 | 225 | def test_config_changed_with_openstack_upgrade(self, configure_https, identity_changed, configs, get_homedir, ensure_user): | ||
250 | 226 | self.openstack_upgrade_available.return_value = True | ||
251 | 227 | self.eligible_leader.return_value = True | ||
252 | 228 | self.relation_ids.return_value = ['identity-service:0'] | ||
253 | 229 | self.relation_list.return_value = ['unit/0'] | ||
254 | 230 | |||
255 | 231 | hooks.config_changed() | ||
256 | 232 | ensure_user.assert_called_with(user=self.ssh_user, group='keystone') | ||
257 | 233 | get_homedir.assert_called_with(self.ssh_user) | ||
258 | 234 | |||
259 | 235 | self.assertTrue(self.do_openstack_upgrade.called) | ||
260 | 236 | |||
261 | 237 | self.save_script_rc.assert_called_with() | ||
262 | 238 | configure_https.assert_called_with() | ||
263 | 239 | self.assertTrue(configs.write_all.called) | ||
264 | 240 | |||
265 | 241 | self.migrate_database.assert_called_with() | ||
266 | 242 | self.assertTrue(self.ensure_initial_admin.called) | ||
267 | 243 | self.log.assert_called_with('Firing identity_changed hook for all related services.') | ||
268 | 244 | identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0') | ||
269 | 245 | |||
270 | 246 | def test_identity_changed_leader(self): | ||
271 | 247 | self.eligible_leader.return_value = True | ||
272 | 248 | hooks.identity_changed(relation_id='identity-service:0', remote_unit='unit/0') | ||
273 | 249 | self.add_service_to_keystone.assert_called_with('identity-service:0', 'unit/0') | ||
274 | 250 | self.assertTrue(self.synchronize_ca.called) | ||
275 | 251 | |||
276 | 252 | def test_identity_changed_no_leader(self): | ||
277 | 253 | self.eligible_leader.return_value = False | ||
278 | 254 | hooks.identity_changed(relation_id='identity-service:0', remote_unit='unit/0') | ||
279 | 255 | self.assertFalse(self.add_service_to_keystone.called) | ||
280 | 256 | self.log.assert_called_with('Deferring identity_changed() to service leader.') | ||
281 | 257 | |||
282 | 258 | @patch.object(unison, 'ssh_authorized_peers') | ||
283 | 259 | def test_cluster_joined(self, ssh_authorized_peers): | ||
284 | 260 | hooks.cluster_joined() | ||
285 | 261 | ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='juju_keystone', | ||
286 | 262 | peer_interface='cluster', ensure_local_user=True) | ||
287 | 263 | |||
288 | 264 | @patch.object(unison, 'ssh_authorized_peers') | ||
289 | 265 | @patch.object(hooks, 'CONFIGS') | ||
290 | 266 | def test_cluster_changed(self, configs, ssh_authorized_peers): | ||
291 | 267 | hooks.cluster_changed() | ||
292 | 268 | self.peer_echo.assert_called_with(includes=['_passwd']) | ||
293 | 269 | ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='keystone', | ||
294 | 270 | peer_interface='cluster', ensure_local_user=True) | ||
295 | 271 | self.assertTrue(self.synchronize_ca.called) | ||
296 | 272 | self.assertTrue(configs.write_all.called) | ||
297 | 273 | |||
298 | 274 | def test_ha_joined(self): | ||
299 | 275 | self.get_hacluster_config.return_value = { | ||
300 | 276 | 'ha-bindiface': 'em0', | ||
301 | 277 | 'ha-mcastport': '8080', | ||
302 | 278 | 'vip': '10.10.10.10', | ||
303 | 279 | 'vip_iface': 'em1', | ||
304 | 280 | 'vip_cidr': '24' | ||
305 | 281 | } | ||
306 | 282 | hooks.ha_joined() | ||
307 | 283 | self.assertTrue(self.get_hacluster_config.called) | ||
308 | 284 | args = { | ||
309 | 285 | 'corosync_bindiface': 'em0', | ||
310 | 286 | 'corosync_mcastport': '8080', | ||
311 | 287 | 'init_services': {'res_ks_haproxy': 'haproxy'}, | ||
312 | 288 | 'resources': {'res_ks_vip': 'ocf:heartbeat:IPaddr2', | ||
313 | 289 | 'res_ks_haproxy': 'lsb:haproxy'}, | ||
314 | 290 | 'resource_params': { | ||
315 | 291 | 'res_ks_vip': 'params ip="10.10.10.10"' | ||
316 | 292 | ' cidr_netmask="24" nic="em1"', | ||
317 | 293 | 'res_ks_haproxy': 'op monitor interval="5s"'}, | ||
318 | 294 | 'clones': {'cl_ks_haproxy': 'res_ks_haproxy'} | ||
319 | 295 | } | ||
320 | 296 | self.relation_set.assert_called_with(**args) | ||
321 | 297 | |||
322 | 298 | @patch.object(hooks, 'CONFIGS') | ||
323 | 299 | def test_ha_relation_changed_not_clustered_not_leader(self, configs): | ||
324 | 300 | self.relation_get.return_value = False | ||
325 | 301 | self.is_leader.return_value = False | ||
326 | 302 | |||
327 | 303 | hooks.ha_changed() | ||
328 | 304 | self.assertTrue(configs.write_all.called) | ||
329 | 305 | |||
330 | 306 | @patch.object(hooks, 'CONFIGS') | ||
331 | 307 | def test_ha_relation_changed_clustered_leader(self, configs): | ||
332 | 308 | self.relation_get.return_value = True | ||
333 | 309 | self.is_leader.return_value = True | ||
334 | 310 | self.relation_ids.return_value = ['identity-service:0'] | ||
335 | 311 | self.test_config.set('vip', '10.10.10.10') | ||
336 | 312 | |||
337 | 313 | hooks.ha_changed() | ||
338 | 314 | self.assertTrue(configs.write_all.called) | ||
339 | 315 | self.log.assert_called_with('Cluster configured, notifying other services and updating ' | ||
340 | 316 | 'keystone endpoint configuration') | ||
341 | 317 | self.relation_set.assert_called_with(relation_id='identity-service:0', | ||
342 | 318 | auth_host='10.10.10.10', | ||
343 | 319 | service_host='10.10.10.10') | ||
344 | 320 | |||
345 | 321 | @patch.object(hooks, 'CONFIGS') | ||
346 | 322 | def test_configure_https_enable(self, configs): | ||
347 | 323 | configs.complete_contexts = MagicMock() | ||
348 | 324 | configs.complete_contexts.return_value = ['https'] | ||
349 | 325 | configs.write = MagicMock() | ||
350 | 326 | |||
351 | 327 | hooks.configure_https() | ||
352 | 328 | self.assertTrue(configs.write_all.called) | ||
353 | 329 | cmd = ['a2ensite', 'openstack_https_frontend'] | ||
354 | 330 | self.check_call.assert_called_with(cmd) | ||
355 | 331 | |||
356 | 332 | @patch.object(hooks, 'CONFIGS') | ||
357 | 333 | def test_configure_https_disable(self, configs): | ||
358 | 334 | configs.complete_contexts = MagicMock() | ||
359 | 335 | configs.complete_contexts.return_value = [''] | ||
360 | 336 | configs.write = MagicMock() | ||
361 | 337 | |||
362 | 338 | hooks.configure_https() | ||
363 | 339 | self.assertTrue(configs.write_all.called) | ||
364 | 340 | cmd = ['a2dissite', 'openstack_https_frontend'] | ||
365 | 341 | self.check_call.assert_called_with(cmd) | ||
366 | 342 | |||
367 | 343 | @patch.object(unison, 'ssh_authorized_peers') | ||
368 | 344 | def test_upgrade_charm_leader(self, ssh_authorized_peers): | ||
369 | 345 | self.eligible_leader.return_value = True | ||
370 | 346 | self.filter_installed_packages.return_value = [] | ||
371 | 347 | hooks.upgrade_charm() | ||
372 | 348 | self.assertTrue(self.apt_install.called) | ||
373 | 349 | ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='keystone', | ||
374 | 350 | peer_interface='cluster', ensure_local_user=True) | ||
375 | 351 | self.assertTrue(self.synchronize_ca.called) | ||
376 | 352 | self.log.assert_called_with('Cluster leader - ensuring endpoint configuration' | ||
377 | 353 | ' is up to date') | ||
378 | 354 | self.assertTrue(self.ensure_initial_admin.called) | ||
379 | 355 | |||
380 | 356 | @patch.object(unison, 'ssh_authorized_peers') | ||
381 | 357 | def test_upgrade_charm_not_leader(self, ssh_authorized_peers): | ||
382 | 358 | self.eligible_leader.return_value = False | ||
383 | 359 | self.filter_installed_packages.return_value = [] | ||
384 | 360 | hooks.upgrade_charm() | ||
385 | 361 | self.assertTrue(self.apt_install.called) | ||
386 | 362 | ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='keystone', | ||
387 | 363 | peer_interface='cluster', ensure_local_user=True) | ||
388 | 364 | self.assertTrue(self.synchronize_ca.called) | ||
389 | 365 | self.assertFalse(self.log.called) | ||
390 | 366 | self.assertFalse(self.ensure_initial_admin.called) | ||
391 | 121 | 367 | ||
392 | === added file 'unit_tests/test_keystone_utils.py' | |||
393 | --- unit_tests/test_keystone_utils.py 1970-01-01 00:00:00 +0000 | |||
394 | +++ unit_tests/test_keystone_utils.py 2014-04-04 12:26:02 +0000 | |||
395 | @@ -0,0 +1,258 @@ | |||
396 | 1 | from mock import patch, call, MagicMock | ||
397 | 2 | from test_utils import CharmTestCase | ||
398 | 3 | from copy import deepcopy | ||
399 | 4 | |||
400 | 5 | from collections import OrderedDict | ||
401 | 6 | import os | ||
402 | 7 | import manager | ||
403 | 8 | |||
404 | 9 | os.environ['JUJU_UNIT_NAME'] = 'keystone' | ||
405 | 10 | with patch('charmhelpers.core.hookenv.config') as config: | ||
406 | 11 | import keystone_utils as utils | ||
407 | 12 | |||
408 | 13 | import keystone_context | ||
409 | 14 | import keystone_hooks as hooks | ||
410 | 15 | from charmhelpers.contrib.openstack import context | ||
411 | 16 | |||
412 | 17 | TO_PATCH = [ | ||
413 | 18 | 'api_port', | ||
414 | 19 | 'config', | ||
415 | 20 | 'create_user', | ||
416 | 21 | 'os_release', | ||
417 | 22 | 'log', | ||
418 | 23 | 'get_ca', | ||
419 | 24 | 'create_role', | ||
420 | 25 | 'create_service_entry', | ||
421 | 26 | 'create_endpoint_template', | ||
422 | 27 | 'get_admin_token', | ||
423 | 28 | 'get_local_endpoint', | ||
424 | 29 | 'get_requested_roles', | ||
425 | 30 | 'get_service_password', | ||
426 | 31 | 'get_os_codename_install_source', | ||
427 | 32 | 'grant_role', | ||
428 | 33 | 'configure_installation_source', | ||
429 | 34 | 'eligible_leader', | ||
430 | 35 | 'https', | ||
431 | 36 | 'is_clustered', | ||
432 | 37 | 'service_stop', | ||
433 | 38 | 'service_start', | ||
434 | 39 | 'relation_get', | ||
435 | 40 | 'relation_set', | ||
436 | 41 | 'https', | ||
437 | 42 | 'unit_private_ip', | ||
438 | 43 | # generic | ||
439 | 44 | 'apt_update', | ||
440 | 45 | 'apt_upgrade', | ||
441 | 46 | 'apt_install', | ||
442 | 47 | 'subprocess', | ||
443 | 48 | 'time', | ||
444 | 49 | 'pwgen', | ||
445 | 50 | ] | ||
446 | 51 | |||
447 | 52 | class TestKeystoneUtils(CharmTestCase): | ||
448 | 53 | |||
449 | 54 | def setUp(self): | ||
450 | 55 | super(TestKeystoneUtils, self).setUp(utils, TO_PATCH) | ||
451 | 56 | self.config.side_effect = self.test_config.get | ||
452 | 57 | |||
453 | 58 | self.ctxt = MagicMock() | ||
454 | 59 | self.rsc_map = { | ||
455 | 60 | '/etc/keystone/keystone.conf': { | ||
456 | 61 | 'services': ['keystone'], | ||
457 | 62 | 'contexts': [self.ctxt], | ||
458 | 63 | }, | ||
459 | 64 | '/etc/apache2/sites-available/openstack_https_frontend': { | ||
460 | 65 | 'services': ['apache2'], | ||
461 | 66 | 'contexts': [self.ctxt], | ||
462 | 67 | }, | ||
463 | 68 | '/etc/apache2/sites-available/openstack_https_frontend.conf': { | ||
464 | 69 | 'services': ['apache2'], | ||
465 | 70 | 'contexts': [self.ctxt], | ||
466 | 71 | } | ||
467 | 72 | } | ||
468 | 73 | |||
469 | 74 | @patch('charmhelpers.contrib.openstack.templating.OSConfigRenderer') | ||
470 | 75 | @patch('os.path.exists') | ||
471 | 76 | @patch.object(utils, 'resource_map') | ||
472 | 77 | def test_register_configs_apache(self, resource_map, exists, renderer): | ||
473 | 78 | exists.return_value = False | ||
474 | 79 | self.os_release.return_value = 'havana' | ||
475 | 80 | fake_renderer = MagicMock() | ||
476 | 81 | fake_renderer.register = MagicMock() | ||
477 | 82 | renderer.return_value = fake_renderer | ||
478 | 83 | |||
479 | 84 | resource_map.return_value = self.rsc_map | ||
480 | 85 | utils.register_configs() | ||
481 | 86 | renderer.assert_called_with( | ||
482 | 87 | openstack_release='havana', templates_dir='templates/') | ||
483 | 88 | |||
484 | 89 | ex_reg = [ | ||
485 | 90 | call('/etc/keystone/keystone.conf', [self.ctxt]), | ||
486 | 91 | call('/etc/apache2/sites-available/openstack_https_frontend', [self.ctxt]), | ||
487 | 92 | call('/etc/apache2/sites-available/openstack_https_frontend.conf', [self.ctxt]), | ||
488 | 93 | ] | ||
489 | 94 | self.assertEquals(fake_renderer.register.call_args_list, ex_reg) | ||
490 | 95 | |||
491 | 96 | def test_determine_ports(self): | ||
492 | 97 | self.test_config.set('admin-port','80') | ||
493 | 98 | self.test_config.set('service-port','81') | ||
494 | 99 | result = utils.determine_ports() | ||
495 | 100 | self.assertEquals(result, ['80', '81']) | ||
496 | 101 | |||
497 | 102 | def test_determine_packages(self): | ||
498 | 103 | result = utils.determine_packages() | ||
499 | 104 | ex = utils.BASE_PACKAGES + ['keystone', 'haproxy', 'apache2'] | ||
500 | 105 | self.assertEquals(set(ex), set(result)) | ||
501 | 106 | |||
502 | 107 | @patch.object(hooks, 'CONFIGS') | ||
503 | 108 | @patch.object(utils, 'determine_packages') | ||
504 | 109 | @patch.object(utils, 'migrate_database') | ||
505 | 110 | def test_openstack_upgrade_leader(self, migrate_database, determine_packages, configs): | ||
506 | 111 | self.test_config.set('openstack-origin', 'precise') | ||
507 | 112 | determine_packages.return_value = [] | ||
508 | 113 | self.eligible_leader.return_value = True | ||
509 | 114 | |||
510 | 115 | utils.do_openstack_upgrade(configs) | ||
511 | 116 | |||
512 | 117 | self.get_os_codename_install_source.assert_called_with('precise') | ||
513 | 118 | self.configure_installation_source.assert_called_with('precise') | ||
514 | 119 | self.assertTrue(self.apt_update.called) | ||
515 | 120 | |||
516 | 121 | dpkg_opts = [ | ||
517 | 122 | '--option', 'Dpkg::Options::=--force-confnew', | ||
518 | 123 | '--option', 'Dpkg::Options::=--force-confdef', | ||
519 | 124 | ] | ||
520 | 125 | self.apt_upgrade.assert_called_with(options=dpkg_opts, fatal=True, dist=True) | ||
521 | 126 | self.apt_install.assert_called_with(packages=[], options=dpkg_opts, fatal=True) | ||
522 | 127 | |||
523 | 128 | self.assertTrue(configs.set_release.called) | ||
524 | 129 | self.assertTrue(configs.write_all.called) | ||
525 | 130 | self.assertTrue(migrate_database.called) | ||
526 | 131 | |||
527 | 132 | def test_migrate_database(self): | ||
528 | 133 | utils.migrate_database() | ||
529 | 134 | |||
530 | 135 | self.service_stop.assert_called_with('keystone') | ||
531 | 136 | cmd = ['sudo', '-u', 'keystone', 'keystone-manage', 'db_sync'] | ||
532 | 137 | self.subprocess.check_output.assert_called_with(cmd) | ||
533 | 138 | self.service_start.assert_called_wkth('keystone') | ||
534 | 139 | |||
535 | 140 | @patch.object(utils, 'b64encode') | ||
536 | 141 | def test_add_service_to_keystone_clustered_https_none_values(self, b64encode): | ||
537 | 142 | relation_id = 'identity-service:0' | ||
538 | 143 | remote_unit = 'unit/0' | ||
539 | 144 | self.is_clustered.return_value = True | ||
540 | 145 | self.https.return_value = True | ||
541 | 146 | self.test_config.set('https-service-endpoints', 'True') | ||
542 | 147 | self.test_config.set('vip', '10.10.10.10') | ||
543 | 148 | self.test_config.set('admin-port', 80) | ||
544 | 149 | self.test_config.set('service-port', 81) | ||
545 | 150 | b64encode.return_value = 'certificate' | ||
546 | 151 | self.get_requested_roles.return_value = ['role1',] | ||
547 | 152 | |||
548 | 153 | self.relation_get.return_value = {'service': 'keystone', | ||
549 | 154 | 'region': 'RegionOne', | ||
550 | 155 | 'public_url': 'None', | ||
551 | 156 | 'admin_url': '10.0.0.2', | ||
552 | 157 | 'internal_url': '192.168.1.2'} | ||
553 | 158 | |||
554 | 159 | utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit) | ||
555 | 160 | self.assertTrue(self.is_clustered.called) | ||
556 | 161 | self.assertTrue(self.https.called) | ||
557 | 162 | self.assertTrue(self.create_role.called) | ||
558 | 163 | |||
559 | 164 | relation_data = {'auth_host': '10.10.10.10', | ||
560 | 165 | 'service_host': '10.10.10.10', | ||
561 | 166 | 'auth_protocol': 'https', | ||
562 | 167 | 'service_protocol': 'https', | ||
563 | 168 | 'auth_port': 80, | ||
564 | 169 | 'service_port': 81, | ||
565 | 170 | 'https_keystone': 'True', | ||
566 | 171 | 'ca_cert': 'certificate'} | ||
567 | 172 | self.relation_set.assert_called_with(relation_id=relation_id, **relation_data) | ||
568 | 173 | |||
569 | 174 | @patch.object(utils, 'ensure_valid_service') | ||
570 | 175 | @patch.object(utils, 'add_endpoint') | ||
571 | 176 | @patch.object(manager, 'KeystoneManager') | ||
572 | 177 | def test_add_service_to_keystone_no_clustered_no_https_complete_values(self, KeystoneManager, add_endpoint, ensure_valid_service): | ||
573 | 178 | relation_id = 'identity-service:0' | ||
574 | 179 | remote_unit = 'unit/0' | ||
575 | 180 | self.get_admin_token.return_value = 'token' | ||
576 | 181 | self.get_service_password.return_value = 'password' | ||
577 | 182 | self.test_config.set('service-tenant', 'tenant') | ||
578 | 183 | self.test_config.set('admin-role', 'admin') | ||
579 | 184 | self.get_requested_roles.return_value = ['role1',] | ||
580 | 185 | self.unit_private_ip.return_value = '10.0.0.3' | ||
581 | 186 | self.test_config.set('admin-port', 80) | ||
582 | 187 | self.test_config.set('service-port', 81) | ||
583 | 188 | self.is_clustered.return_value = False | ||
584 | 189 | self.https.return_value = False | ||
585 | 190 | self.test_config.set('https-service-endpoints', 'False') | ||
586 | 191 | self.get_local_endpoint.return_value = 'http://localhost:80/v2.0/' | ||
587 | 192 | |||
588 | 193 | mock_keystone = MagicMock() | ||
589 | 194 | mock_keystone.resolve_tenant_id.return_value = 'tenant_id' | ||
590 | 195 | KeystoneManager.return_value = mock_keystone | ||
591 | 196 | |||
592 | 197 | self.relation_get.return_value = {'service': 'keystone', | ||
593 | 198 | 'region': 'RegionOne', | ||
594 | 199 | 'public_url': '10.0.0.1', | ||
595 | 200 | 'admin_url': '10.0.0.2', | ||
596 | 201 | 'internal_url': '192.168.1.2'} | ||
597 | 202 | |||
598 | 203 | utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit) | ||
599 | 204 | ensure_valid_service.assert_called_with('keystone') | ||
600 | 205 | add_endpoint.assert_called_with(region='RegionOne', service='keystone', | ||
601 | 206 | publicurl='10.0.0.1', adminurl='10.0.0.2', | ||
602 | 207 | internalurl='192.168.1.2') | ||
603 | 208 | self.assertTrue(self.get_admin_token.called) | ||
604 | 209 | self.get_service_password.assert_called_with('keystone') | ||
605 | 210 | self.create_user.assert_called_with('keystone', 'password', 'tenant') | ||
606 | 211 | self.grant_role.assert_called_with('keystone', 'admin', 'tenant') | ||
607 | 212 | self.create_role.assert_called_with('role1', 'keystone', 'tenant') | ||
608 | 213 | |||
609 | 214 | self.assertTrue(self.is_clustered.called) | ||
610 | 215 | relation_data = {'admin_token': 'token', 'service_port':81, | ||
611 | 216 | 'auth_port':80, 'service_username':'keystone', | ||
612 | 217 | 'service_password': 'password', 'service_tenant': 'tenant', | ||
613 | 218 | 'https_keystone': 'False', 'ssl_cert': '', 'ssl_key': '', | ||
614 | 219 | 'ca_cert': '', 'auth_host':'10.0.0.3', 'service_host': '10.0.0.3', | ||
615 | 220 | 'auth_protocol': 'http', 'service_protocol': 'http', | ||
616 | 221 | 'service_tenant_id': 'tenant_id'} | ||
617 | 222 | self.relation_set.assert_called_with(relation_id=relation_id, **relation_data) | ||
618 | 223 | |||
619 | 224 | @patch.object(utils, 'ensure_valid_service') | ||
620 | 225 | @patch.object(utils, 'add_endpoint') | ||
621 | 226 | @patch.object(manager, 'KeystoneManager') | ||
622 | 227 | def test_add_service_to_keystone_nosubset(self, KeystoneManager, add_endpoint, ensure_valid_service): | ||
623 | 228 | relation_id = 'identity-service:0' | ||
624 | 229 | remote_unit = 'unit/0' | ||
625 | 230 | |||
626 | 231 | self.relation_get.return_value = {'ec2_service': 'nova', | ||
627 | 232 | 'ec2_region': 'RegionOne', | ||
628 | 233 | 'ec2_public_url': '10.0.0.1', | ||
629 | 234 | 'ec2_admin_url': '10.0.0.2', | ||
630 | 235 | 'ec2_internal_url': '192.168.1.2'} | ||
631 | 236 | self.get_local_endpoint.return_value = 'http://localhost:80/v2.0/' | ||
632 | 237 | KeystoneManager.resolve_tenant_id.return_value = 'tenant_id' | ||
633 | 238 | |||
634 | 239 | utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit) | ||
635 | 240 | ensure_valid_service.assert_called_with('nova') | ||
636 | 241 | add_endpoint.assert_called_with(region='RegionOne', service='nova', | ||
637 | 242 | publicurl='10.0.0.1', adminurl='10.0.0.2', | ||
638 | 243 | internalurl='192.168.1.2') | ||
639 | 244 | |||
640 | 245 | def test_ensure_valid_service_incorrect(self): | ||
641 | 246 | utils.ensure_valid_service('fakeservice') | ||
642 | 247 | self.log.assert_called_with("Invalid service requested: 'fakeservice'") | ||
643 | 248 | self.relation_set.assert_called_with(admin_token=-1) | ||
644 | 249 | |||
645 | 250 | def test_add_endpoint(self): | ||
646 | 251 | publicurl = '10.0.0.1' | ||
647 | 252 | adminurl = '10.0.0.2' | ||
648 | 253 | internalurl = '10.0.0.3' | ||
649 | 254 | utils.add_endpoint('RegionOne', 'nova', publicurl, adminurl, internalurl) | ||
650 | 255 | self.create_service_entry.assert_called_with('nova', 'compute', 'Nova Compute Service') | ||
651 | 256 | self.create_endpoint_template.asssert_called_with(region='RegionOne', service='nova', | ||
652 | 257 | publicurl=publicurl, adminurl=adminurl, | ||
653 | 258 | internalurl=internalurl) |
You need to mock out get_local_endpoint:
======= ======= ======= ======= ======= ======= ======= ======= ======= ======= service_ to_keystone_ clustered_ https_none_ values (unit_tests. test_keystone_ utils.TestKeyst oneUtils) ------- ------- ------- ------- ------- ------- ------- ------- ------- python2. 7/dist- packages/ mock.py" , line 1210, in patched jamespage/ src/charms/ icehouse/ keystone/ unit_tests/ test_keystone_ utils.py" , line 158, in test_add_ service_ to_keystone_ clustered_ https_none_ values add_service_ to_keystone( relation_ id=relation_ id, remote_ unit=remote_ unit) keystone_ utils.py" , line 608, in add_service_ to_keystone KeystoneManager (endpoint= get_local_ endpoint( ), keystone_ utils.py" , line 272, in get_local_endpoint api_port( api_port( 'keystone- admin') ) charmhelpers/ contrib/ hahelpers/ cluster. py", line 122, in determine_api_port charmhelpers/ contrib/ hahelpers/ cluster. py", line 59, in peer_units ids('cluster' ) or []): charmhelpers/ core/hookenv. py", line 44, in wrapper charmhelpers/ core/hookenv. py", line 213, in relation_ids subprocess. check_output( relid_cmd_ line)) or [] python2. 7/subprocess. py", line 566, in check_output python2. 7/subprocess. py", line 710, in __init__ python2. 7/subprocess. py", line 1327, in _execute_child
ERROR: test_add_
-------
Traceback (most recent call last):
File "/usr/lib/
return func(*args, **keywargs)
File "/home/
utils.
File "hooks/
manager = manager.
File "hooks/
determine_
File "hooks/
if len(peer_units()) > 0 or is_clustered():
File "hooks/
for r_id in (relation_
File "hooks/
res = func(*args, **kwargs)
File "hooks/
return json.loads(
File "/usr/lib/
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/
errread, errwrite)
File "/usr/lib/
raise child_exception
OSError: [Errno 2] No such file or directory
======= ======= ======= ======= ======= ======= ======= ======= ======= ======= service_ to_keystone_ no_clustered_ no_https_ complete_ values (unit_tests. test_keystone_ utils.TestKeyst oneUtils) ------- ------- ------- ------- ------- ------- ------- ------- ------- python2. 7/dist- packages/ mock.py" , line 1210, in patched jamespage/ src/charms/ icehouse/ keystone/ unit_tests/ test_keystone_ utils.py" , line 196, in test_add_ service_ to_keystone_ no_clustered_ no_https_ complete_ values add_service_ to_keystone( relation_ id=relation_ id, remote_ unit=remote_ unit) keystone_ utils.py" , line 608, in add_service_ to_keystone KeystoneManager (endpoint= get_local_ endpoint( ), keystone_ utils.py" , line 272, in get_local_endpoint api_port( api_port( 'keystone- admin') ) charmhelpers/ contrib/ hahelpers/ cluster. py", line 122, in determine_api_port charmhelpers/ contrib/ hahelpers/ cluster. py", line 59, in peer_units ids('cluster' ) or []): charmhelpers/ core/hookenv. py", line 44, in wrapper charmhelpers/ core/hookenv. py", line 213, in relation_ids subprocess. check_ou. ..
ERROR: test_add_
-------
Traceback (most recent call last):
File "/usr/lib/
return func(*args, **keywargs)
File "/home/
utils.
File "hooks/
manager = manager.
File "hooks/
determine_
File "hooks/
if len(peer_units()) > 0 or is_clustered():
File "hooks/
for r_id in (relation_
File "hooks/
res = func(*args, **kwargs)
File "hooks/
return json.loads(