Merge lp:~mbruzek/charms/precise/rabbitmq-server/add-tests into lp:charms/rabbitmq-server

Proposed by Matt Bruzek on 2015-01-09
Status: Merged
Merged at revision: 74
Proposed branch: lp:~mbruzek/charms/precise/rabbitmq-server/add-tests
Merge into: lp:charms/rabbitmq-server
Diff against target: 657 lines (+605/-1)
9 files modified
Makefile (+5/-1)
tests/00_setup.sh (+16/-0)
tests/10_basic_deploy_test.py (+101/-0)
tests/20_deploy_relations_test.py (+214/-0)
tests/30_configuration_test.py (+142/-0)
tests/amqp_tester.py (+65/-0)
tests/rabbit-server-cacert.pem (+17/-0)
tests/rabbit-server-cert.pem (+18/-0)
tests/rabbit-server-privkey.pem (+27/-0)
To merge this branch: bzr merge lp:~mbruzek/charms/precise/rabbitmq-server/add-tests
Reviewer Review Type Date Requested Status
Review Queue (community) automated testing Needs Fixing on 2015-01-12
José Antonio Rey (community) charmers 2015-01-09 Approve on 2015-01-12
Ryan Beisner Approve on 2015-01-12
Review via email: mp+246025@code.launchpad.net

Description of the change

Adding tests for the rabbitmq-server charm.

To post a comment you must log in.
Ryan Beisner (1chb1n) wrote :

Thank you for the amulet test coverage work on rmq, much appreciated!

If we can get this added to Makefile, that will make OSCI's engine happy:

test:
    @echo Starting amulet tests...
    @juju test -v -p AMULET_HTTP_PROXY --timeout 900

I just sent your branch with ^ that mod through to confirm:
  juju-test.conductor.00_setup.sh RESULT : ✔
  juju-test.conductor.10_basic_deploy_test.py RESULT : ✔
  juju-test.conductor.20_deploy_relations_test.py RESULT : ✔
  juju-test.conductor.30_configuration_test.py RESULT : ✔
  juju-test INFO : Results: 4 passed, 0 failed, 0 errored

I think most of the openstack charms use the 'test' target name. But actually, you can name the make target anything as OSCI just looks for '@juju test' in a target and runs that target.

76. By Matt Bruzek on 2015-01-12

Adding Makefile changes

Matt Bruzek (mbruzek) wrote :

Thanks for the review. I added the functional_test target to the Makefile so these tests work on both testing systems. Charmers please review these changes for inclusion to the precise charm.

Ryan Beisner (1chb1n) wrote :

Re-confirmed with rev76. Precise charm amulet tests succeed. Clear from the OSCI perspective. Thanks again!

review: Approve
José Antonio Rey (jose) wrote :

Hey Matt!

Thank you for taking the time to write this tests. I have ran them on EC2, and turns out they successfully pass!

I will be pushing these on the next few minutes. Thanks again!

review: Approve (charmers)
Review Queue (review-queue) wrote :

This items has failed automated testing! Results available here http://reports.vapour.ws/charm-tests/charm-bundle-test-10905-results

review: Needs Fixing (automated testing)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2014-10-08 15:57:57 +0000
3+++ Makefile 2015-01-12 15:19:55 +0000
4@@ -20,7 +20,11 @@
5 bzr push lp:charms/rabbitmq-server
6 bzr push lp:charms/trusty/rabbitmq-server
7
8+functional_test:
9+ @echo Starting functional tests...
10+ @juju test -v -p AMULET_HTTP_PROXY --timeout 900
11+
12 unit_test:
13- @echo Starting tests...
14+ @echo Starting unit tests...
15 CHARM_DIR=$(CHARM_DIR) $(TEST_PREFIX) nosetests unit_tests
16
17
18=== added directory 'tests'
19=== added file 'tests/00_setup.sh'
20--- tests/00_setup.sh 1970-01-01 00:00:00 +0000
21+++ tests/00_setup.sh 2015-01-12 15:19:55 +0000
22@@ -0,0 +1,16 @@
23+#!/bin/sh
24+
25+# Install Juju Amulet and any other applications that are needed for the tests.
26+
27+set -x
28+
29+# Check if amulet is installed before adding repository and updating apt-get.
30+dpkg -s amulet
31+if [ $? -ne 0 ]; then
32+ sudo add-apt-repository -y ppa:juju/stable
33+ sudo apt-get update
34+ sudo apt-get install -y amulet
35+fi
36+
37+# Install any additional python packages, or software here.
38+sudo apt-get install -y python python-pika python3-requests
39
40=== added file 'tests/10_basic_deploy_test.py'
41--- tests/10_basic_deploy_test.py 1970-01-01 00:00:00 +0000
42+++ tests/10_basic_deploy_test.py 2015-01-12 15:19:55 +0000
43@@ -0,0 +1,101 @@
44+#!/usr/bin/python3
45+
46+# This Amulet test performs a basic deploy and checks if rabbitmq is running.
47+
48+import amulet
49+import os
50+import socket
51+import ssl
52+
53+# The number of seconds to wait for the environment to setup.
54+seconds = 900
55+# Get the directory in this way to load the files from the tests directory.
56+path = os.path.abspath(os.path.dirname(__file__))
57+
58+key_path = os.path.join(path, 'rabbit-server-privkey.pem')
59+# Read the private key file.
60+with open(key_path) as f:
61+ privateKey = f.read()
62+# Read the certificate file.
63+cert_path = os.path.join(path, 'rabbit-server-cert.pem')
64+with open(cert_path) as f:
65+ certificate = f.read()
66+
67+# Create a dictionary for the rabbitmq configuration.
68+rabbitmq_configuration = {
69+ 'ssl_enabled': True,
70+ 'ssl_key': privateKey,
71+ 'ssl_cert': certificate,
72+ 'ssl_port': 5671
73+}
74+
75+d = amulet.Deployment()
76+# Add the rabbitmq-server charm to the deployment.
77+d.add('rabbitmq-server')
78+# Configure options on the rabbitmq-server.
79+d.configure('rabbitmq-server', rabbitmq_configuration)
80+# Expose the server so we can connect.
81+d.expose('rabbitmq-server')
82+
83+try:
84+ # Execute the deployer with the current mapping.
85+ d.setup(timeout=seconds)
86+except amulet.helpers.TimeoutError:
87+ message = 'The environment did not setup in %d seconds.' % seconds
88+ # The SKIP status enables skip or fail the test based on configuration.
89+ amulet.raise_status(amulet.SKIP, msg=message)
90+except:
91+ raise
92+print('The rabbitmq-server has been successfully deployed.')
93+
94+###############################################################################
95+## Verify that the rabbit service is running on the deployed server.
96+###############################################################################
97+rabbitmq_sentry = d.sentry.unit['rabbitmq-server/0']
98+# Get the public address for rabbitmq-server instance.
99+server_address = rabbitmq_sentry.info['public-address']
100+# Create the command that checks if the rabbitmq-server service is running.
101+command = 'rabbitmqctl status'
102+print(command)
103+# Execute the command on the deployed service.
104+output, code = rabbitmq_sentry.run(command)
105+print(output)
106+# Check the return code for the success and failure of this test.
107+if (code != 0):
108+ message = 'The ' + command + ' did not return the expected code of 0.'
109+ amulet.raise_status(amulet.FAIL, msg=message)
110+else:
111+ print('The rabbitmq-server is running on %s' % server_address)
112+
113+###############################################################################
114+## Test the ssl certificate.
115+###############################################################################
116+# Get the port for ssl_port instance.
117+server_port = rabbitmq_configuration['ssl_port']
118+
119+# Get the path to the certificate authority file.
120+ca_cert_path = os.path.join(path, 'rabbit-server-cacert.pem')
121+
122+print('Testing ssl connection to rabbitmq-server.')
123+try:
124+ # Create a normal socket.
125+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
126+ # Require a certificate from the server, since a self-signed certificate
127+ # was used, the ca_certs must be the server certificate file itself.
128+ ssl_sock = ssl.wrap_socket(s, ca_certs=ca_cert_path,
129+ cert_reqs=ssl.CERT_REQUIRED)
130+ # Connect to the rabbitmq server using ssl.
131+ ssl_sock.connect((server_address, server_port))
132+ # Get the certificate.
133+ certificate = ssl_sock.getpeercert()
134+ # SSL socket connected and got the certificate, this passes the ssl test!
135+ print('Connected to the rabbitmq-server {0}:{1} using ssl!'.format(
136+ server_address, server_port))
137+except Exception as e:
138+ message = 'Failed to create an ssl connection to {0}:{1}\n{2}'.format(
139+ server_address, server_port, str(e))
140+ amulet.raise_status(amulet.FAIL, msg=message)
141+finally:
142+ ssl_sock.close()
143+
144+print('The rabbitmq-server passed the basic deploy test!')
145
146=== added file 'tests/20_deploy_relations_test.py'
147--- tests/20_deploy_relations_test.py 1970-01-01 00:00:00 +0000
148+++ tests/20_deploy_relations_test.py 2015-01-12 15:19:55 +0000
149@@ -0,0 +1,214 @@
150+#!/usr/bin/python3
151+
152+# This Amulet test deploys rabbitmq-server, and the related charms.
153+
154+import amulet
155+import os
156+import subprocess
157+import time
158+
159+# The number of seconds to wait for the environment to setup.
160+seconds = 900
161+# The number of units to scale rabbitmq-server to.
162+scale = 2
163+# The port that amqp traffic is sent on.
164+amqp_port = '5672'
165+# The directory to use as a block devie for the ceph
166+devices = '/srv/osd1'
167+# The default version of ceph does not support directories as devices.
168+havana = 'cloud:precise-updates/havana'
169+# Create a dictionary of configuration values for ceph.
170+ceph_configuration = {
171+ 'fsid': 'ecbb8960-0e21-11e2-b495-83a88f44db01',
172+ 'monitor-secret': 'AQBomftSyK1LORAAhg71ukxBxN9ml90stexqEw==',
173+ 'osd-devices': devices,
174+ 'source': havana
175+}
176+# Create a dictionary of configuration values for cinder.
177+cinder_configuration = {
178+ 'block-device': 'None'
179+}
180+# Create a dictionary of the rabbit configuration values.
181+rabbit_configuration = {
182+ 'vip': '192.168.77.11',
183+ 'vip_cidr': 19,
184+ 'vip_iface': 'eth0',
185+ 'ha-bindiface': 'eth0',
186+ 'ha-mcastport': 5406,
187+ 'rbd-size': '2G',
188+ 'rbd-name': 'testrabbit1'
189+}
190+
191+# The AMQP package is only available for python version 2.x.
192+python2 = '/usr/bin/python'
193+if not os.path.isfile(python2):
194+ error_message = 'Error, python version 2 is required for this test.'
195+ amulet.raise_status(amulet.FAIL, msg=error_message)
196+
197+d = amulet.Deployment()
198+# Add rabbitmq-server to the deployment.
199+d.add('rabbitmq-server', units=scale)
200+# Add the ceph charm to the deployment.
201+d.add('ceph')
202+# Add cinder to the deployment to test the AMQP relation.
203+d.add('cinder')
204+# Add hacluster to the deployment to test the ha relation.
205+d.add('hacluster')
206+# The ceph charm requires configuration to deploy successfully.
207+d.configure('ceph', ceph_configuration)
208+# Configure the cinder charm.
209+d.configure('cinder', cinder_configuration)
210+# Configure the rabbit charm.
211+d.configure('rabbitmq-server', rabbit_configuration)
212+# Add relation from rabbitmq-server to ceph testing the ceph relation.
213+d.relate('rabbitmq-server:ceph', 'ceph:client')
214+# Add relation from rabbitmq-server to cinder testing the amqp relation.
215+d.relate('rabbitmq-server:amqp', 'cinder:amqp')
216+# Add relation from rabibtmq-server to hacluster testing the ha relation.
217+d.relate('rabbitmq-server:ha', 'hacluster:ha')
218+# Expose the rabbitmq-server.
219+d.expose('rabbitmq-server')
220+
221+try:
222+ # Execute the deployer with the current mapping.
223+ d.setup(timeout=seconds)
224+ # Wait for the relation to finish the transations.
225+ d.sentry.wait(seconds)
226+except amulet.helpers.TimeoutError:
227+ message = 'The environment did not setup in %d seconds.' % seconds
228+ # The SKIP status enables skip or fail the test based on configuration.
229+ amulet.raise_status(amulet.FAIL, msg=message)
230+except:
231+ raise
232+print('The environment successfully deployed.')
233+
234+# Create a counter to make the messages unique.
235+counter = 1
236+# Get the directory in this way to load the files from the tests directory.
237+path = os.path.abspath(os.path.dirname(__file__))
238+# Create a path to the python test file to call.
239+amqp_tester = os.path.join(path, 'amqp_tester.py')
240+if not os.path.isfile(amqp_tester):
241+ error_message = 'Unable to locate python test file %s' % amqp_tester
242+ amulet.raise_status(amulet.FAIL, msg=error_message)
243+
244+# Verify the ceph unit was created.
245+ceph_unit = d.sentry.unit['ceph/0']
246+# Verify the cinder unit was created.
247+cinder_unit = d.sentry.unit['cinder/0']
248+rabbit_units = []
249+for n in range(scale):
250+ # Get each rabbitmq unit that was deployed.
251+ rabbit_units.append(d.sentry.unit['rabbitmq-server/%d' % n])
252+
253+# Iterate over every rabbitmq-unit to get the different relations.
254+for rabbit_unit in rabbit_units:
255+ ###########################################################################
256+ ## Test Relations
257+ ###########################################################################
258+ # Verify the ceph relation was created for the rabbit unit.
259+ rabbit_relation = rabbit_unit.relation('ceph', 'ceph:client')
260+ print('rabbit relation to ceph:')
261+ for key, value in rabbit_relation.items():
262+ print(key, value)
263+ # Verify the amqp relation was created for the rabbit unit.
264+ rabbit_relation = rabbit_unit.relation('amqp', 'cinder:amqp')
265+ print('rabbit relation to amqp:')
266+ for key, value in rabbit_relation.items():
267+ print(key, value)
268+
269+ # The hacluster charm is a subordinate, since the relation-sentry is also
270+ # a subordinate charm no sentry is created for the hacluster relation.
271+
272+ # Verify the rabbit relation was created with the ceph unit.
273+ ceph_relation = ceph_unit.relation('client', 'rabbitmq-server:ceph')
274+ print('ceph relation to rabbitmq-server:')
275+ for key, value in ceph_relation.items():
276+ print(key, value)
277+ # Verify the rabbit relation was created with the cinder unit.
278+ cinder_relation = cinder_unit.relation('amqp', 'rabbitmq-server:amqp')
279+ print('cinder relation to rabbitmq-server:')
280+ for key, value in cinder_relation.items():
281+ print(key, value)
282+
283+ ###########################################################################
284+ ## Test AMQP
285+ ###########################################################################
286+
287+ # The AMQP python library is only available for python2 at this time.
288+ # Call out a command to run the python2 code to test the AMQP protocol.
289+
290+ # Get the public address for rabbitmq-server instance.
291+ server_address = rabbit_unit.info['public-address']
292+ # Create a time stamp to help make the AMQP message unique.
293+ time_stamp = time.strftime('%F %r')
294+ # Create the message to send on the AMPQ protocol.
295+ amqp_message = "Message #{0} to send using the AMPQ protocol {1}".format(
296+ counter, time_stamp)
297+ # Create the command with arguments that sends the message.
298+ send_command = [python2, amqp_tester, server_address, amqp_port,
299+ amqp_message]
300+ print(send_command)
301+ # Call the python command to send the AMQP message to the server.
302+ output = subprocess.check_output(send_command)
303+ # Create the command with arguments to receive messages.
304+ receive_command = [python2, amqp_tester, server_address, amqp_port]
305+ print(receive_command)
306+ # Call the python command to receive the AMQP message from the same server.
307+ output = subprocess.check_output(receive_command)
308+ # The output is a byte string so convert the message to a byte string.
309+ if output.find(amqp_message.encode()) == -1:
310+ print('The AMQP test to {0}:{1} failed.'.format(server_address,
311+ amqp_port))
312+ amulet.raise_status(amulet.FAIL, msg=output)
313+ else:
314+ print('The AMQP test to {0}:{1} completed successfully.'.format(
315+ server_address, amqp_port))
316+ counter += 1
317+
318+ ###########################################################################
319+ ## Verify that the rabbitmq cluster status is correct.
320+ ###########################################################################
321+ # Create the command that checks if the rabbitmq-server service is running.
322+ command = 'rabbitmqctl cluster_status'
323+ print(command)
324+ # Execute the command on the deployed service.
325+ output, code = rabbit_unit.run(command)
326+ print(output)
327+ # Check the return code for the success and failure of this test.
328+ if (code != 0):
329+ message = 'The ' + command + ' did not return the expected code of 0.'
330+ amulet.raise_status(amulet.FAIL, msg=message)
331+ else:
332+ print('The rabbitmq-server cluster status is OK.')
333+
334+###############################################################################
335+## Test the AMQP messages can be sent from and read from another.
336+###############################################################################
337+# Get the public address for rabbitmq-server instance 0.
338+send_address = rabbit_units[0].info['public-address']
339+# Create a message to send from instance 0 and read it from instance 1.
340+amqp_message = "Message #{0} sent from {1} using the AMQP protocol.".format(
341+ counter, send_address)
342+counter += 1
343+# Create the command that sends the message to instance 0.
344+send_command = [python2, amqp_tester, send_address, amqp_port, amqp_message]
345+print(send_command)
346+output = subprocess.check_output(send_command)
347+# Get the public address for rabbitmq-server instance 1.
348+receive_address = rabbit_units[1].info['public-address']
349+# Create the command that receives the message from instance 1.
350+recieve_command = [python2, amqp_tester, receive_address, amqp_port]
351+print(recieve_command)
352+output = subprocess.check_output(receive_command)
353+# The output is a byte string so convert the message to a byte string.
354+if output.find(amqp_message.encode()) == -1:
355+ print(output)
356+ message = 'Server {0} did not receive the AMQP message "{1}"'.format(
357+ receive_address, amqp_message)
358+ amulet.raise_status(amulet.FAIL, msg=message)
359+else:
360+ print('Server {0} received the AMQP message sent from {1}'.format(
361+ receive_address, send_address))
362+
363+print('The rabbitmq-server charm passed this relations test.')
364
365=== added file 'tests/30_configuration_test.py'
366--- tests/30_configuration_test.py 1970-01-01 00:00:00 +0000
367+++ tests/30_configuration_test.py 2015-01-12 15:19:55 +0000
368@@ -0,0 +1,142 @@
369+#!/usr/bin/python3
370+
371+# This Amulet test exercises the configuration options for rabbitmq-server.
372+
373+import amulet
374+import os
375+import requests
376+import socket
377+import ssl
378+
379+# The number of seconds to wait for the environment to setup.
380+seconds = 900
381+# Get the directory in this way to load the files from the tests directory.
382+path = os.path.abspath(os.path.dirname(__file__))
383+key_path = os.path.join(path, 'rabbit-server-privkey.pem')
384+# Read the private key file.
385+with open(key_path) as f:
386+ privateKey = f.read()
387+cert_path = os.path.join(path, 'rabbit-server-cert.pem')
388+# Read the certificate file.
389+with open(cert_path) as f:
390+ certificate = f.read()
391+
392+# Create a dictionary of all the configuration values.
393+rabbit_configuration = {
394+ 'management_plugin': True,
395+ 'ssl_enabled': True,
396+ 'ssl_port': 5999,
397+ 'ssl_key': privateKey,
398+ 'ssl_cert': certificate
399+}
400+
401+d = amulet.Deployment()
402+# Add the rabbitmq-server charm to the deployment.
403+d.add('rabbitmq-server')
404+# Configure all the options on rabbitmq-server.
405+d.configure('rabbitmq-server', rabbit_configuration)
406+# Expose the rabbitmq-server.
407+d.expose('rabbitmq-server')
408+
409+try:
410+ # Execute the deployer with the current mapping.
411+ d.setup(timeout=seconds)
412+ # Wait for the relation to finish the transations.
413+ #d.sentry.wait(seconds)
414+except amulet.helpers.TimeoutError:
415+ message = 'The environment did not setup in %d seconds.' % seconds
416+ # The SKIP status enables skip or fail the test based on configuration.
417+ amulet.raise_status(amulet.SKIP, msg=message)
418+except:
419+ raise
420+
421+rabbit_unit = d.sentry.unit['rabbitmq-server/0']
422+###############################################################################
423+## Verify that the rabbit service is running on the deployed server.
424+###############################################################################
425+# Create the command that checks if the rabbitmq-server service is running.
426+command = 'rabbitmqctl status'
427+print(command)
428+# Execute the command on the deployed service.
429+output, code = rabbit_unit.run(command)
430+print(output)
431+# Check the return code for the success and failure of this test.
432+if (code != 0):
433+ message = 'The ' + command + ' did not return the expected code of 0.'
434+ amulet.raise_status(amulet.FAIL, msg=message)
435+else:
436+ print('The rabbitmq-server is running.')
437+
438+###############################################################################
439+## Verify the configuration values.
440+###############################################################################
441+# Get the contents of the private key from the rabbitmq-server
442+contents = rabbit_unit.file_contents('/etc/rabbitmq/rabbit-server-privkey.pem')
443+# Verify the private key was saved on the rabbitmq server correctly.
444+if contents != privateKey:
445+ message = 'The private keys did not match!'
446+ amulet.raise_status(amulet.FAIL, msg=message)
447+else:
448+ print('The private keys was configured properly on the rabbitmq server.')
449+
450+# Get the contents of the certificate from the rabbitmq-server.
451+contents = rabbit_unit.file_contents('/etc/rabbitmq/rabbit-server-cert.pem')
452+# Verify the certificate was saved on the rabbitmq server correctly.
453+if contents != certificate:
454+ message = 'The certificates did not match!'
455+ amulet.raise_status(amulet.FAIL, msg=message)
456+else:
457+ print('The certificate was configured properly on the rabbitmq server.')
458+
459+# Get the public address for rabbitmq-server instance.
460+rabbit_host = rabbit_unit.info['public-address']
461+
462+###############################################################################
463+## Verify the management plugin is running and responding on correct port.
464+## According to this: http://www.rabbitmq.com/access-control.html
465+## The guest account can only log in from local host.
466+## Since this test runs on a different system there is no way to test
467+## the management plugin.
468+###############################################################################
469+# Create a url for the rabbitmq server's managment plugin (uses 55672).
470+#management_url = 'http://{0}:55672'.format(rabbit_host)
471+#print(management_url)
472+# Get the management url with the authentication for guest.
473+#r = requests.get(management_url, auth=('guest', 'guest'))
474+# Raise an exception if response is not 200 OK.
475+#r.raise_for_status()
476+#print(str(r))
477+#print('Successfully authenticated to the management console at %s' %
478+# management_url)
479+
480+###############################################################################
481+## Verify that SSL is set up on the non-default port.
482+###############################################################################
483+# Get the port for ssl_port instance.
484+ssl_port = rabbit_configuration['ssl_port']
485+
486+# Get the path to the certificate authority file.
487+ca_cert_path = os.path.join(path, 'rabbit-server-cacert.pem')
488+
489+try:
490+ # Create a normal socket.
491+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
492+ # Require a certificate from the server, since a self-signed certificate
493+ # was used, the ca_certs must be the server certificate file itself.
494+ ssl_sock = ssl.wrap_socket(s, ca_certs=ca_cert_path,
495+ cert_reqs=ssl.CERT_REQUIRED)
496+ # Connect to the rabbitmq server using ssl.
497+ ssl_sock.connect((rabbit_host, ssl_port))
498+ # Get the certificate.
499+ certificate = ssl_sock.getpeercert()
500+ # SSL scoket connected and got the certificate, this passes the ssl test!
501+ print('Connected to the rabbitmq-server {0}:{1} using ssl!'.format(
502+ rabbit_host, ssl_port))
503+except Exception as e:
504+ message = 'Failed to create an ssl connection to {0}:{1}\n{2}'.format(
505+ rabbit_host, ssl_port, str(e))
506+ amulet.raise_status(amulet.FAIL, msg=message)
507+finally:
508+ ssl_sock.close()
509+
510+print('The rabbitmq-server passed the configuration tests.')
511
512=== added file 'tests/amqp_tester.py'
513--- tests/amqp_tester.py 1970-01-01 00:00:00 +0000
514+++ tests/amqp_tester.py 2015-01-12 15:19:55 +0000
515@@ -0,0 +1,65 @@
516+#!/usr/bin/python
517+
518+# This class uses Python to make AMQP calls to send and receive messages.
519+# To send an AMQP message call this module with a host, port, and message.
520+# To receive an AMQP message call this module with a host and port only.
521+
522+import logging
523+import pika
524+import sys
525+
526+
527+def send(host, port, message, queue='test'):
528+ """ Send an AMQP message to a host and port."""
529+ connection = None
530+ try:
531+ parameters = pika.ConnectionParameters(host, port)
532+ connection = pika.BlockingConnection(parameters)
533+
534+ channel = connection.channel()
535+ channel.queue_declare(queue)
536+ channel.basic_publish(exchange='', routing_key=queue, body=message)
537+ print('Message published to {0}:{1}'.format(host, port))
538+ except Exception as e:
539+ print('Unable to send message to {0}:{1}'.format(host, port))
540+ print(e)
541+ finally:
542+ if connection:
543+ connection.close()
544+
545+
546+def callback(ch, method, properties, body):
547+ """ Handle the callback when the channel receives a message. """
548+ print(body)
549+
550+
551+def receive(host, port, queue='test'):
552+ """ Connects to host and port, and consumes AMQP messages. """
553+ connection = None
554+ try:
555+ parameters = pika.ConnectionParameters(host, port)
556+ connection = pika.BlockingConnection(parameters)
557+ channel = connection.channel()
558+ channel.queue_declare(queue)
559+ channel.basic_consume(callback, queue, no_ack=True)
560+ except Exception as e:
561+ print('Unable to receive message from {0}:{1}'.format(host, port))
562+ print(e)
563+ finally:
564+ if connection:
565+ connection.close()
566+
567+# Needed to disable pika complaining about logging levels not set.
568+logging.basicConfig(level=logging.ERROR)
569+
570+if len(sys.argv) == 3:
571+ host = sys.argv[1]
572+ port = int(sys.argv[2])
573+ receive(host, port)
574+elif len(sys.argv) > 3:
575+ host = sys.argv[1]
576+ port = int(sys.argv[2])
577+ message = ' '.join(sys.argv[3:])
578+ send(host, port, message)
579+else:
580+ print('Not enough arguments, host and port are required.')
581
582=== added file 'tests/rabbit-server-cacert.pem'
583--- tests/rabbit-server-cacert.pem 1970-01-01 00:00:00 +0000
584+++ tests/rabbit-server-cacert.pem 2015-01-12 15:19:55 +0000
585@@ -0,0 +1,17 @@
586+-----BEGIN CERTIFICATE-----
587+MIICxjCCAa6gAwIBAgIJAIOIZyP0JpvLMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
588+BAMTCE15VGVzdENBMB4XDTE0MDIyMzIwMDgxOFoXDTE1MDIyMzIwMDgxOFowEzER
589+MA8GA1UEAxMITXlUZXN0Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
590+AQDceXBJOhn9d68M9UiOViWz00Znds1xk9i+GbZFEsqLPkoReS9g/SeXvR5ZFZlU
591+5gzAcg8z8b+n26wgZLFQJ4wQAIVELIu0S6e4sUPKfKl/fo9NmRVv/sPkfZWUZ5sc
592+d9DEk8MiNYjjXT+Ff4TV7DFxdDOJLIDrc09JWzIKrmfOXP5wLFCsIllGbellfNvY
593+FxiHHm3Iz5t3t077+uUXeMD5p1Qd2qQdbJ2p8Dwkg2AyTPNG8RA71tEMIT7FX0nB
594+sTX5M217ocdEZJI67x+3Z8Ll21m6blcnJI3V3Zk5kvccvYRlDuyGh7tiWcv4YKmv
595+xuP64L9174nQ3HXnwipfjBkBAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0P
596+BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAaQWYVUuPKRtAFd6kyugL/UpVhIa/o
597+zfm/2b23UviPA1TIYzzf4m1eDV7kxJynOeP1RRPp166el+sVx7+vqhBsqcm4b5e+
598+epShI3jff0gtODxo5rUVrROS3T6xjHA7AVm60/xmGIIybhDonXzA5YJ8YVBpHUdZ
599+Yc2neOwdDT8k/H95cPXBU3pf3vTVpndjN827fBuyO7KwKDAiKHwtwmSedc1uZtLN
600+sfwkonXF+gNAHXlk28VeygGQ1jHdloIrNG0zYc4ZX4zqPHd7HDeyYItBBHjrznow
601+nf1X6fNjP4YnG5EkUN8hRXf3ct+L8iq8puMNhjb8ssW+bsFRBIufVFaC
602+-----END CERTIFICATE-----
603
604=== added file 'tests/rabbit-server-cert.pem'
605--- tests/rabbit-server-cert.pem 1970-01-01 00:00:00 +0000
606+++ tests/rabbit-server-cert.pem 2015-01-12 15:19:55 +0000
607@@ -0,0 +1,18 @@
608+-----BEGIN CERTIFICATE-----
609+MIIC5TCCAc2gAwIBAgIBATANBgkqhkiG9w0BAQUFADATMREwDwYDVQQDEwhNeVRl
610+c3RDQTAeFw0xNDAyMjMyMDA5MjFaFw0xNTAyMjMyMDA5MjFaMCgxFTATBgNVBAMM
611+DHJlYWxtcy1zbGljZTEPMA0GA1UECgwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEF
612+AAOCAQ8AMIIBCgKCAQEApc6WxtgQZL+PcDHL1S/kLqFyGPaKiJQrOPGYq9djM5pr
613+VGPHUZ3F26VWtlBtPB8PgQFT10Sjr+ec7hC9aqT+THyNq2U8qCizGq4l4e44tfEI
614+LPuE9IluF/dZuVWFR2nbVYp3FeAjuRQ68AwzpcZOXVup3xsXx7dJrGL4KUx/7NUb
615+5+6TzboM1nXX7o/DYCE5BvXncM7U3cLg16SV58T6Rs+JYATAFdzveN6X88AgvQpB
616+rDSD42tSQmQzYu9mO2RwtP48jLvYLHv34dZo2h6G5zNWe/PkUjXxKEGJXHkeXy83
617+vx4UV62Vo8pMLeSSqL4wUV3KMRHJ+MBskP42lmruwQIDAQABoy8wLTAJBgNVHRME
618+AjAAMAsGA1UdDwQEAwIFIDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B
619+AQUFAAOCAQEArEFhWRHb1Nn1ACDNXbRueiMSdqwWtiAEU4yAFB+1maKyAG1VAQC2
620+IegIJ7INbzfwDp6CzNpI3CCyelNO2rcBGwOlXre6XA5K7TxKM6WLJDdodPUt30dY
621+3+/DF/XwH5S/C4oGbeRVWxzCBAFbStMlJqpXFIQkAYYCOfvWKoZzSslxGe7Zj+hQ
622+NYqJbc8BDe0UTyM8KoL9OWucEbdQMQgn0FxwAPqSLXgDkpSo6XHKL15MUbES1u5/
623+iT9gRJU1eN+bIWfrJA3dqh4JxXntTLDZ28pBdFtOV4WEF2O4fmxGiSktCi34tjK6
624+DsIScb+0mUeKS9b2cyQzLSUCwj8LgJW3rQ==
625+-----END CERTIFICATE-----
626
627=== added file 'tests/rabbit-server-privkey.pem'
628--- tests/rabbit-server-privkey.pem 1970-01-01 00:00:00 +0000
629+++ tests/rabbit-server-privkey.pem 2015-01-12 15:19:55 +0000
630@@ -0,0 +1,27 @@
631+-----BEGIN RSA PRIVATE KEY-----
632+MIIEpAIBAAKCAQEApc6WxtgQZL+PcDHL1S/kLqFyGPaKiJQrOPGYq9djM5prVGPH
633+UZ3F26VWtlBtPB8PgQFT10Sjr+ec7hC9aqT+THyNq2U8qCizGq4l4e44tfEILPuE
634+9IluF/dZuVWFR2nbVYp3FeAjuRQ68AwzpcZOXVup3xsXx7dJrGL4KUx/7NUb5+6T
635+zboM1nXX7o/DYCE5BvXncM7U3cLg16SV58T6Rs+JYATAFdzveN6X88AgvQpBrDSD
636+42tSQmQzYu9mO2RwtP48jLvYLHv34dZo2h6G5zNWe/PkUjXxKEGJXHkeXy83vx4U
637+V62Vo8pMLeSSqL4wUV3KMRHJ+MBskP42lmruwQIDAQABAoIBAE6jo/ldQrE19acF
638+xyIum6/OHJpgXCYY+EMCuyFNf5xa8erNhBxekxfw3CaOELECHk1WPtiLkoL8e/6h
639+a+UnqgDG1j5jPpiW7ROLYyY74SPR1MnY5R9CCzhMtX5kZFkRiNiSWpbCfs7qHGX7
640+s4c9fa9jqTbK18V+Ve/v5LlZsha13OQRISQLqZlCM6vKRtHZorQHZVM1KIV4bzdP
641+75/YTrhUA8GKGA+4Le5vZ1PQY8ubTAXPHeeqILvClsmkZ6k0RC/zesB3DUXzMvjA
642+ycbarcpZ+muxyp0Icuv9B7pj3iT/dL4udc+BM82Qg3KvLLiteE9aeOPsW3aJxAHa
643+YYLLCQECgYEA2EUF4QVgJE1U6RHFsRO6xP1KBJO0mVMMlEpgywPV3oN7D5gOVrCK
644+A/iNkyt2ggaX2o2+QHMe+WjINdMLhY6TdhRiYrUQhLteNSrp0w/HDYyY2Cz1IhH3
645+Y/0qHm9rGZhetOWoJ5Ejn/9vnL/ZfsGfSNzwS1VjCUHyXShebS9NHRECgYEAxERZ
646+5HX3zctB2lzzS8KTNAWijUc+hc8c0LV/GcCC8LMsUPNb/V+wQNiSInJa994YI5+9
647+1BkJkw4Lnexvx8GQPaAkX6DzZsWSmwaNSkLICd75f2ga4dqeohWOAIvS3xb4fanr
648+szCLZfd4L8MEb6lVI2wzpM5yADK42y/w03t0drECgYBvDAn3v93c5gRKZIDA6uOE
649+0JXYAcvCypzz67kFpSOEzLg8ipQaOS202kQ/pBqGq0H/y7Y7u6DU6dObp5EL8+iN
650+weu+yUABF4BJBo7ne/t2XpIAthzscJM5uT2OQSGaE93VPvL31hOXzP4PW4cfCeZy
651+8FdGJ0Lh9wWuhdLud1I+MQKBgQC7CwzEPmy38mJC8VxoMfnJlSkyDNiX+ybR/HYx
652+m5buP0MXrqVXVe8KDZtPOr5ZBI7qvFzTmjzWqYcGrQJmU6DcKhcgD6qHofiyx061
653+m+k6BwatlhAweAHAJFydRqPjOef9Eofu0G+48FvY4LkElVLvHDoncRuR9sTXFtwj
654+H7+BMQKBgQDNWXHeXi4bYm17KsBHpK+DMT6O9cF1BqYpgbqLyro554ZjYLYpt0li
655+iiekhVM55NpWlbsOfje0lhD8mr0ZYzW+SmWd/XMj03ZF9EeOBHx8SvWemsrz69Es
656+wAjiQtQoZlvczaLOHLV89p9EaK3OA1trqjAkqq9GFdLBVmG/zVzSaQ==
657+-----END RSA PRIVATE KEY-----

Subscribers

People subscribed via source and target branches