Merge lp:~lazypower/charms/precise/mediawiki/tests into lp:charms/mediawiki

Proposed by Charles Butler
Status: Merged
Merged at revision: 74
Proposed branch: lp:~lazypower/charms/precise/mediawiki/tests
Merge into: lp:charms/mediawiki
Diff against target: 254 lines (+109/-117)
5 files modified
hooks/config-changed (+13/-9)
tests/00_setup.sh (+13/-0)
tests/100-deploy (+83/-0)
tests/100_deploy.test (+0/-62)
tests/get-unit-info (+0/-46)
To merge this branch: bzr merge lp:~lazypower/charms/precise/mediawiki/tests
Reviewer Review Type Date Requested Status
charmers Pending
Review via email: mp+202112@code.launchpad.net

Description of the change

Testing

Adds integration tests for unit deploy, db relationship with mysql, and cache relationship with memcached

https://codereview.appspot.com/54600043/

To post a comment you must log in.
Revision history for this message
Charles Butler (lazypower) wrote :

Reviewers: mp+202112_code.launchpad.net,

Message:
Please take a look.

Description:

Adds integration tests for unit deploy, db relationship with mysql, and
cache relationship with memcached

https://code.launchpad.net/~lazypower/charms/precise/mediawiki/tests/+merge/202112

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/54600043/

Affected files (+270, -4 lines):
   A [revision details]
   M hooks/config-changed
   A tests/00_setup.sh
   A tests/00_setup.sh.moved
   A tests/01_deploy_test.py
   M tests/100_deploy.test
   A tests/100_deploy_cloud.test
   A tests/100_deploy_with_memcached.test
   A tests/10_cache_relation_test.py
   A tests/10_db_relation_test.py
   A tests/__init__.py
   A tests/__init__.py.moved
   A tests/lib.moved/__init__.py
   A tests/lib.moved/helper.py
   A tests/lib/__init__.py
   A tests/lib/helper.py

Revision history for this message
Benjamin Saller (bcsaller) wrote :

Thanks for this. I had a number of suggestions. Also if those .moved
files are in the repo that needs to be taken care of. After that is done
can you re-propose and I can approve it

https://codereview.appspot.com/54600043/diff/1/tests/00_setup.sh.moved
File tests/00_setup.sh.moved (right):

https://codereview.appspot.com/54600043/diff/1/tests/00_setup.sh.moved#newcode3
tests/00_setup.sh.moved:3: sudo apt-get install install amulet
python-requests
This file appears to be an artifact of some bzr op and should be removed

https://codereview.appspot.com/54600043/diff/1/tests/100_deploy_cloud.test
File tests/100_deploy_cloud.test (right):

https://codereview.appspot.com/54600043/diff/1/tests/100_deploy_cloud.test#newcode33
tests/100_deploy_cloud.test:33: search_term =
"\"{}\";".format(mysql_unit.info['public-address'])
Minor but its usually better to use single quotes for the string rather
than escape as the result is more readable

'"{}";'.format(...)

https://codereview.appspot.com/54600043/diff/1/tests/10_cache_relation_test.py
File tests/10_cache_relation_test.py (right):

https://codereview.appspot.com/54600043/diff/1/tests/10_cache_relation_test.py#newcode16
tests/10_cache_relation_test.py:16: # Add mediawiki and mysql db server
This file and the 100_deploy_with_memcache seem redundant. Given that
theses tests are not free we should remove one.

In general for functional tests with spin up times I prefer to assert as
much as possible in a single test. As long as you don't depend on state
manipulation beyond the initial setup that is fine.

https://codereview.appspot.com/54600043/diff/1/tests/10_db_relation_test.py
File tests/10_db_relation_test.py (right):

https://codereview.appspot.com/54600043/diff/1/tests/10_db_relation_test.py#newcode32
tests/10_db_relation_test.py:32:
Again this test is very similar to the deploy_cloud test. Is there a
reason to have twice as much code at twice the runtime cost? Can we
combine theses?

https://codereview.appspot.com/54600043/diff/1/tests/lib/helper.py
File tests/lib/helper.py (right):

https://codereview.appspot.com/54600043/diff/1/tests/lib/helper.py#newcode7
tests/lib/helper.py:7: 'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*',
as a style point defining this above the method as

LOGIN_HEADERS = {
...
}

can save you some indentation space and make things a little easier to
read.

https://codereview.appspot.com/54600043/diff/1/tests/lib/helper.py#newcode15
tests/lib/helper.py:15: def standup_unit(deployment, seconds=900):
deploy as a name? This could bring up more than one unit, no?

https://codereview.appspot.com/54600043/

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

I took a look at these changes and I give it a +1 on my review.

Revision history for this message
Benjamin Saller (bcsaller) wrote :

LGTM

Thanks for the improvements, this version looked much cleaner than the
last.

https://codereview.appspot.com/54600043/

Revision history for this message
Marco Ceppi (marcoceppi) wrote :

See below, LGTM otherwise.

https://codereview.appspot.com/54600043/diff/20001/tests/00_setup.sh
File tests/00_setup.sh (right):

https://codereview.appspot.com/54600043/diff/20001/tests/00_setup.sh#newcode3
tests/00_setup.sh:3: sudo apt-get install install amulet python-requests
This doesn't actually work

https://codereview.appspot.com/54600043/

Revision history for this message
Charles Butler (lazypower) wrote :
Revision history for this message
Peter Petrakis (peter-petrakis) wrote :

On 2014/02/14 21:22:07, lazypower wrote:
> Please take a look.

New to this service, so old school for now:

=== modified file 'hooks/config-changed'
--- hooks/config-changed 2012-06-28 00:01:31 +0000
+++ hooks/config-changed 2014-01-20 05:33:44 +0000
@@ -59,12 +59,16 @@

...
+
+#added to prevent failure when no db relationship exists
+if [ -f /etc/mediawiki/LocalSettings.php ]; then
+ for admin in $admins ; do
+ user=`echo $admin | cut -d: -f1`
+ pass=`echo $admin | cut -d: -f2`

If "admins" is empty this will happily work, the pipe to cut will not
error. In this case I would
exit 1 with meaningful juju-log message.

+ output=`php createAndPromote.php --conf
/etc/mediawiki/LocalSettings.php $user $pass`
+ if [ ! "$output" = "account exists." ] ; then
+ echo $output
+ exit 1
+ fi
+ done
+fi

=== added file 'tests/100-deploy'
--- tests/100-deploy 1970-01-01 00:00:00 +0000
+++ tests/100-deploy 2014-02-14 21:21:50 +0000
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+import amulet
+from splinter import Browser
+
+seconds = 900
+
+d = amulet.Deployment()
+
+#Setup the charms, and relationships

Inconsistent comment pattern, should have a space between hash and
string

+# Perform the setup for the deployment.
+try:
+ d.setup(seconds)
+ #pings every deployed unit
+ d.sentry.wait(seconds)

Same pattern. Also uppercase or lower case for sentence start, either is
fine just be consistent.

=== added file 'tests/100-deploy'
--- tests/100-deploy 1970-01-01 00:00:00 +0000
+++ tests/100-deploy 2014-02-14 21:21:50 +0000
...
+# Validate that the database server was set for the configuration of
MediaWiki
+#Set search term for comparison, and cache the flag in the
configuration file
+output, code = mw_unit.run("cat /etc/mediawiki/LocalSettings.php \
+ | grep wgDBserver | awk '{printf $3}'")

You can do that entirely in awk, something like awk '/wgDBserver/ &&
printf $3' FILE. If you're so inclined.

...
+memcached_relation = d.sentry.unit['memcached/0'].relation(
+ 'cache', 'mediawiki:cache')
+output, code = mw_unit.run("cat /etc/mediawiki/memcached_settings.php \
+ | grep wgMemCachedServers | tr -d \'array\(\)\; | awk '{printf
$3}'")

Just call grep or not, arguably a style call, keeping the file to be
worked on
as the first argument.

=== removed file 'tests/100_deploy.test'
--- tests/100_deploy.test 2012-01-31 01:27:17 +0000
+++ tests/100_deploy.test 1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-#!/bin/sh
-
-if [ -z "`which wget`" ] ; then
- echo SKIP: need wget to run test.
- exit 100
-fi

I know this was removed but...
backticks are typically used in in bash shell, $() in bash scripts.
Tough habit to break.

https://codereview.appspot.com/54600043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/config-changed'
2--- hooks/config-changed 2012-06-28 00:01:31 +0000
3+++ hooks/config-changed 2014-02-14 21:21:57 +0000
4@@ -59,12 +59,16 @@
5 [ ! -f $cfile.old ] || rm $cfile.old
6
7 cd /usr/share/mediawiki/maintenance
8-for admin in $admins ; do
9- user=`echo $admin | cut -d: -f1`
10- pass=`echo $admin | cut -d: -f2`
11- output=`php createAndPromote.php --conf /etc/mediawiki/LocalSettings.php $user $pass`
12- if [ ! "$output" = "account exists." ] ; then
13- echo $output
14- exit 1
15- fi
16-done
17+
18+#added to prevent failure when no db relationship exists
19+if [ -f /etc/mediawiki/LocalSettings.php ]; then
20+ for admin in $admins ; do
21+ user=`echo $admin | cut -d: -f1`
22+ pass=`echo $admin | cut -d: -f2`
23+ output=`php createAndPromote.php --conf /etc/mediawiki/LocalSettings.php $user $pass`
24+ if [ ! "$output" = "account exists." ] ; then
25+ echo $output
26+ exit 1
27+ fi
28+ done
29+fi
30
31=== added file 'tests/00_setup.sh'
32--- tests/00_setup.sh 1970-01-01 00:00:00 +0000
33+++ tests/00_setup.sh 2014-02-14 21:21:57 +0000
34@@ -0,0 +1,13 @@
35+#!/bin/bash
36+
37+#TODO: Some of the python3 packs may not be available in precise.
38+
39+apt-get install python3-setuptools -y
40+
41+apt-add-repository ppa:juju/stable -y
42+apt-get update
43+
44+#I have no idea if this is running via python2 or python3, so fetch both
45+# copies of the requests lib
46+apt-get install juju amulet python3 python3-requests python3-pip phantomjs -y
47+pip3 install splinter selenium
48\ No newline at end of file
49
50=== added file 'tests/100-deploy'
51--- tests/100-deploy 1970-01-01 00:00:00 +0000
52+++ tests/100-deploy 2014-02-14 21:21:57 +0000
53@@ -0,0 +1,83 @@
54+#!/usr/bin/env python3
55+import amulet
56+from splinter import Browser
57+
58+seconds = 900
59+
60+d = amulet.Deployment()
61+
62+#Setup the charms, and relationships
63+d.add('mysql')
64+d.add('memcached')
65+d.add('mediawiki')
66+d.configure('mediawiki', {'admins': 'tom:swordfish', 'name': 'amulet-wiki'})
67+d.relate('mysql:db', 'mediawiki:db')
68+d.relate('memcached:cache', 'mediawiki:cache')
69+d.expose('mediawiki')
70+
71+
72+# Perform the setup for the deployment.
73+try:
74+ d.setup(seconds)
75+ #pings every deployed unit
76+ d.sentry.wait(seconds)
77+except amulet.helpers.TimeoutError:
78+ message = 'The environment did not setup in %d seconds.' % seconds
79+ amulet.raise_status(amulet.SKIP, msg=message)
80+except:
81+ raise
82+
83+mw_unit = d.sentry.unit['mediawiki/0']
84+mysql_unit = d.sentry.unit['mysql/0']
85+
86+#############################################################
87+# Validate the DB Relationship using Amulet Sentry
88+#############################################################
89+sql_relation = d.sentry.unit['mysql/0'].relation('db', 'mediawiki:db')
90+
91+# Validate that the database server was set for the configuration of MediaWiki
92+#Set search term for comparison, and cache the flag in the configuration file
93+output, code = mw_unit.run("cat /etc/mediawiki/LocalSettings.php \
94+ | grep wgDBserver | awk '{printf $3}'")
95+
96+search_term = "\"{}\";".format(sql_relation['private-address'])
97+if search_term != output:
98+ message = "Unable to Determine Remote MYSQL configuration, " \
99+ "expected: %s, got: %s" % (search_term, output)
100+
101+ amulet.raise_status(amulet.FAIL, msg=message)
102+
103+#############################################################
104+# Validate the Memcached Relationship using Amulet Sentry
105+#############################################################
106+memcached_relation = d.sentry.unit['memcached/0'].relation(
107+ 'cache', 'mediawiki:cache')
108+output, code = mw_unit.run("cat /etc/mediawiki/memcached_settings.php \
109+ | grep wgMemCachedServers | tr -d \'array\(\)\; | awk '{printf $3}'")
110+search_term = "%s:%s" % memcached_relation['private-address'],
111+memcached_relation['port']
112+
113+#############################################################
114+# Validate the installation configuration using PhantomJS
115+#############################################################
116+browser = Browser('phantomjs')
117+browser.visit("http://%s/mediawiki/index.php?"
118+ "title=Special:UserLogin&returnto=Main+Page" %
119+ d.sentry.unit['mediawiki/0'].info['public-address'])
120+
121+
122+title = str(browser.title).find("Log in")
123+if title == -1:
124+ amulet.raise_status(amulet.FAIL, msg="Failed login test.")
125+
126+title = str(browser.title).find("amulet-wiki")
127+if title == -1:
128+ amulet.raise_status(amulet.FAIL, msg="Failed to parse provided title")
129+
130+browser.fill("wpName", 'tom')
131+browser.fill('wpPassword', 'swordfish')
132+browser.find_by_id('wpLoginAttempt').first.click()
133+
134+if not browser.is_text_present('tom'):
135+ amulet.raise_status(amulet.FAIL,
136+ msg="Failed to login with configured admin")
137
138=== removed file 'tests/100_deploy.test'
139--- tests/100_deploy.test 2012-01-31 01:27:17 +0000
140+++ tests/100_deploy.test 1970-01-01 00:00:00 +0000
141@@ -1,62 +0,0 @@
142-#!/bin/sh
143-
144-if [ -z "`which wget`" ] ; then
145- echo SKIP: need wget to run test.
146- exit 100
147-fi
148-
149-set -e
150-
151-teardown() {
152- juju destroy-service memcached
153- juju destroy-service mysql
154- juju destroy-service mediawiki
155- if [ -n "$datadir" ] ; then
156- if [ -f $datadir/passed ]; then
157- rm -r $datadir
158- else
159- echo $datadir preserved
160- fi
161- fi
162-}
163-trap teardown EXIT
164-
165-
166-juju deploy mediawiki
167-juju deploy mysql
168-juju deploy memcached
169-juju add-relation mediawiki:db mysql:db
170-juju add-relation memcached mediawiki
171-juju expose mediawiki
172-
173-for try in `seq 1 600` ; do
174- host=`juju status | tests/get-unit-info mediawiki public-address`
175- if [ -z "$host" ] ; then
176- sleep 1
177- else
178- break
179- fi
180-done
181-
182-if [ -z "$host" ] ; then
183- echo FAIL: status timed out
184- exit 1
185-fi
186-
187-datadir=`mktemp -d ${TMPDIR:-/tmp}/wget.test.XXXXXXX`
188-echo INFO: datadir=$datadir
189-
190-wget --tries=100 --timeout=6 http://$host/ -O - -a $datadir/wget.log | grep -q '<title>' || continue
191-
192-if [ $try -eq 600 ] ; then
193- echo FAIL: Timed out waiting.
194- exit 1
195-fi
196-
197-touch $datadir/passed
198-
199-trap - EXIT
200-teardown
201-
202-echo PASS: deployed successfully
203-exit 0
204
205=== removed file 'tests/get-unit-info'
206--- tests/get-unit-info 2012-01-31 01:27:17 +0000
207+++ tests/get-unit-info 1970-01-01 00:00:00 +0000
208@@ -1,46 +0,0 @@
209-#!/usr/bin/python
210-# machines:
211-# 0: {dns-name: ec2-50-17-84-127.compute-1.amazonaws.com, instance-id: i-8c5c3fec}
212-# 1: {dns-name: ec2-184-73-102-113.compute-1.amazonaws.com, instance-id: i-14a2c174}
213-# 2: {dns-name: ec2-75-101-184-93.compute-1.amazonaws.com, instance-id: i-e0a2c180}
214-# services:
215-# mysql:
216-# charm: local:mysql-11
217-# relations: {db: wordpress}
218-# units:
219-# mysql/0:
220-# machine: 2
221-# relations:
222-# db: {state: up}
223-# state: started
224-# wordpress:
225-# charm: local:wordpress-31
226-# exposed: true
227-# relations: {db: mysql}
228-# units:
229-# wordpress/0:
230-# machine: 1
231-# open-ports: []
232-# relations: {}
233-# state: null
234-
235-import yaml
236-import sys
237-from subprocess import Popen, PIPE
238-
239-
240-def main():
241- d = yaml.safe_load(Popen(['juju','status'],stdout=PIPE).stdout)
242- srv = d.get("services", {}).get(sys.argv[1])
243- if srv is None:
244- return
245- units = srv.get("units", {})
246- if units is None:
247- return
248- item = units.items()[0][1].get(sys.argv[2])
249- if item is None:
250- return
251- print item
252-
253-if __name__ == "__main__":
254- main()

Subscribers

People subscribed via source and target branches

to all changes: