Merge lp:~johnsca/charms/trusty/haproxy/xenial-support into lp:~jamesj/charms/trusty/haproxy/xenial-support
- Trusty Tahr (14.04)
- xenial-support
- Merge into xenial-support
Proposed by
Cory Johns
Status: | Merged |
---|---|
Approved by: | James Jesudason |
Approved revision: | 105 |
Merged at revision: | 106 |
Proposed branch: | lp:~johnsca/charms/trusty/haproxy/xenial-support |
Merge into: | lp:~jamesj/charms/trusty/haproxy/xenial-support |
Diff against target: |
603 lines (+372/-184) 6 files modified
hooks/hooks.py (+2/-1) hooks/tests/test_install.py (+3/-1) metadata.yaml (+3/-0) tests/10_deploy_test.py (+0/-182) tests/11_deploy_test_trusty.py (+182/-0) tests/12_deploy_test_xenial.py (+182/-0) |
To merge this branch: | bzr merge lp:~johnsca/charms/trusty/haproxy/xenial-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Jesudason | Approve | ||
Review via email: mp+299470@code.launchpad.net |
Commit message
Description of the change
I added a deploy test for Xenial, and while running tests with that, hit a failure in the unit tests and an import error in the Xenial test, so I added fixes for both of those. I tried to add support for precise, but got a hook error so I removed it: http://
I also added the supported series to the metadata per the new convention.
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 | === modified file 'hooks/hooks.py' |
2 | --- hooks/hooks.py 2016-07-04 16:40:17 +0000 |
3 | +++ hooks/hooks.py 2016-07-07 20:08:09 +0000 |
4 | @@ -914,7 +914,8 @@ |
5 | apt_install(['haproxy', 'python-jinja2'], fatal=True) |
6 | # Install pyasn1 library and modules for inspecting SSL certificates |
7 | apt_install( |
8 | - ['python-pyasn1', 'python-pyasn1-modules', 'python-apt'], fatal=False) |
9 | + ['python-pyasn1', 'python-pyasn1-modules', 'python-apt', |
10 | + 'python-openssl'], fatal=False) |
11 | ensure_package_status(service_affecting_packages, |
12 | config_data['package_status']) |
13 | enable_haproxy() |
14 | |
15 | === modified file 'hooks/tests/test_install.py' |
16 | --- hooks/tests/test_install.py 2015-09-23 15:12:08 +0000 |
17 | +++ hooks/tests/test_install.py 2016-07-07 20:08:09 +0000 |
18 | @@ -48,7 +48,9 @@ |
19 | self.assertEqual((['haproxy', 'python-jinja2'],), calls[0][0]) |
20 | self.assertEqual({'fatal': True}, calls[0][1]) |
21 | self.assertEqual( |
22 | - (['python-pyasn1', 'python-pyasn1-modules'],), calls[1][0]) |
23 | + (['python-pyasn1', 'python-pyasn1-modules', 'python-apt', |
24 | + 'python-openssl'],), |
25 | + calls[1][0]) |
26 | self.assertEqual({'fatal': False}, calls[1][1]) |
27 | |
28 | def test_add_source(self): |
29 | |
30 | === modified file 'metadata.yaml' |
31 | --- metadata.yaml 2016-03-03 20:08:09 +0000 |
32 | +++ metadata.yaml 2016-07-07 20:08:09 +0000 |
33 | @@ -8,6 +8,9 @@ |
34 | has request blocking capabilities and provides interface to display server |
35 | status. |
36 | tags: ["cache-proxy"] |
37 | +series: |
38 | + - xenial |
39 | + - trusty |
40 | requires: |
41 | reverseproxy: |
42 | interface: http |
43 | |
44 | === removed file 'tests/10_deploy_test.py' |
45 | --- tests/10_deploy_test.py 2015-11-19 18:13:43 +0000 |
46 | +++ tests/10_deploy_test.py 1970-01-01 00:00:00 +0000 |
47 | @@ -1,182 +0,0 @@ |
48 | -#!/usr/bin/python3 |
49 | - |
50 | -# This Amulet test deploys haproxy and related charms. |
51 | - |
52 | -import os |
53 | -import amulet |
54 | -import requests |
55 | -import base64 |
56 | -import yaml |
57 | -import time |
58 | - |
59 | -d = amulet.Deployment(series='trusty') |
60 | -# Add the haproxy charm to the deployment. |
61 | -d.add('haproxy') |
62 | -d.add('apache2', units=2) |
63 | - |
64 | -# Get the directory this way to load the file when CWD is different. |
65 | -path = os.path.abspath(os.path.dirname(__file__)) |
66 | -template_path = os.path.join(path, 'default_apache.tmpl') |
67 | -# Read in the Apache2 default template file. |
68 | -with open(template_path) as f: |
69 | - template = f.read() |
70 | - encodedTemplate = base64.b64encode(template.encode('utf-8')) |
71 | -# Create a dictionary with configuration values for apache2. |
72 | -configuration = {'vhost_http_template': encodedTemplate.decode('ascii')} |
73 | -# Apache2 needs a base64 encoded template to configure the web site. |
74 | -d.configure('apache2', configuration) |
75 | - |
76 | -# Relate the haproxy to apache2. |
77 | -d.relate('haproxy:reverseproxy', 'apache2:website') |
78 | -# Make the haproxy visible to the outside world. |
79 | -d.expose('haproxy') |
80 | - |
81 | -# The number of seconds to wait for the environment to setup. |
82 | -seconds = 900 |
83 | -try: |
84 | - # Execute the deployer with the current mapping. |
85 | - d.setup(timeout=seconds) |
86 | - # Wait for the relation to finish the transations. |
87 | - d.sentry.wait(seconds) |
88 | -except amulet.helpers.TimeoutError: |
89 | - message = 'The environment did not setup in %d seconds.' % seconds |
90 | - # The SKIP status enables skip or fail the test based on configuration. |
91 | - amulet.raise_status(amulet.SKIP, msg=message) |
92 | -except: |
93 | - raise |
94 | - |
95 | -# Test that haproxy is acting as the proxy for apache2. |
96 | - |
97 | -# Get the haproxy unit. |
98 | -haproxy_unit = d.sentry['haproxy'][0] |
99 | -haproxy_address = haproxy_unit.info['public-address'] |
100 | -page = requests.get('http://%s/index.html' % haproxy_address) |
101 | -# Raise an error if the page does not load through haproxy. |
102 | -page.raise_for_status() |
103 | -print('Successfully got the Apache2 web page through haproxy IP address.') |
104 | - |
105 | -# Test that sticky session cookie is present |
106 | -if page.cookies.get('SRVNAME') != 'S0': |
107 | - msg = 'Missing or invalid sticky session cookie value: %s' % page.cookies.get('SRVNAME') |
108 | - amulet.raise_status(amulet.FAIL, msg=msg) |
109 | - |
110 | -# Test that the apache2 relation data is saved on the haproxy server. |
111 | - |
112 | -# Get the sentry for apache and get the private IP address. |
113 | -apache_unit = d.sentry['apache2'][0] |
114 | -# Get the relation. |
115 | -relation = apache_unit.relation('website', 'haproxy:reverseproxy') |
116 | -# Get the private address from the relation. |
117 | -apache_private = relation['private-address'] |
118 | - |
119 | -print('Private address of the apache2 relation ', apache_private) |
120 | - |
121 | -# Grep the configuration file for the private address |
122 | -output, code = haproxy_unit.run('grep %s /etc/haproxy/haproxy.cfg' % |
123 | - apache_private) |
124 | -if code == 0: |
125 | - print('Found the relation IP address in the haproxy configuration file!') |
126 | - print(output) |
127 | -else: |
128 | - print(output) |
129 | - message = 'Unable to find the Apache IP address %s in the haproxy ' \ |
130 | - 'configuration file.' % apache_private |
131 | - amulet.raise_status(amulet.FAIL, msg=message) |
132 | - |
133 | -# Test SSL termination |
134 | -d.configure('haproxy', { |
135 | - 'source': 'backports', |
136 | - 'ssl_cert': 'SELFSIGNED', |
137 | - 'services': yaml.safe_dump([ |
138 | - {'service_name': 'apache', |
139 | - 'service_host': '0.0.0.0', |
140 | - 'service_port': 80, |
141 | - 'service_options': [ |
142 | - 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' |
143 | - ], |
144 | - 'servers': [ |
145 | - ['apache', apache_private, 80, 'maxconn 50']]}, |
146 | - {'service_name': 'apache-ssl', |
147 | - 'service_port': 443, |
148 | - 'service_host': '0.0.0.0', |
149 | - 'service_options': [ |
150 | - 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' |
151 | - ], |
152 | - 'crts': ['DEFAULT'], |
153 | - 'servers': [['apache', apache_private, 80, 'maxconn 50']]}]) |
154 | -}) |
155 | -time.sleep(10) |
156 | -d.sentry.wait(seconds) |
157 | - |
158 | -# We need a retry loop here, since there's no way to tell when the new |
159 | -# configuration is in place. |
160 | -url = 'http://%s/index.html' % haproxy_address |
161 | -secure_url = 'https://%s/index.html' % haproxy_address |
162 | -retries = 10 |
163 | -for i in range(retries): |
164 | - try: |
165 | - page = requests.get(url) |
166 | - page.raise_for_status() |
167 | - page = requests.get(secure_url, verify=False) |
168 | - page.raise_for_status() |
169 | - success = True |
170 | - except requests.exceptions.ConnectionError: |
171 | - if i == retries - 1: |
172 | - # This was the last one, let's fail |
173 | - raise |
174 | - time.sleep(6) |
175 | - else: |
176 | - break |
177 | - |
178 | -print('Successfully got the Apache2 web page through haproxy SSL termination.') |
179 | - |
180 | -apache_unit2 = d.sentry['apache2'][1] |
181 | -apache_private2 = apache_unit2.run("unit-get private-address")[0] |
182 | - |
183 | -# Create a file on the second apache unit's www directory. |
184 | -apache_unit2.run("echo foo > /var/www/html/foo") |
185 | - |
186 | -d.configure('haproxy', { |
187 | - 'services': yaml.safe_dump([ |
188 | - {'service_name': 'apache', |
189 | - 'service_host': '0.0.0.0', |
190 | - 'service_port': 80, |
191 | - 'service_options': [ |
192 | - 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0', |
193 | - 'acl foo path_beg -i /foo', 'use_backend foo if foo', |
194 | - ], |
195 | - 'servers': [ |
196 | - ['apache', apache_private, 80, 'maxconn 50']], |
197 | - 'backends': [ |
198 | - {'backend_name': 'foo', |
199 | - 'servers': [ |
200 | - ['apache2', apache_private2, 80, 'maxconn 50']]} |
201 | - ]}]) |
202 | -}) |
203 | -time.sleep(10) |
204 | -d.sentry.wait(seconds) |
205 | - |
206 | -# Let's exercise our URL-based routing by trying to fetch a URL that will |
207 | -# only work for the second apache unit (which is configured as server |
208 | -# of the extra backend). |
209 | -url = 'http://%s/foo' % haproxy_address |
210 | - |
211 | -# We need a retry loop here, since there's no way to tell when the new |
212 | -# configuration is in place. |
213 | -retries = 10 |
214 | -for i in range(retries): |
215 | - try: |
216 | - page = requests.get(url) |
217 | - page.raise_for_status() |
218 | - except: |
219 | - if i == retries - 1: |
220 | - # This was the last one, let's fail |
221 | - raise |
222 | - time.sleep(6) |
223 | - else: |
224 | - break |
225 | - |
226 | -print('Successfully got the /foo URL from the second Apache unit.') |
227 | - |
228 | -# Send a message that the tests are complete. |
229 | -print('The haproxy tests are complete.') |
230 | |
231 | === added file 'tests/11_deploy_test_trusty.py' |
232 | --- tests/11_deploy_test_trusty.py 1970-01-01 00:00:00 +0000 |
233 | +++ tests/11_deploy_test_trusty.py 2016-07-07 20:08:09 +0000 |
234 | @@ -0,0 +1,182 @@ |
235 | +#!/usr/bin/python3 |
236 | + |
237 | +# This Amulet test deploys haproxy and related charms. |
238 | + |
239 | +import os |
240 | +import amulet |
241 | +import requests |
242 | +import base64 |
243 | +import yaml |
244 | +import time |
245 | + |
246 | +d = amulet.Deployment(series='trusty') |
247 | +# Add the haproxy charm to the deployment. |
248 | +d.add('haproxy') |
249 | +d.add('apache2', units=2) |
250 | + |
251 | +# Get the directory this way to load the file when CWD is different. |
252 | +path = os.path.abspath(os.path.dirname(__file__)) |
253 | +template_path = os.path.join(path, 'default_apache.tmpl') |
254 | +# Read in the Apache2 default template file. |
255 | +with open(template_path) as f: |
256 | + template = f.read() |
257 | + encodedTemplate = base64.b64encode(template.encode('utf-8')) |
258 | +# Create a dictionary with configuration values for apache2. |
259 | +configuration = {'vhost_http_template': encodedTemplate.decode('ascii')} |
260 | +# Apache2 needs a base64 encoded template to configure the web site. |
261 | +d.configure('apache2', configuration) |
262 | + |
263 | +# Relate the haproxy to apache2. |
264 | +d.relate('haproxy:reverseproxy', 'apache2:website') |
265 | +# Make the haproxy visible to the outside world. |
266 | +d.expose('haproxy') |
267 | + |
268 | +# The number of seconds to wait for the environment to setup. |
269 | +seconds = 900 |
270 | +try: |
271 | + # Execute the deployer with the current mapping. |
272 | + d.setup(timeout=seconds) |
273 | + # Wait for the relation to finish the transations. |
274 | + d.sentry.wait(seconds) |
275 | +except amulet.helpers.TimeoutError: |
276 | + message = 'The environment did not setup in %d seconds.' % seconds |
277 | + # The SKIP status enables skip or fail the test based on configuration. |
278 | + amulet.raise_status(amulet.SKIP, msg=message) |
279 | +except: |
280 | + raise |
281 | + |
282 | +# Test that haproxy is acting as the proxy for apache2. |
283 | + |
284 | +# Get the haproxy unit. |
285 | +haproxy_unit = d.sentry['haproxy'][0] |
286 | +haproxy_address = haproxy_unit.info['public-address'] |
287 | +page = requests.get('http://%s/index.html' % haproxy_address) |
288 | +# Raise an error if the page does not load through haproxy. |
289 | +page.raise_for_status() |
290 | +print('Successfully got the Apache2 web page through haproxy IP address.') |
291 | + |
292 | +# Test that sticky session cookie is present |
293 | +if page.cookies.get('SRVNAME') != 'S0': |
294 | + msg = 'Missing or invalid sticky session cookie value: %s' % page.cookies.get('SRVNAME') |
295 | + amulet.raise_status(amulet.FAIL, msg=msg) |
296 | + |
297 | +# Test that the apache2 relation data is saved on the haproxy server. |
298 | + |
299 | +# Get the sentry for apache and get the private IP address. |
300 | +apache_unit = d.sentry['apache2'][0] |
301 | +# Get the relation. |
302 | +relation = apache_unit.relation('website', 'haproxy:reverseproxy') |
303 | +# Get the private address from the relation. |
304 | +apache_private = relation['private-address'] |
305 | + |
306 | +print('Private address of the apache2 relation ', apache_private) |
307 | + |
308 | +# Grep the configuration file for the private address |
309 | +output, code = haproxy_unit.run('grep %s /etc/haproxy/haproxy.cfg' % |
310 | + apache_private) |
311 | +if code == 0: |
312 | + print('Found the relation IP address in the haproxy configuration file!') |
313 | + print(output) |
314 | +else: |
315 | + print(output) |
316 | + message = 'Unable to find the Apache IP address %s in the haproxy ' \ |
317 | + 'configuration file.' % apache_private |
318 | + amulet.raise_status(amulet.FAIL, msg=message) |
319 | + |
320 | +# Test SSL termination |
321 | +d.configure('haproxy', { |
322 | + 'source': 'backports', |
323 | + 'ssl_cert': 'SELFSIGNED', |
324 | + 'services': yaml.safe_dump([ |
325 | + {'service_name': 'apache', |
326 | + 'service_host': '0.0.0.0', |
327 | + 'service_port': 80, |
328 | + 'service_options': [ |
329 | + 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' |
330 | + ], |
331 | + 'servers': [ |
332 | + ['apache', apache_private, 80, 'maxconn 50']]}, |
333 | + {'service_name': 'apache-ssl', |
334 | + 'service_port': 443, |
335 | + 'service_host': '0.0.0.0', |
336 | + 'service_options': [ |
337 | + 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' |
338 | + ], |
339 | + 'crts': ['DEFAULT'], |
340 | + 'servers': [['apache', apache_private, 80, 'maxconn 50']]}]) |
341 | +}) |
342 | +time.sleep(10) |
343 | +d.sentry.wait(seconds) |
344 | + |
345 | +# We need a retry loop here, since there's no way to tell when the new |
346 | +# configuration is in place. |
347 | +url = 'http://%s/index.html' % haproxy_address |
348 | +secure_url = 'https://%s/index.html' % haproxy_address |
349 | +retries = 10 |
350 | +for i in range(retries): |
351 | + try: |
352 | + page = requests.get(url) |
353 | + page.raise_for_status() |
354 | + page = requests.get(secure_url, verify=False) |
355 | + page.raise_for_status() |
356 | + success = True |
357 | + except requests.exceptions.ConnectionError: |
358 | + if i == retries - 1: |
359 | + # This was the last one, let's fail |
360 | + raise |
361 | + time.sleep(6) |
362 | + else: |
363 | + break |
364 | + |
365 | +print('Successfully got the Apache2 web page through haproxy SSL termination.') |
366 | + |
367 | +apache_unit2 = d.sentry['apache2'][1] |
368 | +apache_private2 = apache_unit2.run("unit-get private-address")[0] |
369 | + |
370 | +# Create a file on the second apache unit's www directory. |
371 | +apache_unit2.run("echo foo > /var/www/html/foo") |
372 | + |
373 | +d.configure('haproxy', { |
374 | + 'services': yaml.safe_dump([ |
375 | + {'service_name': 'apache', |
376 | + 'service_host': '0.0.0.0', |
377 | + 'service_port': 80, |
378 | + 'service_options': [ |
379 | + 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0', |
380 | + 'acl foo path_beg -i /foo', 'use_backend foo if foo', |
381 | + ], |
382 | + 'servers': [ |
383 | + ['apache', apache_private, 80, 'maxconn 50']], |
384 | + 'backends': [ |
385 | + {'backend_name': 'foo', |
386 | + 'servers': [ |
387 | + ['apache2', apache_private2, 80, 'maxconn 50']]} |
388 | + ]}]) |
389 | +}) |
390 | +time.sleep(10) |
391 | +d.sentry.wait(seconds) |
392 | + |
393 | +# Let's exercise our URL-based routing by trying to fetch a URL that will |
394 | +# only work for the second apache unit (which is configured as server |
395 | +# of the extra backend). |
396 | +url = 'http://%s/foo' % haproxy_address |
397 | + |
398 | +# We need a retry loop here, since there's no way to tell when the new |
399 | +# configuration is in place. |
400 | +retries = 10 |
401 | +for i in range(retries): |
402 | + try: |
403 | + page = requests.get(url) |
404 | + page.raise_for_status() |
405 | + except: |
406 | + if i == retries - 1: |
407 | + # This was the last one, let's fail |
408 | + raise |
409 | + time.sleep(6) |
410 | + else: |
411 | + break |
412 | + |
413 | +print('Successfully got the /foo URL from the second Apache unit.') |
414 | + |
415 | +# Send a message that the tests are complete. |
416 | +print('The haproxy tests are complete.') |
417 | |
418 | === added file 'tests/12_deploy_test_xenial.py' |
419 | --- tests/12_deploy_test_xenial.py 1970-01-01 00:00:00 +0000 |
420 | +++ tests/12_deploy_test_xenial.py 2016-07-07 20:08:09 +0000 |
421 | @@ -0,0 +1,182 @@ |
422 | +#!/usr/bin/python3 |
423 | + |
424 | +# This Amulet test deploys haproxy and related charms. |
425 | + |
426 | +import os |
427 | +import amulet |
428 | +import requests |
429 | +import base64 |
430 | +import yaml |
431 | +import time |
432 | + |
433 | +d = amulet.Deployment(series='xenial') |
434 | +# Add the haproxy charm to the deployment. |
435 | +d.add('haproxy') |
436 | +d.add('apache2', 'cs:trusty/apache2', units=2) |
437 | + |
438 | +# Get the directory this way to load the file when CWD is different. |
439 | +path = os.path.abspath(os.path.dirname(__file__)) |
440 | +template_path = os.path.join(path, 'default_apache.tmpl') |
441 | +# Read in the Apache2 default template file. |
442 | +with open(template_path) as f: |
443 | + template = f.read() |
444 | + encodedTemplate = base64.b64encode(template.encode('utf-8')) |
445 | +# Create a dictionary with configuration values for apache2. |
446 | +configuration = {'vhost_http_template': encodedTemplate.decode('ascii')} |
447 | +# Apache2 needs a base64 encoded template to configure the web site. |
448 | +d.configure('apache2', configuration) |
449 | + |
450 | +# Relate the haproxy to apache2. |
451 | +d.relate('haproxy:reverseproxy', 'apache2:website') |
452 | +# Make the haproxy visible to the outside world. |
453 | +d.expose('haproxy') |
454 | + |
455 | +# The number of seconds to wait for the environment to setup. |
456 | +seconds = 900 |
457 | +try: |
458 | + # Execute the deployer with the current mapping. |
459 | + d.setup(timeout=seconds) |
460 | + # Wait for the relation to finish the transations. |
461 | + d.sentry.wait(seconds) |
462 | +except amulet.helpers.TimeoutError: |
463 | + message = 'The environment did not setup in %d seconds.' % seconds |
464 | + # The SKIP status enables skip or fail the test based on configuration. |
465 | + amulet.raise_status(amulet.SKIP, msg=message) |
466 | +except: |
467 | + raise |
468 | + |
469 | +# Test that haproxy is acting as the proxy for apache2. |
470 | + |
471 | +# Get the haproxy unit. |
472 | +haproxy_unit = d.sentry['haproxy'][0] |
473 | +haproxy_address = haproxy_unit.info['public-address'] |
474 | +page = requests.get('http://%s/index.html' % haproxy_address) |
475 | +# Raise an error if the page does not load through haproxy. |
476 | +page.raise_for_status() |
477 | +print('Successfully got the Apache2 web page through haproxy IP address.') |
478 | + |
479 | +# Test that sticky session cookie is present |
480 | +if page.cookies.get('SRVNAME') != 'S0': |
481 | + msg = 'Missing or invalid sticky session cookie value: %s' % page.cookies.get('SRVNAME') |
482 | + amulet.raise_status(amulet.FAIL, msg=msg) |
483 | + |
484 | +# Test that the apache2 relation data is saved on the haproxy server. |
485 | + |
486 | +# Get the sentry for apache and get the private IP address. |
487 | +apache_unit = d.sentry['apache2'][0] |
488 | +# Get the relation. |
489 | +relation = apache_unit.relation('website', 'haproxy:reverseproxy') |
490 | +# Get the private address from the relation. |
491 | +apache_private = relation['private-address'] |
492 | + |
493 | +print('Private address of the apache2 relation ', apache_private) |
494 | + |
495 | +# Grep the configuration file for the private address |
496 | +output, code = haproxy_unit.run('grep %s /etc/haproxy/haproxy.cfg' % |
497 | + apache_private) |
498 | +if code == 0: |
499 | + print('Found the relation IP address in the haproxy configuration file!') |
500 | + print(output) |
501 | +else: |
502 | + print(output) |
503 | + message = 'Unable to find the Apache IP address %s in the haproxy ' \ |
504 | + 'configuration file.' % apache_private |
505 | + amulet.raise_status(amulet.FAIL, msg=message) |
506 | + |
507 | +# Test SSL termination |
508 | +d.configure('haproxy', { |
509 | + 'source': 'backports', |
510 | + 'ssl_cert': 'SELFSIGNED', |
511 | + 'services': yaml.safe_dump([ |
512 | + {'service_name': 'apache', |
513 | + 'service_host': '0.0.0.0', |
514 | + 'service_port': 80, |
515 | + 'service_options': [ |
516 | + 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' |
517 | + ], |
518 | + 'servers': [ |
519 | + ['apache', apache_private, 80, 'maxconn 50']]}, |
520 | + {'service_name': 'apache-ssl', |
521 | + 'service_port': 443, |
522 | + 'service_host': '0.0.0.0', |
523 | + 'service_options': [ |
524 | + 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' |
525 | + ], |
526 | + 'crts': ['DEFAULT'], |
527 | + 'servers': [['apache', apache_private, 80, 'maxconn 50']]}]) |
528 | +}) |
529 | +time.sleep(10) |
530 | +d.sentry.wait(seconds) |
531 | + |
532 | +# We need a retry loop here, since there's no way to tell when the new |
533 | +# configuration is in place. |
534 | +url = 'http://%s/index.html' % haproxy_address |
535 | +secure_url = 'https://%s/index.html' % haproxy_address |
536 | +retries = 10 |
537 | +for i in range(retries): |
538 | + try: |
539 | + page = requests.get(url) |
540 | + page.raise_for_status() |
541 | + page = requests.get(secure_url, verify=False) |
542 | + page.raise_for_status() |
543 | + success = True |
544 | + except requests.exceptions.ConnectionError: |
545 | + if i == retries - 1: |
546 | + # This was the last one, let's fail |
547 | + raise |
548 | + time.sleep(6) |
549 | + else: |
550 | + break |
551 | + |
552 | +print('Successfully got the Apache2 web page through haproxy SSL termination.') |
553 | + |
554 | +apache_unit2 = d.sentry['apache2'][1] |
555 | +apache_private2 = apache_unit2.run("unit-get private-address")[0] |
556 | + |
557 | +# Create a file on the second apache unit's www directory. |
558 | +apache_unit2.run("echo foo > /var/www/html/foo") |
559 | + |
560 | +d.configure('haproxy', { |
561 | + 'services': yaml.safe_dump([ |
562 | + {'service_name': 'apache', |
563 | + 'service_host': '0.0.0.0', |
564 | + 'service_port': 80, |
565 | + 'service_options': [ |
566 | + 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0', |
567 | + 'acl foo path_beg -i /foo', 'use_backend foo if foo', |
568 | + ], |
569 | + 'servers': [ |
570 | + ['apache', apache_private, 80, 'maxconn 50']], |
571 | + 'backends': [ |
572 | + {'backend_name': 'foo', |
573 | + 'servers': [ |
574 | + ['apache2', apache_private2, 80, 'maxconn 50']]} |
575 | + ]}]) |
576 | +}) |
577 | +time.sleep(10) |
578 | +d.sentry.wait(seconds) |
579 | + |
580 | +# Let's exercise our URL-based routing by trying to fetch a URL that will |
581 | +# only work for the second apache unit (which is configured as server |
582 | +# of the extra backend). |
583 | +url = 'http://%s/foo' % haproxy_address |
584 | + |
585 | +# We need a retry loop here, since there's no way to tell when the new |
586 | +# configuration is in place. |
587 | +retries = 10 |
588 | +for i in range(retries): |
589 | + try: |
590 | + page = requests.get(url) |
591 | + page.raise_for_status() |
592 | + except: |
593 | + if i == retries - 1: |
594 | + # This was the last one, let's fail |
595 | + raise |
596 | + time.sleep(6) |
597 | + else: |
598 | + break |
599 | + |
600 | +print('Successfully got the /foo URL from the second Apache unit.') |
601 | + |
602 | +# Send a message that the tests are complete. |
603 | +print('The haproxy tests are complete.') |
Thanks, that looks good.
I can't run tests locally at the moment as I'm on Juju 2.0. The two tests look as though they are very similar and could be refactored to call a function to remove the code duplication. I'll approve and merge for now and we can look at refactoring later.