Merge lp:~marcoceppi/charms/precise/chamilo/unit-tests into lp:~johnsca/charms/precise/chamilo/services-framework

Proposed by Marco Ceppi
Status: Merged
Merged at revision: 12
Proposed branch: lp:~marcoceppi/charms/precise/chamilo/unit-tests
Merge into: lp:~johnsca/charms/precise/chamilo/services-framework
Diff against target: 268 lines (+191/-26)
5 files modified
.bzrignore (+3/-0)
Makefile (+60/-0)
hooks/actions.py (+27/-25)
hooks/services.py (+2/-1)
tests/test_actions.py (+99/-0)
To merge this branch: bzr merge lp:~marcoceppi/charms/precise/chamilo/unit-tests
Reviewer Review Type Date Requested Status
Cory Johns Pending
Review via email: mp+234000@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2014-09-09 20:31:25 +0000
4@@ -0,0 +1,3 @@
5+venv
6+*.pyc
7+.coverage
8
9=== added file 'Makefile'
10--- Makefile 1970-01-01 00:00:00 +0000
11+++ Makefile 2014-09-09 20:31:25 +0000
12@@ -0,0 +1,60 @@
13+PY := venv/bin/python
14+# If the bin version does not exist look in venv/local/bin
15+ifeq ($(wildcard venv/bin/pip),)
16+ PIP = venv/local/bin/pip
17+else
18+ PIP = venv/bin/pip
19+endif
20+# If the bin version does not exist look in venv/local/bin
21+NOSE = venv/bin/nosetests
22+# ###########
23+# Build
24+# ###########
25+
26+.PHONY: install
27+install: venv test_deps
28+
29+venv: $(PY)
30+$(PY):
31+ virtualenv venv
32+
33+test_deps: $(PY)
34+ $(PIP) install nose coverage mock pyyaml -e bzr+lp:~johnsca/charm-helpers/contexts#egg=charmhelpers
35+
36+.PHONY: clean_all
37+clean_all: clean clean_venv clean_db
38+
39+.PHONY: clean_venv
40+clean_venv:
41+ rm -rf venv
42+
43+.PHONY: clean
44+clean:
45+ find . -name '*.pyc' -delete
46+ find . -name '*.bak' -delete
47+ rm -f .coverage
48+
49+.PHONY: sysdeps
50+sysdeps:
51+ sudo apt-get $(shell tty -s || echo -y) install python3-dev virtualenv
52+
53+.PHONY: test
54+test: unit_test
55+
56+unit_test: $(NOSE)
57+ @$(NOSE) --nologcapture
58+
59+.PHONY: coverage
60+coverage: $(NOSE)
61+ @echo Testing with coverage...
62+ @$(NOSE) --nologcapture --with-coverage --cover-package=hooks
63+
64+.PHONY: lint
65+lint:
66+ @find $(sources) -type f \( -iname '*.py' ! -iname '__init__.py' ! -iwholename '*venv/*' \) -print0 | xargs -r0 flake8
67+
68+.PHONY: check
69+check: test lint
70+
71+.PHONY: all
72+all: clean venv coverage lint
73
74=== added file 'hooks/__init__.py'
75=== modified file 'hooks/actions.py'
76--- hooks/actions.py 2014-09-09 16:51:01 +0000
77+++ hooks/actions.py 2014-09-09 20:31:25 +0000
78@@ -1,4 +1,5 @@
79 import subprocess
80+
81 from charmhelpers.core import hookenv
82 from charmhelpers.core.services import helpers
83
84@@ -10,15 +11,10 @@
85 config = hookenv.config()
86 if config.previous('db_initialized'):
87 return
88+
89 mysql = helpers.MysqlRelation()[0]['mysql']
90 with open('data/chamilo-default-db.sql') as sql:
91- subprocess.check_call([
92- 'mysql',
93- '-u{}'.format(mysql['user']),
94- '-p{}'.format(mysql['password']),
95- '-h', mysql['host'],
96- mysql['database'],
97- ], stdin=sql)
98+ exec_sql(sql, mysql)
99 config['db_initialized'] = True
100 config.save()
101
102@@ -30,23 +26,29 @@
103 config = hookenv.config()
104 mysql = helpers.MysqlRelation()[0]['mysql']
105 if config.changed('user'):
106- subprocess.check_call([
107- 'mysql',
108- '-u{}'.format(mysql['user']),
109- '-p{}'.format(mysql['password']),
110- '-h', mysql['host'],
111- mysql['database'],
112- '-e', "UPDATE user SET username = '%s' "
113- "WHERE user_id = 1;".format(config['user']),
114- ])
115+ exec_sql("UPDATE user SET username = '%s' "
116+ "WHERE user_id = 1;".format(config['user']), mysql)
117
118 if config.changed('pass'):
119- subprocess.check_call([
120- 'mysql',
121- '-u{}'.format(mysql['user']),
122- '-p{}'.format(mysql['password']),
123- '-h', mysql['host'],
124- mysql['database'],
125- '-e', "UPDATE user SET password = SHA1('{}') "
126- "WHERE user_id = 1;".format(config['pass']),
127- ])
128+ exec_sql("UPDATE user SET password = SHA1('{}') "
129+ "WHERE user_id = 1;".format(config['pass']), mysql)
130+
131+
132+def exec_sql(sql, mysql_cfg):
133+ """
134+ Execute SQL against a MySQL instance
135+ """
136+ sql_cmd = [
137+ 'mysql',
138+ '-u{}'.format(mysql_cfg['user']),
139+ '-p{}'.format(mysql_cfg['password']),
140+ '-h', mysql_cfg['host'],
141+ mysql_cfg['database'],
142+ ]
143+
144+ if not hasattr(sql, 'read'):
145+ sql_cmd.extend(['-e', sql])
146+ stdin = None
147+ else:
148+ stdin = sql
149+ subprocess.check_call(sql_cmd, stdin=stdin)
150
151=== modified file 'hooks/services.py'
152--- hooks/services.py 2014-09-09 16:51:01 +0000
153+++ hooks/services.py 2014-09-09 20:31:25 +0000
154@@ -24,7 +24,8 @@
155 ],
156 'data_ready': [
157 helpers.render_template(source='data/configuration.php',
158- target='/var/www/main/inc/conf/configuration.php'),
159+ target="/var/www/main/inc/conf/"
160+ "configuration.php"),
161 actions.init_database,
162 actions.update_admin_account,
163 ],
164
165=== added directory 'tests'
166=== added file 'tests/test_actions.py'
167--- tests/test_actions.py 1970-01-01 00:00:00 +0000
168+++ tests/test_actions.py 2014-09-09 20:31:25 +0000
169@@ -0,0 +1,99 @@
170+import os
171+import shutil
172+import tempfile
173+import unittest
174+import StringIO
175+import contextlib
176+
177+from mock import patch
178+from hooks import actions
179+
180+from charmhelpers.core.hookenv import Config
181+
182+MYSQL_CFG = {
183+ 'user': '__user',
184+ 'password': 'pass',
185+ 'host': '0.0.0.0',
186+ 'port': 3306,
187+ 'database': 'test'
188+}
189+
190+
191+@contextlib.contextmanager
192+def charm_dir():
193+ temp_dir = tempfile.mkdtemp()
194+ with patch.dict(os.environ, {'CHARM_DIR': temp_dir}):
195+ yield
196+ shutil.rmtree(temp_dir)
197+
198+
199+class TestHelpers(unittest.TestCase):
200+ @patch('hooks.actions.subprocess.check_call')
201+ def test_exec_sql_string(self, mchk):
202+ actions.exec_sql('SELECT * FROM Something', MYSQL_CFG)
203+ mchk.assert_called_with([
204+ 'mysql',
205+ '-u__user',
206+ '-ppass',
207+ '-h', '0.0.0.0',
208+ 'test',
209+ '-e', 'SELECT * FROM Something',
210+ ], stdin=None)
211+
212+ @patch('hooks.actions.subprocess.check_call')
213+ def test_exec_sql_file(self, mchk):
214+ sql_file = StringIO.StringIO('SELECT * FROM Something')
215+ actions.exec_sql(sql_file, MYSQL_CFG)
216+ mchk.assert_called_with([
217+ 'mysql',
218+ '-u__user',
219+ '-ppass',
220+ '-h', '0.0.0.0',
221+ 'test',
222+ ], stdin=sql_file)
223+
224+ @patch('hooks.actions.hookenv.config')
225+ def test_init_database_initd(self, mcfg):
226+ sql_file = StringIO.StringIO('SELECT * FROM Something')
227+
228+ with charm_dir():
229+ config = Config()
230+ config._prev_dict = {'db_initialized': True}
231+ mcfg.return_value = config
232+ actions.init_database('foo')
233+
234+ @patch('hooks.actions.hookenv.config')
235+ @patch('hooks.actions.helpers.MysqlRelation')
236+ @patch('hooks.actions.exec_sql')
237+ def test_init_database(self, mexc, mrel, mcfg):
238+ mrel.return_value = [{'mysql': MYSQL_CFG}]
239+
240+ with charm_dir():
241+ mcfg.return_value = Config()
242+ actions.init_database('foo')
243+ self.assertEqual(True, mcfg.return_value['db_initialized'])
244+ mexc.assert_called_once()
245+
246+ @patch('hooks.actions.hookenv.config')
247+ @patch('hooks.actions.helpers.MysqlRelation')
248+ @patch('hooks.actions.exec_sql')
249+ def test_uodate_admin_acct(self, mexc, mrel, mcfg):
250+ mrel.return_value = [{'mysql': MYSQL_CFG}]
251+
252+ with charm_dir():
253+ mcfg.return_value = Config({'user': 'what', 'pass': 'going on'})
254+ actions.update_admin_account('foo')
255+ mexc.assert_not_called()
256+
257+ @patch('hooks.actions.hookenv.config')
258+ @patch('hooks.actions.helpers.MysqlRelation')
259+ @patch('hooks.actions.exec_sql')
260+ def test_uodate_admin_no_change(self, mexc, mrel, mcfg):
261+ mrel.return_value = [{'mysql': MYSQL_CFG}]
262+
263+ with charm_dir():
264+ config = Config({'pass': 'hey', 'user': 'hey'})
265+ config._prev_dict = {'pass': 'hey', 'user': 'hey'}
266+ mcfg.return_value = config
267+ actions.init_database('foo')
268+ mexc.assert_called()

Subscribers

People subscribed via source and target branches