Merge ~barryprice/charm-k8s-wordpress/+git/charm-k8s-wordpress:master into charm-k8s-wordpress:master

Proposed by Barry Price
Status: Merged
Approved by: Barry Price
Approved revision: 410a1bbd10ce135917e4518ed6c86f9df763fefa
Merged at revision: 876bb9c7d963f549def98bf9631d797c6da0e69e
Proposed branch: ~barryprice/charm-k8s-wordpress/+git/charm-k8s-wordpress:master
Merge into: charm-k8s-wordpress:master
Diff against target: 192 lines (+138/-3)
6 files modified
Makefile (+19/-2)
reactive/wordpress.py (+1/-1)
requirements.txt (+2/-0)
tests/unit/requirements.txt (+7/-0)
tests/unit/test_wordpress.py (+64/-0)
tox.ini (+45/-0)
Reviewer Review Type Date Requested Status
Stuart Bishop (community) Approve
Canonical IS Reviewers Pending
Review via email: mp+376327@code.launchpad.net

Commit message

Set up our first basic unit test

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Tom Haddon (mthaddon) wrote :

Let's switch to using tox targets for lint

Revision history for this message
Stuart Bishop (stub) wrote :

Looks good. Makefile lint target needs to call the tox rule you have created, per Tom's comment.

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 876bb9c7d963f549def98bf9631d797c6da0e69e

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/Makefile b/Makefile
2index 6dc2159..a46c2e2 100644
3--- a/Makefile
4+++ b/Makefile
5@@ -1,6 +1,23 @@
6 lint:
7- black -l 120 -t py37 reactive/
8- flake8 reactive/
9+ @echo "Normalising python layout with black."
10+ @tox -e black
11+ @echo "Running flake8"
12+ @tox -e lint
13+
14+unittest:
15+ @tox -e unit
16+
17+test: lint unittest
18
19 build: lint
20 charm build
21+
22+clean:
23+ @echo "Cleaning files"
24+ @rm -rf ./.tox
25+ @rm -rf ./.pytest_cache
26+ @rm -rf ./tests/unit/__pycache__ ./reactive/__pycache__ ./lib/__pycache__
27+ @rm -rf ./.coverage ./.unit-state.db
28+
29+
30+.PHONY: lint test unittest build clean
31diff --git a/reactive/wordpress.py b/reactive/wordpress.py
32index ededd46..39ea6dc 100644
33--- a/reactive/wordpress.py
34+++ b/reactive/wordpress.py
35@@ -14,6 +14,7 @@ from charms.reactive import hook, when, when_not
36
37 @hook("upgrade-charm")
38 def upgrade_charm():
39+ status.maintenance("maintenance", "Upgrading charm")
40 reactive.clear_flag("wordpress.configured")
41
42
43@@ -136,7 +137,6 @@ def first_install():
44 hookenv.log("No initial_setting provided or wordpress already configured. Skipping first install.")
45 return True
46 hookenv.log("Starting wordpress initial configuration")
47- # TODO: more of the below ought to be configurable
48 payload = {"admin_password": host.pwgen(24), "blog_public": "checked", "Submit": "submit"}
49 payload.update(safe_load(config["initial_settings"]))
50 payload["admin_password2"] = payload["admin_password"]
51diff --git a/requirements.txt b/requirements.txt
52new file mode 100644
53index 0000000..888e37a
54--- /dev/null
55+++ b/requirements.txt
56@@ -0,0 +1,2 @@
57+# Include python requirements here
58+requests
59diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt
60new file mode 100644
61index 0000000..2d27572
62--- /dev/null
63+++ b/tests/unit/requirements.txt
64@@ -0,0 +1,7 @@
65+requests
66+charmhelpers
67+charms.reactive
68+freezegun
69+mock
70+pytest
71+pytest-cov
72diff --git a/tests/unit/test_wordpress.py b/tests/unit/test_wordpress.py
73new file mode 100644
74index 0000000..5ade069
75--- /dev/null
76+++ b/tests/unit/test_wordpress.py
77@@ -0,0 +1,64 @@
78+import os
79+import shutil
80+import sys
81+import tempfile
82+import unittest
83+from unittest import mock
84+
85+# We also need to mock up charms.layer so we can run unit tests without having
86+# to build the charm and pull in layers such as layer-status.
87+sys.modules['charms.layer'] = mock.MagicMock()
88+
89+from charms.layer import status # NOQA: E402
90+
91+# Add path to where our reactive layer lives and import.
92+sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
93+from reactive import wordpress # NOQA: E402
94+
95+
96+class TestCharm(unittest.TestCase):
97+ def setUp(self):
98+ self.maxDiff = None
99+ self.tmpdir = tempfile.mkdtemp(prefix='charm-unittests-')
100+ self.addCleanup(shutil.rmtree, self.tmpdir)
101+
102+ self.charm_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
103+
104+ patcher = mock.patch('charmhelpers.core.hookenv.log')
105+ self.mock_log = patcher.start()
106+ self.addCleanup(patcher.stop)
107+ self.mock_log.return_value = ''
108+
109+ patcher = mock.patch('charmhelpers.core.hookenv.charm_dir')
110+ self.mock_charm_dir = patcher.start()
111+ self.addCleanup(patcher.stop)
112+ self.mock_charm_dir.return_value = self.charm_dir
113+
114+ patcher = mock.patch('charmhelpers.core.hookenv.local_unit')
115+ self.mock_local_unit = patcher.start()
116+ self.addCleanup(patcher.stop)
117+ self.mock_local_unit.return_value = 'mock-wordpress/0'
118+
119+ patcher = mock.patch('charmhelpers.core.hookenv.config')
120+ self.mock_config = patcher.start()
121+ self.addCleanup(patcher.stop)
122+ self.mock_config.return_value = {'blog_hostname': 'myblog.example.com'}
123+
124+ patcher = mock.patch('charmhelpers.core.host.log')
125+ self.mock_log = patcher.start()
126+ self.addCleanup(patcher.stop)
127+ self.mock_log.return_value = ''
128+
129+ status.active.reset_mock()
130+ status.blocked.reset_mock()
131+ status.maintenance.reset_mock()
132+
133+ @mock.patch('charms.reactive.clear_flag')
134+ def test_hook_upgrade_charm_flags(self, clear_flag):
135+ '''Test correct flags set via upgrade-charm hook'''
136+ wordpress.upgrade_charm()
137+ self.assertFalse(status.maintenance.assert_called())
138+ want = [
139+ mock.call('wordpress.configured'),
140+ ]
141+ self.assertFalse(clear_flag.assert_has_calls(want, any_order=True))
142diff --git a/tox.ini b/tox.ini
143new file mode 100644
144index 0000000..7b45934
145--- /dev/null
146+++ b/tox.ini
147@@ -0,0 +1,45 @@
148+[tox]
149+skipsdist=True
150+envlist = unit, functional
151+skip_missing_interpreters = True
152+
153+[testenv]
154+basepython = python3
155+setenv =
156+ PYTHONPATH = .
157+
158+[testenv:unit]
159+commands =
160+ pytest --ignore {toxinidir}/tests/functional \
161+ {posargs:-v --cov=reactive --cov-report=term-missing --cov-branch}
162+deps = -r{toxinidir}/tests/unit/requirements.txt
163+ -r{toxinidir}/requirements.txt
164+setenv =
165+ PYTHONPATH={toxinidir}/lib
166+ TZ=UTC
167+
168+[testenv:functional]
169+passenv =
170+ HOME
171+ JUJU_REPOSITORY
172+ PATH
173+commands =
174+ pytest -v --ignore {toxinidir}/tests/unit {posargs}
175+deps = -r{toxinidir}/tests/functional/requirements.txt
176+ -r{toxinidir}/requirements.txt
177+
178+[testenv:black]
179+commands = black --skip-string-normalization --line-length=120 .
180+deps = black
181+
182+[testenv:lint]
183+commands = flake8
184+deps = flake8
185+
186+[flake8]
187+exclude =
188+ .git,
189+ __pycache__,
190+ .tox,
191+max-line-length = 120
192+max-complexity = 10

Subscribers

People subscribed via source and target branches