Merge lp:~ack/charms/trusty/glance/pause-and-resume into lp:~openstack-charmers-archive/charms/trusty/glance/next
- Trusty Tahr (14.04)
- pause-and-resume
- Merge into next
Status: | Merged |
---|---|
Merged at revision: | 136 |
Proposed branch: | lp:~ack/charms/trusty/glance/pause-and-resume |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/glance/next |
Diff against target: |
834 lines (+356/-124) 15 files modified
.coveragerc (+1/-0) actions.yaml (+11/-0) actions/actions.py (+56/-0) actions/git_reinstall.py (+3/-5) actions/openstack_upgrade.py (+3/-4) charm-helpers-hooks.yaml (+1/-1) hooks/glance_utils.py (+7/-11) tests/basic_deployment.py (+35/-0) unit_tests/__init__.py (+0/-4) unit_tests/test_actions.py (+157/-0) unit_tests/test_actions_git_reinstall.py (+12/-16) unit_tests/test_actions_openstack_upgrade.py (+16/-16) unit_tests/test_glance_contexts.py (+22/-30) unit_tests/test_glance_relations.py (+23/-30) unit_tests/test_glance_utils.py (+9/-7) |
To merge this branch: | bzr merge lp:~ack/charms/trusty/glance/pause-and-resume |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Billy Olsen | Approve | ||
Adam Collard (community) | Approve | ||
Review via email: mp+269369@code.launchpad.net |
Commit message
Description of the change
This branch adds pause/resume actions that can be used to pause the service for maintenance on a unit.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #8152 glance-next for ack mp269369
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #6058 glance-next for ack mp269369
AMULET OK: passed
Build: http://
- 157. By Alberto Donato
-
Expand description.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #8933 glance-next for ack mp269369
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #8254 glance-next for ack mp269369
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #6079 glance-next for ack mp269369
AMULET OK: passed
Build: http://
Billy Olsen (billy-olsen) wrote : | # |
Please fix inline comments below
- 158. By Alberto Donato
-
Drop leftover debug print.
Alberto Donato (ack) wrote : | # |
> Please fix inline comments below
Fixed, thanks.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #9154 glance-next for ack mp269369
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #8460 glance-next for ack mp269369
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #6166 glance-next for ack mp269369
AMULET OK: passed
Build: http://
Alberto Donato (ack) : | # |
- 159. By Alberto Donato
-
Fix docstring.
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #9235 glance-next for ack mp269369
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #8538 glance-next for ack mp269369
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #6198 glance-next for ack mp269369
AMULET OK: passed
Build: http://
Billy Olsen (billy-olsen) wrote : | # |
Thanks Alberto! LGTM, Approved.
Preview Diff
1 | === modified file '.coveragerc' |
2 | --- .coveragerc 2013-08-14 22:56:40 +0000 |
3 | +++ .coveragerc 2015-09-02 11:42:23 +0000 |
4 | @@ -4,3 +4,4 @@ |
5 | if __name__ == .__main__.: |
6 | include= |
7 | hooks/glance_* |
8 | + actions/actions.py |
9 | |
10 | === modified file 'actions.yaml' |
11 | --- actions.yaml 2015-08-03 15:36:41 +0000 |
12 | +++ actions.yaml 2015-09-02 11:42:23 +0000 |
13 | @@ -2,3 +2,14 @@ |
14 | description: Reinstall glance from the openstack-origin-git repositories. |
15 | openstack-upgrade: |
16 | description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True. |
17 | +pause: |
18 | + description: | |
19 | + Pause glance services. |
20 | + If the glance deployment is clustered using the hacluster charm, the |
21 | + corresponding hacluster unit on the node must first be paused as well. |
22 | + Not doing so may lead to an interruption of service. |
23 | +resume: |
24 | + description: | |
25 | + Resume glance services. |
26 | + If the glance deployment is clustered using the hacluster charm, the |
27 | + corresponding hacluster unit on the node must be resumed as well. |
28 | |
29 | === added file 'actions/__init__.py' |
30 | === added file 'actions/actions.py' |
31 | --- actions/actions.py 1970-01-01 00:00:00 +0000 |
32 | +++ actions/actions.py 2015-09-02 11:42:23 +0000 |
33 | @@ -0,0 +1,56 @@ |
34 | +#!/usr/bin/python |
35 | + |
36 | +import sys |
37 | +import os |
38 | + |
39 | +from charmhelpers.core.host import service_pause, service_resume |
40 | +from charmhelpers.core.hookenv import action_fail, status_set |
41 | + |
42 | +from hooks.glance_utils import services |
43 | + |
44 | + |
45 | +def pause(args): |
46 | + """Pause all the Glance services. |
47 | + |
48 | + @raises Exception if any services fail to stop |
49 | + """ |
50 | + for service in services(): |
51 | + stopped = service_pause(service) |
52 | + if not stopped: |
53 | + raise Exception("{} didn't stop cleanly.".format(service)) |
54 | + status_set( |
55 | + "maintenance", "Paused. Use 'resume' action to resume normal service.") |
56 | + |
57 | + |
58 | +def resume(args): |
59 | + """Resume all the Glance services. |
60 | + |
61 | + @raises Exception if any services fail to start |
62 | + """ |
63 | + for service in services(): |
64 | + started = service_resume(service) |
65 | + if not started: |
66 | + raise Exception("{} didn't start cleanly.".format(service)) |
67 | + status_set("active", "") |
68 | + |
69 | + |
70 | +# A dictionary of all the defined actions to callables (which take |
71 | +# parsed arguments). |
72 | +ACTIONS = {"pause": pause, "resume": resume} |
73 | + |
74 | + |
75 | +def main(args): |
76 | + action_name = os.path.basename(args[0]) |
77 | + try: |
78 | + action = ACTIONS[action_name] |
79 | + except KeyError: |
80 | + return "Action %s undefined" % action_name |
81 | + else: |
82 | + try: |
83 | + action(args) |
84 | + except Exception as e: |
85 | + action_fail(str(e)) |
86 | + |
87 | + |
88 | +if __name__ == "__main__": |
89 | + sys.exit(main(sys.argv)) |
90 | |
91 | === added symlink 'actions/charmhelpers' |
92 | === target is u'../charmhelpers' |
93 | === modified file 'actions/git_reinstall.py' |
94 | --- actions/git_reinstall.py 2015-04-15 16:29:59 +0000 |
95 | +++ actions/git_reinstall.py 2015-09-02 11:42:23 +0000 |
96 | @@ -1,9 +1,7 @@ |
97 | #!/usr/bin/python |
98 | -import sys |
99 | + |
100 | import traceback |
101 | |
102 | -sys.path.append('hooks/') |
103 | - |
104 | from charmhelpers.contrib.openstack.utils import ( |
105 | git_install_requested, |
106 | ) |
107 | @@ -14,11 +12,11 @@ |
108 | config, |
109 | ) |
110 | |
111 | -from glance_utils import ( |
112 | +from hooks.glance_utils import ( |
113 | git_install, |
114 | ) |
115 | |
116 | -from glance_relations import ( |
117 | +from hooks.glance_relations import ( |
118 | config_changed, |
119 | ) |
120 | |
121 | |
122 | === added symlink 'actions/hooks' |
123 | === target is u'../hooks' |
124 | === modified file 'actions/openstack_upgrade.py' |
125 | --- actions/openstack_upgrade.py 2015-08-14 15:55:32 +0000 |
126 | +++ actions/openstack_upgrade.py 2015-09-02 11:42:23 +0000 |
127 | @@ -1,8 +1,7 @@ |
128 | #!/usr/bin/python |
129 | -import sys |
130 | + |
131 | import traceback |
132 | |
133 | -sys.path.append('hooks/') |
134 | |
135 | from charmhelpers.core.hookenv import ( |
136 | action_set, |
137 | @@ -10,7 +9,7 @@ |
138 | config |
139 | ) |
140 | |
141 | -from glance_relations import config_changed |
142 | +from hooks.glance_relations import config_changed |
143 | |
144 | from charmhelpers.contrib.openstack.utils import ( |
145 | juju_log, |
146 | @@ -18,7 +17,7 @@ |
147 | openstack_upgrade_available |
148 | ) |
149 | |
150 | -from glance_utils import ( |
151 | +from hooks.glance_utils import ( |
152 | do_openstack_upgrade, |
153 | register_configs |
154 | ) |
155 | |
156 | === added symlink 'actions/pause' |
157 | === target is u'actions.py' |
158 | === added symlink 'actions/resume' |
159 | === target is u'actions.py' |
160 | === modified file 'charm-helpers-hooks.yaml' |
161 | --- charm-helpers-hooks.yaml 2015-07-31 13:10:57 +0000 |
162 | +++ charm-helpers-hooks.yaml 2015-09-02 11:42:23 +0000 |
163 | @@ -1,5 +1,5 @@ |
164 | branch: lp:charm-helpers |
165 | -destination: hooks/charmhelpers |
166 | +destination: charmhelpers |
167 | include: |
168 | - core |
169 | - cli |
170 | |
171 | === renamed directory 'hooks/charmhelpers' => 'charmhelpers' |
172 | === added symlink 'hooks/charmhelpers' |
173 | === target is u'../charmhelpers' |
174 | === modified file 'hooks/glance_utils.py' |
175 | --- hooks/glance_utils.py 2015-06-04 08:44:46 +0000 |
176 | +++ hooks/glance_utils.py 2015-09-02 11:42:23 +0000 |
177 | @@ -3,6 +3,7 @@ |
178 | import os |
179 | import shutil |
180 | import subprocess |
181 | +from itertools import chain |
182 | |
183 | import glance_contexts |
184 | |
185 | @@ -227,15 +228,13 @@ |
186 | # mysql might be restarting or suchlike. |
187 | @retry_on_exception(5, base_delay=3, exc_type=subprocess.CalledProcessError) |
188 | def determine_packages(): |
189 | - packages = [] + PACKAGES |
190 | + packages = set(PACKAGES) |
191 | |
192 | if git_install_requested(): |
193 | - packages.extend(BASE_GIT_PACKAGES) |
194 | - # don't include packages that will be installed from git |
195 | - for p in GIT_PACKAGE_BLACKLIST: |
196 | - packages.remove(p) |
197 | + packages |= set(BASE_GIT_PACKAGES) |
198 | + packages -= set(GIT_PACKAGE_BLACKLIST) |
199 | |
200 | - return list(set(packages)) |
201 | + return sorted(packages) |
202 | |
203 | |
204 | def migrate_database(): |
205 | @@ -296,11 +295,8 @@ |
206 | |
207 | |
208 | def services(): |
209 | - ''' Returns a list of services associate with this charm ''' |
210 | - _services = [] |
211 | - for v in restart_map().values(): |
212 | - _services = _services + v |
213 | - return list(set(_services)) |
214 | + ''' Returns a list of (unique) services associate with this charm ''' |
215 | + return list(set(chain(*restart_map().values()))) |
216 | |
217 | |
218 | def setup_ipv6(): |
219 | |
220 | === modified file 'tests/basic_deployment.py' |
221 | --- tests/basic_deployment.py 2015-07-13 16:07:29 +0000 |
222 | +++ tests/basic_deployment.py 2015-09-02 11:42:23 +0000 |
223 | @@ -28,6 +28,8 @@ |
224 | relations, service status, endpoint service catalog, create and |
225 | delete new image.""" |
226 | |
227 | + SERVICES = ('apache2', 'haproxy', 'glance-api', 'glance-registry') |
228 | + |
229 | def __init__(self, series=None, openstack=None, source=None, git=False, |
230 | stable=False): |
231 | """Deploy the entire test environment.""" |
232 | @@ -40,6 +42,21 @@ |
233 | self._deploy() |
234 | self._initialize_tests() |
235 | |
236 | + def _assert_services(self, should_run): |
237 | + u.get_unit_process_ids( |
238 | + {self.glance_sentry: self.SERVICES}, |
239 | + expect_success=should_run) |
240 | + |
241 | + def get_service_overrides(self, unit): |
242 | + """ |
243 | + Return a dict mapping service names to a boolean indicating whether |
244 | + an override file exists for that service. |
245 | + """ |
246 | + init_contents = unit.directory_contents("/etc/init/") |
247 | + return { |
248 | + service: "{}.override".format(service) in init_contents["files"] |
249 | + for service in self.SERVICES} |
250 | + |
251 | def _add_services(self): |
252 | """Add services |
253 | |
254 | @@ -544,3 +561,21 @@ |
255 | sleep_time = 0 |
256 | |
257 | self.d.configure(juju_service, set_default) |
258 | + |
259 | + def test_901_pause_resume(self): |
260 | + """Test pause and resume actions.""" |
261 | + unit_name = "glance/0" |
262 | + unit = self.d.sentry.unit[unit_name] |
263 | + self._assert_services(should_run=True) |
264 | + action_id = u.run_action(unit, "pause") |
265 | + assert u.wait_on_action(action_id), "Pause action failed." |
266 | + |
267 | + self._assert_services(should_run=False) |
268 | + assert all(self.get_service_overrides(unit).itervalues()), \ |
269 | + "Not all override files were created." |
270 | + |
271 | + action_id = u.run_action(unit, "resume") |
272 | + assert u.wait_on_action(action_id), "Resume action failed" |
273 | + assert not any(self.get_service_overrides(unit).itervalues()), \ |
274 | + "Not all override files were removed." |
275 | + self._assert_services(should_run=True) |
276 | |
277 | === modified file 'unit_tests/__init__.py' |
278 | --- unit_tests/__init__.py 2015-03-21 01:36:16 +0000 |
279 | +++ unit_tests/__init__.py 2015-09-02 11:42:23 +0000 |
280 | @@ -1,4 +0,0 @@ |
281 | -import sys |
282 | - |
283 | -sys.path.append('actions/') |
284 | -sys.path.append('hooks/') |
285 | |
286 | === added file 'unit_tests/test_actions.py' |
287 | --- unit_tests/test_actions.py 1970-01-01 00:00:00 +0000 |
288 | +++ unit_tests/test_actions.py 2015-09-02 11:42:23 +0000 |
289 | @@ -0,0 +1,157 @@ |
290 | +import os |
291 | +import mock |
292 | + |
293 | +os.environ['JUJU_UNIT_NAME'] = 'glance' |
294 | + |
295 | +from test_utils import CharmTestCase |
296 | + |
297 | +import actions.actions |
298 | + |
299 | + |
300 | +class PauseTestCase(CharmTestCase): |
301 | + |
302 | + def setUp(self): |
303 | + super(PauseTestCase, self).setUp( |
304 | + actions.actions, ["service_pause", "status_set"]) |
305 | + |
306 | + def test_pauses_services(self): |
307 | + """Pause action pauses all Glance services.""" |
308 | + pause_calls = [] |
309 | + |
310 | + def fake_service_pause(svc): |
311 | + pause_calls.append(svc) |
312 | + return True |
313 | + |
314 | + self.service_pause.side_effect = fake_service_pause |
315 | + |
316 | + actions.actions.pause([]) |
317 | + self.assertItemsEqual( |
318 | + pause_calls, |
319 | + ['glance-api', 'glance-registry', 'haproxy', 'apache2']) |
320 | + |
321 | + def test_bails_out_early_on_error(self): |
322 | + """Pause action fails early if there are errors stopping a service.""" |
323 | + pause_calls = [] |
324 | + |
325 | + def maybe_kill(svc): |
326 | + if svc == "glance-registry": |
327 | + return False |
328 | + else: |
329 | + pause_calls.append(svc) |
330 | + return True |
331 | + |
332 | + self.service_pause.side_effect = maybe_kill |
333 | + self.assertRaisesRegexp( |
334 | + Exception, "glance-registry didn't stop cleanly.", |
335 | + actions.actions.pause, []) |
336 | + self.assertEqual(pause_calls, ['haproxy', 'glance-api']) |
337 | + |
338 | + def test_status_mode(self): |
339 | + """Pause action sets the status to maintenance.""" |
340 | + status_calls = [] |
341 | + self.status_set.side_effect = lambda state, msg: status_calls.append( |
342 | + state) |
343 | + |
344 | + actions.actions.pause([]) |
345 | + self.assertEqual(status_calls, ["maintenance"]) |
346 | + |
347 | + def test_status_message(self): |
348 | + """Pause action sets a status message reflecting that it's paused.""" |
349 | + status_calls = [] |
350 | + self.status_set.side_effect = lambda state, msg: status_calls.append( |
351 | + msg) |
352 | + |
353 | + actions.actions.pause([]) |
354 | + self.assertEqual( |
355 | + status_calls, ["Paused. " |
356 | + "Use 'resume' action to resume normal service."]) |
357 | + |
358 | + |
359 | +class ResumeTestCase(CharmTestCase): |
360 | + |
361 | + def setUp(self): |
362 | + super(ResumeTestCase, self).setUp( |
363 | + actions.actions, ["service_resume", "status_set"]) |
364 | + |
365 | + def test_resumes_services(self): |
366 | + """Resume action resumes all Glance services.""" |
367 | + resume_calls = [] |
368 | + |
369 | + def fake_service_resume(svc): |
370 | + resume_calls.append(svc) |
371 | + return True |
372 | + |
373 | + self.service_resume.side_effect = fake_service_resume |
374 | + actions.actions.resume([]) |
375 | + self.assertItemsEqual( |
376 | + resume_calls, |
377 | + ['glance-api', 'glance-registry', 'haproxy', 'apache2']) |
378 | + |
379 | + def test_bails_out_early_on_error(self): |
380 | + """Resume action fails early if there are errors starting a service.""" |
381 | + resume_calls = [] |
382 | + |
383 | + def maybe_kill(svc): |
384 | + if svc == "glance-registry": |
385 | + return False |
386 | + else: |
387 | + resume_calls.append(svc) |
388 | + return True |
389 | + |
390 | + self.service_resume.side_effect = maybe_kill |
391 | + self.assertRaisesRegexp( |
392 | + Exception, "glance-registry didn't start cleanly.", |
393 | + actions.actions.resume, []) |
394 | + self.assertEqual(resume_calls, ['haproxy', 'glance-api']) |
395 | + |
396 | + def test_status_mode(self): |
397 | + """Resume action sets the status to active.""" |
398 | + status_calls = [] |
399 | + self.status_set.side_effect = lambda state, msg: status_calls.append( |
400 | + state) |
401 | + |
402 | + actions.actions.resume([]) |
403 | + self.assertEqual(status_calls, ["active"]) |
404 | + |
405 | + def test_status_message(self): |
406 | + """Resume action sets an empty status message.""" |
407 | + status_calls = [] |
408 | + self.status_set.side_effect = lambda state, msg: status_calls.append( |
409 | + msg) |
410 | + |
411 | + actions.actions.resume([]) |
412 | + self.assertEqual(status_calls, [""]) |
413 | + |
414 | + |
415 | +class MainTestCase(CharmTestCase): |
416 | + |
417 | + def setUp(self): |
418 | + super(MainTestCase, self).setUp(actions.actions, ["action_fail"]) |
419 | + |
420 | + def test_invokes_action(self): |
421 | + dummy_calls = [] |
422 | + |
423 | + def dummy_action(args): |
424 | + dummy_calls.append(True) |
425 | + |
426 | + with mock.patch.dict(actions.actions.ACTIONS, {"foo": dummy_action}): |
427 | + actions.actions.main(["foo"]) |
428 | + self.assertEqual(dummy_calls, [True]) |
429 | + |
430 | + def test_unknown_action(self): |
431 | + """Unknown actions aren't a traceback.""" |
432 | + exit_string = actions.actions.main(["foo"]) |
433 | + self.assertEqual("Action foo undefined", exit_string) |
434 | + |
435 | + def test_failing_action(self): |
436 | + """Actions which traceback trigger action_fail() calls.""" |
437 | + dummy_calls = [] |
438 | + |
439 | + self.action_fail.side_effect = dummy_calls.append |
440 | + |
441 | + def dummy_action(args): |
442 | + raise ValueError("uh oh") |
443 | + |
444 | + with mock.patch.dict(actions.actions.ACTIONS, {"foo": dummy_action}): |
445 | + actions.actions.main(["foo"]) |
446 | + self.assertEqual(dummy_calls, ["uh oh"]) |
447 | |
448 | === modified file 'unit_tests/test_actions_git_reinstall.py' |
449 | --- unit_tests/test_actions_git_reinstall.py 2015-04-15 16:29:59 +0000 |
450 | +++ unit_tests/test_actions_git_reinstall.py 2015-09-02 11:42:23 +0000 |
451 | @@ -3,8 +3,9 @@ |
452 | |
453 | os.environ['JUJU_UNIT_NAME'] = 'glance' |
454 | |
455 | -with patch('glance_utils.register_configs') as register_configs: |
456 | - import git_reinstall |
457 | +with patch('charmhelpers.core.hookenv.config') as config: |
458 | + with patch('actions.hooks.glance_utils.register_configs'): |
459 | + from actions import git_reinstall |
460 | |
461 | from test_utils import ( |
462 | CharmTestCase |
463 | @@ -35,10 +36,9 @@ |
464 | @patch.object(git_reinstall, 'action_fail') |
465 | @patch.object(git_reinstall, 'git_install') |
466 | @patch.object(git_reinstall, 'config_changed') |
467 | - @patch('charmhelpers.contrib.openstack.utils.config') |
468 | - def test_git_reinstall(self, _config, config_changed, git_install, |
469 | - action_fail, action_set): |
470 | - _config.return_value = openstack_origin_git |
471 | + def test_git_reinstall(self, config_changed, git_install, action_fail, |
472 | + action_set): |
473 | + config.return_value = openstack_origin_git |
474 | self.test_config.set('openstack-origin-git', openstack_origin_git) |
475 | |
476 | git_reinstall.git_reinstall() |
477 | @@ -53,11 +53,9 @@ |
478 | @patch.object(git_reinstall, 'action_fail') |
479 | @patch.object(git_reinstall, 'git_install') |
480 | @patch.object(git_reinstall, 'config_changed') |
481 | - @patch('charmhelpers.contrib.openstack.utils.config') |
482 | - def test_git_reinstall_not_configured(self, _config, config_changed, |
483 | - git_install, action_fail, |
484 | - action_set): |
485 | - _config.return_value = None |
486 | + def test_git_reinstall_not_configured(self, config_changed, git_install, |
487 | + action_fail, action_set): |
488 | + config.return_value = None |
489 | |
490 | git_reinstall.git_reinstall() |
491 | |
492 | @@ -71,11 +69,9 @@ |
493 | @patch.object(git_reinstall, 'git_install') |
494 | @patch.object(git_reinstall, 'config_changed') |
495 | @patch('traceback.format_exc') |
496 | - @patch('charmhelpers.contrib.openstack.utils.config') |
497 | - def test_git_reinstall_exception(self, _config, format_exc, |
498 | - config_changed, git_install, action_fail, |
499 | - action_set): |
500 | - _config.return_value = openstack_origin_git |
501 | + def test_git_reinstall_exception(self, format_exc, config_changed, |
502 | + git_install, action_fail, action_set): |
503 | + config.return_value = openstack_origin_git |
504 | e = OSError('something bad happened') |
505 | git_install.side_effect = e |
506 | traceback = ( |
507 | |
508 | === modified file 'unit_tests/test_actions_openstack_upgrade.py' |
509 | --- unit_tests/test_actions_openstack_upgrade.py 2015-08-14 15:55:32 +0000 |
510 | +++ unit_tests/test_actions_openstack_upgrade.py 2015-09-02 11:42:23 +0000 |
511 | @@ -3,8 +3,9 @@ |
512 | |
513 | os.environ['JUJU_UNIT_NAME'] = 'glance' |
514 | |
515 | -with patch('glance_utils.register_configs') as register_configs: |
516 | - import openstack_upgrade |
517 | +with patch('actions.hooks.glance_utils.register_configs'): |
518 | + with patch('hooks.glance_utils.register_configs'): |
519 | + from actions import openstack_upgrade |
520 | |
521 | from test_utils import ( |
522 | CharmTestCase |
523 | @@ -27,12 +28,12 @@ |
524 | @patch.object(openstack_upgrade, 'do_openstack_upgrade') |
525 | @patch.object(openstack_upgrade, 'openstack_upgrade_available') |
526 | @patch.object(openstack_upgrade, 'config_changed') |
527 | - @patch('charmhelpers.contrib.openstack.utils.config') |
528 | - def test_openstack_upgrade(self, _config, config_changed, |
529 | + @patch('subprocess.check_output') |
530 | + def test_openstack_upgrade(self, _check_output, config_changed, |
531 | openstack_upgrade_available, |
532 | do_openstack_upgrade, action_fail, |
533 | action_set): |
534 | - _config.return_value = None |
535 | + _check_output.return_value = 'null' |
536 | openstack_upgrade_available.return_value = True |
537 | |
538 | self.test_config.set('action-managed-upgrade', True) |
539 | @@ -47,12 +48,13 @@ |
540 | @patch.object(openstack_upgrade, 'do_openstack_upgrade') |
541 | @patch.object(openstack_upgrade, 'openstack_upgrade_available') |
542 | @patch.object(openstack_upgrade, 'config_changed') |
543 | - @patch('charmhelpers.contrib.openstack.utils.config') |
544 | - def test_openstack_upgrade_not_configured(self, _config, config_changed, |
545 | + @patch('subprocess.check_output') |
546 | + def test_openstack_upgrade_not_configured(self, _check_output, |
547 | + config_changed, |
548 | openstack_upgrade_available, |
549 | do_openstack_upgrade, |
550 | action_set): |
551 | - _config.return_value = None |
552 | + _check_output.return_value = 'null' |
553 | openstack_upgrade_available.return_value = True |
554 | |
555 | openstack_upgrade.openstack_upgrade() |
556 | @@ -66,14 +68,12 @@ |
557 | @patch.object(openstack_upgrade, 'do_openstack_upgrade') |
558 | @patch.object(openstack_upgrade, 'openstack_upgrade_available') |
559 | @patch.object(openstack_upgrade, 'config_changed') |
560 | - @patch('charmhelpers.contrib.openstack.utils.config') |
561 | - def test_openstack_upgrade_git_install(self, _config, config_changed, |
562 | + @patch.object(openstack_upgrade, 'git_install_requested') |
563 | + def test_openstack_upgrade_git_install(self, git_install_requested, |
564 | + config_changed, |
565 | openstack_upgrade_available, |
566 | - do_openstack_upgrade, |
567 | - action_set): |
568 | - |
569 | - self.test_config.set('action-managed-upgrade', True) |
570 | - self.test_config.set('openstack-origin-git', True) |
571 | + do_openstack_upgrade, action_set): |
572 | + git_install_requested.return_value = True |
573 | |
574 | openstack_upgrade.openstack_upgrade() |
575 | |
576 | @@ -87,7 +87,7 @@ |
577 | @patch.object(openstack_upgrade, 'openstack_upgrade_available') |
578 | @patch.object(openstack_upgrade, 'config_changed') |
579 | @patch('traceback.format_exc') |
580 | - @patch('charmhelpers.contrib.openstack.utils.config') |
581 | + @patch('charmhelpers.core.hookenv.config') |
582 | def test_openstack_upgrade_exception(self, _config, format_exc, |
583 | config_changed, |
584 | openstack_upgrade_available, |
585 | |
586 | === modified file 'unit_tests/test_glance_contexts.py' |
587 | --- unit_tests/test_glance_contexts.py 2014-10-07 15:50:12 +0000 |
588 | +++ unit_tests/test_glance_contexts.py 2015-09-02 11:42:23 +0000 |
589 | @@ -1,11 +1,14 @@ |
590 | -import glance_contexts as contexts |
591 | from mock import patch, MagicMock |
592 | |
593 | +from hooks import glance_contexts as contexts |
594 | + |
595 | + |
596 | from test_utils import ( |
597 | CharmTestCase |
598 | ) |
599 | |
600 | TO_PATCH = [ |
601 | + "config", |
602 | 'relation_ids', |
603 | 'is_relation_made', |
604 | 'service_name', |
605 | @@ -18,6 +21,9 @@ |
606 | |
607 | def setUp(self): |
608 | super(TestGlanceContexts, self).setUp(contexts, TO_PATCH) |
609 | + from charmhelpers.core.hookenv import cache |
610 | + self.cache = cache |
611 | + cache.clear() |
612 | |
613 | def test_swift_not_related(self): |
614 | self.relation_ids.return_value = [] |
615 | @@ -55,52 +61,38 @@ |
616 | {'known_stores': "glance.store.filesystem.Store," |
617 | "glance.store.http.Store"}) |
618 | |
619 | - @patch('charmhelpers.contrib.openstack.context.config') |
620 | - @patch('charmhelpers.contrib.openstack.context.is_clustered') |
621 | - @patch('charmhelpers.contrib.openstack.context.determine_apache_port') |
622 | - @patch('charmhelpers.contrib.openstack.context.determine_api_port') |
623 | - @patch('charmhelpers.contrib.openstack.context.unit_get') |
624 | + @patch('charmhelpers.contrib.hahelpers.cluster.config_get') |
625 | @patch('charmhelpers.contrib.openstack.context.https') |
626 | def test_apache_ssl_context_service_enabled(self, mock_https, |
627 | - mock_unit_get, |
628 | - mock_determine_api_port, |
629 | - mock_determine_apache_port, |
630 | - mock_is_clustered, |
631 | mock_config): |
632 | + mock_config.return_value = 'true' |
633 | mock_https.return_value = True |
634 | - mock_unit_get.return_value = '1.2.3.4' |
635 | - mock_determine_api_port.return_value = '12' |
636 | - mock_determine_apache_port.return_value = '34' |
637 | - mock_is_clustered.return_value = False |
638 | |
639 | ctxt = contexts.ApacheSSLContext() |
640 | ctxt.enable_modules = MagicMock() |
641 | ctxt.configure_cert = MagicMock() |
642 | ctxt.configure_ca = MagicMock() |
643 | ctxt.canonical_names = MagicMock() |
644 | + ctxt.get_network_addresses = MagicMock() |
645 | + ctxt.get_network_addresses.return_value = [('1.2.3.4', '1.2.3.4')] |
646 | + |
647 | self.assertEquals(ctxt(), {'endpoints': [('1.2.3.4', '1.2.3.4', |
648 | - 34, 12)], |
649 | - 'ext_ports': [34], |
650 | + 9282, 9272)], |
651 | + 'ext_ports': [9282], |
652 | 'namespace': 'glance'}) |
653 | - self.assertTrue(mock_https.called) |
654 | - mock_unit_get.assert_called_with('private-address') |
655 | |
656 | - @patch('charmhelpers.contrib.openstack.context.config') |
657 | - @patch('glance_contexts.config') |
658 | - def test_glance_ipv6_context_service_enabled(self, mock_config, |
659 | - mock_context_config): |
660 | - mock_config.return_value = True |
661 | - mock_context_config.return_value = True |
662 | + @patch("subprocess.check_output") |
663 | + def test_glance_ipv6_context_service_enabled(self, mock_subprocess): |
664 | + self.config.return_value = True |
665 | + mock_subprocess.return_value = 'true' |
666 | ctxt = contexts.GlanceIPv6Context() |
667 | self.assertEquals(ctxt(), {'bind_host': '::', |
668 | 'registry_host': '[::]'}) |
669 | |
670 | - @patch('charmhelpers.contrib.openstack.context.config') |
671 | - @patch('glance_contexts.config') |
672 | - def test_glance_ipv6_context_service_disabled(self, mock_config, |
673 | - mock_context_config): |
674 | - mock_config.return_value = False |
675 | - mock_context_config.return_value = False |
676 | + @patch("subprocess.check_output") |
677 | + def test_glance_ipv6_context_service_disabled(self, mock_subprocess): |
678 | + self.config.return_value = False |
679 | + mock_subprocess.return_value = 'false' |
680 | ctxt = contexts.GlanceIPv6Context() |
681 | self.assertEquals(ctxt(), {'bind_host': '0.0.0.0', |
682 | 'registry_host': '0.0.0.0'}) |
683 | |
684 | === modified file 'unit_tests/test_glance_relations.py' |
685 | --- unit_tests/test_glance_relations.py 2015-08-10 15:21:34 +0000 |
686 | +++ unit_tests/test_glance_relations.py 2015-09-02 11:42:23 +0000 |
687 | @@ -6,7 +6,7 @@ |
688 | from test_utils import CharmTestCase |
689 | |
690 | os.environ['JUJU_UNIT_NAME'] = 'glance' |
691 | -import glance_utils as utils |
692 | +import hooks.glance_utils as utils |
693 | |
694 | _reg = utils.register_configs |
695 | _map = utils.restart_map |
696 | @@ -14,7 +14,7 @@ |
697 | utils.register_configs = MagicMock() |
698 | utils.restart_map = MagicMock() |
699 | |
700 | -import glance_relations as relations |
701 | +import hooks.glance_relations as relations |
702 | |
703 | relations.hooks._config_save = False |
704 | |
705 | @@ -47,7 +47,7 @@ |
706 | 'openstack_upgrade_available', |
707 | # charmhelpers.contrib.hahelpers.cluster_utils |
708 | 'is_elected_leader', |
709 | - # glance_utils |
710 | + # hooks.glance_utils |
711 | 'restart_map', |
712 | 'register_configs', |
713 | 'do_openstack_upgrade', |
714 | @@ -86,11 +86,10 @@ |
715 | relations.install_hook() |
716 | self.configure_installation_source.assert_called_with(repo) |
717 | self.apt_update.assert_called_with(fatal=True) |
718 | - self.apt_install.assert_called_with(['haproxy', 'python-six', 'uuid', |
719 | - 'python-mysqldb', 'apache2', |
720 | - 'python-psycopg2', 'glance', |
721 | - 'python-keystone', |
722 | - 'python-swiftclient'], fatal=True) |
723 | + self.apt_install.assert_called_with( |
724 | + ['apache2', 'glance', 'haproxy', 'python-keystone', |
725 | + 'python-mysqldb', 'python-psycopg2', 'python-six', |
726 | + 'python-swiftclient', 'uuid'], fatal=True) |
727 | self.assertTrue(self.execd_preinstall.called) |
728 | self.git_install.assert_called_with(None) |
729 | |
730 | @@ -128,17 +127,12 @@ |
731 | self.assertTrue(self.execd_preinstall.called) |
732 | self.configure_installation_source.assert_called_with(repo) |
733 | self.apt_update.assert_called_with(fatal=True) |
734 | - self.apt_install.assert_called_with(['haproxy', 'python-setuptools', |
735 | - 'python-six', 'uuid', |
736 | - 'python-mysqldb', |
737 | - 'libmysqlclient-dev', |
738 | - 'libssl-dev', 'libffi-dev', |
739 | - 'apache2', 'python-pip', |
740 | - 'libxslt1-dev', 'libyaml-dev', |
741 | - 'python-psycopg2', |
742 | - 'zlib1g-dev', 'python-dev', |
743 | - 'libxml2-dev'], |
744 | - fatal=True) |
745 | + self.apt_install.assert_called_with( |
746 | + ['apache2', 'haproxy', 'libffi-dev', 'libmysqlclient-dev', |
747 | + 'libssl-dev', 'libxml2-dev', 'libxslt1-dev', 'libyaml-dev', |
748 | + 'python-dev', 'python-mysqldb', 'python-pip', 'python-psycopg2', |
749 | + 'python-setuptools', 'python-six', 'uuid', 'zlib1g-dev'], |
750 | + fatal=True) |
751 | self.git_install.assert_called_with(projects_yaml) |
752 | |
753 | def test_db_joined(self): |
754 | @@ -398,8 +392,8 @@ |
755 | 'Could not create ceph keyring: peer not ready?' |
756 | ) |
757 | |
758 | - @patch("glance_relations.relation_set") |
759 | - @patch("glance_relations.relation_get") |
760 | + @patch("hooks.glance_relations.relation_set") |
761 | + @patch("hooks.glance_relations.relation_get") |
762 | @patch.object(relations, 'CONFIGS') |
763 | def test_ceph_changed_broker_send_rq(self, configs, mock_relation_get, |
764 | mock_relation_set): |
765 | @@ -420,7 +414,7 @@ |
766 | self.assertNotIn(c, configs.write.call_args_list) |
767 | |
768 | @patch("charmhelpers.core.host.service") |
769 | - @patch("glance_relations.relation_get", autospec=True) |
770 | + @patch("hooks.glance_relations.relation_get", autospec=True) |
771 | @patch.object(relations, 'CONFIGS') |
772 | def test_ceph_changed_with_key_and_relation_data(self, configs, |
773 | mock_relation_get, |
774 | @@ -472,15 +466,14 @@ |
775 | } |
776 | self.relation_set.assert_called_with(**ex) |
777 | |
778 | - @patch('charmhelpers.contrib.openstack.ip.is_clustered') |
779 | - @patch('charmhelpers.contrib.openstack.ip.unit_get') |
780 | - @patch('charmhelpers.contrib.openstack.ip.config') |
781 | - def test_keystone_joined_public_endpoint(self, _config, _unit_get, |
782 | - _is_clustered): |
783 | - _unit_get.return_value = 'glancehost' |
784 | - _is_clustered.return_value = False |
785 | + @patch.object(relations, 'canonical_url') |
786 | + def test_keystone_joined_public_endpoint(self, _canonical_url): |
787 | + def fake_canonical_url(configs, endpoint_type): |
788 | + return {"public": "http://glance.example.com", |
789 | + "int": "http://glancehost", |
790 | + "admin": "http://glancehost"}[endpoint_type] |
791 | + _canonical_url.side_effect = fake_canonical_url |
792 | self.test_config.set('os-public-hostname', 'glance.example.com') |
793 | - _config.side_effect = self.test_config.get |
794 | relations.keystone_joined() |
795 | ex = { |
796 | 'region': 'RegionOne', |
797 | |
798 | === modified file 'unit_tests/test_glance_utils.py' |
799 | --- unit_tests/test_glance_utils.py 2015-06-04 08:44:46 +0000 |
800 | +++ unit_tests/test_glance_utils.py 2015-09-02 11:42:23 +0000 |
801 | @@ -4,7 +4,9 @@ |
802 | import os |
803 | |
804 | os.environ['JUJU_UNIT_NAME'] = 'glance' |
805 | -import glance_utils as utils |
806 | + |
807 | +with patch('charmhelpers.core.hookenv.config') as config: |
808 | + import hooks.glance_utils as utils |
809 | |
810 | from test_utils import ( |
811 | CharmTestCase, |
812 | @@ -131,16 +133,16 @@ |
813 | ]) |
814 | self.assertEquals(ex_map, utils.restart_map()) |
815 | |
816 | - @patch('charmhelpers.contrib.openstack.utils.config') |
817 | - def test_determine_packages(self, _config): |
818 | - _config.return_value = None |
819 | + @patch.object(utils, 'git_install_requested') |
820 | + def test_determine_packages(self, git_install_requested): |
821 | + git_install_requested.return_value = False |
822 | result = utils.determine_packages() |
823 | ex = utils.PACKAGES |
824 | self.assertEquals(set(ex), set(result)) |
825 | |
826 | - @patch('charmhelpers.contrib.openstack.utils.config') |
827 | - def test_determine_packages_git(self, _config): |
828 | - _config.return_value = openstack_origin_git |
829 | + @patch.object(utils, 'git_install_requested') |
830 | + def test_determine_packages_git(self, git_install_requested): |
831 | + git_install_requested.return_value = True |
832 | result = utils.determine_packages() |
833 | ex = utils.PACKAGES + utils.BASE_GIT_PACKAGES |
834 | for p in utils.GIT_PACKAGE_BLACKLIST: |
charm_lint_check #8824 glance-next for ack mp269369
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/8824/