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 | 1 | #!/bin/sh | ||
7 | 2 | |||
8 | 3 | # The script installs amulet and other tools needed for the amulet tests. | ||
9 | 4 | |||
10 | 5 | set -x | ||
11 | 6 | |||
12 | 7 | # Get the status of the amulet package, this returns 0 of package is installed. | ||
13 | 8 | dpkg -s amulet | ||
14 | 9 | if [ $? -ne 0 ]; then | ||
15 | 10 | # Install the Amulet testing harness. | ||
16 | 11 | sudo add-apt-repository -y ppa:juju/stable | ||
17 | 12 | sudo apt-get update | ||
18 | 13 | sudo apt-get install -y amulet juju-core charm-tools | ||
19 | 14 | fi | ||
20 | 15 | dpkg -s python3 | ||
21 | 16 | if [ $? -ne 0 ]; then | ||
22 | 17 | # Install the Python3 libraries. | ||
23 | 18 | sudo apt-get install -y python3 | ||
24 | 19 | fi | ||
25 | 0 | 20 | ||
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 | 1 | #!/usr/bin/python3 | ||
31 | 2 | |||
32 | 3 | ## This Amulet test deploys memcached. | ||
33 | 4 | |||
34 | 5 | import amulet | ||
35 | 6 | import telnetlib | ||
36 | 7 | import time | ||
37 | 8 | |||
38 | 9 | # The number of seconds to wait for the environment to setup. | ||
39 | 10 | seconds = 1200 | ||
40 | 11 | |||
41 | 12 | d = amulet.Deployment() | ||
42 | 13 | # Add the memcached charm to the deployment. | ||
43 | 14 | d.add('memcached') | ||
44 | 15 | # Add the mediawiki charm to the deployment. | ||
45 | 16 | d.add('mediawiki') | ||
46 | 17 | # Create a relation from memcached to mediawiki | ||
47 | 18 | d.relate('memcached:cache', 'mediawiki:cache') | ||
48 | 19 | |||
49 | 20 | # Create a configuration dictionary for custom memcached values. | ||
50 | 21 | configuration = {'size': 512, 'connection-limit': 128, 'factor': 1.10, | ||
51 | 22 | 'tcp-port': 11212, 'udp-port': 11213} | ||
52 | 23 | d.configure('memcached', configuration) | ||
53 | 24 | # Expose memcached so it is visible to the tests. | ||
54 | 25 | d.expose('memcached') | ||
55 | 26 | |||
56 | 27 | try: | ||
57 | 28 | # Execute the deployer with the current mapping. | ||
58 | 29 | d.setup(timeout=seconds) | ||
59 | 30 | # Wait for the relation to finish the translations. | ||
60 | 31 | d.sentry.wait(seconds) | ||
61 | 32 | except amulet.helpers.TimeoutError: | ||
62 | 33 | message = 'The environment did not setup in %d seconds.' % seconds | ||
63 | 34 | # The SKIP status enables skip or fail the test based on configuration. | ||
64 | 35 | amulet.raise_status(amulet.SKIP, msg=message) | ||
65 | 36 | except: | ||
66 | 37 | raise | ||
67 | 38 | |||
68 | 39 | # Get the sentry for memcached. | ||
69 | 40 | memcached_unit = d.sentry.unit['memcached/0'] | ||
70 | 41 | |||
71 | 42 | ## Test if the memcached service is running. | ||
72 | 43 | |||
73 | 44 | # Run the command that checks if the memcached server instance is running. | ||
74 | 45 | command = 'service memcached status' | ||
75 | 46 | # Execute the command on the deployed service. | ||
76 | 47 | output, code = memcached_unit.run(command) | ||
77 | 48 | |||
78 | 49 | if code != 0: | ||
79 | 50 | message = 'The ' + command + ' returned %d.' % code | ||
80 | 51 | print(output) | ||
81 | 52 | amulet.raise_status(amulet.FAIL, msg=message) | ||
82 | 53 | else: | ||
83 | 54 | message = 'The memcached service is running.' | ||
84 | 55 | print(output) | ||
85 | 56 | print(message) | ||
86 | 57 | |||
87 | 58 | ## Test memcached using telnet commands. | ||
88 | 59 | |||
89 | 60 | # Get the public address for memcached instance. | ||
90 | 61 | memcached_address = memcached_unit.info['public-address'] | ||
91 | 62 | # Get the port for memcached instance. | ||
92 | 63 | memcached_port = configuration['tcp-port'] | ||
93 | 64 | |||
94 | 65 | try: | ||
95 | 66 | # Connect to memcached via telnet. | ||
96 | 67 | tn = telnetlib.Telnet(memcached_address, memcached_port) | ||
97 | 68 | date_time = time.strftime("%F %r") | ||
98 | 69 | # Write the command that gets the current greeting. | ||
99 | 70 | tn.write(b'get greeting\r\n') | ||
100 | 71 | # Read the current greeting. | ||
101 | 72 | response = tn.read_until(b'END', 2) | ||
102 | 73 | # Create a string with date and time for this test. | ||
103 | 74 | string = 'memcached test %s' % date_time | ||
104 | 75 | command = 'set greeting 1 0 %d' % len(string) | ||
105 | 76 | # Write the command that sets the new greeting. | ||
106 | 77 | tn.write(command.encode() + b'\r\n') | ||
107 | 78 | tn.write(string.encode() + b'\r\n') | ||
108 | 79 | # Read the response | ||
109 | 80 | response = tn.read_until(b'STORED', 2) | ||
110 | 81 | # Write the command that gets the greeting. | ||
111 | 82 | tn.write(b'get greeting\r\n') | ||
112 | 83 | # Get the new greeting in memcached. | ||
113 | 84 | response = tn.read_until(b'END', 2) | ||
114 | 85 | response = response.decode() | ||
115 | 86 | print('get greeting response:') | ||
116 | 87 | print(response) | ||
117 | 88 | # Look for the string in the response. | ||
118 | 89 | index = response.find(string) | ||
119 | 90 | if index != -1: | ||
120 | 91 | print('Found %s in the greeting response.' % string) | ||
121 | 92 | else: | ||
122 | 93 | print(response) | ||
123 | 94 | message = 'Did not find %s in the greeting from memcached.' % string | ||
124 | 95 | amulet.raise_status(amulet.FAIL, msg=message) | ||
125 | 96 | tn.write(b'quit\n') | ||
126 | 97 | except Exception as e: | ||
127 | 98 | message = 'An error occurred communicating with memcached over telnet ' \ | ||
128 | 99 | '{0}:{1} {3}'.format(memcached_address, memcached_port, str(e)) | ||
129 | 100 | amulet.raise_status(amulet.FAIL, msg=message) | ||
130 | 101 | finally: | ||
131 | 102 | tn.close() | ||
132 | 103 | |||
133 | 104 | ## Test if the memcached service is configured properly. | ||
134 | 105 | |||
135 | 106 | # Get the contents of the memcached configuration file. | ||
136 | 107 | config_string = memcached_unit.file_contents('/etc/memcached.conf') | ||
137 | 108 | # Parse the configuration file for the values sent in the deployment. | ||
138 | 109 | for line in config_string.splitlines(): | ||
139 | 110 | if line.startswith('-m '): | ||
140 | 111 | size = line.split()[1] | ||
141 | 112 | elif line.startswith('-c '): | ||
142 | 113 | limit = line.split()[1] | ||
143 | 114 | elif line.startswith('-f '): | ||
144 | 115 | factor = line.split()[1] | ||
145 | 116 | |||
146 | 117 | # Check for the configured values. | ||
147 | 118 | if (configuration['size'] != int(size) or | ||
148 | 119 | configuration['connection-limit'] != int(limit) or | ||
149 | 120 | configuration['factor'] != float(factor)): | ||
150 | 121 | message = 'The memcached deployment was not configured correctly, size: ' \ | ||
151 | 122 | '{0} limit: {1} factor: {2}'.format(size, limit, factor) | ||
152 | 123 | amulet.raise_status(amulet.FAIL, msg=message) | ||
153 | 124 | else: | ||
154 | 125 | message = 'The memcached deployment was configured correctly.' | ||
155 | 126 | print(message) | ||
156 | 127 | |||
157 | 128 | ## Test if the relation is complete and data was exchanged properly. | ||
158 | 129 | |||
159 | 130 | memcached_unit = d.sentry.unit['memcached/0'] | ||
160 | 131 | # Get the relation from memcached to mediawiki. | ||
161 | 132 | relation = memcached_unit.relation('cache', 'mediawiki:cache') | ||
162 | 133 | |||
163 | 134 | # Make sure the relation got the port information set by the configuration. | ||
164 | 135 | if (configuration['tcp-port'] != int(relation['port']) or | ||
165 | 136 | configuration['udp-port'] != int(relation['udp-port'])): | ||
166 | 137 | message = 'The memcached relation was not configured correctly, port: ' \ | ||
167 | 138 | '{0} udp-port: {1}'.format(relation['port'], relation['udp-port']) | ||
168 | 139 | amulet.raise_status(amulet.FAIL, msg=message) | ||
169 | 140 | else: | ||
170 | 141 | message = 'The memcached relation was configured correctly.' | ||
171 | 142 | print(message) | ||
172 | 143 | |||
173 | 144 | # Print a message indicating the charm passed all the tests. | ||
174 | 145 | message = 'The memcached charm passed the deploy tests!' | ||
175 | 146 | print(message) |
Please take a look.