Merge lp:~james-page/charms/precise/glance/unit-tests into lp:~charmers/charms/precise/glance/trunk

Proposed by James Page
Status: Merged
Approved by: Adam Gandelman
Approved revision: 40
Merged at revision: 38
Proposed branch: lp:~james-page/charms/precise/glance/unit-tests
Merge into: lp:~charmers/charms/precise/glance/trunk
Diff against target: 519 lines (+153/-105)
6 files modified
Makefile (+1/-0)
hooks/glance_contexts.py (+2/-3)
hooks/glance_relations.py (+11/-11)
hooks/glance_utils.py (+6/-5)
unit_tests/test_glance_relations.py (+132/-85)
unit_tests/test_utils.py (+1/-1)
To merge this branch: bzr merge lp:~james-page/charms/precise/glance/unit-tests
Reviewer Review Type Date Requested Status
charmers Pending
Review via email: mp+191915@code.launchpad.net

Description of the change

Improve unit testing coverage + a couple of minor tweaks.

To post a comment you must log in.
40. By James Page

Fixup use of assert_called()

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2013-09-26 09:47:58 +0000
3+++ Makefile 2013-10-20 18:36:29 +0000
4@@ -2,6 +2,7 @@
5
6 lint:
7 @flake8 --exclude hooks/charmhelpers hooks
8+ @flake8 unit_tests
9 @charm proof
10
11 sync:
12
13=== modified file 'hooks/glance_contexts.py'
14--- hooks/glance_contexts.py 2013-10-14 11:24:25 +0000
15+++ hooks/glance_contexts.py 2013-10-20 18:36:29 +0000
16@@ -16,6 +16,8 @@
17 )
18
19
20+# TODO: switch to charmhelpers once landed
21+# NOTE: zero units tests - done in charmhelpers
22 def is_relation_made(relation, key='private-address'):
23 for r_id in relation_ids(relation):
24 for unit in related_units(r_id):
25@@ -83,7 +85,4 @@
26 service_namespace = 'glance'
27
28 def __call__(self):
29- #from glance_utils import service_enabled
30- #if not service_enabled('glance-api'):
31- # return {}
32 return super(ApacheSSLContext, self).__call__()
33
34=== modified file 'hooks/glance_relations.py'
35--- hooks/glance_relations.py 2013-09-27 16:15:43 +0000
36+++ hooks/glance_relations.py 2013-10-20 18:36:29 +0000
37@@ -1,5 +1,4 @@
38 #!/usr/bin/python
39-import os
40 import sys
41
42 from glance_utils import (
43@@ -31,12 +30,15 @@
44 unit_get,
45 UnregisteredHookError, )
46
47-from charmhelpers.core.host import restart_on_change, service_stop
48+from charmhelpers.core.host import (
49+ restart_on_change,
50+ service_stop,
51+ mkdir, )
52
53 from charmhelpers.fetch import apt_install, apt_update
54
55 from charmhelpers.contrib.hahelpers.cluster import (
56- canonical_url, eligible_leader, is_leader)
57+ canonical_url, eligible_leader)
58
59 from charmhelpers.contrib.openstack.utils import (
60 configure_installation_source,
61@@ -48,9 +50,8 @@
62 from charmhelpers.payload.execd import execd_preinstall
63
64 from subprocess import (
65- check_call, )
66-
67-from commands import getstatusoutput
68+ check_call,
69+ call, )
70
71 hooks = Hooks()
72
73@@ -97,7 +98,7 @@
74
75 if eligible_leader(CLUSTER_RES):
76 if rel == "essex":
77- (status, output) = getstatusoutput('glance-manage db_version')
78+ status = call(['glance-manage', 'db_version'])
79 if status != 0:
80 juju_log('Setting version_control to 0')
81 check_call(["glance-manage", "version_control", "0"])
82@@ -126,7 +127,7 @@
83 def object_store_joined():
84
85 if 'identity-service' not in CONFIGS.complete_contexts():
86- juju_log('Deferring swift stora configuration until '
87+ juju_log('Deferring swift storage configuration until '
88 'an identity-service relation exists')
89 return
90
91@@ -139,8 +140,7 @@
92
93 @hooks.hook('ceph-relation-joined')
94 def ceph_joined():
95- if not os.path.isdir('/etc/ceph'):
96- os.mkdir('/etc/ceph')
97+ mkdir('/etc/ceph')
98 apt_install(['ceph-common', 'python-ceph'])
99
100
101@@ -274,7 +274,7 @@
102 if not clustered or clustered in [None, 'None', '']:
103 juju_log('ha_changed: hacluster subordinate is not fully clustered.')
104 return
105- if not is_leader(CLUSTER_RES):
106+ if not eligible_leader(CLUSTER_RES):
107 juju_log('ha_changed: hacluster complete but we are not leader.')
108 return
109
110
111=== modified file 'hooks/glance_utils.py'
112--- hooks/glance_utils.py 2013-10-14 11:24:25 +0000
113+++ hooks/glance_utils.py 2013-10-20 18:36:29 +0000
114@@ -13,9 +13,11 @@
115
116 from charmhelpers.core.hookenv import (
117 config,
118- log as juju_log,
119+ log,
120 relation_ids)
121
122+from charmhelpers.core.host import mkdir
123+
124 from charmhelpers.contrib.openstack import (
125 templating,
126 context, )
127@@ -82,7 +84,7 @@
128 }),
129 (CEPH_CONF, {
130 'hook_contexts': [context.CephContext()],
131- 'services': []
132+ 'services': ['glance-api', 'glance-registry']
133 }),
134 (HAPROXY_CONF, {
135 'hook_contexts': [context.HAProxyContext(),
136@@ -115,8 +117,7 @@
137 HAPROXY_CONF]
138
139 if relation_ids('ceph'):
140- if not os.path.isdir('/etc/ceph'):
141- os.mkdir('/etc/ceph')
142+ mkdir('/etc/ceph')
143 confs.append(CEPH_CONF)
144
145 for conf in confs:
146@@ -157,7 +158,7 @@
147 new_src = config('openstack-origin')
148 new_os_rel = get_os_codename_install_source(new_src)
149
150- juju_log('Performing OpenStack upgrade to %s.' % (new_os_rel))
151+ log('Performing OpenStack upgrade to %s.' % (new_os_rel))
152
153 configure_installation_source(new_src)
154 dpkg_opts = [
155
156=== modified file 'unit_tests/test_glance_relations.py'
157--- unit_tests/test_glance_relations.py 2013-09-27 16:15:43 +0000
158+++ unit_tests/test_glance_relations.py 2013-10-20 18:36:29 +0000
159@@ -38,7 +38,6 @@
160 'openstack_upgrade_available',
161 # charmhelpers.contrib.hahelpers.cluster_utils
162 'eligible_leader',
163- 'is_leader',
164 # glance_utils
165 'restart_map',
166 'register_configs',
167@@ -47,9 +46,11 @@
168 'ensure_ceph_keyring',
169 'ensure_ceph_pool',
170 # other
171- 'getstatusoutput',
172+ 'call',
173 'check_call',
174- 'execd_preinstall'
175+ 'execd_preinstall',
176+ 'mkdir',
177+ 'lsb_release'
178 ]
179
180
181@@ -65,15 +66,27 @@
182 relations.install_hook()
183 self.configure_installation_source.assert_called_with(repo)
184 self.assertTrue(self.apt_update.called)
185- self.apt_install.assert_called_with(['apache2', 'glance', 'python-mysqldb',
186- 'python-swift', 'python-keystone',
187+ self.apt_install.assert_called_with(['apache2', 'glance',
188+ 'python-mysqldb',
189+ 'python-swift',
190+ 'python-keystone',
191 'uuid', 'haproxy'])
192- self.execd_preinstall.assert_called()
193+ self.assertTrue(self.execd_preinstall.called)
194+
195+ def test_install_hook_precise_distro(self):
196+ self.test_config.set('openstack-origin', 'distro')
197+ self.lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'}
198+ self.service_stop.return_value = True
199+ relations.install_hook()
200+ self.configure_installation_source.assert_called_with(
201+ "cloud:precise-folsom"
202+ )
203
204 def test_db_joined(self):
205 self.unit_get.return_value = 'glance.foohost.com'
206 relations.db_joined()
207- self.relation_set.assert_called_with(database='glance', username='glance',
208+ self.relation_set.assert_called_with(database='glance',
209+ username='glance',
210 hostname='glance.foohost.com')
211 self.unit_get.assert_called_with('private-address')
212
213@@ -97,7 +110,7 @@
214 self._shared_db_test(configs)
215 self.assertEquals([call('/etc/glance/glance-registry.conf'),
216 call('/etc/glance/glance-api.conf')],
217- configs.write.call_args_list)
218+ configs.write.call_args_list)
219 self.juju_log.assert_called_with(
220 'Cluster leader, performing db sync'
221 )
222@@ -106,10 +119,10 @@
223 @patch.object(relations, 'CONFIGS')
224 def test_db_changed_with_essex_not_setting_version_control(self, configs):
225 self.get_os_codename_package.return_value = "essex"
226- self.getstatusoutput.return_value = (0, "version")
227+ self.call.return_value = 0
228 self._shared_db_test(configs)
229 self.assertEquals([call('/etc/glance/glance-registry.conf')],
230- configs.write.call_args_list)
231+ configs.write.call_args_list)
232 self.juju_log.assert_called_with(
233 'Cluster leader, performing db sync'
234 )
235@@ -118,10 +131,10 @@
236 @patch.object(relations, 'CONFIGS')
237 def test_db_changed_with_essex_setting_version_control(self, configs):
238 self.get_os_codename_package.return_value = "essex"
239- self.getstatusoutput.return_value = (1, "version")
240+ self.call.return_value = 1
241 self._shared_db_test(configs)
242 self.assertEquals([call('/etc/glance/glance-registry.conf')],
243- configs.write.call_args_list)
244+ configs.write.call_args_list)
245 self.check_call.assert_called_with(
246 ["glance-manage", "version_control", "0"]
247 )
248@@ -162,12 +175,13 @@
249 configs.write = MagicMock()
250 relations.object_store_joined()
251 self.juju_log.assert_called_with(
252- 'Deferring swift stora configuration until '
253+ 'Deferring swift storage configuration until '
254 'an identity-service relation exists'
255 )
256
257 @patch.object(relations, 'CONFIGS')
258- def test_object_store_joined_with_identity_service_without_object_store(self, configs):
259+ def test_object_store_joined_with_identity_service_without_object_store(
260+ self, configs):
261 configs.complete_contexts = MagicMock()
262 configs.complete_contexts.return_value = ['identity-service']
263 configs.write = MagicMock()
264@@ -177,20 +191,19 @@
265 )
266
267 @patch.object(relations, 'CONFIGS')
268- def test_object_store_joined_with_identity_service_with_object_store(self, configs):
269+ def test_object_store_joined_with_identity_service_with_object_store(
270+ self, configs):
271 configs.complete_contexts = MagicMock()
272- configs.complete_contexts.return_value = ['identity-service', 'object-store']
273+ configs.complete_contexts.return_value = ['identity-service',
274+ 'object-store']
275 configs.write = MagicMock()
276 relations.object_store_joined()
277 self.assertEquals([call('/etc/glance/glance-api.conf')],
278- configs.write.call_args_list)
279+ configs.write.call_args_list)
280
281- @patch('os.mkdir')
282- @patch('os.path.isdir')
283- def test_ceph_joined(self, isdir, mkdir):
284- isdir.return_value = False
285+ def test_ceph_joined(self):
286 relations.ceph_joined()
287- mkdir.assert_called_with('/etc/ceph')
288+ self.mkdir.assert_called_with('/etc/ceph')
289 self.apt_install.assert_called_with(['ceph-common', 'python-ceph'])
290
291 @patch.object(relations, 'CONFIGS')
292@@ -223,7 +236,7 @@
293 relations.ceph_changed()
294 self.assertEquals([call('/etc/glance/glance-api.conf'),
295 call('/etc/ceph/ceph.conf')],
296- configs.write.call_args_list)
297+ configs.write.call_args_list)
298 self.ensure_ceph_pool.assert_called_with(service=self.service_name(),
299 replicas=2)
300
301@@ -260,35 +273,44 @@
302 }
303 self.relation_set.assert_called_with(**ex)
304
305+ @patch.object(relations, 'CONFIGS')
306+ def test_keystone_changes_incomplete(self, configs):
307+ configs.complete_contexts.return_value = []
308+ relations.keystone_changed()
309+ self.assertTrue(self.juju_log.called)
310+ self.assertFalse(configs.write.called)
311+
312 @patch.object(relations, 'configure_https')
313 @patch.object(relations, 'CONFIGS')
314- def test_keystone_changed_no_object_store_relation(self, configs, configure_https):
315+ def test_keystone_changed_no_object_store_relation(self, configs,
316+ configure_https):
317 configs.complete_contexts = MagicMock()
318 configs.complete_contexts.return_value = ['identity-service']
319 configs.write = MagicMock()
320- self.relation_ids.return_value = False
321+ self.relation_ids.return_value = []
322 relations.keystone_changed()
323 self.assertEquals([call('/etc/glance/glance-api.conf'),
324 call('/etc/glance/glance-registry.conf'),
325 call('/etc/glance/glance-api-paste.ini'),
326 call('/etc/glance/glance-registry-paste.ini')],
327- configs.write.call_args_list)
328+ configs.write.call_args_list)
329 self.assertTrue(configure_https.called)
330
331 @patch.object(relations, 'configure_https')
332 @patch.object(relations, 'object_store_joined')
333 @patch.object(relations, 'CONFIGS')
334- def test_keystone_changed_with_object_store_relation(self, configs, object_store_joined, configure_https):
335+ def test_keystone_changed_with_object_store_relation(
336+ self, configs, object_store_joined, configure_https):
337 configs.complete_contexts = MagicMock()
338 configs.complete_contexts.return_value = ['identity-service']
339 configs.write = MagicMock()
340- self.relation_ids.return_value = True
341+ self.relation_ids.return_value = ['object-store:0']
342 relations.keystone_changed()
343 self.assertEquals([call('/etc/glance/glance-api.conf'),
344 call('/etc/glance/glance-registry.conf'),
345 call('/etc/glance/glance-api-paste.ini'),
346 call('/etc/glance/glance-registry-paste.ini')],
347- configs.write.call_args_list)
348+ configs.write.call_args_list)
349 object_store_joined.assert_called_with()
350 self.assertTrue(configure_https.called)
351
352@@ -317,7 +339,7 @@
353 relations.cluster_changed()
354 self.assertEquals([call('/etc/glance/glance-api.conf'),
355 call('/etc/haproxy/haproxy.cfg')],
356- configs.write.call_args_list)
357+ configs.write.call_args_list)
358
359 @patch.object(relations, 'cluster_changed')
360 def test_upgrade_charm(self, cluster_changed):
361@@ -337,8 +359,10 @@
362 'init_services': {'res_glance_haproxy': 'haproxy'},
363 'resources': {'res_glance_vip': 'ocf:heartbeat:IPaddr2',
364 'res_glance_haproxy': 'lsb:haproxy'},
365- 'resource_params': {'res_glance_vip': 'params ip="10.10.10.10" cidr_netmask="24" nic="em1"',
366- 'res_glance_haproxy': 'op monitor interval="5s"'},
367+ 'resource_params': {
368+ 'res_glance_vip': 'params ip="10.10.10.10"'
369+ ' cidr_netmask="24" nic="em1"',
370+ 'res_glance_haproxy': 'op monitor interval="5s"'},
371 'clones': {'cl_glance_haproxy': 'res_glance_haproxy'}
372 }
373 self.relation_set.assert_called_with(**args)
374@@ -346,56 +370,79 @@
375 def test_ha_relation_changed_not_clustered(self):
376 self.relation_get.return_value = False
377 relations.ha_relation_changed()
378-
379- self.juju_log.assert_called_with(
380- 'ha_changed: hacluster subordinate is not fully clustered.'
381- )
382-
383- @patch.object(relations, 'keystone_joined')
384- @patch.object(relations, 'CONFIGS')
385- def test_configure_https_enable_with_identity_service(self, configs, keystone_joined):
386- configs.complete_contexts = MagicMock()
387- configs.complete_contexts.return_value = ['https']
388- configs.write = MagicMock()
389- self.relation_ids.return_value = ['identity-service:0']
390- relations.configure_https()
391- cmd = ['a2ensite', 'openstack_https_frontend']
392- self.check_call.assert_called_with(cmd)
393- keystone_joined.assert_called_with(relation_id='identity-service:0')
394-
395- @patch.object(relations, 'keystone_joined')
396- @patch.object(relations, 'CONFIGS')
397- def test_configure_https_disable_with_keystone_joined(self, configs, keystone_joined):
398- configs.complete_contexts = MagicMock()
399- configs.complete_contexts.return_value = ['']
400- configs.write = MagicMock()
401- self.relation_ids.return_value = ['identity-service:0']
402- relations.configure_https()
403- cmd = ['a2dissite', 'openstack_https_frontend']
404- self.check_call.assert_called_with(cmd)
405- keystone_joined.assert_called_with(relation_id='identity-service:0')
406-
407- @patch.object(relations, 'image_service_joined')
408- @patch.object(relations, 'CONFIGS')
409- def test_configure_https_enable_with_image_service(self, configs, image_service_joined):
410- configs.complete_contexts = MagicMock()
411- configs.complete_contexts.return_value = ['https']
412- configs.write = MagicMock()
413- self.relation_ids.return_value = ['image-service:0']
414- relations.configure_https()
415- cmd = ['a2ensite', 'openstack_https_frontend']
416- self.check_call.assert_called_with(cmd)
417- image_service_joined.assert_called_with(relation_id='image-service:0')
418-
419- @patch.object(relations, 'image_service_joined')
420- @patch.object(relations, 'CONFIGS')
421- def test_configure_https_disable_with_image_service(self, configs, image_service_joined):
422- configs.complete_contexts = MagicMock()
423- configs.complete_contexts.return_value = ['']
424- configs.write = MagicMock()
425- self.relation_ids.return_value = ['image-service:0']
426- relations.configure_https()
427- cmd = ['a2dissite', 'openstack_https_frontend']
428- self.check_call.assert_called_with(cmd)
429- image_service_joined.assert_called_with(relation_id='image-service:0')
430-
431+ self.assertTrue(self.juju_log.called)
432+
433+ @patch.object(relations, 'keystone_joined')
434+ def test_ha_relation_changed_not_leader(self, joined):
435+ self.relation_get.return_value = True
436+ self.eligible_leader.return_value = False
437+ relations.ha_relation_changed()
438+ self.assertTrue(self.juju_log.called)
439+ self.assertFalse(joined.called)
440+
441+ @patch.object(relations, 'image_service_joined')
442+ @patch.object(relations, 'keystone_joined')
443+ def test_ha_relation_changed_leader(self, ks_joined, image_joined):
444+ self.relation_get.return_value = True
445+ self.eligible_leader.return_value = True
446+ self.relation_ids.side_effect = [['identity:0'], ['image:1']]
447+ relations.ha_relation_changed()
448+ ks_joined.assert_called_with('identity:0')
449+ image_joined.assert_called_with('image:1')
450+
451+ @patch.object(relations, 'keystone_joined')
452+ @patch.object(relations, 'CONFIGS')
453+ def test_configure_https_enable_with_identity_service(
454+ self, configs, keystone_joined):
455+ configs.complete_contexts = MagicMock()
456+ configs.complete_contexts.return_value = ['https']
457+ configs.write = MagicMock()
458+ self.relation_ids.return_value = ['identity-service:0']
459+ relations.configure_https()
460+ cmd = ['a2ensite', 'openstack_https_frontend']
461+ self.check_call.assert_called_with(cmd)
462+ keystone_joined.assert_called_with(relation_id='identity-service:0')
463+
464+ @patch.object(relations, 'keystone_joined')
465+ @patch.object(relations, 'CONFIGS')
466+ def test_configure_https_disable_with_keystone_joined(
467+ self, configs, keystone_joined):
468+ configs.complete_contexts = MagicMock()
469+ configs.complete_contexts.return_value = ['']
470+ configs.write = MagicMock()
471+ self.relation_ids.return_value = ['identity-service:0']
472+ relations.configure_https()
473+ cmd = ['a2dissite', 'openstack_https_frontend']
474+ self.check_call.assert_called_with(cmd)
475+ keystone_joined.assert_called_with(relation_id='identity-service:0')
476+
477+ @patch.object(relations, 'image_service_joined')
478+ @patch.object(relations, 'CONFIGS')
479+ def test_configure_https_enable_with_image_service(
480+ self, configs, image_service_joined):
481+ configs.complete_contexts = MagicMock()
482+ configs.complete_contexts.return_value = ['https']
483+ configs.write = MagicMock()
484+ self.relation_ids.return_value = ['image-service:0']
485+ relations.configure_https()
486+ cmd = ['a2ensite', 'openstack_https_frontend']
487+ self.check_call.assert_called_with(cmd)
488+ image_service_joined.assert_called_with(relation_id='image-service:0')
489+
490+ @patch.object(relations, 'image_service_joined')
491+ @patch.object(relations, 'CONFIGS')
492+ def test_configure_https_disable_with_image_service(
493+ self, configs, image_service_joined):
494+ configs.complete_contexts = MagicMock()
495+ configs.complete_contexts.return_value = ['']
496+ configs.write = MagicMock()
497+ self.relation_ids.return_value = ['image-service:0']
498+ relations.configure_https()
499+ cmd = ['a2dissite', 'openstack_https_frontend']
500+ self.check_call.assert_called_with(cmd)
501+ image_service_joined.assert_called_with(relation_id='image-service:0')
502+
503+ @patch.object(relations, 'CONFIGS')
504+ def test_relation_broken(self, configs):
505+ relations.relation_broken()
506+ self.assertTrue(configs.write_all.called)
507
508=== modified file 'unit_tests/test_utils.py'
509--- unit_tests/test_utils.py 2013-08-09 18:45:02 +0000
510+++ unit_tests/test_utils.py 2013-10-20 18:36:29 +0000
511@@ -93,7 +93,7 @@
512 self.relation_data = relation_data
513
514 def get(self, attr=None, unit=None, rid=None):
515- if attr == None:
516+ if attr is None:
517 return self.relation_data
518 elif attr in self.relation_data:
519 return self.relation_data[attr]

Subscribers

People subscribed via source and target branches

to all changes: