252 lines
9.9 KiB
Python
252 lines
9.9 KiB
Python
#!/usr/bin/python3
|
|
|
|
# This Amulet test deploys rabbitmq-server, and the related charms.
|
|
|
|
import amulet
|
|
import os
|
|
import subprocess
|
|
import time
|
|
|
|
# The number of seconds to wait for the environment to setup.
|
|
seconds = 2700
|
|
# The number of units to scale rabbitmq-server to.
|
|
scale = 2
|
|
# The port that amqp traffic is sent on.
|
|
amqp_port = '5672'
|
|
# The directory to use as a block devie for the ceph
|
|
devices = '/srv/osd1'
|
|
# The default version of ceph does not support directories as devices.
|
|
havana = 'cloud:precise-updates/havana'
|
|
# Create a dictionary of configuration values for ceph.
|
|
ceph_configuration = {
|
|
'fsid': 'ecbb8960-0e21-11e2-b495-83a88f44db01',
|
|
'monitor-secret': 'AQBomftSyK1LORAAhg71ukxBxN9ml90stexqEw==',
|
|
'osd-devices': devices,
|
|
'source': havana
|
|
}
|
|
# Create a dictionary of configuration values for cinder.
|
|
cinder_configuration = {
|
|
'block-device': 'None'
|
|
}
|
|
# Create a dictionary of the rabbit configuration values.
|
|
rabbit_configuration = {
|
|
'vip': '192.168.77.11',
|
|
'vip_cidr': 19,
|
|
'vip_iface': 'eth0',
|
|
'ha-bindiface': 'eth0',
|
|
'ha-mcastport': 5406,
|
|
'rbd-size': '2G',
|
|
'rbd-name': 'testrabbit1'
|
|
}
|
|
|
|
# The AMQP package is only available for python version 2.x.
|
|
python2 = '/usr/bin/python'
|
|
if not os.path.isfile(python2):
|
|
error_message = 'Error, python version 2 is required for this test.'
|
|
amulet.raise_status(amulet.FAIL, msg=error_message)
|
|
|
|
series = 'trusty'
|
|
d = amulet.Deployment(series=series)
|
|
# Add rabbitmq-server to the deployment.
|
|
d.add('rabbitmq-server', units=scale)
|
|
|
|
# TODO(billy-olsen) - Rework this following set of code to be more in-line
|
|
# with how the other openstack services are done. For now, we want to test
|
|
# the current branch with the appropriate branches of related charms in
|
|
# order to test /next with /next branches and /trunk with /trunk branches.
|
|
stable = False
|
|
|
|
|
|
def determine_charm_branches(services):
|
|
if stable:
|
|
for svc in services:
|
|
temp = 'lp:charms/{}'
|
|
svc['location'] = temp.format(svc['name'])
|
|
else:
|
|
for svc in services:
|
|
temp = 'lp:~openstack-charmers/charms/{}/{}/next'
|
|
svc['location'] = temp.format(series, svc['name'])
|
|
|
|
return services
|
|
|
|
|
|
def add_services(services):
|
|
"""
|
|
Adds services to the deployment. The input is a list of dicts with
|
|
the key of 'name' name for the service name. The branch location
|
|
will be determined automatically.
|
|
"""
|
|
services = determine_charm_branches(services)
|
|
|
|
for svc in services:
|
|
d.add(svc['name'], charm=svc['location'])
|
|
|
|
|
|
services_to_add = [
|
|
{'name': 'ceph'},
|
|
{'name': 'cinder'},
|
|
{'name': 'hacluster'},
|
|
]
|
|
|
|
# Add the services to the deployment
|
|
add_services(services_to_add)
|
|
|
|
# The ceph charm requires configuration to deploy successfully.
|
|
d.configure('ceph', ceph_configuration)
|
|
# Configure the cinder charm.
|
|
d.configure('cinder', cinder_configuration)
|
|
# Configure the rabbit charm.
|
|
d.configure('rabbitmq-server', rabbit_configuration)
|
|
# Add relation from rabbitmq-server to ceph testing the ceph relation.
|
|
d.relate('rabbitmq-server:ceph', 'ceph:client')
|
|
# Add relation from rabbitmq-server to cinder testing the amqp relation.
|
|
d.relate('rabbitmq-server:amqp', 'cinder:amqp')
|
|
# Add relation from rabibtmq-server to hacluster testing the ha relation.
|
|
d.relate('rabbitmq-server:ha', 'hacluster:ha')
|
|
# Expose the rabbitmq-server.
|
|
d.expose('rabbitmq-server')
|
|
|
|
try:
|
|
# Execute the deployer with the current mapping.
|
|
d.setup(timeout=seconds)
|
|
# Wait for the relation to finish the transations.
|
|
d.sentry.wait(seconds)
|
|
except amulet.helpers.TimeoutError:
|
|
message = 'The environment did not setup in %d seconds.' % seconds
|
|
# The SKIP status enables skip or fail the test based on configuration.
|
|
amulet.raise_status(amulet.FAIL, msg=message)
|
|
except:
|
|
raise
|
|
print('The environment successfully deployed.')
|
|
|
|
# Create a counter to make the messages unique.
|
|
counter = 1
|
|
# Get the directory in this way to load the files from the tests directory.
|
|
path = os.path.abspath(os.path.dirname(__file__))
|
|
# Create a path to the python test file to call.
|
|
amqp_tester = os.path.join(path, 'amqp_tester.py')
|
|
if not os.path.isfile(amqp_tester):
|
|
error_message = 'Unable to locate python test file %s' % amqp_tester
|
|
amulet.raise_status(amulet.FAIL, msg=error_message)
|
|
|
|
# Verify the ceph unit was created.
|
|
ceph_unit = d.sentry.unit['ceph/0']
|
|
# Verify the cinder unit was created.
|
|
cinder_unit = d.sentry.unit['cinder/0']
|
|
rabbit_units = []
|
|
for n in range(scale):
|
|
# Get each rabbitmq unit that was deployed.
|
|
rabbit_units.append(d.sentry.unit['rabbitmq-server/%d' % n])
|
|
|
|
# Iterate over every rabbitmq-unit to get the different relations.
|
|
for rabbit_unit in rabbit_units:
|
|
###########################################################################
|
|
# Test Relations
|
|
###########################################################################
|
|
# Verify the ceph relation was created for the rabbit unit.
|
|
rabbit_relation = rabbit_unit.relation('ceph', 'ceph:client')
|
|
print('rabbit relation to ceph:')
|
|
for key, value in rabbit_relation.items():
|
|
print(key, value)
|
|
# Verify the amqp relation was created for the rabbit unit.
|
|
rabbit_relation = rabbit_unit.relation('amqp', 'cinder:amqp')
|
|
print('rabbit relation to amqp:')
|
|
for key, value in rabbit_relation.items():
|
|
print(key, value)
|
|
|
|
# The hacluster charm is a subordinate, since the relation-sentry is also
|
|
# a subordinate charm no sentry is created for the hacluster relation.
|
|
|
|
# Verify the rabbit relation was created with the ceph unit.
|
|
ceph_relation = ceph_unit.relation('client', 'rabbitmq-server:ceph')
|
|
print('ceph relation to rabbitmq-server:')
|
|
for key, value in ceph_relation.items():
|
|
print(key, value)
|
|
# Verify the rabbit relation was created with the cinder unit.
|
|
cinder_relation = cinder_unit.relation('amqp', 'rabbitmq-server:amqp')
|
|
print('cinder relation to rabbitmq-server:')
|
|
for key, value in cinder_relation.items():
|
|
print(key, value)
|
|
|
|
###########################################################################
|
|
# Test AMQP
|
|
###########################################################################
|
|
|
|
# The AMQP python library is only available for python2 at this time.
|
|
# Call out a command to run the python2 code to test the AMQP protocol.
|
|
|
|
# Get the public address for rabbitmq-server instance.
|
|
server_address = rabbit_unit.info['public-address']
|
|
# Create a time stamp to help make the AMQP message unique.
|
|
time_stamp = time.strftime('%F %r')
|
|
# Create the message to send on the AMPQ protocol.
|
|
amqp_message = "Message #{0} to send using the AMPQ protocol {1}".format(
|
|
counter, time_stamp)
|
|
# Create the command with arguments that sends the message.
|
|
send_command = [python2, amqp_tester, server_address, amqp_port,
|
|
amqp_message]
|
|
print(send_command)
|
|
# Call the python command to send the AMQP message to the server.
|
|
output = subprocess.check_output(send_command)
|
|
# Create the command with arguments to receive messages.
|
|
receive_command = [python2, amqp_tester, server_address, amqp_port]
|
|
print(receive_command)
|
|
# Call the python command to receive the AMQP message from the same server.
|
|
output = subprocess.check_output(receive_command)
|
|
# The output is a byte string so convert the message to a byte string.
|
|
if output.find(amqp_message.encode()) == -1:
|
|
print('The AMQP test to {0}:{1} failed.'.format(server_address,
|
|
amqp_port))
|
|
amulet.raise_status(amulet.FAIL, msg=output)
|
|
else:
|
|
print('The AMQP test to {0}:{1} completed successfully.'.format(
|
|
server_address, amqp_port))
|
|
counter += 1
|
|
|
|
###########################################################################
|
|
# Verify that the rabbitmq cluster status is correct.
|
|
###########################################################################
|
|
# Create the command that checks if the rabbitmq-server service is running.
|
|
command = 'rabbitmqctl cluster_status'
|
|
print(command)
|
|
# Execute the command on the deployed service.
|
|
output, code = rabbit_unit.run(command)
|
|
print(output)
|
|
# Check the return code for the success and failure of this test.
|
|
if (code != 0):
|
|
message = 'The ' + command + ' did not return the expected code of 0.'
|
|
amulet.raise_status(amulet.FAIL, msg=message)
|
|
else:
|
|
print('The rabbitmq-server cluster status is OK.')
|
|
|
|
###############################################################################
|
|
# Test the AMQP messages can be sent from and read from another.
|
|
###############################################################################
|
|
# Get the public address for rabbitmq-server instance 0.
|
|
send_address = rabbit_units[0].info['public-address']
|
|
# Create a message to send from instance 0 and read it from instance 1.
|
|
amqp_message = "Message #{0} sent from {1} using the AMQP protocol.".format(
|
|
counter, send_address)
|
|
counter += 1
|
|
# Create the command that sends the message to instance 0.
|
|
send_command = [python2, amqp_tester, send_address, amqp_port, amqp_message]
|
|
print(send_command)
|
|
output = subprocess.check_output(send_command)
|
|
# Get the public address for rabbitmq-server instance 1.
|
|
receive_address = rabbit_units[1].info['public-address']
|
|
# Create the command that receives the message from instance 1.
|
|
recieve_command = [python2, amqp_tester, receive_address, amqp_port]
|
|
print(recieve_command)
|
|
output = subprocess.check_output(receive_command)
|
|
# The output is a byte string so convert the message to a byte string.
|
|
if output.find(amqp_message.encode()) == -1:
|
|
print(output)
|
|
message = 'Server {0} did not receive the AMQP message "{1}"'.format(
|
|
receive_address, amqp_message)
|
|
amulet.raise_status(amulet.FAIL, msg=message)
|
|
else:
|
|
print('Server {0} received the AMQP message sent from {1}'.format(
|
|
receive_address, send_address))
|
|
|
|
print('The rabbitmq-server charm passed this relations test.')
|