Merge lp:~adam-collard/charms/precise/reviewboard/trunk into lp:charms/reviewboard

Proposed by Adam Collard
Status: Merged
Merged at revision: 31
Proposed branch: lp:~adam-collard/charms/precise/reviewboard/trunk
Merge into: lp:charms/reviewboard
Diff against target: 655 lines (+551/-18)
4 files modified
Makefile (+12/-0)
README.md (+1/-2)
hooks/hooks.py (+24/-16)
hooks/tests/test_hooks.py (+514/-0)
To merge this branch: bzr merge lp:~adam-collard/charms/precise/reviewboard/trunk
Reviewer Review Type Date Requested Status
Charles Butler (community) Approve
Review via email: mp+224041@code.launchpad.net

Description of the change

This branch adds unit test coverage to all of the implemented hooks and fixes a couple of bugs:

1. Lack of apt update before apt install meant (with out of date image files) units failed to install python-setuptools and therefore easy_install failed.
2. Ordering of relating and config setting (relating first and then setting config) meant a theoretical bug with failing to setup apache site.

To post a comment you must log in.
31. By Adam Collard

Add test dependencies and setup target

Revision history for this message
Charles Butler (lazypower) wrote :

Adam,

Thanks for the updated test suite and the make targets.

+1 LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Makefile'
2--- Makefile 1970-01-01 00:00:00 +0000
3+++ Makefile 2014-06-29 13:52:25 +0000
4@@ -0,0 +1,12 @@
5+.PHONY: check test lint setup
6+
7+test: setup
8+ cd hooks; trial tests
9+
10+lint:
11+ flake8 --exclude=charmhelpers hooks/
12+
13+check: test lint
14+
15+setup:
16+ @sudo apt-get install python-twisted-core python-django python-mock
17
18=== modified file 'README.md'
19--- README.md 2014-06-10 18:53:50 +0000
20+++ README.md 2014-06-29 13:52:25 +0000
21@@ -35,11 +35,10 @@
22
23 ## Known Limitations and Issues
24
25-* Add test coverage
26-* Add configuration for setting up initial repositories?
27 * Add support for MySQL as a database backend.
28 * Switch package installation between `python-psycopg2` and `python-mysqldb`.
29 * Change configuration of rb-site command.
30+* Add configuration for setting up initial repositories?
31 * Optionally allow relation to separate
32 [memcached](https://jujucharms.com/sidebar/search/precise/memcached/)
33 charm instead of using local memcached.
34
35=== modified file 'hooks/hooks.py'
36--- hooks/hooks.py 2014-06-11 18:52:18 +0000
37+++ hooks/hooks.py 2014-06-29 13:52:25 +0000
38@@ -7,7 +7,7 @@
39
40 import charmhelpers.core.hookenv as hookenv
41 from charmhelpers.core.host import service_restart, service_stop
42-from charmhelpers.fetch import apt_install
43+from charmhelpers.fetch import apt_install, apt_update
44
45
46 hooks = hookenv.Hooks()
47@@ -42,7 +42,8 @@
48
49
50 @contextmanager
51-def django_environ():
52+def _django_environ():
53+ """Context manager for setting up DJANGO_SETTINGS_MODULE."""
54 cwd = os.getcwd()
55 config_dir = "/var/www/reviewboard/conf"
56 os.chdir(config_dir)
57@@ -119,8 +120,9 @@
58 @hooks.hook('db-relation-changed')
59 def db_relation_changed():
60 if not is_rb_site_installed():
61- if install_rb_site():
62- configure_apache2()
63+ install_rb_site()
64+ if is_rb_site_installed():
65+ configure_apache2()
66
67
68 @hooks.hook("website-relation-joined")
69@@ -134,23 +136,24 @@
70 def config_changed():
71 config = hookenv.config()
72 if not is_rb_site_installed():
73- if install_rb_site():
74- configure_apache2()
75- else:
76- # Failed to install rb site for some reason, try again later.
77- return
78- if config["admin-password"]:
79- with django_environ():
80+ install_rb_site()
81+ if is_rb_site_installed():
82+ configure_apache2()
83+ else:
84+ # Failed to install rb site for some reason, try again later.
85+ return
86+ if config.get("admin-password"):
87+ with _django_environ():
88 from django.contrib.auth.management.commands import changepassword
89 command = changepassword.Command()
90 command._get_pass = lambda *args: config["admin-password"]
91 command.execute("admin")
92- if config["host"]:
93+ if config.get("host"):
94 if config["host"] == "localhost":
95 host = hookenv.unit_get("public-address")
96 else:
97 host = config["host"]
98- with django_environ():
99+ with _django_environ():
100 from django.contrib.sites.models import Site
101 cur_site = Site.objects.get_current()
102 cur_site.domain = host
103@@ -159,6 +162,7 @@
104
105 @hooks.hook("install")
106 def install():
107+ apt_update(fatal=True)
108 apt_install(["apache2-mpm-prefork",
109 "libapache2-mod-wsgi",
110 "python-setuptools",
111@@ -166,7 +170,7 @@
112 "memcached",
113 "python-memcache",
114 "patch",
115- "python-psycopg2"])
116+ "python-psycopg2"], fatal=True)
117 hookenv.log("Installing ReviewBoard")
118 subprocess.check_call(["easy_install", "ReviewBoard"])
119
120@@ -183,8 +187,12 @@
121 service_stop("apache2")
122
123
124-if __name__ == '__main__':
125+def main(argv):
126 try:
127- hooks.execute(sys.argv)
128+ hooks.execute(argv)
129 except hookenv.UnregisteredHookError as e:
130 hookenv.log('Unknown hook {} - skipping.'.format(e))
131+
132+
133+if __name__ == '__main__':
134+ main(sys.argv)
135
136=== added directory 'hooks/tests'
137=== added file 'hooks/tests/__init__.py'
138=== added file 'hooks/tests/test_hooks.py'
139--- hooks/tests/test_hooks.py 1970-01-01 00:00:00 +0000
140+++ hooks/tests/test_hooks.py 2014-06-29 13:52:25 +0000
141@@ -0,0 +1,514 @@
142+from contextlib import contextmanager
143+import unittest
144+
145+from django.conf import settings
146+settings.configure()
147+
148+from mock import patch
149+
150+import hooks
151+
152+
153+class IsPostgresAvailableTest(unittest.TestCase):
154+
155+ def setUp(self):
156+ super(IsPostgresAvailableTest, self).setUp()
157+ log_patcher = patch("charmhelpers.core.hookenv.log")
158+ self.mock_log = log_patcher.start()
159+ self.addCleanup(log_patcher.stop)
160+
161+ @patch('charmhelpers.core.hookenv.is_relation_made')
162+ def test_requires_relation_to_db(self, mock_is_relation_made):
163+ """is_postgres_available depends on relation to PostgreSQL."""
164+ mock_is_relation_made.return_value = False
165+ self.assertFalse(hooks.is_postgres_available())
166+ mock_is_relation_made.assert_called_with("db")
167+ self.mock_log.assert_called_with("Missing relation to PostgreSQL")
168+
169+ @patch('charmhelpers.core.hookenv.is_relation_made')
170+ @patch('charmhelpers.core.hookenv.local_unit')
171+ @patch('charmhelpers.core.hookenv.relation_get')
172+ def test_requires_unit_in_allowed_units(
173+ self, mock_relation_get, mock_local_unit, mock_is_relation_made):
174+ """is_postgres_available checks if unit is in allowed-units."""
175+ mock_is_relation_made.return_value = True
176+ mock_local_unit.return_value = "test-unit/0"
177+ mock_relation_get.return_value = "another-unit/0"
178+ self.assertFalse(hooks.is_postgres_available())
179+ self.mock_log.assert_called_with(
180+ "Unit is not yet allowed (another-unit/0)")
181+
182+ @patch('charmhelpers.core.hookenv.is_relation_made')
183+ @patch('charmhelpers.core.hookenv.local_unit')
184+ @patch('charmhelpers.core.hookenv.relation_get')
185+ def test_checks_database_name(
186+ self, mock_relation_get, mock_local_unit, mock_is_relation_made):
187+ """If we are an allowed_unit then check the database name"""
188+
189+ def relation_get_side_effect(relation_key):
190+ if relation_key == "allowed-units":
191+ return "test-unit/0"
192+ elif relation_key == "database":
193+ return "not-reviewboard"
194+ else:
195+ assert False, "Unexpected relation key %s" % relation_key
196+
197+ mock_is_relation_made.return_value = True
198+ mock_local_unit.return_value = "test-unit/0"
199+ mock_relation_get.side_effect = relation_get_side_effect
200+ self.assertFalse(hooks.is_postgres_available())
201+ self.mock_log.assert_called_with(
202+ "Database provided by PostgreSQL is "
203+ "not 'reviewboard': 'not-reviewboard'")
204+
205+ @patch('charmhelpers.core.hookenv.is_relation_made')
206+ @patch('charmhelpers.core.hookenv.local_unit')
207+ @patch('charmhelpers.core.hookenv.relation_get')
208+ def test_everything_green(
209+ self, mock_relation_get, mock_local_unit, mock_is_relation_made):
210+ """When everything is OK, is_postgres_available returns True"""
211+ def relation_get_side_effect(relation_key):
212+ if relation_key == "allowed-units":
213+ return "test-unit/0"
214+ elif relation_key == "database":
215+ return "reviewboard"
216+ else:
217+ assert False, "Unexpected relation key %s" % relation_key
218+
219+ mock_is_relation_made.return_value = True
220+ mock_local_unit.return_value = "test-unit/0"
221+ mock_relation_get.side_effect = relation_get_side_effect
222+ self.assertTrue(hooks.is_postgres_available())
223+ self.assertFalse(self.mock_log.called)
224+
225+
226+class IsRbSiteInstalledTest(unittest.TestCase):
227+
228+ @patch("os.path.exists")
229+ def test_looks_for_site_directory(self, mock_exists):
230+ mock_exists.return_value = False
231+ self.assertFalse(hooks.is_rb_site_installed())
232+ mock_exists.assert_called_with("/var/www/reviewboard")
233+ mock_exists.return_value = True
234+ self.assertTrue(hooks.is_rb_site_installed())
235+
236+
237+class InstallRbSiteTest(unittest.TestCase):
238+
239+ def setUp(self):
240+ super(InstallRbSiteTest, self).setUp()
241+ config_patcher = patch("charmhelpers.core.hookenv.config")
242+ self.mock_config = config_patcher.start()
243+ self.addCleanup(config_patcher.stop)
244+
245+ log_patcher = patch("charmhelpers.core.hookenv.log")
246+ self.mock_log = log_patcher.start()
247+ self.addCleanup(log_patcher.stop)
248+
249+ available_patcher = patch("hooks.is_postgres_available")
250+ self.mock_available = available_patcher.start()
251+ self.mock_available.return_value = True
252+ self.addCleanup(available_patcher.stop)
253+
254+ def test_guarded_on_is_postgres_available(self):
255+ self.mock_available.return_value = False
256+ self.assertFalse(hooks.install_rb_site())
257+ self.mock_available.assert_called_with()
258+
259+ def test_guarded_on_admin_password(self):
260+ self.mock_config.return_value = {}
261+ self.assertFalse(hooks.install_rb_site())
262+ self.mock_log.assert_called_with(
263+ "admin-password is not set, refusing to configure site")
264+
265+ @patch('charmhelpers.core.hookenv.unit_get')
266+ @patch('charmhelpers.core.hookenv.relation_get')
267+ @patch('subprocess.check_call')
268+ def test_host_info_from_config_defaults_to_public_address(
269+ self, mock_call, mock_relation_get, mock_unit_get):
270+ """
271+ The host information is a config value which defaults to
272+ "localhost". When it is "localhost" that means use the public
273+ address of the unit.
274+ """
275+ self.mock_config.return_value = {"admin-password": "a-password"}
276+ mock_unit_get.return_value = "8.8.8.8"
277+ mock_relation_get.return_value = {"host": "psql.example.com",
278+ "port": "5432",
279+ "user": "rb-db-user",
280+ "password": "hunter2"}
281+ self.assertTrue(hooks.install_rb_site())
282+ args_list, kwargs_list = mock_call.call_args
283+ self.assertIn("--domain-name=8.8.8.8", args_list[0])
284+ self.mock_log.assert_any_call(
285+ "Installing rb-site for 8.8.8.8 in /var/www/reviewboard")
286+
287+ @patch('charmhelpers.core.hookenv.unit_get')
288+ @patch('charmhelpers.core.hookenv.relation_get')
289+ @patch('subprocess.check_call')
290+ def test_db_host_and_port_used_from_relation(
291+ self, mock_call, mock_relation_get, mock_unit_get):
292+ self.mock_config.return_value = {"admin-password": "a-password",
293+ "host": "rb.example.com"}
294+ mock_relation_get.return_value = {"host": "psql.example.com",
295+ "port": "5432",
296+ "user": "rb-db-user",
297+ "password": "hunter2"}
298+ self.assertTrue(hooks.install_rb_site())
299+ args_list, kwargs_list = mock_call.call_args
300+ self.assertIn("--db-host=psql.example.com:5432", args_list[0])
301+
302+ @patch('charmhelpers.core.hookenv.unit_get')
303+ @patch('charmhelpers.core.hookenv.relation_get')
304+ @patch('subprocess.check_call')
305+ def test_db_user_used_from_relation(
306+ self, mock_call, mock_relation_get, mock_unit_get):
307+ self.mock_config.return_value = {"admin-password": "a-password",
308+ "host": "rb.example.com"}
309+ mock_relation_get.return_value = {"host": "psql.example.com",
310+ "port": "5432",
311+ "user": "rb-db-user",
312+ "password": "hunter2"}
313+ self.assertTrue(hooks.install_rb_site())
314+ args_list, kwargs_list = mock_call.call_args
315+ self.assertIn("--db-user=rb-db-user", args_list[0])
316+
317+ @patch('charmhelpers.core.hookenv.unit_get')
318+ @patch('charmhelpers.core.hookenv.relation_get')
319+ @patch('subprocess.check_call')
320+ def test_db_password_used_from_relation(
321+ self, mock_call, mock_relation_get, mock_unit_get):
322+ self.mock_config.return_value = {"admin-password": "a-password",
323+ "host": "rb.example.com"}
324+ mock_relation_get.return_value = {"host": "psql.example.com",
325+ "port": "5432",
326+ "user": "rb-db-user",
327+ "password": "hunter2"}
328+ self.assertTrue(hooks.install_rb_site())
329+ args_list, kwargs_list = mock_call.call_args
330+ self.assertIn("--db-pass=hunter2", args_list[0])
331+
332+ @patch('charmhelpers.core.hookenv.unit_get')
333+ @patch('charmhelpers.core.hookenv.relation_get')
334+ @patch('subprocess.check_call')
335+ def test_admin_password_used_from_config(
336+ self, mock_call, mock_relation_get, mock_unit_get):
337+ self.mock_config.return_value = {"admin-password": "a-password",
338+ "host": "rb.example.com"}
339+ mock_relation_get.return_value = {"host": "psql.example.com",
340+ "port": "5432",
341+ "user": "rb-db-user",
342+ "password": "hunter2"}
343+ self.assertTrue(hooks.install_rb_site())
344+ args_list, kwargs_list = mock_call.call_args
345+ self.assertIn("--admin-password=a-password", args_list[0])
346+
347+ @patch('charmhelpers.core.hookenv.unit_get')
348+ @patch('charmhelpers.core.hookenv.relation_get')
349+ @patch('subprocess.check_call')
350+ def test_log_confirmation(
351+ self, mock_call, mock_relation_get, mock_unit_get):
352+ self.mock_config.return_value = {"admin-password": "a-password",
353+ "host": "rb.example.com"}
354+ mock_relation_get.return_value = {"host": "psql.example.com",
355+ "port": "5432",
356+ "user": "rb-db-user",
357+ "password": "hunter2"}
358+ self.assertTrue(hooks.install_rb_site())
359+ self.mock_log.assert_called_with("Installed rb-site!")
360+
361+ @patch('charmhelpers.core.hookenv.unit_get')
362+ @patch('charmhelpers.core.hookenv.relation_get')
363+ @patch('subprocess.check_call')
364+ def test_full_rb_site_install_command(
365+ self, mock_call, mock_relation_get, mock_unit_get):
366+ self.mock_config.return_value = {"admin-password": "a-password",
367+ "host": "rb.example.com"}
368+ mock_relation_get.return_value = {"host": "psql.example.com",
369+ "port": "5432",
370+ "user": "rb-db-user",
371+ "password": "hunter2"}
372+ self.assertTrue(hooks.install_rb_site())
373+ args_list, kwargs_list = mock_call.call_args
374+ full_command_args = [
375+ "rb-site",
376+ "install",
377+ "--noinput",
378+ "--domain-name=rb.example.com",
379+ "--db-type=postgresql",
380+ "--db-name=reviewboard",
381+ "--db-host=psql.example.com:5432",
382+ "--db-user=rb-db-user",
383+ "--db-pass=hunter2",
384+ "--cache-type=memcached",
385+ "--web-server-type=apache",
386+ "--web-server-port=80",
387+ "--python-loader=wsgi",
388+ "--admin-user=admin",
389+ "--admin-password=a-password",
390+ "/var/www/reviewboard"]
391+
392+ self.assertEqual(full_command_args, args_list[0])
393+
394+
395+class ConfigureApache2Test(unittest.TestCase):
396+
397+ def setUp(self):
398+ super(ConfigureApache2Test, self).setUp()
399+ log_patcher = patch("charmhelpers.core.hookenv.log")
400+ self.mock_log = log_patcher.start()
401+ self.addCleanup(log_patcher.stop)
402+
403+ call_patcher = patch("subprocess.check_call")
404+ self.mock_call = call_patcher.start()
405+ self.addCleanup(call_patcher.stop)
406+
407+ restart_patcher = patch("hooks.service_restart")
408+ self.mock_restart = restart_patcher.start()
409+ self.addCleanup(restart_patcher.stop)
410+
411+ def test_copies_wsgi_conf(self):
412+ hooks.configure_apache2()
413+ self.mock_call.assert_any_call(
414+ ["cp", "/var/www/reviewboard/conf/apache-wsgi.conf",
415+ "/etc/apache2/sites-available/reviewboard.conf"])
416+
417+ def test_disables_default_site(self):
418+ hooks.configure_apache2()
419+ self.mock_call.assert_any_call(["a2dissite", "000-default"])
420+
421+ def test_enables_reviewboard_site(self):
422+ hooks.configure_apache2()
423+ self.mock_call.assert_any_call(["a2ensite", "reviewboard.conf"])
424+
425+ def test_chowns_dirs(self):
426+ hooks.configure_apache2()
427+ for leaf in ["htdocs/media/uploaded", "htdocs/media/ext",
428+ "htdocs/static/ext", "data"]:
429+ self.mock_call.assert_any_call(
430+ ["chown", "-R", "www-data", "/var/www/reviewboard/%s" % leaf])
431+
432+ def test_restarts_apache2(self):
433+ hooks.configure_apache2()
434+ self.mock_restart.assert_called_with("apache2")
435+
436+ def test_log_confirmation(self):
437+ hooks.configure_apache2()
438+ self.mock_log.assert_called_with("Apache configured!")
439+ self.mock_log.assert_any_call("Configuring Apache...")
440+
441+
442+class DbRelationJoinedTest(unittest.TestCase):
443+
444+ @patch('charmhelpers.core.hookenv.relation_set')
445+ def test_requests_database(self, mock_relation_set):
446+ hooks.db_relation_joined()
447+ mock_relation_set.assert_called_with(
448+ relation_settings={"database": "reviewboard"})
449+
450+
451+class DbRelationChangedTest(unittest.TestCase):
452+
453+ @patch('hooks.is_rb_site_installed')
454+ @patch('hooks.install_rb_site')
455+ @patch('hooks.configure_apache2')
456+ def test_configures_apache2_if_rb_needs_installing(
457+ self, mock_configure, mock_install, mock_installed):
458+
459+ def mock_installed_side_effect():
460+ mock_installed.side_effect = lambda: True
461+ return False
462+
463+ mock_installed.side_effect = mock_installed_side_effect
464+ mock_install.return_value = True
465+ hooks.db_relation_changed()
466+ mock_install.assert_called_with()
467+ mock_configure.assert_called_with()
468+
469+ @patch('hooks.is_rb_site_installed')
470+ @patch('hooks.configure_apache2')
471+ def test_configures_apache2_if_rb_already_installed(
472+ self, mock_configure, mock_installed):
473+ mock_installed.return_value = True
474+ hooks.db_relation_changed()
475+ mock_configure.assert_called_with()
476+
477+
478+class WebsiteRelationJoinedTest(unittest.TestCase):
479+
480+ @patch('charmhelpers.core.hookenv.unit_get')
481+ @patch('charmhelpers.core.hookenv.relation_set')
482+ def test_requests_database(self, mock_relation_set, mock_unit_get):
483+ mock_unit_get.return_value = "127.0.0.1"
484+ hooks.website_relation_joined()
485+ mock_relation_set.assert_called_with(
486+ relation_settings={"hostname": "127.0.0.1", "port": 80})
487+
488+
489+class ConfigChangedTest(unittest.TestCase):
490+
491+ def setUp(self):
492+ super(ConfigChangedTest, self).setUp()
493+ config_patcher = patch("charmhelpers.core.hookenv.config")
494+ self.mock_config = config_patcher.start()
495+ self.mock_config.return_value = {}
496+ self.addCleanup(config_patcher.stop)
497+
498+ @contextmanager
499+ def _fake_django_environ():
500+ yield
501+
502+ @patch('hooks.is_rb_site_installed')
503+ @patch('hooks.install_rb_site')
504+ @patch('hooks.configure_apache2')
505+ def test_configures_apache2_if_rb_needs_installing(
506+ self, mock_configure, mock_install, mock_installed):
507+
508+ def mock_installed_side_effect():
509+ mock_installed.side_effect = lambda: True
510+ return False
511+
512+ mock_installed.side_effect = mock_installed_side_effect
513+ mock_install.return_value = True
514+ hooks.config_changed()
515+ mock_install.assert_called_with()
516+ mock_configure.assert_called_with()
517+
518+ @patch('hooks.is_rb_site_installed')
519+ @patch('hooks.configure_apache2')
520+ def test_configures_apache2_if_rb_already_installed(
521+ self, mock_configure, mock_installed):
522+ mock_installed.return_value = True
523+ hooks.config_changed()
524+ mock_configure.assert_called_with()
525+
526+ @patch('hooks.is_rb_site_installed')
527+ @patch('hooks.configure_apache2')
528+ @patch('hooks._django_environ', _fake_django_environ)
529+ @patch("django.contrib.auth.management.commands.changepassword.Command")
530+ def test_changes_password_for_admin_user(
531+ self, mock_command, mock_configure, mock_installed):
532+ mock_installed.return_value = True
533+ self.mock_config.return_value = {"admin-password": "a-password"}
534+ instance = mock_command.return_value
535+ hooks.config_changed()
536+ instance.execute.assert_called_with("admin")
537+ self.assertEqual(instance._get_pass(), "a-password")
538+
539+ @patch('hooks.is_rb_site_installed')
540+ @patch('hooks.configure_apache2')
541+ @patch('hooks._django_environ', _fake_django_environ)
542+ @patch("django.contrib.sites.models.Site")
543+ def test_changes_host(self, mock_site, mock_configure, mock_installed):
544+ mock_installed.return_value = True
545+ self.mock_config.return_value = {"host": "rb.example.com"}
546+ instance = mock_site.objects.get_current.return_value
547+ hooks.config_changed()
548+ instance.save.assert_called_with()
549+ self.assertEqual(instance.domain, "rb.example.com")
550+
551+ @patch('hooks.is_rb_site_installed')
552+ @patch('hooks.configure_apache2')
553+ @patch('charmhelpers.core.hookenv.unit_get')
554+ @patch('hooks._django_environ', _fake_django_environ)
555+ @patch("django.contrib.sites.models.Site")
556+ def test_localhost_means_public_address(
557+ self, mock_site, mock_unit_get, mock_configure, mock_installed):
558+ mock_installed.return_value = True
559+ self.mock_config.return_value = {"host": "localhost"}
560+ mock_unit_get.return_value = "8.8.8.8"
561+ instance = mock_site.objects.get_current.return_value
562+ hooks.config_changed()
563+ instance.save.assert_called_with()
564+ self.assertEqual(instance.domain, "8.8.8.8")
565+
566+
567+class InstallTest(unittest.TestCase):
568+
569+ def setUp(self):
570+ super(InstallTest, self).setUp()
571+ log_patcher = patch("charmhelpers.core.hookenv.log")
572+ self.mock_log = log_patcher.start()
573+ self.addCleanup(log_patcher.stop)
574+
575+ update_patcher = patch("hooks.apt_update")
576+ self.mock_update = update_patcher.start()
577+ self.addCleanup(update_patcher.stop)
578+
579+ install_patcher = patch("hooks.apt_install")
580+ self.mock_install = install_patcher.start()
581+ self.addCleanup(install_patcher.stop)
582+
583+ call_patcher = patch("subprocess.check_call")
584+ self.mock_call = call_patcher.start()
585+ self.addCleanup(call_patcher.stop)
586+
587+ def test_apt_packages(self):
588+ hooks.install()
589+ self.mock_install.assert_called_with(
590+ ["apache2-mpm-prefork",
591+ "libapache2-mod-wsgi",
592+ "python-setuptools",
593+ "python-dev",
594+ "memcached",
595+ "python-memcache",
596+ "patch",
597+ "python-psycopg2"], fatal=True)
598+
599+ def test_apt_update(self):
600+ hooks.install()
601+ self.mock_update.assert_called_with(fatal=True)
602+
603+ def test_easy_install(self):
604+ hooks.install()
605+ self.mock_call.assert_called_with(["easy_install", "ReviewBoard"])
606+
607+ def test_log(self):
608+ hooks.install()
609+ self.mock_log.assert_called_with("Installing ReviewBoard")
610+
611+
612+class StartTest(unittest.TestCase):
613+
614+ @patch("hooks.service_restart")
615+ @patch('charmhelpers.core.hookenv.open_port')
616+ def test_restarts_apache(self, mock_open_port, mock_restart):
617+ hooks.start()
618+ mock_restart.assert_called_with("apache2")
619+
620+ @patch("hooks.service_restart")
621+ @patch('charmhelpers.core.hookenv.open_port')
622+ def test_opens_port_80(self, mock_open_port, mock_restart):
623+ hooks.start()
624+ mock_open_port.assert_called_with(80)
625+
626+
627+class StopTest(unittest.TestCase):
628+
629+ @patch("hooks.service_stop")
630+ @patch('charmhelpers.core.hookenv.close_port')
631+ def test_stops_apache(self, mock_close_port, mock_stop):
632+ hooks.stop()
633+ mock_stop.assert_called_with("apache2")
634+
635+ @patch("hooks.service_stop")
636+ @patch('charmhelpers.core.hookenv.close_port')
637+ def test_closes_port_80(self, mock_close_port, mock_stop):
638+ hooks.stop()
639+ mock_close_port.assert_called_with(80)
640+
641+
642+class MainTest(unittest.TestCase):
643+
644+ @patch("hooks.hooks")
645+ def test_executes_sys_argv(self, mock_hooks):
646+ hooks.main(["arg", "v"])
647+ mock_hooks.execute.assert_called_with(["arg", "v"])
648+
649+ @patch("hooks.hooks")
650+ @patch("charmhelpers.core.hookenv.log")
651+ def test_logs_about_unknown_hooks(self, mock_log, mock_hooks):
652+ mock_hooks.execute.side_effect =\
653+ hooks.hookenv.UnregisteredHookError("missing-hook")
654+ hooks.main(["arg", "v"])
655+ mock_log.assert_called_with("Unknown hook missing-hook - skipping.")

Subscribers

People subscribed via source and target branches

to all changes: