github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/trusty/haproxy/tests/10_deploy_test.py (about) 1 #!/usr/bin/python3 2 3 # This Amulet test deploys haproxy and related charms. 4 5 import os 6 import amulet 7 import requests 8 import base64 9 import yaml 10 import time 11 12 d = amulet.Deployment(series='trusty') 13 # Add the haproxy charm to the deployment. 14 d.add('haproxy') 15 d.add('apache2', units=2) 16 17 # Get the directory this way to load the file when CWD is different. 18 path = os.path.abspath(os.path.dirname(__file__)) 19 template_path = os.path.join(path, 'default_apache.tmpl') 20 # Read in the Apache2 default template file. 21 with open(template_path) as f: 22 template = f.read() 23 encodedTemplate = base64.b64encode(template.encode('utf-8')) 24 # Create a dictionary with configuration values for apache2. 25 configuration = {'vhost_http_template': encodedTemplate.decode('ascii')} 26 # Apache2 needs a base64 encoded template to configure the web site. 27 d.configure('apache2', configuration) 28 29 # Relate the haproxy to apache2. 30 d.relate('haproxy:reverseproxy', 'apache2:website') 31 # Make the haproxy visible to the outside world. 32 d.expose('haproxy') 33 34 # The number of seconds to wait for the environment to setup. 35 seconds = 900 36 try: 37 # Execute the deployer with the current mapping. 38 d.setup(timeout=seconds) 39 # Wait for the relation to finish the transations. 40 d.sentry.wait(seconds) 41 except amulet.helpers.TimeoutError: 42 message = 'The environment did not setup in %d seconds.' % seconds 43 # The SKIP status enables skip or fail the test based on configuration. 44 amulet.raise_status(amulet.SKIP, msg=message) 45 except: 46 raise 47 48 # Test that haproxy is acting as the proxy for apache2. 49 50 # Get the haproxy unit. 51 haproxy_unit = d.sentry['haproxy'][0] 52 haproxy_address = haproxy_unit.info['public-address'] 53 page = requests.get('http://%s/index.html' % haproxy_address) 54 # Raise an error if the page does not load through haproxy. 55 page.raise_for_status() 56 print('Successfully got the Apache2 web page through haproxy IP address.') 57 58 # Test that sticky session cookie is present 59 if page.cookies.get('SRVNAME') != 'S0': 60 msg = 'Missing or invalid sticky session cookie value: %s' % page.cookies.get('SRVNAME') 61 amulet.raise_status(amulet.FAIL, msg=msg) 62 63 # Test that the apache2 relation data is saved on the haproxy server. 64 65 # Get the sentry for apache and get the private IP address. 66 apache_unit = d.sentry['apache2'][0] 67 # Get the relation. 68 relation = apache_unit.relation('website', 'haproxy:reverseproxy') 69 # Get the private address from the relation. 70 apache_private = relation['private-address'] 71 72 print('Private address of the apache2 relation ', apache_private) 73 74 # Grep the configuration file for the private address 75 output, code = haproxy_unit.run('grep %s /etc/haproxy/haproxy.cfg' % 76 apache_private) 77 if code == 0: 78 print('Found the relation IP address in the haproxy configuration file!') 79 print(output) 80 else: 81 print(output) 82 message = 'Unable to find the Apache IP address %s in the haproxy ' \ 83 'configuration file.' % apache_private 84 amulet.raise_status(amulet.FAIL, msg=message) 85 86 # Test SSL termination 87 d.configure('haproxy', { 88 'source': 'backports', 89 'ssl_cert': 'SELFSIGNED', 90 'services': yaml.safe_dump([ 91 {'service_name': 'apache', 92 'service_host': '0.0.0.0', 93 'service_port': 80, 94 'service_options': [ 95 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' 96 ], 97 'servers': [ 98 ['apache', apache_private, 80, 'maxconn 50']]}, 99 {'service_name': 'apache-ssl', 100 'service_port': 443, 101 'service_host': '0.0.0.0', 102 'service_options': [ 103 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0' 104 ], 105 'crts': ['DEFAULT'], 106 'servers': [['apache', apache_private, 80, 'maxconn 50']]}]) 107 }) 108 time.sleep(10) 109 d.sentry.wait(seconds) 110 111 # We need a retry loop here, since there's no way to tell when the new 112 # configuration is in place. 113 url = 'http://%s/index.html' % haproxy_address 114 secure_url = 'https://%s/index.html' % haproxy_address 115 retries = 10 116 for i in range(retries): 117 try: 118 page = requests.get(url) 119 page.raise_for_status() 120 page = requests.get(secure_url, verify=False) 121 page.raise_for_status() 122 success = True 123 except requests.exceptions.ConnectionError: 124 if i == retries - 1: 125 # This was the last one, let's fail 126 raise 127 time.sleep(6) 128 else: 129 break 130 131 print('Successfully got the Apache2 web page through haproxy SSL termination.') 132 133 apache_unit2 = d.sentry['apache2'][1] 134 apache_private2 = apache_unit2.run("unit-get private-address")[0] 135 136 # Create a file on the second apache unit's www directory. 137 apache_unit2.run("echo foo > /var/www/html/foo") 138 139 d.configure('haproxy', { 140 'services': yaml.safe_dump([ 141 {'service_name': 'apache', 142 'service_host': '0.0.0.0', 143 'service_port': 80, 144 'service_options': [ 145 'mode http', 'balance leastconn', 'option httpchk GET / HTTP/1.0', 146 'acl foo path_beg -i /foo', 'use_backend foo if foo', 147 ], 148 'servers': [ 149 ['apache', apache_private, 80, 'maxconn 50']], 150 'backends': [ 151 {'backend_name': 'foo', 152 'servers': [ 153 ['apache2', apache_private2, 80, 'maxconn 50']]} 154 ]}]) 155 }) 156 time.sleep(10) 157 d.sentry.wait(seconds) 158 159 # Let's exercise our URL-based routing by trying to fetch a URL that will 160 # only work for the second apache unit (which is configured as server 161 # of the extra backend). 162 url = 'http://%s/foo' % haproxy_address 163 164 # We need a retry loop here, since there's no way to tell when the new 165 # configuration is in place. 166 retries = 10 167 for i in range(retries): 168 try: 169 page = requests.get(url) 170 page.raise_for_status() 171 except: 172 if i == retries - 1: 173 # This was the last one, let's fail 174 raise 175 time.sleep(6) 176 else: 177 break 178 179 print('Successfully got the /foo URL from the second Apache unit.') 180 181 # Send a message that the tests are complete. 182 print('The haproxy tests are complete.')