diff options
| author | Gordon Sim <gsim@apache.org> | 2013-07-16 10:50:43 +0000 |
|---|---|---|
| committer | Gordon Sim <gsim@apache.org> | 2013-07-16 10:50:43 +0000 |
| commit | 156e666579700160b56331c89c8216e278fed90f (patch) | |
| tree | 5fd77e11c9165f2c619501d5274ec2b379f106b8 | |
| parent | 42b37635a7b0252c7cdaae11b431d8d3c67cbae9 (diff) | |
| download | qpid-python-156e666579700160b56331c89c8216e278fed90f.tar.gz | |
QPID-4988: Add test runs using swigged python client
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1503652 13f79535-47bb-0310-9956-ffa450edef68
21 files changed, 442 insertions, 38 deletions
diff --git a/qpid/cpp/bindings/qpid/python/CMakeLists.txt b/qpid/cpp/bindings/qpid/python/CMakeLists.txt index 2693475dea..373f4bead1 100644 --- a/qpid/cpp/bindings/qpid/python/CMakeLists.txt +++ b/qpid/cpp/bindings/qpid/python/CMakeLists.txt @@ -24,8 +24,8 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES CPLU set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES SWIG_FLAGS "-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/bindings") -swig_add_module(cqpid_python python ${CMAKE_CURRENT_SOURCE_DIR}/python.i) -swig_link_libraries(cqpid_python qpidmessaging qpidtypes qmf2 ${PYTHON_LIBRARIES}) +swig_add_module(cqpid python ${CMAKE_CURRENT_SOURCE_DIR}/python.i) +swig_link_libraries(cqpid qpidmessaging qpidtypes ${PYTHON_LIBRARIES}) set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing") include_directories(${PYTHON_INCLUDE_PATH} @@ -45,8 +45,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cqpid.py DESTINATION ${PYTHON_SITEARCH_PACKAGES} COMPONENT ${QPID_COMPONENT_CLIENT} ) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/_cqpid_python.so - RENAME _cqpid.so +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/_cqpid.so DESTINATION ${PYTHON_SITEARCH_PACKAGES} COMPONENT ${QPID_COMPONENT_CLIENT} ) diff --git a/qpid/cpp/bindings/qpid/python/python.i b/qpid/cpp/bindings/qpid/python/python.i index 148cad5e63..c10ea46000 100644 --- a/qpid/cpp/bindings/qpid/python/python.i +++ b/qpid/cpp/bindings/qpid/python/python.i @@ -139,8 +139,9 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) /* This only renames the non-const version (I believe). Then again, I * don't even know why there is a non-const version of the method. */ %rename(opened) qpid::messaging::Connection::isOpen(); +%rename(_close) qpid::messaging::Connection::close(); %rename(receiver) qpid::messaging::Session::createReceiver; -%rename(sender) qpid::messaging::Session::createSender; +%rename(_sender) qpid::messaging::Session::createSender; %rename(_acknowledge_all) qpid::messaging::Session::acknowledge(bool); %rename(_acknowledge_msg) qpid::messaging::Session::acknowledge( Message &, bool); @@ -169,20 +170,26 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) # when possible. def __init__(self, url=None, **options): if url: - args = [url] + args = [str(url)] else: args = [] - if options : - if "sasl_mechanisms" in options : - if ' ' in options.get("sasl_mechanisms",'') : - raise Exception( - "C++ Connection objects are unable to handle " - "multiple sasl-mechanisms") - options["sasl_mechanism"] = options.pop("sasl_mechanisms") - args.append(options) + if options: + # remove null valued options + clean_opts = {} + for k, v in options.iteritems(): + if v: + clean_opts[k] = v + args.append(clean_opts) this = _cqpid.new_Connection(*args) try: self.this.append(this) except: self.this = this + + def attached(self): + return self.opened() + + def close(self, timeout=None): + #timeout not supported in c++ + self._close() %} /* Return a pre-existing session with the given name, if one @@ -236,18 +243,29 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) __swig_getmethods__["connection"] = getConnection if _newclass: connection = property(getConnection) + + def sender(self, target, **options) : + s = self._sender(target) + s._setDurable(options.get("durable")) + return s %} } %extend qpid::messaging::Receiver { %pythoncode %{ + def _get_source(self): + return self.getAddress().str() + __swig_getmethods__["capacity"] = getCapacity __swig_setmethods__["capacity"] = setCapacity if _newclass: capacity = property(getCapacity, setCapacity) __swig_getmethods__["session"] = getSession if _newclass: session = property(getSession) + + __swig_getmethods__["source"] = _get_source + if _newclass: source = property(_get_source) %} %pythoncode %{ @@ -263,19 +281,31 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) %extend qpid::messaging::Sender { %pythoncode %{ + def _get_target(self): + return self.getAddress().str() + + def _setDurable(self, d): + self.durable = d + def send(self, object, sync=True) : if isinstance(object, Message): message = object else: message = Message(object) + if self.durable and message.durable is None: + message.durable = self.durable return self._send(message, sync) - + __swig_getmethods__["capacity"] = getCapacity __swig_setmethods__["capacity"] = setCapacity if _newclass: capacity = property(getCapacity, setCapacity) __swig_getmethods__["session"] = getSession if _newclass: session = property(getSession) + + __swig_getmethods__["target"] = _get_target + if _newclass: source = property(_get_target) + %} } @@ -293,7 +323,7 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) this = _cqpid.new_Message('') try: self.this.append(this) except: self.this = this - if content : + if not content is None: self.content = content if content_type != UNSPECIFIED : self.content_type = content_type @@ -327,21 +357,29 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) return decodeMap(self) return self.getContent() def _set_content(self, content) : - if isinstance(content, basestring) : + if isinstance(content, str) : self.setContent(content) + elif isinstance(content, unicode) : + if not self.content_type: self.content_type = "text/plain" + self.setContent(str(content)) elif isinstance(content, list) or isinstance(content, dict) : encode(content, self) else : # Not a type we can handle. Try setting it anyway, # although this will probably lead to a swig error - self.setContent(content) + self.setContent(str(content)) __swig_getmethods__["content"] = _get_content __swig_setmethods__["content"] = _set_content if _newclass: content = property(_get_content, _set_content) - __swig_getmethods__["content_type"] = getContentType + def _get_content_type(self) : + ct = self.getContentType() + if ct == "": return None + else: return ct + + __swig_getmethods__["content_type"] = _get_content_type __swig_setmethods__["content_type"] = setContentType - if _newclass: content_type = property(getContentType, setContentType) + if _newclass: content_type = property(_get_content_type, setContentType) __swig_getmethods__["id"] = getMessageId __swig_setmethods__["id"] = setMessageId diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am index f2253e22a1..3a6740f140 100644 --- a/qpid/cpp/src/Makefile.am +++ b/qpid/cpp/src/Makefile.am @@ -861,7 +861,7 @@ amqp_la_CXXFLAGS=$(AM_CXXFLAGS) $(BROKER_CXXFLAGS) $(PROTON_CFLAGS) amqp_la_LDFLAGS = $(PLUGINLDFLAGS) $(PROTON_LIBS) cmoduleexec_LTLIBRARIES += amqpc.la -amqpc_la_LIBADD = libqpidcommon.la +amqpc_la_LIBADD = libqpidcommon.la libqpidclient.la libqpidmessaging.la libqpidtypes.la amqpc_la_SOURCES = \ qpid/messaging/amqp/AddressHelper.h \ qpid/messaging/amqp/AddressHelper.cpp \ diff --git a/qpid/cpp/src/amqp.cmake b/qpid/cpp/src/amqp.cmake index 2d0ca06250..45b0c51527 100644 --- a/qpid/cpp/src/amqp.cmake +++ b/qpid/cpp/src/amqp.cmake @@ -142,7 +142,7 @@ if (BUILD_AMQP) qpid/messaging/amqp/TcpTransport.cpp ) add_library (amqpc MODULE ${amqpc_SOURCES}) - target_link_libraries (amqpc qpidclient qpidcommon) + target_link_libraries (amqpc qpidmessaging qpidclient qpidcommon) set_target_properties (amqpc PROPERTIES PREFIX "" COMPILE_FLAGS "${PROTON_COMPILE_FLAGS}" diff --git a/qpid/cpp/src/tests/CMakeLists.txt b/qpid/cpp/src/tests/CMakeLists.txt index 4763bc0b80..723754cfc7 100644 --- a/qpid/cpp/src/tests/CMakeLists.txt +++ b/qpid/cpp/src/tests/CMakeLists.txt @@ -357,6 +357,7 @@ if (PYTHON_EXECUTABLE) if (BUILD_AMQP) add_test (interlink_tests ${test_wrap} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/interlink_tests.py) endif (BUILD_AMQP) + add_test (swig_python_tests ${test_wrap} ${CMAKE_CURRENT_SOURCE_DIR}/swig_python_tests${test_script_suffix}) endif (PYTHON_EXECUTABLE) add_test (ipv6_test ${shell} ${CMAKE_CURRENT_SOURCE_DIR}/ipv6_test${test_script_suffix}) add_test (federation_tests ${shell} ${CMAKE_CURRENT_SOURCE_DIR}/run_federation_tests${test_script_suffix}) diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am index 808d9f9731..73fc3f8a1a 100644 --- a/qpid/cpp/src/tests/Makefile.am +++ b/qpid/cpp/src/tests/Makefile.am @@ -297,7 +297,7 @@ TESTS_ENVIRONMENT = \ system_tests = qpid-client-test quick_perftest quick_topictest run_header_test quick_txtest \ run_msg_group_tests TESTS += start_broker $(system_tests) python_tests stop_broker \ - run_ha_tests run_interlink_tests run_federation_tests run_federation_sys_tests \ + run_ha_tests run_interlink_tests swig_python_tests run_federation_tests run_federation_sys_tests \ run_acl_tests run_cli_tests dynamic_log_level_test \ dynamic_log_hires_timestamp run_queue_flow_limit_tests ipv6_test diff --git a/qpid/cpp/src/tests/failing-amqp0-10-python-tests b/qpid/cpp/src/tests/failing-amqp0-10-python-tests new file mode 100644 index 0000000000..cb742a25e5 --- /dev/null +++ b/qpid/cpp/src/tests/failing-amqp0-10-python-tests @@ -0,0 +1,7 @@ +#The following four tests fail the because pure python client excludes +#the node type for queues from the reply-to address, weheras the swigged +#client does not (as that prevents it resolving the node on every send) +qpid.tests.messaging.message.MessageEchoTests.testReplyTo +qpid.tests.messaging.message.MessageEchoTests.testReplyToQueue +qpid.tests.messaging.message.MessageEchoTests.testReplyToQueueSubject +qpid.tests.messaging.message.MessageEchoTests.testProperties diff --git a/qpid/cpp/src/tests/failing-amqp1.0-python-tests b/qpid/cpp/src/tests/failing-amqp1.0-python-tests new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/qpid/cpp/src/tests/failing-amqp1.0-python-tests diff --git a/qpid/cpp/src/tests/swig_python_tests b/qpid/cpp/src/tests/swig_python_tests new file mode 100755 index 0000000000..adf08cbc63 --- /dev/null +++ b/qpid/cpp/src/tests/swig_python_tests @@ -0,0 +1,65 @@ +#!/bin/bash + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Run the python tests. +source ./test_env.sh +trap stop_broker INT TERM QUIT + +if [ -f $AMQP_LIB ] ; then + MODULES="--load-module $AMQP_LIB" +fi + +fail() { + echo "FAIL swigged python tests: $1"; exit 1; +} +skip() { + echo "SKIPPED swigged python tests: $1"; exit 0; +} + +start_broker() { + QPID_PORT=$($QPIDD_EXEC --daemon --port 0 --interface 127.0.0.1 --no-data-dir $MODULES --auth no) || fail "Could not start broker" +} + +stop_broker() { + $QPIDD_EXEC -q --port $QPID_PORT +} + +test -d $PYTHON_DIR || skip "no python dir" +test -f $PYTHONSWIGMODULE || skip "no swigged python client" + +start_broker +echo "Running swigged python tests using broker on port $QPID_PORT" + +export PYTHONPATH=$PYTHONPATH:$PYTHONPATH_SWIG +export QPID_LOAD_MODULE=$AMQPC_LIB +$QPID_PYTHON_TEST -m qpid.tests.messaging.message -m qpid_tests.broker_0_10.priority -m qpid_tests.broker_0_10.lvq -m qpid_tests.broker_0_10.new_api -b localhost:$QPID_PORT -I $srcdir/failing-amqp0-10-python-tests +RESULT=$? +if [ -f $AMQPC_LIB ] ; then + $QPID_PYTHON_TEST --define="protocol_version=amqp1.0" -m qpid_tests.broker_1_0 -b localhost:$QPID_PORT -I $srcdir/failing-amqp1.0-python-tests + if test x$RESULT == x0; then + RESULT=$? + fi +fi +stop_broker +if test x$RESULT != x0; then + fail "" +fi + diff --git a/qpid/cpp/src/tests/test_env.sh.in b/qpid/cpp/src/tests/test_env.sh.in index bafdacf944..f20fb317aa 100644 --- a/qpid/cpp/src/tests/test_env.sh.in +++ b/qpid/cpp/src/tests/test_env.sh.in @@ -25,6 +25,8 @@ builddir=`absdir @abs_builddir@` top_srcdir=`absdir @abs_top_srcdir@` top_builddir=`absdir @abs_top_builddir@` moduledir=$top_builddir/src@builddir_lib_suffix@ +pythonswigdir=$top_builddir/bindings/qpid/python/ +pythonswiglibdir=$top_builddir/bindings/qpid/python@builddir_lib_suffix@ testmoduledir=$builddir@builddir_lib_suffix@ export QPID_INSTALL_PREFIX=@prefix@ @@ -44,7 +46,8 @@ export PYTHONPATH=$srcdir:$PYTHON_DIR:$PYTHON_COMMANDS:$QPID_TESTS_PY:$QMF_LIB:$ export QPID_CONFIG_EXEC=$PYTHON_COMMANDS/qpid-config export QPID_ROUTE_EXEC=$PYTHON_COMMANDS/qpid-route export QPID_HA_EXEC=$PYTHON_COMMANDS/qpid-ha - +export PYTHONPATH_SWIG=$pythonswigdir:$pythonswiglibdir +export PYTHONSWIGMODULE=$pythonswigdir/cqpid.py # Executables export QPIDD_EXEC=$top_builddir/src/qpidd diff --git a/qpid/python/qpid/tests/messaging/__init__.py b/qpid/python/qpid/tests/messaging/__init__.py index 8f6680d5e3..5c9cdf2f27 100644 --- a/qpid/python/qpid/tests/messaging/__init__.py +++ b/qpid/python/qpid/tests/messaging/__init__.py @@ -20,7 +20,7 @@ import time from math import ceil from qpid.harness import Skipped -from qpid.messaging import * +from qpid.tests.messaging.implementation import * from qpid.tests import Test class Base(Test): @@ -115,7 +115,7 @@ class Base(Test): echo = echo.content assert msg == echo, "expected %s, got %s" % (msg, echo) else: - delta = self.diff(msg, echo, ("x-amqp-0-10.routing-key",)) + delta = self.diff(msg, echo, ("x-amqp-0-10.routing-key","qpid.subject")) mttl, ettl = delta.pop("ttl", (0, 0)) if redelivered: assert echo.redelivered, \ @@ -179,7 +179,13 @@ class Base(Test): return "tcp" def connection_options(self): - return {"reconnect": self.reconnect(), - "transport": self.transport()} + protocol_version = self.config.defines.get("protocol_version") + if protocol_version: + return {"reconnect": self.reconnect(), + "transport": self.transport(), + "protocol":protocol_version} + else: + return {"reconnect": self.reconnect(), + "transport": self.transport()} import address, endpoints, message diff --git a/qpid/python/qpid/tests/messaging/implementation.py b/qpid/python/qpid/tests/messaging/implementation.py new file mode 100644 index 0000000000..ac0e02dba7 --- /dev/null +++ b/qpid/python/qpid/tests/messaging/implementation.py @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +try: + from cqpid import * + from qpid.datatypes import uuid4 +except ImportError, e: + print "Falling back to pure bindings, %s" % e + from qpid.messaging import * diff --git a/qpid/python/qpid/tests/messaging/message.py b/qpid/python/qpid/tests/messaging/message.py index 7328165db7..b59dc53084 100644 --- a/qpid/python/qpid/tests/messaging/message.py +++ b/qpid/python/qpid/tests/messaging/message.py @@ -17,7 +17,8 @@ # under the License. # -from qpid.messaging import * +from qpid.tests.messaging.implementation import * +from qpid.messaging.address import parse from qpid.tests.messaging import Base class MessageTests(Base): @@ -126,7 +127,14 @@ class MessageEchoTests(Base): msg = Message(reply_to=addr) self.snd.send(msg) echo = self.rcv.fetch(0) - assert echo.reply_to == expected, echo.reply_to + #reparse addresses and check individual parts as this avoids + #failing due to differenecs in whitespace when running over + #swigged client: + (actual_name, actual_subject, actual_options) = parse(echo.reply_to) + (expected_name, expected_subject, expected_options) = parse(expected) + assert actual_name == expected_name, (actual_name, expected_name) + assert actual_subject == expected_subject, (actual_subject, expected_subject) + assert actual_options == expected_options, (actual_options, expected_options) self.ssn.acknowledge(echo) def testReplyTo(self): diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/lvq.py b/qpid/tests/src/py/qpid_tests/broker_0_10/lvq.py index 8fd6b88d78..476b6ee052 100644 --- a/qpid/tests/src/py/qpid_tests/broker_0_10/lvq.py +++ b/qpid/tests/src/py/qpid_tests/broker_0_10/lvq.py @@ -17,7 +17,7 @@ # under the License. # -from qpid.messaging import * +from qpid.tests.messaging.implementation import * from qpid.tests.messaging import Base import math @@ -61,8 +61,7 @@ class LVQTests (Base): def create_message(key, content): - msg = Message(content=content) - msg.properties["lvq-key"] = key + msg = Message(content=content, properties={"lvq-key":key}) return msg def fetch_all(rcv): diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/new_api.py b/qpid/tests/src/py/qpid_tests/broker_0_10/new_api.py index c4a47029b9..ad0c32dac7 100644 --- a/qpid/tests/src/py/qpid_tests/broker_0_10/new_api.py +++ b/qpid/tests/src/py/qpid_tests/broker_0_10/new_api.py @@ -17,9 +17,8 @@ # under the License. # -from qpid.messaging import * +from qpid.tests.messaging.implementation import * from qpid.tests.messaging import Base -import qmf.console from time import sleep # diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py b/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py index bf4f1209b1..47aae6dfd6 100644 --- a/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py +++ b/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py @@ -17,7 +17,7 @@ # under the License. # -from qpid.messaging import * +from qpid.tests.messaging.implementation import * from qpid.tests.messaging import Base from qpid.compat import set import math diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/stats.py b/qpid/tests/src/py/qpid_tests/broker_0_10/stats.py index d36cc79acc..353f3631eb 100644 --- a/qpid/tests/src/py/qpid_tests/broker_0_10/stats.py +++ b/qpid/tests/src/py/qpid_tests/broker_0_10/stats.py @@ -17,9 +17,8 @@ # under the License. # -from qpid.messaging import * +from qpid.tests.messaging.implementation import * from qpid.tests.messaging import Base -import qmf.console from time import sleep from qpidtoollibs.broker import BrokerAgent diff --git a/qpid/tests/src/py/qpid_tests/broker_1_0/__init__.py b/qpid/tests/src/py/qpid_tests/broker_1_0/__init__.py new file mode 100644 index 0000000000..8088ddd95f --- /dev/null +++ b/qpid/tests/src/py/qpid_tests/broker_1_0/__init__.py @@ -0,0 +1,24 @@ +# Do not delete - marks this directory as a python package. + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from legacy_exchanges import * +from selector import * +from general import * diff --git a/qpid/tests/src/py/qpid_tests/broker_1_0/general.py b/qpid/tests/src/py/qpid_tests/broker_1_0/general.py new file mode 100644 index 0000000000..085acf8405 --- /dev/null +++ b/qpid/tests/src/py/qpid_tests/broker_1_0/general.py @@ -0,0 +1,52 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from qpid.tests.messaging.implementation import * +from qpid.tests.messaging import Base + +class GeneralTests (Base): + """ + Miscellaneous tests for core AMQP 1.0 messaging behaviour. + """ + def setup_connection(self): + return Connection.establish(self.broker, **self.connection_options()) + + def setup_session(self): + return self.conn.session() + + def test_request_response(self): + snd_request = self.ssn.sender("#") + rcv_response = self.ssn.receiver("#") + + #send request + snd_request.send(Message(reply_to=rcv_response.source, id="a1", content="request")) + + #receive request + rcv_request = self.ssn.receiver(snd_request.target) + request = rcv_request.fetch(5) + assert request.content == "request" and request.id == "a1", request + #send response + snd_response = self.ssn.sender(request.reply_to) + snd_response.send(Message(correlation_id=request.id, content="response")) + + #receive response + response = rcv_response.fetch(5) + assert response.content == "response" and response.correlation_id == "a1", response + + self.ssn.acknowledge() diff --git a/qpid/tests/src/py/qpid_tests/broker_1_0/legacy_exchanges.py b/qpid/tests/src/py/qpid_tests/broker_1_0/legacy_exchanges.py new file mode 100644 index 0000000000..d2b8c643bd --- /dev/null +++ b/qpid/tests/src/py/qpid_tests/broker_1_0/legacy_exchanges.py @@ -0,0 +1,101 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from qpid.tests.messaging.implementation import * +from qpid.tests.messaging import Base + +class LegacyExchangeTests (Base): + """ + Tests for the legacy (i.e. pre 1.0) AMQP exchanges and the filters + defined for them and registered for AMQP 1.0. + """ + def setup_connection(self): + return Connection.establish(self.broker, **self.connection_options()) + + def setup_session(self): + return self.conn.session() + + def test_fanout(self): + msgs = [Message(content=s, subject = s) for s in ['a','b','c','d']] + + snd = self.ssn.sender("amq.fanout") + rcv = self.ssn.receiver("amq.fanout") + + for m in msgs: snd.send(m) + + for expected in msgs: + msg = rcv.fetch(0) + assert msg.content == expected.content + self.ssn.acknowledge(msg) + + def test_direct(self): + msgs = [Message(content=c, subject=s) for s, c in [('a', 'one'), ('b', 'two'),('a', 'three'),('b', 'four')]] + + snd = self.ssn.sender("amq.direct") + rcv_a = self.ssn.receiver("amq.direct/a") + rcv_b = self.ssn.receiver("amq.direct/b") + + for m in msgs: snd.send(m) + + for expected in ['one', 'three']: + msg = rcv_a.fetch(0) + assert msg.content == expected, (msg, expected) + self.ssn.acknowledge(msg) + + for expected in ['two', 'four']: + msg = rcv_b.fetch(0) + assert msg.content == expected + self.ssn.acknowledge(msg), (msg, expected) + + def test_topic(self): + msgs = [Message(content=s, subject=s) for s in ['red.dog', 'black.cat', 'red.squirrel', 'grey.squirrel']] + + snd = self.ssn.sender("amq.topic") + rcv_a = self.ssn.receiver("amq.topic/red.*") + rcv_b = self.ssn.receiver("amq.topic/*.squirrel") + + for m in msgs: snd.send(m) + + for expected in ['red.dog', 'red.squirrel']: + msg = rcv_a.fetch(0) + assert msg.content == expected, (msg, expected) + self.ssn.acknowledge(msg) + + for expected in ['red.squirrel', 'grey.squirrel']: + msg = rcv_b.fetch(0) + assert msg.content == expected + self.ssn.acknowledge(msg), (msg, expected) + + def test_headers(self): + msgs = [Message(content="%s.%s" % (colour, creature), properties={'creature':creature,'colour':colour}) for colour, creature in [('red','dog'), ('black', 'cat'), ('red', 'squirrel'), ('grey', 'squirrel')]] + + snd = self.ssn.sender("amq.match") + rcv_a = self.ssn.receiver("amq.match; {link:{filter:{descriptor:'apache.org:legacy-amqp-headers-binding:map',name:'red-things',value:{'colour':'red','x-match':'all'}}}}") + rcv_b = self.ssn.receiver("amq.match; {link:{filter:{descriptor:'apache.org:legacy-amqp-headers-binding:map',name:'cats-and-squirrels',value:{'creature':'squirrel','colour':'black','x-match':'any'}}}}") + for m in msgs: snd.send(m) + + for expected in ['red.dog', 'red.squirrel']: + msg = rcv_a.fetch(0) + assert msg.content == expected, (msg, expected) + self.ssn.acknowledge(msg) + + for expected in ['black.cat', 'red.squirrel', 'grey.squirrel']: + msg = rcv_b.fetch(0) + assert msg.content == expected + self.ssn.acknowledge(msg), (msg, expected) diff --git a/qpid/tests/src/py/qpid_tests/broker_1_0/selector.py b/qpid/tests/src/py/qpid_tests/broker_1_0/selector.py new file mode 100644 index 0000000000..2e956cecb6 --- /dev/null +++ b/qpid/tests/src/py/qpid_tests/broker_1_0/selector.py @@ -0,0 +1,79 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from qpid.tests.messaging.implementation import * +from qpid.tests.messaging import Base + +class SelectorTests (Base): + """ + Tests for the selector filter registered for AMQP 1.0 under the + apache namespace. + """ + def setup_connection(self): + return Connection.establish(self.broker, **self.connection_options()) + + def setup_session(self): + return self.conn.session() + + def basic_selection_test(self, node): + properties = [(1, 'red','dog'), (2, 'black', 'cat'), (3, 'red', 'squirrel'), (4, 'grey', 'squirrel')] + msgs = [Message(content="%s.%s" % (colour, creature), properties={'sequence':sequence,'colour':colour}) for sequence, colour, creature in properties] + + snd = self.ssn.sender(node) + rcv = self.ssn.receiver("%s; {link:{selector:\"colour IN ('red', 'grey') AND (sequence > 3 OR sequence = 1)\"}}" % snd.target) + + for m in msgs: snd.send(m) + + for expected in ["red.dog", "grey.squirrel"]: + msg = rcv.fetch(0) + assert msg.content == expected + self.ssn.acknowledge(msg) + + def test_topic(self): + self.basic_selection_test(self.config.defines.get("topic_name", "amq.fanout")) + + def test_queue(self): + self.basic_selection_test("#") + + def test_special_fields(self): + msgs = [Message(content=i, id=i, correlation_id=i, priority=p) for p, i in enumerate(['a', 'b', 'c', 'd'], 1)] + + snd = self.ssn.sender("#") + rcv_1 = self.ssn.receiver("%s; {link:{selector:\"amqp.message_id = 'c'\"}}" % snd.target) + rcv_2 = self.ssn.receiver("%s; {link:{selector:\"amqp.correlation_id = 'b'\"}}" % snd.target) + rcv_3 = self.ssn.receiver("%s; {link:{selector:\"amqp.priority = 1\"}}" % snd.target) + + for m in msgs: snd.send(m) + + msg = rcv_1.fetch(0) + assert msg.content == 'c', msg + self.ssn.acknowledge(msg) + + msg = rcv_2.fetch(0) + assert msg.content == 'b', msg + self.ssn.acknowledge(msg) + + msg = rcv_3.fetch(0) + assert msg.content == 'a', msg + self.ssn.acknowledge(msg) + + rcv_4 = self.ssn.receiver(snd.target) + msg = rcv_4.fetch(0) + assert msg.content == 'd' + self.ssn.acknowledge(msg) |
