Merge lp:~yolanda.robla/charms/precise/keystone/unit_testing into lp:~openstack-charmers/charms/precise/keystone/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
Reviewer Review Type Date Requested Status
James Page Needs Fixing
Review via email: mp+214009@code.launchpad.net

Description of the change

Added unit testing

To post a comment you must log in.
Revision history for this message
James Page (james-page) wrote :
Download full text (6.9 KiB)

You need to mock out get_local_endpoint:

======================================================================
ERROR: test_add_service_to_keystone_clustered_https_none_values (unit_tests.test_keystone_utils.TestKeystoneUtils)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/mock.py", line 1210, in patched
    return func(*args, **keywargs)
  File "/home/jamespage/src/charms/icehouse/keystone/unit_tests/test_keystone_utils.py", line 158, in test_add_service_to_keystone_clustered_https_none_values
    utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit)
  File "hooks/keystone_utils.py", line 608, in add_service_to_keystone
    manager = manager.KeystoneManager(endpoint=get_local_endpoint(),
  File "hooks/keystone_utils.py", line 272, in get_local_endpoint
    determine_api_port(api_port('keystone-admin'))
  File "hooks/charmhelpers/contrib/hahelpers/cluster.py", line 122, in determine_api_port
    if len(peer_units()) > 0 or is_clustered():
  File "hooks/charmhelpers/contrib/hahelpers/cluster.py", line 59, in peer_units
    for r_id in (relation_ids('cluster') or []):
  File "hooks/charmhelpers/core/hookenv.py", line 44, in wrapper
    res = func(*args, **kwargs)
  File "hooks/charmhelpers/core/hookenv.py", line 213, in relation_ids
    return json.loads(subprocess.check_output(relid_cmd_line)) or []
  File "/usr/lib/python2.7/subprocess.py", line 566, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

======================================================================
ERROR: test_add_service_to_keystone_no_clustered_no_https_complete_values (unit_tests.test_keystone_utils.TestKeystoneUtils)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/mock.py", line 1210, in patched
    return func(*args, **keywargs)
  File "/home/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
    utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit)
  File "hooks/keystone_utils.py", line 608, in add_service_to_keystone
    manager = manager.KeystoneManager(endpoint=get_local_endpoint(),
  File "hooks/keystone_utils.py", line 272, in get_local_endpoint
    determine_api_port(api_port('keystone-admin'))
  File "hooks/charmhelpers/contrib/hahelpers/cluster.py", line 122, in determine_api_port
    if len(peer_units()) > 0 or is_clustered():
  File "hooks/charmhelpers/contrib/hahelpers/cluster.py", line 59, in peer_units
    for r_id in (relation_ids('cluster') or []):
  File "hooks/charmhelpers/core/hookenv.py", line 44, in wrapper
    res = func(*args, **kwargs)
  File "hooks/charmhelpers/core/hookenv.py", line 213, in relation_ids
    return json.loads(subprocess.check_ou...

Read more...

review: Needs Fixing
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.assertTrue(self.<function>.called).

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
=== added file 'unit_tests/test_keystone_contexts.py'
--- unit_tests/test_keystone_contexts.py 1970-01-01 00:00:00 +0000
+++ unit_tests/test_keystone_contexts.py 2014-04-04 12:26:02 +0000
@@ -0,0 +1,70 @@
1import keystone_context as context
2from mock import patch
3
4with patch('charmhelpers.core.hookenv.config') as config:
5 config.return_value = 'keystone'
6 import keystone_utils as utils
7
8from test_utils import (
9 CharmTestCase
10)
11
12TO_PATCH = [
13 'determine_apache_port',
14 'determine_api_port',
15]
16
17
18class TestKeystoneContexts(CharmTestCase):
19
20 def setUp(self):
21 super(TestKeystoneContexts, self).setUp(context, TO_PATCH)
22
23 @patch('charmhelpers.contrib.openstack.context.is_clustered')
24 @patch('charmhelpers.contrib.openstack.context.determine_apache_port')
25 @patch('charmhelpers.contrib.openstack.context.determine_api_port')
26 @patch('charmhelpers.contrib.openstack.context.unit_get')
27 @patch('charmhelpers.contrib.openstack.context.https')
28 def test_apache_ssl_context_service_enabled(self, mock_https,
29 mock_unit_get,
30 mock_determine_api_port,
31 mock_determine_apache_port,
32 mock_is_clustered):
33 mock_https.return_value = True
34 mock_unit_get.return_value = '1.2.3.4'
35 mock_determine_api_port.return_value = '12'
36 mock_determine_apache_port.return_value = '34'
37 mock_is_clustered.return_value = False
38
39 ctxt = context.ApacheSSLContext()
40 with patch.object(ctxt, 'enable_modules') as mock_enable_modules:
41 with patch.object(ctxt, 'configure_cert') as mock_configure_cert:
42 self.assertEquals(ctxt(), {'endpoints': [(34, 12)],
43 'private_address': '1.2.3.4',
44 'namespace': 'keystone'})
45 self.assertTrue(mock_https.called)
46 mock_unit_get.assert_called_with('private-address')
47
48 @patch('charmhelpers.contrib.openstack.context.relation_ids')
49 @patch('charmhelpers.contrib.openstack.context.unit_get')
50 @patch('charmhelpers.contrib.openstack.context.related_units')
51 @patch('charmhelpers.contrib.openstack.context.relation_get')
52 @patch('charmhelpers.contrib.openstack.context.log')
53 @patch('__builtin__.open')
54 def test_haproxy_context_service_enabled(self, mock_open, mock_log, mock_relation_get, mock_related_units,
55 mock_unit_get, mock_relation_ids):
56 mock_relation_ids.return_value = ['identity-service:0',]
57 mock_unit_get.return_value = '1.2.3.4'
58 mock_relation_get.return_value = '10.0.0.0'
59 mock_related_units.return_value = ['unit/0',]
60 self.determine_apache_port.return_value = '34'
61
62 ctxt = context.HAProxyContext()
63
64 self.assertEquals(ctxt(), {'listen_ports': {'admin_port': 'keystone', 'public_port': 'keystone'},
65 'service_ports': {'admin-port': ['keystone', '34'],
66 'public-port': ['keystone', '34']},
67 'units': {'keystone': '1.2.3.4', 'unit-0':'10.0.0.0'}})
68 mock_unit_get.assert_called_with('private-address')
69 mock_relation_get.assert_called_with('private-address', rid='identity-service:0', unit='unit/0')
70 mock_open.assert_called_with('/etc/default/haproxy', 'w')
071
=== modified file 'unit_tests/test_keystone_hooks.py'
--- unit_tests/test_keystone_hooks.py 2014-03-31 08:35:19 +0000
+++ unit_tests/test_keystone_hooks.py 2014-04-04 12:26:02 +0000
@@ -15,6 +15,7 @@
15utils.restart_map = MagicMock()15utils.restart_map = MagicMock()
1616
17import keystone_hooks as hooks17import keystone_hooks as hooks
18from charmhelpers.contrib import unison
1819
19utils.register_configs = _reg20utils.register_configs = _reg
20utils.restart_map = _map21utils.restart_map = _map
@@ -25,10 +26,14 @@
25 'config',26 'config',
26 'is_relation_made',27 'is_relation_made',
27 'log',28 'log',
29 'filter_installed_packages',
28 'relation_ids',30 'relation_ids',
31 'relation_list',
29 'relation_set',32 'relation_set',
30 'relation_get',33 'relation_get',
34 'related_units',
31 'unit_get',35 'unit_get',
36 'peer_echo',
32 # charmhelpers.core.host37 # charmhelpers.core.host
33 'apt_install',38 'apt_install',
34 'apt_update',39 'apt_update',
@@ -41,11 +46,20 @@
41 'restart_map',46 'restart_map',
42 'register_configs',47 'register_configs',
43 'do_openstack_upgrade',48 'do_openstack_upgrade',
49 'openstack_upgrade_available',
50 'save_script_rc',
44 'migrate_database',51 'migrate_database',
52 'ensure_initial_admin',
53 'add_service_to_keystone',
54 'synchronize_ca',
55 'get_hacluster_config',
56 'is_leader',
45 # other57 # other
46 'check_call',58 'check_call',
47 'execd_preinstall',59 'execd_preinstall',
48 'mkdir'60 'mkdir',
61 'os',
62 'time',
49]63]
5064
5165
@@ -54,7 +68,18 @@
54 def setUp(self):68 def setUp(self):
55 super(KeystoneRelationTests, self).setUp(hooks, TO_PATCH)69 super(KeystoneRelationTests, self).setUp(hooks, TO_PATCH)
56 self.config.side_effect = self.test_config.get70 self.config.side_effect = self.test_config.get
71 self.ssh_user = 'juju_keystone'
5772
73 def test_install_hook(self):
74 repo = 'cloud:precise-grizzly'
75 self.test_config.set('openstack-origin', repo)
76 hooks.install()
77 self.configure_installation_source.assert_called_with(repo)
78 self.assertTrue(self.apt_update.called)
79 self.apt_install.assert_called_with(['haproxy', 'unison', 'python-keystoneclient',
80 'uuid', 'python-mysqldb', 'openssl', 'apache2',
81 'pwgen', 'keystone', 'python-psycopg2'], fatal=True)
82 self.assertTrue(self.execd_preinstall.called)
5883
59 def test_db_joined(self):84 def test_db_joined(self):
60 self.unit_get.return_value = 'keystone.foohost.com'85 self.unit_get.return_value = 'keystone.foohost.com'
@@ -76,18 +101,20 @@
76101
77 with self.assertRaises(Exception) as context:102 with self.assertRaises(Exception) as context:
78 hooks.db_joined()103 hooks.db_joined()
79 self.assertEqual(context.exception.message,104 self.assertEqual(
105 context.exception.message,
80 'Attempting to associate a mysql database when there '106 'Attempting to associate a mysql database when there '
81 'is already associated a postgresql one') 107 'is already associated a postgresql one')
82108
83 def test_postgresql_joined_with_db(self):109 def test_postgresql_joined_with_db(self):
84 self.is_relation_made.return_value = True110 self.is_relation_made.return_value = True
85111
86 with self.assertRaises(Exception) as context:112 with self.assertRaises(Exception) as context:
87 hooks.pgsql_db_joined()113 hooks.pgsql_db_joined()
88 self.assertEqual(context.exception.message,114 self.assertEqual(
115 context.exception.message,
89 'Attempting to associate a postgresql database when there '116 'Attempting to associate a postgresql database when there '
90 'is already associated a mysql one') 117 'is already associated a mysql one')
91118
92 @patch.object(hooks, 'CONFIGS')119 @patch.object(hooks, 'CONFIGS')
93 def test_db_changed_missing_relation_data(self, configs):120 def test_db_changed_missing_relation_data(self, configs):
@@ -118,3 +145,222 @@
118 configs.complete_contexts.return_value = ['pgsql-db']145 configs.complete_contexts.return_value = ['pgsql-db']
119 configs.write = MagicMock()146 configs.write = MagicMock()
120 hooks.pgsql_db_changed()147 hooks.pgsql_db_changed()
148
149 @patch.object(hooks, 'CONFIGS')
150 @patch.object(hooks, 'identity_changed')
151 def test_db_changed(self, identity_changed, configs):
152 self.relation_ids.return_value = ['identity-service:0']
153 self.related_units.return_value = ['unit/0']
154
155 self._shared_db_test(configs)
156 self.assertEquals([call('/etc/keystone/keystone.conf')],
157 configs.write.call_args_list)
158 self.migrate_database.assert_called_with()
159 self.assertTrue(self.ensure_initial_admin.called)
160 identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0')
161
162 @patch.object(hooks, 'CONFIGS')
163 @patch.object(hooks, 'identity_changed')
164 def test_postgresql_db_changed(self, identity_changed, configs):
165 self.relation_ids.return_value = ['identity-service:0']
166 self.related_units.return_value = ['unit/0']
167
168 self._postgresql_db_test(configs)
169 self.assertEquals([call('/etc/keystone/keystone.conf')],
170 configs.write.call_args_list)
171 self.migrate_database.assert_called_with()
172 self.assertTrue(self.ensure_initial_admin.called)
173 identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0')
174
175 @patch.object(unison, 'ensure_user')
176 @patch.object(unison, 'get_homedir')
177 @patch.object(hooks, 'CONFIGS')
178 @patch.object(hooks, 'identity_changed')
179 @patch.object(hooks, 'configure_https')
180 def test_config_changed_no_openstack_upgrade_leader(self, configure_https, identity_changed, configs, get_homedir, ensure_user):
181 self.openstack_upgrade_available.return_value = False
182 self.eligible_leader.return_value = True
183 self.relation_ids.return_value = ['identity-service:0']
184 self.relation_list.return_value = ['unit/0']
185
186 hooks.config_changed()
187 ensure_user.assert_called_with(user=self.ssh_user, group='keystone')
188 get_homedir.assert_called_with(self.ssh_user)
189
190 self.save_script_rc.assert_called_with()
191 configure_https.assert_called_with()
192 self.assertTrue(configs.write_all.called)
193
194 self.migrate_database.assert_called_with()
195 self.assertTrue(self.ensure_initial_admin.called)
196 self.log.assert_called_with('Firing identity_changed hook for all related services.')
197 identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0')
198
199 @patch.object(unison, 'ensure_user')
200 @patch.object(unison, 'get_homedir')
201 @patch.object(hooks, 'CONFIGS')
202 @patch.object(hooks, 'identity_changed')
203 @patch.object(hooks, 'configure_https')
204 def test_config_changed_no_openstack_upgrade_not_leader(self, configure_https, identity_changed, configs, get_homedir, ensure_user):
205 self.openstack_upgrade_available.return_value = False
206 self.eligible_leader.return_value = False
207
208 hooks.config_changed()
209 ensure_user.assert_called_with(user=self.ssh_user, group='keystone')
210 get_homedir.assert_called_with(self.ssh_user)
211
212 self.save_script_rc.assert_called_with()
213 configure_https.assert_called_with()
214 self.assertTrue(configs.write_all.called)
215
216 self.assertFalse(self.migrate_database.called)
217 self.assertFalse(self.ensure_initial_admin.called)
218 self.assertFalse(identity_changed.called)
219
220 @patch.object(unison, 'ensure_user')
221 @patch.object(unison, 'get_homedir')
222 @patch.object(hooks, 'CONFIGS')
223 @patch.object(hooks, 'identity_changed')
224 @patch.object(hooks, 'configure_https')
225 def test_config_changed_with_openstack_upgrade(self, configure_https, identity_changed, configs, get_homedir, ensure_user):
226 self.openstack_upgrade_available.return_value = True
227 self.eligible_leader.return_value = True
228 self.relation_ids.return_value = ['identity-service:0']
229 self.relation_list.return_value = ['unit/0']
230
231 hooks.config_changed()
232 ensure_user.assert_called_with(user=self.ssh_user, group='keystone')
233 get_homedir.assert_called_with(self.ssh_user)
234
235 self.assertTrue(self.do_openstack_upgrade.called)
236
237 self.save_script_rc.assert_called_with()
238 configure_https.assert_called_with()
239 self.assertTrue(configs.write_all.called)
240
241 self.migrate_database.assert_called_with()
242 self.assertTrue(self.ensure_initial_admin.called)
243 self.log.assert_called_with('Firing identity_changed hook for all related services.')
244 identity_changed.assert_called_with(relation_id='identity-service:0', remote_unit='unit/0')
245
246 def test_identity_changed_leader(self):
247 self.eligible_leader.return_value = True
248 hooks.identity_changed(relation_id='identity-service:0', remote_unit='unit/0')
249 self.add_service_to_keystone.assert_called_with('identity-service:0', 'unit/0')
250 self.assertTrue(self.synchronize_ca.called)
251
252 def test_identity_changed_no_leader(self):
253 self.eligible_leader.return_value = False
254 hooks.identity_changed(relation_id='identity-service:0', remote_unit='unit/0')
255 self.assertFalse(self.add_service_to_keystone.called)
256 self.log.assert_called_with('Deferring identity_changed() to service leader.')
257
258 @patch.object(unison, 'ssh_authorized_peers')
259 def test_cluster_joined(self, ssh_authorized_peers):
260 hooks.cluster_joined()
261 ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='juju_keystone',
262 peer_interface='cluster', ensure_local_user=True)
263
264 @patch.object(unison, 'ssh_authorized_peers')
265 @patch.object(hooks, 'CONFIGS')
266 def test_cluster_changed(self, configs, ssh_authorized_peers):
267 hooks.cluster_changed()
268 self.peer_echo.assert_called_with(includes=['_passwd'])
269 ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='keystone',
270 peer_interface='cluster', ensure_local_user=True)
271 self.assertTrue(self.synchronize_ca.called)
272 self.assertTrue(configs.write_all.called)
273
274 def test_ha_joined(self):
275 self.get_hacluster_config.return_value = {
276 'ha-bindiface': 'em0',
277 'ha-mcastport': '8080',
278 'vip': '10.10.10.10',
279 'vip_iface': 'em1',
280 'vip_cidr': '24'
281 }
282 hooks.ha_joined()
283 self.assertTrue(self.get_hacluster_config.called)
284 args = {
285 'corosync_bindiface': 'em0',
286 'corosync_mcastport': '8080',
287 'init_services': {'res_ks_haproxy': 'haproxy'},
288 'resources': {'res_ks_vip': 'ocf:heartbeat:IPaddr2',
289 'res_ks_haproxy': 'lsb:haproxy'},
290 'resource_params': {
291 'res_ks_vip': 'params ip="10.10.10.10"'
292 ' cidr_netmask="24" nic="em1"',
293 'res_ks_haproxy': 'op monitor interval="5s"'},
294 'clones': {'cl_ks_haproxy': 'res_ks_haproxy'}
295 }
296 self.relation_set.assert_called_with(**args)
297
298 @patch.object(hooks, 'CONFIGS')
299 def test_ha_relation_changed_not_clustered_not_leader(self, configs):
300 self.relation_get.return_value = False
301 self.is_leader.return_value = False
302
303 hooks.ha_changed()
304 self.assertTrue(configs.write_all.called)
305
306 @patch.object(hooks, 'CONFIGS')
307 def test_ha_relation_changed_clustered_leader(self, configs):
308 self.relation_get.return_value = True
309 self.is_leader.return_value = True
310 self.relation_ids.return_value = ['identity-service:0']
311 self.test_config.set('vip', '10.10.10.10')
312
313 hooks.ha_changed()
314 self.assertTrue(configs.write_all.called)
315 self.log.assert_called_with('Cluster configured, notifying other services and updating '
316 'keystone endpoint configuration')
317 self.relation_set.assert_called_with(relation_id='identity-service:0',
318 auth_host='10.10.10.10',
319 service_host='10.10.10.10')
320
321 @patch.object(hooks, 'CONFIGS')
322 def test_configure_https_enable(self, configs):
323 configs.complete_contexts = MagicMock()
324 configs.complete_contexts.return_value = ['https']
325 configs.write = MagicMock()
326
327 hooks.configure_https()
328 self.assertTrue(configs.write_all.called)
329 cmd = ['a2ensite', 'openstack_https_frontend']
330 self.check_call.assert_called_with(cmd)
331
332 @patch.object(hooks, 'CONFIGS')
333 def test_configure_https_disable(self, configs):
334 configs.complete_contexts = MagicMock()
335 configs.complete_contexts.return_value = ['']
336 configs.write = MagicMock()
337
338 hooks.configure_https()
339 self.assertTrue(configs.write_all.called)
340 cmd = ['a2dissite', 'openstack_https_frontend']
341 self.check_call.assert_called_with(cmd)
342
343 @patch.object(unison, 'ssh_authorized_peers')
344 def test_upgrade_charm_leader(self, ssh_authorized_peers):
345 self.eligible_leader.return_value = True
346 self.filter_installed_packages.return_value = []
347 hooks.upgrade_charm()
348 self.assertTrue(self.apt_install.called)
349 ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='keystone',
350 peer_interface='cluster', ensure_local_user=True)
351 self.assertTrue(self.synchronize_ca.called)
352 self.log.assert_called_with('Cluster leader - ensuring endpoint configuration'
353 ' is up to date')
354 self.assertTrue(self.ensure_initial_admin.called)
355
356 @patch.object(unison, 'ssh_authorized_peers')
357 def test_upgrade_charm_not_leader(self, ssh_authorized_peers):
358 self.eligible_leader.return_value = False
359 self.filter_installed_packages.return_value = []
360 hooks.upgrade_charm()
361 self.assertTrue(self.apt_install.called)
362 ssh_authorized_peers.assert_called_with(user=self.ssh_user, group='keystone',
363 peer_interface='cluster', ensure_local_user=True)
364 self.assertTrue(self.synchronize_ca.called)
365 self.assertFalse(self.log.called)
366 self.assertFalse(self.ensure_initial_admin.called)
121367
=== added file 'unit_tests/test_keystone_utils.py'
--- unit_tests/test_keystone_utils.py 1970-01-01 00:00:00 +0000
+++ unit_tests/test_keystone_utils.py 2014-04-04 12:26:02 +0000
@@ -0,0 +1,258 @@
1from mock import patch, call, MagicMock
2from test_utils import CharmTestCase
3from copy import deepcopy
4
5from collections import OrderedDict
6import os
7import manager
8
9os.environ['JUJU_UNIT_NAME'] = 'keystone'
10with patch('charmhelpers.core.hookenv.config') as config:
11 import keystone_utils as utils
12
13import keystone_context
14import keystone_hooks as hooks
15from charmhelpers.contrib.openstack import context
16
17TO_PATCH = [
18 'api_port',
19 'config',
20 'create_user',
21 'os_release',
22 'log',
23 'get_ca',
24 'create_role',
25 'create_service_entry',
26 'create_endpoint_template',
27 'get_admin_token',
28 'get_local_endpoint',
29 'get_requested_roles',
30 'get_service_password',
31 'get_os_codename_install_source',
32 'grant_role',
33 'configure_installation_source',
34 'eligible_leader',
35 'https',
36 'is_clustered',
37 'service_stop',
38 'service_start',
39 'relation_get',
40 'relation_set',
41 'https',
42 'unit_private_ip',
43 # generic
44 'apt_update',
45 'apt_upgrade',
46 'apt_install',
47 'subprocess',
48 'time',
49 'pwgen',
50]
51
52class TestKeystoneUtils(CharmTestCase):
53
54 def setUp(self):
55 super(TestKeystoneUtils, self).setUp(utils, TO_PATCH)
56 self.config.side_effect = self.test_config.get
57
58 self.ctxt = MagicMock()
59 self.rsc_map = {
60 '/etc/keystone/keystone.conf': {
61 'services': ['keystone'],
62 'contexts': [self.ctxt],
63 },
64 '/etc/apache2/sites-available/openstack_https_frontend': {
65 'services': ['apache2'],
66 'contexts': [self.ctxt],
67 },
68 '/etc/apache2/sites-available/openstack_https_frontend.conf': {
69 'services': ['apache2'],
70 'contexts': [self.ctxt],
71 }
72 }
73
74 @patch('charmhelpers.contrib.openstack.templating.OSConfigRenderer')
75 @patch('os.path.exists')
76 @patch.object(utils, 'resource_map')
77 def test_register_configs_apache(self, resource_map, exists, renderer):
78 exists.return_value = False
79 self.os_release.return_value = 'havana'
80 fake_renderer = MagicMock()
81 fake_renderer.register = MagicMock()
82 renderer.return_value = fake_renderer
83
84 resource_map.return_value = self.rsc_map
85 utils.register_configs()
86 renderer.assert_called_with(
87 openstack_release='havana', templates_dir='templates/')
88
89 ex_reg = [
90 call('/etc/keystone/keystone.conf', [self.ctxt]),
91 call('/etc/apache2/sites-available/openstack_https_frontend', [self.ctxt]),
92 call('/etc/apache2/sites-available/openstack_https_frontend.conf', [self.ctxt]),
93 ]
94 self.assertEquals(fake_renderer.register.call_args_list, ex_reg)
95
96 def test_determine_ports(self):
97 self.test_config.set('admin-port','80')
98 self.test_config.set('service-port','81')
99 result = utils.determine_ports()
100 self.assertEquals(result, ['80', '81'])
101
102 def test_determine_packages(self):
103 result = utils.determine_packages()
104 ex = utils.BASE_PACKAGES + ['keystone', 'haproxy', 'apache2']
105 self.assertEquals(set(ex), set(result))
106
107 @patch.object(hooks, 'CONFIGS')
108 @patch.object(utils, 'determine_packages')
109 @patch.object(utils, 'migrate_database')
110 def test_openstack_upgrade_leader(self, migrate_database, determine_packages, configs):
111 self.test_config.set('openstack-origin', 'precise')
112 determine_packages.return_value = []
113 self.eligible_leader.return_value = True
114
115 utils.do_openstack_upgrade(configs)
116
117 self.get_os_codename_install_source.assert_called_with('precise')
118 self.configure_installation_source.assert_called_with('precise')
119 self.assertTrue(self.apt_update.called)
120
121 dpkg_opts = [
122 '--option', 'Dpkg::Options::=--force-confnew',
123 '--option', 'Dpkg::Options::=--force-confdef',
124 ]
125 self.apt_upgrade.assert_called_with(options=dpkg_opts, fatal=True, dist=True)
126 self.apt_install.assert_called_with(packages=[], options=dpkg_opts, fatal=True)
127
128 self.assertTrue(configs.set_release.called)
129 self.assertTrue(configs.write_all.called)
130 self.assertTrue(migrate_database.called)
131
132 def test_migrate_database(self):
133 utils.migrate_database()
134
135 self.service_stop.assert_called_with('keystone')
136 cmd = ['sudo', '-u', 'keystone', 'keystone-manage', 'db_sync']
137 self.subprocess.check_output.assert_called_with(cmd)
138 self.service_start.assert_called_wkth('keystone')
139
140 @patch.object(utils, 'b64encode')
141 def test_add_service_to_keystone_clustered_https_none_values(self, b64encode):
142 relation_id = 'identity-service:0'
143 remote_unit = 'unit/0'
144 self.is_clustered.return_value = True
145 self.https.return_value = True
146 self.test_config.set('https-service-endpoints', 'True')
147 self.test_config.set('vip', '10.10.10.10')
148 self.test_config.set('admin-port', 80)
149 self.test_config.set('service-port', 81)
150 b64encode.return_value = 'certificate'
151 self.get_requested_roles.return_value = ['role1',]
152
153 self.relation_get.return_value = {'service': 'keystone',
154 'region': 'RegionOne',
155 'public_url': 'None',
156 'admin_url': '10.0.0.2',
157 'internal_url': '192.168.1.2'}
158
159 utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit)
160 self.assertTrue(self.is_clustered.called)
161 self.assertTrue(self.https.called)
162 self.assertTrue(self.create_role.called)
163
164 relation_data = {'auth_host': '10.10.10.10',
165 'service_host': '10.10.10.10',
166 'auth_protocol': 'https',
167 'service_protocol': 'https',
168 'auth_port': 80,
169 'service_port': 81,
170 'https_keystone': 'True',
171 'ca_cert': 'certificate'}
172 self.relation_set.assert_called_with(relation_id=relation_id, **relation_data)
173
174 @patch.object(utils, 'ensure_valid_service')
175 @patch.object(utils, 'add_endpoint')
176 @patch.object(manager, 'KeystoneManager')
177 def test_add_service_to_keystone_no_clustered_no_https_complete_values(self, KeystoneManager, add_endpoint, ensure_valid_service):
178 relation_id = 'identity-service:0'
179 remote_unit = 'unit/0'
180 self.get_admin_token.return_value = 'token'
181 self.get_service_password.return_value = 'password'
182 self.test_config.set('service-tenant', 'tenant')
183 self.test_config.set('admin-role', 'admin')
184 self.get_requested_roles.return_value = ['role1',]
185 self.unit_private_ip.return_value = '10.0.0.3'
186 self.test_config.set('admin-port', 80)
187 self.test_config.set('service-port', 81)
188 self.is_clustered.return_value = False
189 self.https.return_value = False
190 self.test_config.set('https-service-endpoints', 'False')
191 self.get_local_endpoint.return_value = 'http://localhost:80/v2.0/'
192
193 mock_keystone = MagicMock()
194 mock_keystone.resolve_tenant_id.return_value = 'tenant_id'
195 KeystoneManager.return_value = mock_keystone
196
197 self.relation_get.return_value = {'service': 'keystone',
198 'region': 'RegionOne',
199 'public_url': '10.0.0.1',
200 'admin_url': '10.0.0.2',
201 'internal_url': '192.168.1.2'}
202
203 utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit)
204 ensure_valid_service.assert_called_with('keystone')
205 add_endpoint.assert_called_with(region='RegionOne', service='keystone',
206 publicurl='10.0.0.1', adminurl='10.0.0.2',
207 internalurl='192.168.1.2')
208 self.assertTrue(self.get_admin_token.called)
209 self.get_service_password.assert_called_with('keystone')
210 self.create_user.assert_called_with('keystone', 'password', 'tenant')
211 self.grant_role.assert_called_with('keystone', 'admin', 'tenant')
212 self.create_role.assert_called_with('role1', 'keystone', 'tenant')
213
214 self.assertTrue(self.is_clustered.called)
215 relation_data = {'admin_token': 'token', 'service_port':81,
216 'auth_port':80, 'service_username':'keystone',
217 'service_password': 'password', 'service_tenant': 'tenant',
218 'https_keystone': 'False', 'ssl_cert': '', 'ssl_key': '',
219 'ca_cert': '', 'auth_host':'10.0.0.3', 'service_host': '10.0.0.3',
220 'auth_protocol': 'http', 'service_protocol': 'http',
221 'service_tenant_id': 'tenant_id'}
222 self.relation_set.assert_called_with(relation_id=relation_id, **relation_data)
223
224 @patch.object(utils, 'ensure_valid_service')
225 @patch.object(utils, 'add_endpoint')
226 @patch.object(manager, 'KeystoneManager')
227 def test_add_service_to_keystone_nosubset(self, KeystoneManager, add_endpoint, ensure_valid_service):
228 relation_id = 'identity-service:0'
229 remote_unit = 'unit/0'
230
231 self.relation_get.return_value = {'ec2_service': 'nova',
232 'ec2_region': 'RegionOne',
233 'ec2_public_url': '10.0.0.1',
234 'ec2_admin_url': '10.0.0.2',
235 'ec2_internal_url': '192.168.1.2'}
236 self.get_local_endpoint.return_value = 'http://localhost:80/v2.0/'
237 KeystoneManager.resolve_tenant_id.return_value = 'tenant_id'
238
239 utils.add_service_to_keystone(relation_id=relation_id, remote_unit=remote_unit)
240 ensure_valid_service.assert_called_with('nova')
241 add_endpoint.assert_called_with(region='RegionOne', service='nova',
242 publicurl='10.0.0.1', adminurl='10.0.0.2',
243 internalurl='192.168.1.2')
244
245 def test_ensure_valid_service_incorrect(self):
246 utils.ensure_valid_service('fakeservice')
247 self.log.assert_called_with("Invalid service requested: 'fakeservice'")
248 self.relation_set.assert_called_with(admin_token=-1)
249
250 def test_add_endpoint(self):
251 publicurl = '10.0.0.1'
252 adminurl = '10.0.0.2'
253 internalurl = '10.0.0.3'
254 utils.add_endpoint('RegionOne', 'nova', publicurl, adminurl, internalurl)
255 self.create_service_entry.assert_called_with('nova', 'compute', 'Nova Compute Service')
256 self.create_endpoint_template.asssert_called_with(region='RegionOne', service='nova',
257 publicurl=publicurl, adminurl=adminurl,
258 internalurl=internalurl)

Subscribers

People subscribed via source and target branches