Merge lp:~mbruzek/charms/precise/memcached/trunk into lp:charms/memcached
- Precise Pangolin (12.04)
- trunk
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 60 |
Proposed branch: | lp:~mbruzek/charms/precise/memcached/trunk |
Merge into: | lp:charms/memcached |
Diff against target: |
175 lines (+165/-0) 2 files modified
tests/00_setup.sh (+19/-0) tests/10_deploy_test.py (+146/-0) |
To merge this branch: | bzr merge lp:~mbruzek/charms/precise/memcached/trunk |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marco Ceppi (community) | Approve | ||
Review via email: mp+203565@code.launchpad.net |
Commit message
Description of the change
Added Juju Amulet tests for memcached charm.
Added a deploy test, testing memcached with telnet, and configuration test.
Matt Bruzek (mbruzek) wrote : | # |
Matt Bruzek (mbruzek) wrote : | # |
Reviewers: mp+203565_
Message:
Please take a look.
Description:
Added Juju Amulet tests for memcached charm.
Added a deploy test, testing memcached with telnet, and configuration
test.
https:/
(do not edit description out of merge proposal)
Please review this at https:/
Affected files (+154, -0 lines):
A [revision details]
A tests/00_setup.sh
A tests/10_
Charles Butler (lazypower) wrote : | # |
Matt, Thank you for your work on this charm test suite, it looks
comprehensive enough to be comfortable, the only issue I found was in
the setup script there were missing dependencies.
Correct those issues and you get a +1 from me
https:/
File tests/00_setup.sh (right):
https:/
tests/00_
This is missing python3, and any associated python3 libraries to
complete the test run. The assumption is we are running this test on a
machine with nothing more than juju-core on it.
https:/
File tests/10_
https:/
tests/10_
I like how you did this test. +1
https:/
tests/10_
deply tests!'
Typo on Deploy
- 61. By Matt Bruzek <email address hidden>
-
Making changes based on lazyPower's code review comments.
Matt Bruzek (mbruzek) wrote : | # |
Please take a look.
Matt Bruzek (mbruzek) wrote : | # |
I updated the code to respond to lazypower's code review comments.
Marco Ceppi (marcoceppi) wrote : | # |
This looks good as a test, needs some additional robustness, see inline
comments
https:/
File tests/10_
https:/
tests/10_
It would be nice if you used
except Exception as e:
which would allow you to use the e to detail which of the areas failed
in the test. So for your message you could add a third option, str(e) to
get the message of the error which caused the exception. This should
help show authors why the charm is failing if it fails
https:/
tests/10_
'memcached:cache')
The cache relation for memcache sends host, port, and udp-port with the
last two being configurable. You should set these to non-standard ports
in the initial configuration and test that the values are sent on the
wire properly.
- 62. By Matt Bruzek <email address hidden>
-
Addressed code review comments.
Matt Bruzek (mbruzek) wrote : | # |
Please take a look.
Marco Ceppi (marcoceppi) wrote : | # |
LGTM, with one minor fix below
https:/
File tests/10_
https:/
tests/10_
memcached_
It'd be better to use configuration[
querying the unit.info data.
- 63. By Matt Bruzek <email address hidden>
-
Addressing the tcp-port review comment.
Matt Bruzek (mbruzek) wrote : | # |
Please take a look.
Preview Diff
1 | === added directory 'tests' |
2 | === added file 'tests/00_setup.sh' |
3 | --- tests/00_setup.sh 1970-01-01 00:00:00 +0000 |
4 | +++ tests/00_setup.sh 2014-02-06 18:10:42 +0000 |
5 | @@ -0,0 +1,19 @@ |
6 | +#!/bin/sh |
7 | + |
8 | +# The script installs amulet and other tools needed for the amulet tests. |
9 | + |
10 | +set -x |
11 | + |
12 | +# Get the status of the amulet package, this returns 0 of package is installed. |
13 | +dpkg -s amulet |
14 | +if [ $? -ne 0 ]; then |
15 | + # Install the Amulet testing harness. |
16 | + sudo add-apt-repository -y ppa:juju/stable |
17 | + sudo apt-get update |
18 | + sudo apt-get install -y amulet juju-core charm-tools |
19 | +fi |
20 | +dpkg -s python3 |
21 | +if [ $? -ne 0 ]; then |
22 | + # Install the Python3 libraries. |
23 | + sudo apt-get install -y python3 |
24 | +fi |
25 | |
26 | === added file 'tests/10_deploy_test.py' |
27 | --- tests/10_deploy_test.py 1970-01-01 00:00:00 +0000 |
28 | +++ tests/10_deploy_test.py 2014-02-06 18:10:42 +0000 |
29 | @@ -0,0 +1,146 @@ |
30 | +#!/usr/bin/python3 |
31 | + |
32 | +## This Amulet test deploys memcached. |
33 | + |
34 | +import amulet |
35 | +import telnetlib |
36 | +import time |
37 | + |
38 | +# The number of seconds to wait for the environment to setup. |
39 | +seconds = 1200 |
40 | + |
41 | +d = amulet.Deployment() |
42 | +# Add the memcached charm to the deployment. |
43 | +d.add('memcached') |
44 | +# Add the mediawiki charm to the deployment. |
45 | +d.add('mediawiki') |
46 | +# Create a relation from memcached to mediawiki |
47 | +d.relate('memcached:cache', 'mediawiki:cache') |
48 | + |
49 | +# Create a configuration dictionary for custom memcached values. |
50 | +configuration = {'size': 512, 'connection-limit': 128, 'factor': 1.10, |
51 | + 'tcp-port': 11212, 'udp-port': 11213} |
52 | +d.configure('memcached', configuration) |
53 | +# Expose memcached so it is visible to the tests. |
54 | +d.expose('memcached') |
55 | + |
56 | +try: |
57 | + # Execute the deployer with the current mapping. |
58 | + d.setup(timeout=seconds) |
59 | + # Wait for the relation to finish the translations. |
60 | + d.sentry.wait(seconds) |
61 | +except amulet.helpers.TimeoutError: |
62 | + message = 'The environment did not setup in %d seconds.' % seconds |
63 | + # The SKIP status enables skip or fail the test based on configuration. |
64 | + amulet.raise_status(amulet.SKIP, msg=message) |
65 | +except: |
66 | + raise |
67 | + |
68 | +# Get the sentry for memcached. |
69 | +memcached_unit = d.sentry.unit['memcached/0'] |
70 | + |
71 | +## Test if the memcached service is running. |
72 | + |
73 | +# Run the command that checks if the memcached server instance is running. |
74 | +command = 'service memcached status' |
75 | +# Execute the command on the deployed service. |
76 | +output, code = memcached_unit.run(command) |
77 | + |
78 | +if code != 0: |
79 | + message = 'The ' + command + ' returned %d.' % code |
80 | + print(output) |
81 | + amulet.raise_status(amulet.FAIL, msg=message) |
82 | +else: |
83 | + message = 'The memcached service is running.' |
84 | + print(output) |
85 | + print(message) |
86 | + |
87 | +## Test memcached using telnet commands. |
88 | + |
89 | +# Get the public address for memcached instance. |
90 | +memcached_address = memcached_unit.info['public-address'] |
91 | +# Get the port for memcached instance. |
92 | +memcached_port = configuration['tcp-port'] |
93 | + |
94 | +try: |
95 | + # Connect to memcached via telnet. |
96 | + tn = telnetlib.Telnet(memcached_address, memcached_port) |
97 | + date_time = time.strftime("%F %r") |
98 | + # Write the command that gets the current greeting. |
99 | + tn.write(b'get greeting\r\n') |
100 | + # Read the current greeting. |
101 | + response = tn.read_until(b'END', 2) |
102 | + # Create a string with date and time for this test. |
103 | + string = 'memcached test %s' % date_time |
104 | + command = 'set greeting 1 0 %d' % len(string) |
105 | + # Write the command that sets the new greeting. |
106 | + tn.write(command.encode() + b'\r\n') |
107 | + tn.write(string.encode() + b'\r\n') |
108 | + # Read the response |
109 | + response = tn.read_until(b'STORED', 2) |
110 | + # Write the command that gets the greeting. |
111 | + tn.write(b'get greeting\r\n') |
112 | + # Get the new greeting in memcached. |
113 | + response = tn.read_until(b'END', 2) |
114 | + response = response.decode() |
115 | + print('get greeting response:') |
116 | + print(response) |
117 | + # Look for the string in the response. |
118 | + index = response.find(string) |
119 | + if index != -1: |
120 | + print('Found %s in the greeting response.' % string) |
121 | + else: |
122 | + print(response) |
123 | + message = 'Did not find %s in the greeting from memcached.' % string |
124 | + amulet.raise_status(amulet.FAIL, msg=message) |
125 | + tn.write(b'quit\n') |
126 | +except Exception as e: |
127 | + message = 'An error occurred communicating with memcached over telnet ' \ |
128 | + '{0}:{1} {3}'.format(memcached_address, memcached_port, str(e)) |
129 | + amulet.raise_status(amulet.FAIL, msg=message) |
130 | +finally: |
131 | + tn.close() |
132 | + |
133 | +## Test if the memcached service is configured properly. |
134 | + |
135 | +# Get the contents of the memcached configuration file. |
136 | +config_string = memcached_unit.file_contents('/etc/memcached.conf') |
137 | +# Parse the configuration file for the values sent in the deployment. |
138 | +for line in config_string.splitlines(): |
139 | + if line.startswith('-m '): |
140 | + size = line.split()[1] |
141 | + elif line.startswith('-c '): |
142 | + limit = line.split()[1] |
143 | + elif line.startswith('-f '): |
144 | + factor = line.split()[1] |
145 | + |
146 | +# Check for the configured values. |
147 | +if (configuration['size'] != int(size) or |
148 | + configuration['connection-limit'] != int(limit) or |
149 | + configuration['factor'] != float(factor)): |
150 | + message = 'The memcached deployment was not configured correctly, size: ' \ |
151 | + '{0} limit: {1} factor: {2}'.format(size, limit, factor) |
152 | + amulet.raise_status(amulet.FAIL, msg=message) |
153 | +else: |
154 | + message = 'The memcached deployment was configured correctly.' |
155 | + print(message) |
156 | + |
157 | +## Test if the relation is complete and data was exchanged properly. |
158 | + |
159 | +memcached_unit = d.sentry.unit['memcached/0'] |
160 | +# Get the relation from memcached to mediawiki. |
161 | +relation = memcached_unit.relation('cache', 'mediawiki:cache') |
162 | + |
163 | +# Make sure the relation got the port information set by the configuration. |
164 | +if (configuration['tcp-port'] != int(relation['port']) or |
165 | + configuration['udp-port'] != int(relation['udp-port'])): |
166 | + message = 'The memcached relation was not configured correctly, port: ' \ |
167 | + '{0} udp-port: {1}'.format(relation['port'], relation['udp-port']) |
168 | + amulet.raise_status(amulet.FAIL, msg=message) |
169 | +else: |
170 | + message = 'The memcached relation was configured correctly.' |
171 | + print(message) |
172 | + |
173 | +# Print a message indicating the charm passed all the tests. |
174 | +message = 'The memcached charm passed the deploy tests!' |
175 | +print(message) |
Please take a look.