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

Subscribers

People subscribed via source and target branches

to all changes: