diff options
Diffstat (limited to 'qpid/cpp/src/tests')
45 files changed, 1024 insertions, 390 deletions
diff --git a/qpid/cpp/src/tests/AsyncCompletion.cpp b/qpid/cpp/src/tests/AsyncCompletion.cpp index 4492e6b6bc..e32097106f 100644 --- a/qpid/cpp/src/tests/AsyncCompletion.cpp +++ b/qpid/cpp/src/tests/AsyncCompletion.cpp @@ -70,9 +70,11 @@ class AsyncCompletionMessageStore : public NullMessageStore { QPID_AUTO_TEST_SUITE(AsyncCompletionTestSuite) QPID_AUTO_TEST_CASE(testWaitTillComplete) { - AsyncCompletionMessageStore* store = new AsyncCompletionMessageStore; SessionFixture fix; - fix.broker->setStore(store); // Broker will delete store. + AsyncCompletionMessageStore* store = new AsyncCompletionMessageStore; + boost::shared_ptr<qpid::broker::MessageStore> p; + p.reset(store); + fix.broker->setStore(p); AsyncSession s = fix.session; static const int count = 3; diff --git a/qpid/cpp/src/tests/ClusterFixture.h b/qpid/cpp/src/tests/ClusterFixture.h index 5952cc1736..1eee32b9a4 100644 --- a/qpid/cpp/src/tests/ClusterFixture.h +++ b/qpid/cpp/src/tests/ClusterFixture.h @@ -75,10 +75,10 @@ class ClusterFixture : public vector<uint16_t> { /** @param localIndex can be -1 meaning don't automatically start a local broker. * A local broker can be started with addLocal(). */ - ClusterFixture(size_t n, const Args& args, int localIndex=0); + ClusterFixture(size_t n, const Args& args, int localIndex=-1); /**@param updateArgs function is passed the index of the cluster member and can update the arguments. */ - ClusterFixture(size_t n, boost::function<void (Args&, size_t)> updateArgs, int localIndex); + ClusterFixture(size_t n, boost::function<void (Args&, size_t)> updateArgs, int localIndex=-1); void add(size_t n) { for (size_t i=0; i < n; ++i) add(); } void add(); // Add a broker. diff --git a/qpid/cpp/src/tests/ExchangeTest.cpp b/qpid/cpp/src/tests/ExchangeTest.cpp index 44835c6184..88a1cd99c2 100644 --- a/qpid/cpp/src/tests/ExchangeTest.cpp +++ b/qpid/cpp/src/tests/ExchangeTest.cpp @@ -60,7 +60,7 @@ QPID_AUTO_TEST_CASE(testMe) queue.reset(); queue2.reset(); - intrusive_ptr<Message> msgPtr(MessageUtils::createMessage("exchange", "key", "id")); + intrusive_ptr<Message> msgPtr(MessageUtils::createMessage("exchange", "key", false, "id")); DeliverableMessage msg(msgPtr); topic.route(msg, "abc", 0); direct.route(msg, "abc", 0); diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am index a15ba3578c..15133505a3 100644 --- a/qpid/cpp/src/tests/Makefile.am +++ b/qpid/cpp/src/tests/Makefile.am @@ -22,6 +22,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src PUBLIC_INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include # Use public API only abs_builddir=@abs_builddir@ +abs_srcdir=@abs_srcdir@ extra_libs = lib_client = $(abs_builddir)/../libqpidclient.la lib_common = $(abs_builddir)/../libqpidcommon.la @@ -275,7 +276,6 @@ qpid_stream_INCLUDES=$(PUBLIC_INCLUDES) qpid_stream_SOURCES=qpid_stream.cpp qpid_stream_LDADD=$(lib_client) - TESTS_ENVIRONMENT = \ VALGRIND=$(VALGRIND) \ srcdir=$(srcdir) \ @@ -311,7 +311,7 @@ EXTRA_DIST += \ TxMocks.h \ replication_test \ run_perftest \ - ring_queue_test \ + ring_queue_test \ run_ring_queue_test check_LTLIBRARIES += libdlclose_noop.la @@ -327,25 +327,47 @@ LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_p run_failover_soak reliable_replication_test \ federated_cluster_test_with_node_failure -EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test \ - federated_cluster_test_with_node_failure \ - tests.sln \ - client_test.vcproj \ - consume.vcproj \ - echotest.vcproj \ - header_test.vcproj \ - latencytest.vcproj \ - perftest.vcproj \ - publish.vcproj \ - receiver.vcproj \ - sender.vcproj \ - shlibtest.vcproj \ - topic_listener.vcproj \ - topic_publisher.vcproj \ - txjob.vcproj \ - txshift.vcproj \ - txtest.vcproj \ - unit_test.vcproj +EXTRA_DIST+= \ + python_env.sh \ + fanout_perftest \ + shared_perftest \ + multiq_perftest \ + topic_perftest \ + run_failover_soak \ + reliable_replication_test \ + federated_cluster_test_with_node_failure \ + tests.sln \ + client_test.vcproj \ + consume.vcproj \ + echotest.vcproj \ + header_test.vcproj \ + latencytest.vcproj \ + perftest.vcproj \ + publish.vcproj \ + receiver.vcproj \ + sender.vcproj \ + shlibtest.vcproj \ + topic_listener.vcproj \ + topic_publisher.vcproj \ + txjob.vcproj \ + txshift.vcproj \ + txtest.vcproj \ + unit_test.vcproj check-long: $(MAKE) check TESTS="$(LONG_TESTS)" VALGRIND= + +check: python_prep + +PYTHON_SRC_DIR=$(abs_srcdir)/../../../python +PYTHON_BLD_DIR=$(abs_builddir)/python +AMQP_SPEC_DIR=$(abs_srcdir)/../../../specs + +# Generate python client as part of the all-am target so it gets built before tests. +all-am: python_prep + +python_prep: + if test -d $(PYTHON_SRC_DIR) -a -d $(AMQP_SPEC_DIR); \ + then $(MAKE) -C $(PYTHON_SRC_DIR) install PREFIX=$(PYTHON_BLD_DIR) PYTHON_LIB=$(PYTHON_BLD_DIR) EXEC_PREFIX=$(PYTHON_BLD_DIR)/commands AMQP_SPEC_DIR=$(AMQP_SPEC_DIR); \ + else echo "WARNING: python client not built, missing one of $(PYTHON_SRC_DIR) $(AMQP_SPEC_DIR)"; fi + diff --git a/qpid/cpp/src/tests/MessageUtils.h b/qpid/cpp/src/tests/MessageUtils.h index dae74cce7d..a1b140d484 100644 --- a/qpid/cpp/src/tests/MessageUtils.h +++ b/qpid/cpp/src/tests/MessageUtils.h @@ -34,7 +34,8 @@ namespace tests { struct MessageUtils { static boost::intrusive_ptr<Message> createMessage(const string& exchange="", const string& routingKey="", - const Uuid& messageId=Uuid(true), uint64_t contentSize = 0) + const bool durable = false, const Uuid& messageId=Uuid(true), + uint64_t contentSize = 0) { boost::intrusive_ptr<broker::Message> msg(new broker::Message()); @@ -47,6 +48,8 @@ struct MessageUtils props->setContentLength(contentSize); props->setMessageId(messageId); msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setRoutingKey(routingKey); + if (durable) + msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setDeliveryMode(2); return msg; } diff --git a/qpid/cpp/src/tests/MessagingSessionTests.cpp b/qpid/cpp/src/tests/MessagingSessionTests.cpp index f5a5420d3a..206f5ba691 100644 --- a/qpid/cpp/src/tests/MessagingSessionTests.cpp +++ b/qpid/cpp/src/tests/MessagingSessionTests.cpp @@ -22,6 +22,10 @@ #include "test_tools.h" #include "BrokerFixture.h" #include "qpid/messaging/Connection.h" +#include "qpid/messaging/ListContent.h" +#include "qpid/messaging/ListView.h" +#include "qpid/messaging/MapContent.h" +#include "qpid/messaging/MapView.h" #include "qpid/messaging/Message.h" #include "qpid/messaging/MessageListener.h" #include "qpid/messaging/Receiver.h" @@ -160,7 +164,7 @@ struct MessageDataCollector : MessageListener std::vector<std::string> messageData; void received(Message& message) { - messageData.push_back(message.getBytes()); + messageData.push_back(message.getContent()); } }; @@ -169,7 +173,7 @@ std::vector<std::string> fetch(Receiver& receiver, int count, qpid::sys::Duratio std::vector<std::string> data; Message message; for (int i = 0; i < count && receiver.fetch(message, timeout); i++) { - data.push_back(message.getBytes()); + data.push_back(message.getContent()); } return data; } @@ -183,7 +187,7 @@ QPID_AUTO_TEST_CASE(testSimpleSendReceive) Receiver receiver = fix.session.createReceiver(fix.queue); Message in = receiver.fetch(5 * qpid::sys::TIME_SEC); fix.session.acknowledge(); - BOOST_CHECK_EQUAL(in.getBytes(), out.getBytes()); + BOOST_CHECK_EQUAL(in.getContent(), out.getContent()); } QPID_AUTO_TEST_CASE(testSendReceiveHeaders) @@ -199,7 +203,7 @@ QPID_AUTO_TEST_CASE(testSendReceiveHeaders) Message in; for (uint i = 0; i < 10; ++i) { BOOST_CHECK(receiver.fetch(in, 5 * qpid::sys::TIME_SEC)); - BOOST_CHECK_EQUAL(in.getBytes(), out.getBytes()); + BOOST_CHECK_EQUAL(in.getContent(), out.getContent()); BOOST_CHECK_EQUAL(in.getHeaders()["a"].asUint32(), i); fix.session.acknowledge(); } @@ -229,22 +233,22 @@ QPID_AUTO_TEST_CASE(testSimpleTopic) Receiver sub1 = fix.session.createReceiver(fix.topic); sub1.setCapacity(10u); sub1.start(); - msg.setBytes("two"); + msg.setContent("two"); sender.send(msg); Receiver sub2 = fix.session.createReceiver(fix.topic); sub2.setCapacity(10u); sub2.start(); - msg.setBytes("three"); + msg.setContent("three"); sender.send(msg); Receiver sub3 = fix.session.createReceiver(fix.topic); sub3.setCapacity(10u); sub3.start(); - msg.setBytes("four"); + msg.setContent("four"); sender.send(msg); BOOST_CHECK_EQUAL(fetch(sub2, 2), boost::assign::list_of<std::string>("three")("four")); sub2.cancel(); - msg.setBytes("five"); + msg.setContent("five"); sender.send(msg); BOOST_CHECK_EQUAL(fetch(sub1, 4), boost::assign::list_of<std::string>("two")("three")("four")("five")); BOOST_CHECK_EQUAL(fetch(sub3, 2), boost::assign::list_of<std::string>("four")("five")); @@ -274,7 +278,7 @@ QPID_AUTO_TEST_CASE(testSessionFetch) for (uint i = 0; i < fix.queues.size(); i++) { Message msg; BOOST_CHECK(fix.session.fetch(msg, qpid::sys::TIME_SEC)); - BOOST_CHECK_EQUAL(msg.getBytes(), (boost::format("Message_%1%") % (i+1)).str()); + BOOST_CHECK_EQUAL(msg.getContent(), (boost::format("Message_%1%") % (i+1)).str()); } } @@ -307,13 +311,16 @@ QPID_AUTO_TEST_CASE(testMapMessage) QueueFixture fix; Sender sender = fix.session.createSender(fix.queue); Message out; - out.getContent().asMap()["abc"] = "def"; - out.getContent().asMap()["pi"] = 3.14f; + MapContent content(out); + content["abc"] = "def"; + content["pi"] = 3.14f; + content.encode(); sender.send(out); Receiver receiver = fix.session.createReceiver(fix.queue); Message in = receiver.fetch(5 * qpid::sys::TIME_SEC); - BOOST_CHECK_EQUAL(in.getContent().asMap()["abc"].asString(), "def"); - BOOST_CHECK_EQUAL(in.getContent().asMap()["pi"].asFloat(), 3.14f); + MapView view(in); + BOOST_CHECK_EQUAL(view["abc"].asString(), "def"); + BOOST_CHECK_EQUAL(view["pi"].asFloat(), 3.14f); fix.session.acknowledge(); } @@ -322,23 +329,31 @@ QPID_AUTO_TEST_CASE(testListMessage) QueueFixture fix; Sender sender = fix.session.createSender(fix.queue); Message out; - out.getContent() = Variant::List(); - out.getContent() << "abc"; - out.getContent() << 1234; - out.getContent() << "def"; - out.getContent() << 56.789; + ListContent content(out); + content.push_back(Variant("abc")); + content.push_back(Variant(1234)); + content.push_back(Variant("def")); + content.push_back(Variant(56.789)); + content.encode(); sender.send(out); Receiver receiver = fix.session.createReceiver(fix.queue); Message in = receiver.fetch(5 * qpid::sys::TIME_SEC); - Variant::List& list = in.getContent().asList(); - BOOST_CHECK_EQUAL(list.size(), out.getContent().asList().size()); - BOOST_CHECK_EQUAL(list.front().asString(), "abc"); - list.pop_front(); - BOOST_CHECK_EQUAL(list.front().asInt64(), 1234); - list.pop_front(); - BOOST_CHECK_EQUAL(list.front().asString(), "def"); - list.pop_front(); - BOOST_CHECK_EQUAL(list.front().asDouble(), 56.789); + ListView view(in); + BOOST_CHECK_EQUAL(view.size(), content.size()); + BOOST_CHECK_EQUAL(view.front().asString(), "abc"); + BOOST_CHECK_EQUAL(view.back().asDouble(), 56.789); + + ListView::const_iterator i = view.begin(); + BOOST_CHECK(i != view.end()); + BOOST_CHECK_EQUAL(i->asString(), "abc"); + BOOST_CHECK(++i != view.end()); + BOOST_CHECK_EQUAL(i->asInt64(), 1234); + BOOST_CHECK(++i != view.end()); + BOOST_CHECK_EQUAL(i->asString(), "def"); + BOOST_CHECK(++i != view.end()); + BOOST_CHECK_EQUAL(i->asDouble(), 56.789); + BOOST_CHECK(++i == view.end()); + fix.session.acknowledge(); } @@ -352,10 +367,10 @@ QPID_AUTO_TEST_CASE(testReject) sender.send(m2); Receiver receiver = fix.session.createReceiver(fix.queue); Message in = receiver.fetch(5 * qpid::sys::TIME_SEC); - BOOST_CHECK_EQUAL(in.getBytes(), m1.getBytes()); + BOOST_CHECK_EQUAL(in.getContent(), m1.getContent()); fix.session.reject(in); in = receiver.fetch(5 * qpid::sys::TIME_SEC); - BOOST_CHECK_EQUAL(in.getBytes(), m2.getBytes()); + BOOST_CHECK_EQUAL(in.getContent(), m2.getContent()); fix.session.acknowledge(); } @@ -384,15 +399,15 @@ QPID_AUTO_TEST_CASE(testAvailable) for (uint i = 0; i < 5; ++i) { BOOST_CHECK_EQUAL(fix.session.available(), 15u - 2*i); BOOST_CHECK_EQUAL(r1.available(), 10u - i); - BOOST_CHECK_EQUAL(r1.fetch().getBytes(), (boost::format("A_%1%") % (i+1)).str()); + BOOST_CHECK_EQUAL(r1.fetch().getContent(), (boost::format("A_%1%") % (i+1)).str()); BOOST_CHECK_EQUAL(r2.available(), 5u - i); - BOOST_CHECK_EQUAL(r2.fetch().getBytes(), (boost::format("B_%1%") % (i+1)).str()); + BOOST_CHECK_EQUAL(r2.fetch().getContent(), (boost::format("B_%1%") % (i+1)).str()); fix.session.acknowledge(); } for (uint i = 5; i < 10; ++i) { BOOST_CHECK_EQUAL(fix.session.available(), 10u - i); BOOST_CHECK_EQUAL(r1.available(), 10u - i); - BOOST_CHECK_EQUAL(r1.fetch().getBytes(), (boost::format("A_%1%") % (i+1)).str()); + BOOST_CHECK_EQUAL(r1.fetch().getContent(), (boost::format("A_%1%") % (i+1)).str()); } } @@ -405,7 +420,7 @@ QPID_AUTO_TEST_CASE(testPendingAck) } Receiver receiver = fix.session.createReceiver(fix.queue); for (uint i = 0; i < 10; ++i) { - BOOST_CHECK_EQUAL(receiver.fetch().getBytes(), (boost::format("Message_%1%") % (i+1)).str()); + BOOST_CHECK_EQUAL(receiver.fetch().getContent(), (boost::format("Message_%1%") % (i+1)).str()); } BOOST_CHECK_EQUAL(fix.session.pendingAck(), 0u); fix.session.acknowledge(); @@ -431,7 +446,7 @@ QPID_AUTO_TEST_CASE(testPendingSend) Receiver receiver = fix.session.createReceiver(fix.queue); for (uint i = 0; i < 10; ++i) { - BOOST_CHECK_EQUAL(receiver.fetch().getBytes(), (boost::format("Message_%1%") % (i+1)).str()); + BOOST_CHECK_EQUAL(receiver.fetch().getContent(), (boost::format("Message_%1%") % (i+1)).str()); } fix.session.acknowledge(); } diff --git a/qpid/cpp/src/tests/PartialFailure.cpp b/qpid/cpp/src/tests/PartialFailure.cpp index 8d9970f909..5de8ecb189 100644 --- a/qpid/cpp/src/tests/PartialFailure.cpp +++ b/qpid/cpp/src/tests/PartialFailure.cpp @@ -105,7 +105,6 @@ QPID_AUTO_TEST_CASE(testCoincidentErrors) { } } -#if 0 // FIXME aconway 2009-07-30: // Verify normal cluster-wide errors. QPID_AUTO_TEST_CASE(testNormalErrors) { // FIXME aconway 2009-04-10: Would like to put a scope just around @@ -120,7 +119,7 @@ QPID_AUTO_TEST_CASE(testNormalErrors) { { ScopedSuppressLogging allQuiet; - queueAndsub(c0); + queueAndSub(c0); c0.session.messageTransfer(content=Message("x", "c0")); BOOST_CHECK_EQUAL(c0.lq.get(TIMEOUT).getData(), "x"); @@ -258,7 +257,7 @@ QPID_AUTO_TEST_CASE(testPartialFailureMemberLeaves) { } } #endif -#endif // FIXME aconway 2009-07-30: + QPID_AUTO_TEST_SUITE_END() }} // namespace qpid::tests diff --git a/qpid/cpp/src/tests/QueuePolicyTest.cpp b/qpid/cpp/src/tests/QueuePolicyTest.cpp index f40d30b588..875976db85 100644 --- a/qpid/cpp/src/tests/QueuePolicyTest.cpp +++ b/qpid/cpp/src/tests/QueuePolicyTest.cpp @@ -48,56 +48,56 @@ QueuedMessage createMessage(uint32_t size) QPID_AUTO_TEST_CASE(testCount) { - std::auto_ptr<QueuePolicy> policy(QueuePolicy::createQueuePolicy(5, 0)); + std::auto_ptr<QueuePolicy> policy(QueuePolicy::createQueuePolicy("test", 5, 0)); BOOST_CHECK_EQUAL((uint64_t) 0, policy->getMaxSize()); BOOST_CHECK_EQUAL((uint32_t) 5, policy->getMaxCount()); QueuedMessage msg = createMessage(10); for (size_t i = 0; i < 5; i++) { - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); } try { - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on enqueuing sixth message"); } catch (const ResourceLimitExceededException&) {} policy->dequeued(msg); - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); try { - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on enqueuing sixth message (after dequeue)"); } catch (const ResourceLimitExceededException&) {} } QPID_AUTO_TEST_CASE(testSize) { - std::auto_ptr<QueuePolicy> policy(QueuePolicy::createQueuePolicy(0, 50)); + std::auto_ptr<QueuePolicy> policy(QueuePolicy::createQueuePolicy("test", 0, 50)); QueuedMessage msg = createMessage(10); for (size_t i = 0; i < 5; i++) { - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); } try { - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on aggregate size exceeding 50. " << *policy); } catch (const ResourceLimitExceededException&) {} policy->dequeued(msg); - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); try { - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on aggregate size exceeding 50 (after dequeue). " << *policy); } catch (const ResourceLimitExceededException&) {} } QPID_AUTO_TEST_CASE(testBoth) { - std::auto_ptr<QueuePolicy> policy(QueuePolicy::createQueuePolicy(5, 50)); + std::auto_ptr<QueuePolicy> policy(QueuePolicy::createQueuePolicy("test", 5, 50)); try { QueuedMessage msg = createMessage(51); - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on single message exceeding 50. " << *policy); } catch (const ResourceLimitExceededException&) {} @@ -108,17 +108,17 @@ QPID_AUTO_TEST_CASE(testBoth) messages.push_back(createMessage(2)); messages.push_back(createMessage(7)); for (size_t i = 0; i < messages.size(); i++) { - policy->tryEnqueue(messages[i]); + policy->tryEnqueue(messages[i].payload); } //size = 45 at this point, count = 5 try { QueuedMessage msg = createMessage(5); - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on count exceeding 6. " << *policy); } catch (const ResourceLimitExceededException&) {} try { QueuedMessage msg = createMessage(10); - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); BOOST_FAIL("Policy did not fail on aggregate size exceeding 50. " << *policy); } catch (const ResourceLimitExceededException&) {} @@ -126,7 +126,7 @@ QPID_AUTO_TEST_CASE(testBoth) policy->dequeued(messages[0]); try { QueuedMessage msg = createMessage(20); - policy->tryEnqueue(msg); + policy->tryEnqueue(msg.payload); } catch (const ResourceLimitExceededException&) { BOOST_FAIL("Policy failed incorrectly after dequeue. " << *policy); } @@ -135,10 +135,10 @@ QPID_AUTO_TEST_CASE(testBoth) QPID_AUTO_TEST_CASE(testSettings) { //test reading and writing the policy from/to field table - std::auto_ptr<QueuePolicy> a(QueuePolicy::createQueuePolicy(101, 303)); + std::auto_ptr<QueuePolicy> a(QueuePolicy::createQueuePolicy("test", 101, 303)); FieldTable settings; a->update(settings); - std::auto_ptr<QueuePolicy> b(QueuePolicy::createQueuePolicy(settings)); + std::auto_ptr<QueuePolicy> b(QueuePolicy::createQueuePolicy("test", settings)); BOOST_CHECK_EQUAL(a->getMaxCount(), b->getMaxCount()); BOOST_CHECK_EQUAL(a->getMaxSize(), b->getMaxSize()); } @@ -146,7 +146,7 @@ QPID_AUTO_TEST_CASE(testSettings) QPID_AUTO_TEST_CASE(testRingPolicy) { FieldTable args; - std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy(5, 0, QueuePolicy::RING); + std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy("test", 5, 0, QueuePolicy::RING); policy->update(args); ProxySessionFixture f; @@ -175,7 +175,7 @@ QPID_AUTO_TEST_CASE(testRingPolicy) QPID_AUTO_TEST_CASE(testStrictRingPolicy) { FieldTable args; - std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy(5, 0, QueuePolicy::RING_STRICT); + std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy("test", 5, 0, QueuePolicy::RING_STRICT); policy->update(args); ProxySessionFixture f; @@ -201,7 +201,7 @@ QPID_AUTO_TEST_CASE(testStrictRingPolicy) QPID_AUTO_TEST_CASE(testPolicyWithDtx) { FieldTable args; - std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy(5, 0, QueuePolicy::REJECT); + std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy("test", 5, 0, QueuePolicy::REJECT); policy->update(args); ProxySessionFixture f; @@ -282,6 +282,22 @@ QPID_AUTO_TEST_CASE(testFlowToDiskWithNoStore) } catch (const ResourceLimitExceededException&) {} } +QPID_AUTO_TEST_CASE(testPolicyFailureOnCommit) +{ + FieldTable args; + std::auto_ptr<QueuePolicy> policy = QueuePolicy::createQueuePolicy("test", 5, 0, QueuePolicy::REJECT); + policy->update(args); + + ProxySessionFixture f; + std::string q("q"); + f.session.queueDeclare(arg::queue=q, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args); + f.session.txSelect(); + for (int i = 0; i < 10; i++) { + f.session.messageTransfer(arg::content=client::Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), q)); + } + ScopedSuppressLogging sl; // Suppress messages for expected errors. + BOOST_CHECK_THROW(f.session.txCommit(), InternalErrorException); +} QPID_AUTO_TEST_SUITE_END() diff --git a/qpid/cpp/src/tests/QueueTest.cpp b/qpid/cpp/src/tests/QueueTest.cpp index 841a19f7c1..3cfaa763ca 100644 --- a/qpid/cpp/src/tests/QueueTest.cpp +++ b/qpid/cpp/src/tests/QueueTest.cpp @@ -18,10 +18,13 @@ * under the License. * */ +#include "MessageUtils.h" #include "unit_test.h" #include "test_tools.h" #include "qpid/Exception.h" #include "qpid/broker/Broker.h" +#include "qpid/broker/DeliverableMessage.h" +#include "qpid/broker/FanOutExchange.h" #include "qpid/broker/Queue.h" #include "qpid/broker/Deliverable.h" #include "qpid/broker/ExchangeRegistry.h" @@ -30,12 +33,16 @@ #include "qpid/broker/ExpiryPolicy.h" #include "qpid/framing/MessageTransferBody.h" #include "qpid/client/QueueOptions.h" +#include "qpid/framing/AMQFrame.h" +#include "qpid/framing/MessageTransferBody.h" +#include "qpid/framing/reply_exceptions.h" #include <iostream> #include "boost/format.hpp" using boost::intrusive_ptr; using namespace qpid; using namespace qpid::broker; +using namespace qpid::client; using namespace qpid::framing; using namespace qpid::sys; @@ -61,13 +68,14 @@ public: class FailOnDeliver : public Deliverable { - Message msg; + boost::intrusive_ptr<Message> msg; public: + FailOnDeliver() : msg(MessageUtils::createMessage()) {} void deliverTo(const boost::shared_ptr<Queue>& queue) { throw Exception(QPID_MSG("Invalid delivery to " << queue->getName())); } - Message& getMessage() { return msg; } + Message& getMessage() { return *(msg.get()); } }; intrusive_ptr<Message> create_message(std::string exchange, std::string routingKey) { @@ -210,8 +218,7 @@ QPID_AUTO_TEST_CASE(testDequeue){ } -QPID_AUTO_TEST_CASE(testBound) -{ +QPID_AUTO_TEST_CASE(testBound){ //test the recording of bindings, and use of those to allow a queue to be unbound string key("my-key"); FieldTable args; @@ -245,7 +252,6 @@ QPID_AUTO_TEST_CASE(testBound) } QPID_AUTO_TEST_CASE(testPersistLastNodeStanding){ - client::QueueOptions args; args.setPersistLastNode(); @@ -273,14 +279,35 @@ QPID_AUTO_TEST_CASE(testPersistLastNodeStanding){ } -class TestMessageStoreOC : public NullMessageStore +const std::string nullxid = ""; + +class SimpleDummyCtxt : public TransactionContext {}; + +class DummyCtxt : public TPCTransactionContext +{ + const std::string xid; + public: + DummyCtxt(const std::string& _xid) : xid(_xid) {} + static std::string getXid(TransactionContext& ctxt) + { + DummyCtxt* c(dynamic_cast<DummyCtxt*>(&ctxt)); + return c ? c->xid : nullxid; + } +}; + +class TestMessageStoreOC : public MessageStore { + std::set<std::string> prepared; + uint64_t nextPersistenceId; public: uint enqCnt; uint deqCnt; bool error; + TestMessageStoreOC() : MessageStore(),nextPersistenceId(1),enqCnt(0),deqCnt(0),error(false) {} + ~TestMessageStoreOC(){} + virtual void dequeue(TransactionContext*, const boost::intrusive_ptr<PersistableMessage>& /*msg*/, const PersistableQueue& /*queue*/) @@ -290,11 +317,12 @@ class TestMessageStoreOC : public NullMessageStore } virtual void enqueue(TransactionContext*, - const boost::intrusive_ptr<PersistableMessage>& /*msg*/, + const boost::intrusive_ptr<PersistableMessage>& msg, const PersistableQueue& /* queue */) { if (error) throw Exception("Enqueue error test"); enqCnt++; + msg->enqueueComplete(); } void createError() @@ -302,8 +330,32 @@ class TestMessageStoreOC : public NullMessageStore error=true; } - TestMessageStoreOC() : NullMessageStore(),enqCnt(0),deqCnt(0),error(false) {} - ~TestMessageStoreOC(){} + bool init(const Options*) { return true; } + void truncateInit(const bool) {} + void create(PersistableQueue& queue, const framing::FieldTable&) { queue.setPersistenceId(nextPersistenceId++); } + void destroy(PersistableQueue&) {} + void create(const PersistableExchange& exchange, const framing::FieldTable&) { exchange.setPersistenceId(nextPersistenceId++); } + void destroy(const PersistableExchange&) {} + void bind(const PersistableExchange&, const PersistableQueue&, const std::string&, const framing::FieldTable&) {} + void unbind(const PersistableExchange&, const PersistableQueue&, const std::string&, const framing::FieldTable&) {} + void create(const PersistableConfig& config) { config.setPersistenceId(nextPersistenceId++); } + void destroy(const PersistableConfig&) {} + void stage(const boost::intrusive_ptr<PersistableMessage>&) {} + void destroy(PersistableMessage&) {} + void appendContent(const boost::intrusive_ptr<const PersistableMessage>&, const std::string&) {} + void loadContent(const qpid::broker::PersistableQueue&, const boost::intrusive_ptr<const PersistableMessage>&, + std::string&, uint64_t, uint32_t) { throw qpid::framing::InternalErrorException("Can't load content; persistence not enabled"); } + void flush(const qpid::broker::PersistableQueue&) {} + uint32_t outstandingQueueAIO(const PersistableQueue&) { return 0; } + + std::auto_ptr<TransactionContext> begin() { return std::auto_ptr<TransactionContext>(new SimpleDummyCtxt()); } + std::auto_ptr<TPCTransactionContext> begin(const std::string& xid) { return std::auto_ptr<TPCTransactionContext>(new DummyCtxt(xid)); } + void prepare(TPCTransactionContext& ctxt) { prepared.insert(DummyCtxt::getXid(ctxt)); } + void commit(TransactionContext& ctxt) { prepared.erase(DummyCtxt::getXid(ctxt)); } + void abort(TransactionContext& ctxt) { prepared.erase(DummyCtxt::getXid(ctxt)); } + void collectPreparedXids(std::set<std::string>& out) { out.insert(prepared.begin(), prepared.end()); } + + void recover(RecoveryManager&) {} }; @@ -703,7 +755,7 @@ not requeued to the store. QPID_AUTO_TEST_CASE(testLastNodeJournalError){ /* -simulate store excption going into last node standing +simulate store exception going into last node standing */ TestMessageStoreOC testStore; @@ -727,16 +779,271 @@ simulate store excption going into last node standing } -intrusive_ptr<Message> mkMsg(std::string exchange, std::string routingKey) { - intrusive_ptr<Message> msg(new Message()); - AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0))); - AMQFrame header((AMQHeaderBody())); - msg->getFrames().append(method); - msg->getFrames().append(header); - msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setRoutingKey(routingKey); +intrusive_ptr<Message> mkMsg(MessageStore& store, std::string content = "", bool durable = false) +{ + intrusive_ptr<Message> msg = MessageUtils::createMessage("", "", durable); + if (content.size()) MessageUtils::addContent(msg, content); + msg->setStore(&store); return msg; } +QPID_AUTO_TEST_CASE(testFlowToDiskBlocking){ + + TestMessageStoreOC testStore; + client::QueueOptions args0; // No size policy + client::QueueOptions args1; + args1.setSizePolicy(FLOW_TO_DISK, 0, 1); + client::QueueOptions args2; + args2.setSizePolicy(FLOW_TO_DISK, 0, 2); + + // --- Fanout exchange bound to single transient queue ------------------------------------------------------------- + + FanOutExchange sbtFanout1("sbtFanout1", false, args0); // single binding to transient queue + Queue::shared_ptr tq1(new Queue("tq1", true)); // transient w/ limit + tq1->configure(args1); + sbtFanout1.bind(tq1, "", 0); + + intrusive_ptr<Message> msg01 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg01(msg01); + sbtFanout1.route(dmsg01, "", 0); // Brings queue 1 to capacity limit + msg01->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg01->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, tq1->getMessageCount()); + + intrusive_ptr<Message> msg02 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg02(msg02); + BOOST_CHECK_THROW(sbtFanout1.route(dmsg02, "", 0), ResourceLimitExceededException); + msg02->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg02->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, tq1->getMessageCount()); + + intrusive_ptr<Message> msg03 = mkMsg(testStore, std::string(5, 'X'), true); // durable w/ content + DeliverableMessage dmsg03(msg03); + BOOST_CHECK_THROW(sbtFanout1.route(dmsg03, "", 0), ResourceLimitExceededException); + msg03->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg03->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, tq1->getMessageCount()); + + intrusive_ptr<Message> msg04 = mkMsg(testStore); // transient no content + DeliverableMessage dmsg04(msg04); + BOOST_CHECK_THROW(sbtFanout1.route(dmsg04, "", 0), ResourceLimitExceededException); + msg04->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg04->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, tq1->getMessageCount()); + + intrusive_ptr<Message> msg05 = mkMsg(testStore, "", true); // durable no content + DeliverableMessage dmsg05(msg05); + BOOST_CHECK_THROW(sbtFanout1.route(dmsg05, "", 0), ResourceLimitExceededException); + msg05->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg05->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, tq1->getMessageCount()); + + // --- Fanout exchange bound to single durable queue --------------------------------------------------------------- + + FanOutExchange sbdFanout2("sbdFanout2", false, args0); // single binding to durable queue + Queue::shared_ptr dq2(new Queue("dq2", true, &testStore)); // durable w/ limit + dq2->configure(args1); + sbdFanout2.bind(dq2, "", 0); + + intrusive_ptr<Message> msg06 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg06(msg06); + sbdFanout2.route(dmsg06, "", 0); // Brings queue 2 to capacity limit + msg06->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg06->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, dq2->getMessageCount()); + + intrusive_ptr<Message> msg07 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg07(msg07); + sbdFanout2.route(dmsg07, "", 0); + msg07->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg07->isContentReleased(), true); + BOOST_CHECK_EQUAL(2u, dq2->getMessageCount()); + + intrusive_ptr<Message> msg08 = mkMsg(testStore, std::string(5, 'X'), true); // durable w/ content + DeliverableMessage dmsg08(msg08); + sbdFanout2.route(dmsg08, "", 0); + msg08->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg08->isContentReleased(), true); + BOOST_CHECK_EQUAL(3u, dq2->getMessageCount()); + + intrusive_ptr<Message> msg09 = mkMsg(testStore); // transient no content + DeliverableMessage dmsg09(msg09); + sbdFanout2.route(dmsg09, "", 0); + msg09->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg09->isContentReleased(), true); + BOOST_CHECK_EQUAL(4u, dq2->getMessageCount()); + + intrusive_ptr<Message> msg10 = mkMsg(testStore, "", true); // durable no content + DeliverableMessage dmsg10(msg10); + sbdFanout2.route(dmsg10, "", 0); + msg10->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg10->isContentReleased(), true); + BOOST_CHECK_EQUAL(5u, dq2->getMessageCount()); + + // --- Fanout exchange bound to multiple durable queues ------------------------------------------------------------ + + FanOutExchange mbdFanout3("mbdFanout3", false, args0); // multiple bindings to durable queues + Queue::shared_ptr dq3(new Queue("dq3", true, &testStore)); // durable w/ limit 2 + dq3->configure(args2); + mbdFanout3.bind(dq3, "", 0); + Queue::shared_ptr dq4(new Queue("dq4", true, &testStore)); // durable w/ limit 1 + dq4->configure(args1); + mbdFanout3.bind(dq4, "", 0); + Queue::shared_ptr dq5(new Queue("dq5", true, &testStore)); // durable no limit + dq5->configure(args0); + mbdFanout3.bind(dq5, "", 0); + + intrusive_ptr<Message> msg11 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg11(msg11); + mbdFanout3.route(dmsg11, "", 0); // Brings queues 3 and 4 to capacity limit + msg11->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg11->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(1u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(1u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg12 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg12(msg12); + mbdFanout3.route(dmsg12, "", 0); + msg12->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg12->isContentReleased(), false); // XXXX - consequence of transient msg multi-queue ftd policy-handling limitations, fix in broker at some point! + BOOST_CHECK_EQUAL(2u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(2u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(2u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg13 = mkMsg(testStore, std::string(5, 'X'), true); // durable w/ content + DeliverableMessage dmsg13(msg13); + mbdFanout3.route(dmsg13, "", 0); + msg13->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg13->isContentReleased(), true); + BOOST_CHECK_EQUAL(3u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(3u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(3u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg14 = mkMsg(testStore); // transient no content + DeliverableMessage dmsg14(msg14); + mbdFanout3.route(dmsg14, "", 0); + msg14->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg14->isContentReleased(), false); // XXXX - consequence of transient msg multi-queue ftd policy-handling limitations, fix in broker at some point! + BOOST_CHECK_EQUAL(4u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(4u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(4u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg15 = mkMsg(testStore, "", true); // durable no content + DeliverableMessage dmsg15(msg15); + mbdFanout3.route(dmsg15, "", 0); + msg15->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg15->isContentReleased(), true); + BOOST_CHECK_EQUAL(5u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(5u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(5u, dq5->getMessageCount()); + + // Bind a transient queue, this should block the release of any further messages. + // Note: this will result in a violation of the count policy of dq3 and dq4 - but this + // is expected until a better overall multi-queue design is implemented. Similarly + // for the other tests in this section. + + Queue::shared_ptr tq6(new Queue("tq6", true)); // transient no limit + tq6->configure(args0); + mbdFanout3.bind(tq6, "", 0); + + intrusive_ptr<Message> msg16 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg16(msg16); + mbdFanout3.route(dmsg16, "", 0); + msg16->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg16->isContentReleased(), false); + BOOST_CHECK_EQUAL(6u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(6u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(6u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg17 = mkMsg(testStore, std::string(5, 'X'), true); // durable w/ content + DeliverableMessage dmsg17(msg17); + mbdFanout3.route(dmsg17, "", 0); + msg17->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg17->isContentReleased(), false); + BOOST_CHECK_EQUAL(7u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(7u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(7u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg18 = mkMsg(testStore); // transient no content + DeliverableMessage dmsg18(msg18); + mbdFanout3.route(dmsg18, "", 0); + msg18->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg18->isContentReleased(), false); + BOOST_CHECK_EQUAL(8u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(8u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(8u, dq5->getMessageCount()); + + intrusive_ptr<Message> msg19 = mkMsg(testStore, "", true); // durable no content + DeliverableMessage dmsg19(msg19); + mbdFanout3.route(dmsg19, "", 0); + msg19->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg19->isContentReleased(), false); + BOOST_CHECK_EQUAL(9u, dq3->getMessageCount()); + BOOST_CHECK_EQUAL(9u, dq4->getMessageCount()); + BOOST_CHECK_EQUAL(9u, dq5->getMessageCount()); + + + // --- Fanout exchange bound to multiple durable and transient queues ---------------------------------------------- + + FanOutExchange mbmFanout4("mbmFanout4", false, args0); // multiple bindings to durable/transient queues + Queue::shared_ptr dq7(new Queue("dq7", true, &testStore)); // durable no limit + dq7->configure(args0); + mbmFanout4.bind(dq7, "", 0); + Queue::shared_ptr dq8(new Queue("dq8", true, &testStore)); // durable w/ limit + dq8->configure(args1); + mbmFanout4.bind(dq8, "", 0); + Queue::shared_ptr tq9(new Queue("tq9", true)); // transient no limit + tq9->configure(args0); + mbmFanout4.bind(tq9, "", 0); + + intrusive_ptr<Message> msg20 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg20(msg20); + mbmFanout4.route(dmsg20, "", 0); // Brings queue 7 to capacity limit + msg20->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg20->isContentReleased(), false); + BOOST_CHECK_EQUAL(1u, dq7->getMessageCount()); + BOOST_CHECK_EQUAL(1u, dq8->getMessageCount()); + BOOST_CHECK_EQUAL(1u, tq9->getMessageCount()); + + intrusive_ptr<Message> msg21 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content + DeliverableMessage dmsg21(msg21); + mbmFanout4.route(dmsg21, "", 0); + msg21->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg21->isContentReleased(), false); + BOOST_CHECK_EQUAL(2u, dq7->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(2u, dq8->getMessageCount()); + BOOST_CHECK_EQUAL(2u, tq9->getMessageCount()); + + intrusive_ptr<Message> msg22 = mkMsg(testStore, std::string(5, 'X'), true); // durable w/ content + DeliverableMessage dmsg22(msg22); + mbmFanout4.route(dmsg22, "", 0); + msg22->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg22->isContentReleased(), false); + BOOST_CHECK_EQUAL(3u, dq7->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(3u, dq8->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(3u, tq9->getMessageCount()); + + intrusive_ptr<Message> msg23 = mkMsg(testStore); // transient no content + DeliverableMessage dmsg23(msg23); + mbmFanout4.route(dmsg23, "", 0); + msg23->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg23->isContentReleased(), false); + BOOST_CHECK_EQUAL(4u, dq7->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(4u, dq8->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(4u, tq9->getMessageCount()); + + intrusive_ptr<Message> msg24 = mkMsg(testStore, "", true); // durable no content + DeliverableMessage dmsg24(msg24); + mbmFanout4.route(dmsg24, "", 0); + msg24->tryReleaseContent(); + BOOST_CHECK_EQUAL(msg24->isContentReleased(), false); + BOOST_CHECK_EQUAL(5u, dq7->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(5u, dq8->getMessageCount()); // over limit + BOOST_CHECK_EQUAL(5u, tq9->getMessageCount()); +} + + QPID_AUTO_TEST_SUITE_END() }} // namespace qpid::tests diff --git a/qpid/cpp/src/tests/TxPublishTest.cpp b/qpid/cpp/src/tests/TxPublishTest.cpp index fabb01b864..6b44d95baa 100644 --- a/qpid/cpp/src/tests/TxPublishTest.cpp +++ b/qpid/cpp/src/tests/TxPublishTest.cpp @@ -50,7 +50,7 @@ struct TxPublishTest TxPublishTest() : queue1(new Queue("queue1", false, &store, 0)), queue2(new Queue("queue2", false, &store, 0)), - msg(MessageUtils::createMessage("exchange", "routing_key", "id")), + msg(MessageUtils::createMessage("exchange", "routing_key", false, "id")), op(msg) { msg->getProperties<DeliveryProperties>()->setDeliveryMode(PERSISTENT); diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py index fc53d2ce8b..2d776e9941 100755 --- a/qpid/cpp/src/tests/acl.py +++ b/qpid/cpp/src/tests/acl.py @@ -220,10 +220,11 @@ class ACLTests(TestBase010): """ aclf = ACLFile() aclf.write('acl deny bob@QPID create queue name=q1 durable=true passive=true\n') - aclf.write('acl deny bob@QPID create queue name=q2 exclusive=true\n') + aclf.write('acl deny bob@QPID create queue name=q2 exclusive=true policytype=ring\n') aclf.write('acl deny bob@QPID access queue name=q3\n') aclf.write('acl deny bob@QPID purge queue name=q3\n') - aclf.write('acl deny bob@QPID delete queue name=q4\n') + aclf.write('acl deny bob@QPID delete queue name=q4\n') + aclf.write('acl deny bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n') aclf.write('acl allow all all') aclf.close() @@ -241,19 +242,41 @@ class ACLTests(TestBase010): session = self.get_session('bob','bob') try: - session.queue_declare(queue="q2", exclusive=True) - self.fail("ACL should deny queue create request with name=q2 exclusive=true"); + queue_options = {} + queue_options["qpid.policy_type"] = "ring" + session.queue_declare(queue="q2", exclusive=True, arguments=queue_options) + self.fail("ACL should deny queue create request with name=q2 exclusive=true qpid.policy_type=ring"); except qpid.session.SessionException, e: self.assertEqual(530,e.args[0].error_code) session = self.get_session('bob','bob') try: - session.queue_declare(queue="q2", durable=True) + queue_options = {} + queue_options["qpid.policy_type"] = "ring_strict" + session.queue_declare(queue="q2", exclusive=True, arguments=queue_options) except qpid.session.SessionException, e: if (530 == e.args[0].error_code): - self.fail("ACL should allow queue create request for q2 with any parameter other than exclusive=true"); + self.fail("ACL should allow queue create request with name=q2 exclusive=true qpid.policy_type=ring_strict"); try: + queue_options = {} + queue_options["qpid.max_count"] = 200 + queue_options["qpid.max_size"] = 500 + session.queue_declare(queue="q5", exclusive=True, arguments=queue_options) + self.fail("ACL should deny queue create request with name=q2, qpid.max_size=500 and qpid.max_count=200"); + except qpid.session.SessionException, e: + self.assertEqual(530,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.max_count"] = 200 + queue_options["qpid.max_size"] = 100 + session.queue_declare(queue="q2", exclusive=True, arguments=queue_options) + except qpid.session.SessionException, e: + if (530 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=q2, qpid.max_size=100 and qpid.max_count=200 "); + try: session.queue_declare(queue="q3", exclusive=True) session.queue_declare(queue="q4", durable=True) except qpid.session.SessionException, e: @@ -300,12 +323,13 @@ class ACLTests(TestBase010): """ aclf = ACLFile() aclf.write('acl allow bob@QPID create queue name=q1 durable=true passive=true\n') - aclf.write('acl allow bob@QPID create queue name=q2 exclusive=true\n') + aclf.write('acl allow bob@QPID create queue name=q2 exclusive=true policytype=ring\n') aclf.write('acl allow bob@QPID access queue name=q3\n') aclf.write('acl allow bob@QPID purge queue name=q3\n') aclf.write('acl allow bob@QPID create queue name=q3\n') aclf.write('acl allow bob@QPID create queue name=q4\n') - aclf.write('acl allow bob@QPID delete queue name=q4\n') + aclf.write('acl allow bob@QPID delete queue name=q4\n') + aclf.write('acl allow bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n') aclf.write('acl allow guest@QPID all all\n') aclf.write('acl deny all all') aclf.close() @@ -337,10 +361,31 @@ class ACLTests(TestBase010): session = self.get_session('bob','bob') try: - session.queue_declare(queue="q2", exclusive=True) + queue_options = {} + queue_options["qpid.max_count"] = 200 + queue_options["qpid.max_size"] = 500 + session.queue_declare(queue="q5", arguments=queue_options) + self.fail("ACL should deny queue create request with name=q2 maxqueuesize=500 maxqueuecount=200"); + except qpid.session.SessionException, e: + self.assertEqual(530,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.max_count"] = 100 + queue_options["qpid.max_size"] = 500 + session.queue_declare(queue="q5", arguments=queue_options) except qpid.session.SessionException, e: if (530 == e.args[0].error_code): - self.fail("ACL should allow queue create request for q2 with exclusive=true"); + self.fail("ACL should allow queue create request with name=q2 maxqueuesize=500 maxqueuecount=200"); + + try: + queue_options = {} + queue_options["qpid.policy_type"] = "ring" + session.queue_declare(queue="q2", exclusive=True, arguments=queue_options) + except qpid.session.SessionException, e: + if (530 == e.args[0].error_code): + self.fail("ACL should allow queue create request for q2 with exclusive=true policytype=ring"); try: session.queue_declare(queue="q3") @@ -733,7 +778,7 @@ class ACLTests(TestBase010): # ACL publish tests #===================================== - def test_publish_acl(self): + def test_publish_acl_allow_mode(self): """ Test various publish acl """ @@ -779,4 +824,61 @@ class ACLTests(TestBase010): session.message_transfer(destination="amq.direct", message=Message(props,"Test")) except qpid.session.SessionException, e: if (530 == e.args[0].error_code): - self.fail("ACL should allow message transfer to exchange amq.direct"); + self.fail("ACL should allow message transfer to exchange amq.direct with routing key rk2"); + + + def test_publish_acl_deny_mode(self): + """ + Test various publish acl + """ + aclf = ACLFile() + aclf.write('acl allow bob@QPID publish exchange name=amq.direct routingkey=rk1\n') + aclf.write('acl allow bob@QPID publish exchange name=amq.topic\n') + aclf.write('acl allow bob@QPID publish exchange name=myEx routingkey=rk2\n') + aclf.write('acl allow bob@QPID create exchange\n') + aclf.write('acl allow guest@QPID all all \n') + aclf.write('acl deny all all') + aclf.close() + + result = self.reload_acl() + if (result.text.find("format error",0,len(result.text)) != -1): + self.fail(result) + + session = self.get_session('bob','bob') + + props = session.delivery_properties(routing_key="rk2") + + try: + session.message_transfer(destination="amq.direct", message=Message(props,"Test")) + self.fail("ACL should deny message transfer to name=amq.direct routingkey=rk2"); + except qpid.session.SessionException, e: + self.assertEqual(530,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.message_transfer(destination="amq.topic", message=Message(props,"Test")) + except qpid.session.SessionException, e: + if (530 == e.args[0].error_code): + self.fail("ACL should allow message transfer to exchange amq.topic with any routing key"); + + try: + session.exchange_declare(exchange='myEx', type='direct', durable=False) + session.message_transfer(destination="myEx", message=Message(props,"Test")) + except qpid.session.SessionException, e: + if (530 == e.args[0].error_code): + self.fail("ACL should allow message transfer to exchange myEx with routing key=rk2"); + + props = session.delivery_properties(routing_key="rk1") + + try: + session.message_transfer(destination="myEx", message=Message(props,"Test")) + self.fail("ACL should deny message transfer to name=myEx routingkey=rk1"); + except qpid.session.SessionException, e: + self.assertEqual(530,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.message_transfer(destination="amq.direct", message=Message(props,"Test")) + except qpid.session.SessionException, e: + if (530 == e.args[0].error_code): + self.fail("ACL should allow message transfer to exchange amq.direct with routing key rk1"); diff --git a/qpid/cpp/src/tests/ais_check b/qpid/cpp/src/tests/ais_check index 79862d7439..92eaa9dd39 100755 --- a/qpid/cpp/src/tests/ais_check +++ b/qpid/cpp/src/tests/ais_check @@ -21,35 +21,14 @@ srcdir=`dirname $0` # Check AIS requirements and run tests if found. -id -nG | grep '\<ais\>' >/dev/null || \ - NOGROUP="You are not a member of the ais group." -ps -u root | grep 'aisexec\|corosync' >/dev/null || \ - NOAISEXEC="The aisexec or corosync daemon is not running as root" - -if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then - cat <<EOF - - =========== WARNING: NOT RUNNING AIS TESTS ============== - - Tests that depend on the openais library (used for clustering) - will not be run because: - $NOGROUP - $NOAISEXEC - - ========================================================== - -EOF +ps -u root | grep 'aisexec\|corosync' >/dev/null || { + echo WARNING: Skipping cluster tests, the aisexec or corosync daemon is not running. exit 0; # A warning, not a failure. -fi +} -# Execute command with the ais group set. +# Execute command with the ais group set if user is a member. with_ais_group() { - id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group."; exit 1; } - echo $* | newgrp ais + if id -nG | grep '\<ais\>' >/dev/null; then sg ais -c "$*" + else "$@" + fi } - -# Run the tests -srcdir=`dirname $0` -with_ais_group $srcdir/run_test ./cluster_test || ERROR=1 -exit $ERROR - diff --git a/qpid/cpp/src/tests/background.ps1 b/qpid/cpp/src/tests/background.ps1 index 934078602b..36e9e4e6e9 100644 --- a/qpid/cpp/src/tests/background.ps1 +++ b/qpid/cpp/src/tests/background.ps1 @@ -30,11 +30,26 @@ trap { break } $encodedScript = [convert]::ToBase64String(
[Text.Encoding]::Unicode.GetBytes([string] $script))
-$p = new-object System.Diagnostics.Process
+#$p = new-object System.Diagnostics.Process
$si = new-object System.Diagnostics.ProcessStartInfo
$si.WorkingDirectory = $pwd
-$si.UseShellExecute = $true
$si.FileName = (get-command powershell.exe).Definition
$si.Arguments = "-encodedCommand $encodedScript"
-[diagnostics.process]::Start($si)
+###### debugging setup
+#$si.CreateNoWindow = $true
+# UseShellExecute false required for RedirectStandard(Error, Output)
+#$si.UseShellExecute = $false
+#$si.RedirectStandardError = $true
+#$si.RedirectStandardOutput = $true
+######
+$si.UseShellExecute = $true
+
+##### Debugging, instead of the plain Start() above.
+#$output = [io.File]::AppendText("start.out")
+#$error = [io.File]::AppendText("start.err")
+$p = [System.Diagnostics.Process]::Start($si)
+#$output.WriteLine($p.StandardOutput.ReadToEnd())
+#$error.WriteLine($p.StandardError.ReadToEnd())
+#$p.WaitForExit()
+#$output.Close()
diff --git a/qpid/cpp/src/tests/cluster.mk b/qpid/cpp/src/tests/cluster.mk index 05e18ab9eb..bdec10ebb0 100644 --- a/qpid/cpp/src/tests/cluster.mk +++ b/qpid/cpp/src/tests/cluster.mk @@ -30,7 +30,8 @@ if HAVE_LIBCPG # ais_check checks pre-requisites for cluster tests and runs them if ok. TESTS += \ - ais_check \ + run_cluster_test \ + cluster_read_credit \ test_watchdog \ run_cluster_tests \ federated_cluster_test \ @@ -38,6 +39,8 @@ TESTS += \ EXTRA_DIST += \ ais_check \ + run_cluster_test \ + cluster_read_credit \ test_watchdog \ start_cluster \ stop_cluster \ diff --git a/qpid/cpp/src/tests/cluster_read_credit b/qpid/cpp/src/tests/cluster_read_credit new file mode 100755 index 0000000000..370d4098c5 --- /dev/null +++ b/qpid/cpp/src/tests/cluster_read_credit @@ -0,0 +1,27 @@ +#!/bin/sh +# +# 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. +# + +# Regression test for http://issues.apache.org/jira/browse/QPID-2086 + +srcdir=`dirname $0` +. $srcdir/ais_check +$srcdir/start_cluster 1 --cluster-read-max=2 || exit 1 +trap $srcdir/stop_cluster EXIT +seq 1 10000 | ./sender --port `cat cluster.ports` --routing-key no-such-queue diff --git a/qpid/cpp/src/tests/cluster_test.cpp b/qpid/cpp/src/tests/cluster_test.cpp index 28fcdd13ad..247aef1b2a 100644 --- a/qpid/cpp/src/tests/cluster_test.cpp +++ b/qpid/cpp/src/tests/cluster_test.cpp @@ -85,6 +85,12 @@ void prepareArgs(ClusterFixture::Args& args, const bool durableFlag = false) { args += "--no-data-dir"; } +ClusterFixture::Args prepareArgs(const bool durableFlag = false) { + ClusterFixture::Args args; + prepareArgs(args, durableFlag); + return args; +} + // Timeout for tests that wait for messages const sys::Duration TIMEOUT=sys::TIME_SEC/4; @@ -596,16 +602,19 @@ QPID_AUTO_TEST_CASE(testUpdateConsumers) { } } -QPID_AUTO_TEST_CASE(testCatchupSharedState) { +// Test that message data and delivery properties are updated properly. +QPID_AUTO_TEST_CASE(testUpdateMessages) { ClusterFixture::Args args; prepareArgs(args, durableFlag); ClusterFixture cluster(1, args, -1); Client c0(cluster[0], "c0"); - // Create some shared state. + // Create messages with different delivery properties c0.session.queueDeclare("q", arg::durable=durableFlag); + c0.session.exchangeBind(arg::exchange="amq.fanout", arg::queue="q"); c0.session.messageTransfer(arg::content=makeMessage("foo","q", durableFlag)); - c0.session.messageTransfer(arg::content=makeMessage("bar","q", durableFlag)); + c0.session.messageTransfer(arg::content=makeMessage("bar","q", durableFlag), + arg::destination="amq.fanout"); while (c0.session.queueQuery("q").getMessageCount() != 2) sys::usleep(1000); // Wait for message to show up on broker 0. @@ -628,9 +637,12 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) { BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT)); BOOST_CHECK_EQUAL(m.getData(), "foo"); + BOOST_CHECK(m.getDeliveryProperties().hasExchange()); BOOST_CHECK_EQUAL(m.getDeliveryProperties().getExchange(), ""); BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT)); BOOST_CHECK_EQUAL(m.getData(), "bar"); + BOOST_CHECK(m.getDeliveryProperties().hasExchange()); + BOOST_CHECK_EQUAL(m.getDeliveryProperties().getExchange(), "amq.fanout"); BOOST_CHECK_EQUAL(c1.session.queueQuery("q").getMessageCount(), 0u); // Add another broker, don't wait for join - should be stalled till ready. @@ -905,6 +917,7 @@ QPID_AUTO_TEST_CASE(testExclusiveQueueUpdate) { BOOST_CHECK(!result.getDurable()); BOOST_CHECK_EQUAL(result.getAlternateExchange(), std::string("amq.fanout")); BOOST_CHECK_THROW(c2.session.queueDeclare(arg::queue="q", arg::exclusive=true, arg::passive=true), framing::ResourceLockedException); + c1.session.close(); c1.connection.close(); c2.session = c2.connection.newSession(); BOOST_CHECK_THROW(c2.session.queueDeclare(arg::queue="q", arg::passive=true), framing::NotFoundException); @@ -1100,6 +1113,44 @@ QPID_AUTO_TEST_CASE(testRelease) { } } -QPID_AUTO_TEST_SUITE_END() +// Browse for 1 message with byte credit, return true if a message was +// received false if not. +bool browseByteCredit(Client& c, const string& q, int n, Message& m) { + SubscriptionSettings browseSettings( + FlowControl(1, n, false), // 1 message, n bytes credit, no window + ACCEPT_MODE_NONE, + ACQUIRE_MODE_NOT_ACQUIRED, + 0 // No auto-ack. + ); + LocalQueue lq; + Subscription s = c.subs.subscribe(lq, q, browseSettings); + c.session.messageFlush(arg::destination=q, arg::sync=true); + c.session.sync(); + c.subs.getSubscription(q).cancel(); + return lq.get(m, 0); // No timeout, flush should push message thru. +} + +// Ensure cluster update preserves exact message size, use byte credt as test. +QPID_AUTO_TEST_CASE(testExactByteCredit) { + ClusterFixture cluster(1, prepareArgs(), -1); + Client c0(cluster[0], "c0"); + c0.session.queueDeclare("q"); + c0.session.messageTransfer(arg::content=Message("MyMessage", "q")); + cluster.add(); + + int size=36; // Size of message on broker: headers+body + Client c1(cluster[1], "c1"); + Message m; + + // Ensure we get the message with exact credit. + BOOST_CHECK(browseByteCredit(c0, "q", size, m)); + BOOST_CHECK(browseByteCredit(c1, "q", size, m)); + // and not with one byte less. + BOOST_CHECK(!browseByteCredit(c0, "q", size-1, m)); + BOOST_CHECK(!browseByteCredit(c1, "q", size-1, m)); +} + + +QPID_AUTO_TEST_SUITE_END() }} // namespace qpid::tests diff --git a/qpid/cpp/src/tests/clustered_replication_test b/qpid/cpp/src/tests/clustered_replication_test index cc331957ad..4f13b4672c 100755 --- a/qpid/cpp/src/tests/clustered_replication_test +++ b/qpid/cpp/src/tests/clustered_replication_test @@ -22,8 +22,7 @@ # Test reliability of the replication feature in the face of link # failures: srcdir=`dirname $0` -PYTHON_DIR=$srcdir/../../../python -export PYTHONPATH=$PYTHON_DIR +. $srcdir/python_env.sh trap stop_brokers INT EXIT @@ -31,10 +30,6 @@ fail() { echo $1 exit 1 } -with_ais_group() { - id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group." 1>&2; exit 1; } - echo $* | newgrp ais -} stop_brokers() { if [[ $PRIMARY1 ]] ; then @@ -55,26 +50,8 @@ stop_brokers() { fi } -if test -d ${PYTHON_DIR}; then - id -nG | grep '\<ais\>' >/dev/null || \ - NOGROUP="You are not a member of the ais group." - ps -u root | grep 'aisexec\|corosync' >/dev/null || \ - NOAISEXEC="The aisexec or corosync daemon is not running as root" - - if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then - cat <<EOF - - =========== WARNING: NOT RUNNING AIS TESTS ============== - - Not running cluster replication test because: - $NOGROUP - $NOAISEXEC - - ========================================================== - -EOF - exit 0; - fi +if test -d $PYTHON_DIR; then + . $srcdir/ais_check #todo: these cluster names need to be unique to prevent clashes PRIMARY_CLUSTER=PRIMARY_$(hostname)_$(pwd) @@ -89,8 +66,8 @@ EOF #start first node of primary cluster and set up test queue echo Starting primary cluster PRIMARY1=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.1.tmp) || fail "Could not start node" - $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue test-queue --generate-queue-events 2 - $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue control-queue --generate-queue-events 1 + $PYTHON_COMMANDS/qpid-config -a "localhost:$PRIMARY1" add queue test-queue --generate-queue-events 2 + $PYTHON_COMMANDS/qpid-config -a "localhost:$PRIMARY1" add queue control-queue --generate-queue-events 1 #send 10 messages, consume 5 of them for i in `seq 1 10`; do echo Message$i; done | ./sender --port $PRIMARY1 @@ -105,10 +82,10 @@ EOF DR1=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.1.tmp) DR2=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.2.tmp) - $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue test-queue - $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue control-queue - $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add exchange replication REPLICATION_EXCHANGE - $PYTHON_DIR/commands/qpid-route queue add localhost:$DR2 localhost:$PRIMARY2 REPLICATION_EXCHANGE REPLICATION_QUEUE + $PYTHON_COMMANDS/qpid-config -a "localhost:$DR1" add queue test-queue + $PYTHON_COMMANDS/qpid-config -a "localhost:$DR1" add queue control-queue + $PYTHON_COMMANDS/qpid-config -a "localhost:$DR1" add exchange replication REPLICATION_EXCHANGE + $PYTHON_COMMANDS/qpid-route queue add localhost:$DR2 localhost:$PRIMARY2 REPLICATION_EXCHANGE REPLICATION_QUEUE #send more messages to primary for i in `seq 11 20`; do echo Message$i; done | ./sender --port $PRIMARY1 --send-eos 1 diff --git a/qpid/cpp/src/tests/federated_cluster_test b/qpid/cpp/src/tests/federated_cluster_test index a781e269d6..8b3ce3cb95 100755 --- a/qpid/cpp/src/tests/federated_cluster_test +++ b/qpid/cpp/src/tests/federated_cluster_test @@ -22,7 +22,7 @@ # Test reliability of the replication feature in the face of link # failures: srcdir=`dirname $0` -PYTHON_DIR=$srcdir/../../../python +. $srcdir/python_env.sh trap stop_brokers EXIT @@ -61,22 +61,21 @@ start_brokers() { } setup() { - export PYTHONPATH=$PYTHON_DIR #create exchange on both cluster and single broker - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add exchange direct test-exchange - $PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add exchange direct test-exchange + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add exchange direct test-exchange + $PYTHON_COMMANDS/qpid-config -a "localhost:$NODE_1" add exchange direct test-exchange #create dynamic routes for test exchange - $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_2" "localhost:$BROKER_A" test-exchange - $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_2" test-exchange + $PYTHON_COMMANDS/qpid-route dynamic add "localhost:$NODE_2" "localhost:$BROKER_A" test-exchange + $PYTHON_COMMANDS/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_2" test-exchange #create test queue on cluster and bind it to the test exchange - $PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add queue test-queue - $PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" bind test-exchange test-queue to-cluster + $PYTHON_COMMANDS/qpid-config -a "localhost:$NODE_1" add queue test-queue + $PYTHON_COMMANDS/qpid-config -a "localhost:$NODE_1" bind test-exchange test-queue to-cluster #create test queue on single broker and bind it to the test exchange - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue test-queue - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" bind test-exchange test-queue from-cluster + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue test-queue + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" bind test-exchange test-queue from-cluster } run_test_pull_to_cluster_two_consumers() { @@ -127,25 +126,7 @@ run_test_pull_from_cluster() { if test -d ${PYTHON_DIR}; then - id -nG | grep '\<ais\>' >/dev/null || \ - NOGROUP="You are not a member of the ais group." - ps -u root | grep 'aisexec\|corosync' >/dev/null || \ - NOAISEXEC="The aisexec or corosync daemon is not running as root" - - if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then - cat <<EOF - - =========== WARNING: NOT RUNNING AIS TESTS ============== - - Not running federation to cluster test because: - $NOGROUP - $NOAISEXEC - - ========================================================== - -EOF - exit 0; - fi + . $srcdir/ais_check rm -f fed*.tmp #cleanup any files left from previous run start_brokers diff --git a/qpid/cpp/src/tests/federated_topic_test b/qpid/cpp/src/tests/federated_topic_test index 21d8411eaf..dbe9a85e95 100755 --- a/qpid/cpp/src/tests/federated_topic_test +++ b/qpid/cpp/src/tests/federated_topic_test @@ -43,7 +43,7 @@ while getopts "s:m:b:" opt ; do done MY_DIR=$(dirname $(which $0)) -PYTHON_DIR=${MY_DIR}/../../../python +. $MY_DIR/python_env.sh trap stop_brokers EXIT @@ -87,29 +87,28 @@ setup_routes() { BROKER_A="localhost:$PORT_A" BROKER_B="localhost:$PORT_B" BROKER_C="localhost:$PORT_C" - export PYTHONPATH=$PYTHON_DIR if (($VERBOSE)); then echo "Establishing routes for topic..." fi - $PYTHON_DIR/commands/qpid-route route add $BROKER_B $BROKER_A amq.topic topic_control B B - $PYTHON_DIR/commands/qpid-route route add $BROKER_C $BROKER_B amq.topic topic_control C C + $PYTHON_COMMANDS/qpid-route route add $BROKER_B $BROKER_A amq.topic topic_control B B + $PYTHON_COMMANDS/qpid-route route add $BROKER_C $BROKER_B amq.topic topic_control C C if (($VERBOSE)); then echo "linked A->B->C" fi - $PYTHON_DIR/commands/qpid-route route add $BROKER_B $BROKER_C amq.topic topic_control B B - $PYTHON_DIR/commands/qpid-route route add $BROKER_A $BROKER_B amq.topic topic_control A A + $PYTHON_COMMANDS/qpid-route route add $BROKER_B $BROKER_C amq.topic topic_control B B + $PYTHON_COMMANDS/qpid-route route add $BROKER_A $BROKER_B amq.topic topic_control A A if (($VERBOSE)); then echo "linked C->B->A" echo "Establishing routes for response queue..." fi - $PYTHON_DIR/commands/qpid-route route add $BROKER_B $BROKER_C amq.direct response B B - $PYTHON_DIR/commands/qpid-route route add $BROKER_A $BROKER_B amq.direct response A A + $PYTHON_COMMANDS/qpid-route route add $BROKER_B $BROKER_C amq.direct response B B + $PYTHON_COMMANDS/qpid-route route add $BROKER_A $BROKER_B amq.direct response A A if (($VERBOSE)); then echo "linked C->B->A" for b in $BROKER_A $BROKER_B $BROKER_C; do echo "Routes for $b" - $PYTHON_DIR/commands/qpid-route route list $b + $PYTHON_COMMANDS/qpid-route route list $b done fi } diff --git a/qpid/cpp/src/tests/python_env.sh b/qpid/cpp/src/tests/python_env.sh new file mode 100644 index 0000000000..f5dca97a56 --- /dev/null +++ b/qpid/cpp/src/tests/python_env.sh @@ -0,0 +1,26 @@ +# +# 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. +# + +# Environment for python tests +test -d python || { echo "WARNING: skipping `basename $0`, no python directory."; exit 0; } +PYTHON_DIR=$PWD/python +PYTHON_COMMANDS=$PYTHON_DIR/commands +PYTHONPATH=$PYTHON_DIR +export PYTHONPATH PYTHON_DIR + diff --git a/qpid/cpp/src/tests/python_tests b/qpid/cpp/src/tests/python_tests index e3906c1685..e2077ef7dc 100755 --- a/qpid/cpp/src/tests/python_tests +++ b/qpid/cpp/src/tests/python_tests @@ -20,14 +20,10 @@ # # Run the python tests. +. `dirname $0`/python_env.sh QPID_PORT=${QPID_PORT:-5672} PYTHON_TESTS=${PYTHON_TESTS:-$*} -QPID_PYTHON_DIR=${QPID_PYTHON_DIR:-`dirname $0`/../../../python} FAILING=${FAILING:-/dev/null} -if test -d $QPID_PYTHON_DIR; then - cd $QPID_PYTHON_DIR - ./qpid-python-test -b localhost:$QPID_PORT -I $FAILING $PYTHON_TESTS || { echo "FAIL python tests"; exit 1; } -else - echo "WARNING: No python tests. $QPID_PYTHON_DIR not found." -fi +cd $PYTHON_DIR +python commands/qpid-python-test -b localhost:$QPID_PORT -I $FAILING $PYTHON_TESTS || exit 1 diff --git a/qpid/cpp/src/tests/python_tests.ps1 b/qpid/cpp/src/tests/python_tests.ps1 new file mode 100644 index 0000000000..a7f6920783 --- /dev/null +++ b/qpid/cpp/src/tests/python_tests.ps1 @@ -0,0 +1,42 @@ +# +# 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; intended to be run by run_test.ps1 which sets up +# QPID_PORT +$srcdir = Split-Path $myInvocation.InvocationName +$PYTHON_DIR = "$srcdir\..\..\..\python" +if (!(Test-Path $PYTHON_DIR -pathType Container)) { + "Skipping header test as python libs not found" + exit 1 +} + +if (Test-Path env:FAILING) { + $fails = "-I $env:FAILING" +} +if (Test-Path env:PYTHON_TESTS) { + $tests = "$env:PYTHON_TESTS" +} +else { + $tests = "*" +} + +#cd $PYTHON_DIR +$env:PYTHONPATH="$PYTHON_DIR;$env:PYTHONPATH" +python $PYTHON_DIR/qpid-python-test -b localhost:$env:QPID_PORT $fails $tests +exit $LASTEXITCODE diff --git a/qpid/cpp/src/tests/qpid_stream.cpp b/qpid/cpp/src/tests/qpid_stream.cpp index 8e02baa8a0..8195bf390e 100644 --- a/qpid/cpp/src/tests/qpid_stream.cpp +++ b/qpid/cpp/src/tests/qpid_stream.cpp @@ -34,6 +34,9 @@ using namespace qpid::messaging; using namespace qpid::sys; +namespace qpid { +namespace tests { + struct Args : public qpid::Options { std::string url; @@ -139,10 +142,14 @@ struct Consume : Client << ", min=" << minLatency << ", max=" << maxLatency << std::endl; } - } + } } }; +}} // namespace qpid::tests + +using namespace qpid::tests; + int main(int argc, char** argv) { try { diff --git a/qpid/cpp/src/tests/quick_topictest.ps1 b/qpid/cpp/src/tests/quick_topictest.ps1 index 2b857edfff..b1e0ed1f7d 100644 --- a/qpid/cpp/src/tests/quick_topictest.ps1 +++ b/qpid/cpp/src/tests/quick_topictest.ps1 @@ -18,12 +18,13 @@ # # Quick and quiet topic test for make check. -$srcdir = Split-Path $myInvocation.ScriptName -$PsHome\powershell $srcdir\topictest.ps1 -subscribers 2 -messages 2 -batches 1 > topictest.log 2>&1 -if ($LastExitCode != 0) { - echo $0 FAILED: +[string]$me = $myInvocation.InvocationName +$srcdir = Split-Path $me +powershell "$srcdir\topictest.ps1" -subscribers 2 -messages 2 -batches 1 > topictest.log 2>&1 +if (!$?) { + "$me FAILED:" cat topictest.log exit $LastExitCode } -rm topictest.log +Remove-Item topictest.log exit 0 diff --git a/qpid/cpp/src/tests/reliable_replication_test b/qpid/cpp/src/tests/reliable_replication_test index a788d5a76b..db06259f0c 100755 --- a/qpid/cpp/src/tests/reliable_replication_test +++ b/qpid/cpp/src/tests/reliable_replication_test @@ -22,7 +22,7 @@ # Test reliability of the replication feature in the face of link # failures: MY_DIR=`dirname \`which $0\`` -PYTHON_DIR=${MY_DIR}/../../../python +. ${MY_DIR}/python_env.sh trap stop_brokers EXIT @@ -53,12 +53,12 @@ setup() { echo "Testing replication from port $BROKER_A to port $BROKER_B" export PYTHONPATH=$PYTHON_DIR - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication - $PYTHON_DIR/commands/qpid-route --ack 500 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add exchange replication replication + $PYTHON_COMMANDS/qpid-route --ack 500 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication #create test queue (only replicate enqueues for this test): - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 1 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-a + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 1 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-a } send() { @@ -72,10 +72,10 @@ receive() { bounce_link() { echo "Destroying link..." - $PYTHON_DIR/commands/qpid-route link del "localhost:$BROKER_B" "localhost:$BROKER_A" + $PYTHON_COMMANDS/qpid-route link del "localhost:$BROKER_B" "localhost:$BROKER_A" echo "Link destroyed; recreating route..." sleep 2 - $PYTHON_DIR/commands/qpid-route --ack 500 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication + $PYTHON_COMMANDS/qpid-route --ack 500 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication echo "Route re-established" } diff --git a/qpid/cpp/src/tests/replication_test b/qpid/cpp/src/tests/replication_test index 8b3022b260..000b4591da 100755 --- a/qpid/cpp/src/tests/replication_test +++ b/qpid/cpp/src/tests/replication_test @@ -21,7 +21,8 @@ # Run a test of the replication feature MY_DIR=`dirname \`which $0\`` -PYTHON_DIR=${MY_DIR}/../../../python +. `dirname $0`/python_env.sh + trap stop_brokers INT TERM QUIT stop_brokers() { @@ -47,21 +48,21 @@ if test -d ${PYTHON_DIR} && test -f ../.libs/replicating_listener.so && test -f export PYTHONPATH echo "Running replication test between localhost:$BROKER_A and localhost:$BROKER_B" - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication - $PYTHON_DIR/commands/qpid-route --ack 5 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add exchange replication replication + $PYTHON_COMMANDS/qpid-route --ack 5 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication #create test queues - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 2 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-b --generate-queue-events 2 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-c --generate-queue-events 1 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 2 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-e --generate-queue-events 1 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 2 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-b --generate-queue-events 2 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-c --generate-queue-events 1 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 2 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-e --generate-queue-events 1 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-a - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-b - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-c - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-e + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-a + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-b + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-c + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-e #queue-d deliberately not declared on DR; this error case should be handled #publish and consume from test queues on broker A: @@ -125,13 +126,13 @@ if test -d ${PYTHON_DIR} && test -f ../.libs/replicating_listener.so && test -f ../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replication_exchange.so --log-enable info+ --log-to-file replication-dest.log --log-to-stderr 0 > qpidd.port BROKER_B=`cat qpidd.port` - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication - $PYTHON_DIR/commands/qpid-route --ack 5 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add exchange replication replication + $PYTHON_COMMANDS/qpid-route --ack 5 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-e --generate-queue-events 2 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-e - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 1 - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-d + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-e --generate-queue-events 2 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-e + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 1 + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-d i=1 while [ $i -le 10 ]; do @@ -153,9 +154,9 @@ if test -d ${PYTHON_DIR} && test -f ../.libs/replicating_listener.so && test -f ../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replication_exchange.so --log-enable info+ --log-to-file replication-dest.log --log-to-stderr 0 > qpidd.port BROKER_B=`cat qpidd.port` - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-e - $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication - $PYTHON_DIR/commands/qpid-route --ack 5 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add queue queue-e + $PYTHON_COMMANDS/qpid-config -a "localhost:$BROKER_B" add exchange replication replication + $PYTHON_COMMANDS/qpid-route --ack 5 queue add "localhost:$BROKER_B" "localhost:$BROKER_A" replication replication # now send another 15 i=11 while [ $i -le 15 ]; do diff --git a/qpid/cpp/src/tests/ring_queue_test b/qpid/cpp/src/tests/ring_queue_test index 5805989d7e..553746eb49 100755 --- a/qpid/cpp/src/tests/ring_queue_test +++ b/qpid/cpp/src/tests/ring_queue_test @@ -48,7 +48,7 @@ receive() { cleanup() { rm -f sender_${QUEUE_NAME}_* receiver_${QUEUE_NAME}_* - qpid-config $BROKER_URL add queue $QUEUE_NAME + qpid-config $BROKER_URL del queue $QUEUE_NAME --force } log() { @@ -64,10 +64,11 @@ validate() { if [[ $RECEIVERS -eq 0 ]]; then #queue should have $LIMIT messages on it, but need to send an eos also sender --routing-key $QUEUE_NAME --send-eos 1 < /dev/null - if [[ $(receiver --queue $QUEUE_NAME --browse | wc -l) -eq $(( $LIMIT - 1)) ]]; then + received=$(receiver --queue $QUEUE_NAME --browse | wc -l) + if [[ received -eq $(( $LIMIT - 1)) ]]; then log "queue contains $LIMIT messages as expected" else - fail "queue does not contain the expected $LIMIT messages" + fail "queue does not contain the expected $LIMIT messages (received $received)" fi elif [[ $CONCURRENT -eq 0 ]]; then #sum of length of all output files should be equal to $LIMIT - $RECEIVERS (1 eos message each) diff --git a/qpid/cpp/src/tests/run_acl_tests b/qpid/cpp/src/tests/run_acl_tests index d9b654c7cd..c67e2d421d 100755 --- a/qpid/cpp/src/tests/run_acl_tests +++ b/qpid/cpp/src/tests/run_acl_tests @@ -20,7 +20,7 @@ # # Run the acl tests. $srcdir is set by the Makefile. -PYTHON_DIR=$srcdir/../../../python +. `dirname $0`/python_env.sh DATA_DIR=`pwd`/data_dir trap stop_brokers INT TERM QUIT @@ -55,7 +55,7 @@ if test -d ${PYTHON_DIR} ; then echo "Running acl tests using brokers on ports $LOCAL_PORT" PYTHONPATH=$PYTHON_DIR:$srcdir export PYTHONPATH - $PYTHON_DIR/qpid-python-test -b localhost:$LOCAL_PORT -m acl || EXITCODE=1 + $PYTHON_COMMANDS/qpid-python-test -b localhost:$LOCAL_PORT -m acl || EXITCODE=1 stop_brokers || EXITCODE=1 test_loading_acl_from_absolute_path || EXITCODE=1 rm -rf $DATA_DIR diff --git a/qpid/cpp/src/tests/run_cli_tests b/qpid/cpp/src/tests/run_cli_tests index ea0d591176..bb9605410c 100755 --- a/qpid/cpp/src/tests/run_cli_tests +++ b/qpid/cpp/src/tests/run_cli_tests @@ -21,8 +21,8 @@ # Run the cli-utility tests. MY_DIR=`dirname \`which $0\`` -PYTHON_DIR=${MY_DIR}/../../../python -CLI_DIR=${PYTHON_DIR}/commands +. `dirname $0`/python_env.sh +CLI_DIR=$PYTHON_COMMANDS trap stop_brokers INT TERM QUIT @@ -43,7 +43,7 @@ if test -d ${PYTHON_DIR} ; then echo "Running CLI tests using brokers on ports $LOCAL_PORT $REMOTE_PORT" PYTHONPATH=${PYTHON_DIR}:${MY_DIR} export PYTHONPATH - ${PYTHON_DIR}/qpid-python-test -m cli_tests -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT -Dcli-dir=$CLI_DIR $@ + $PYTHON_COMMANDS/qpid-python-test -m cli_tests -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT -Dcli-dir=$CLI_DIR $@ RETCODE=$? stop_brokers if test x$RETCODE != x0; then diff --git a/qpid/cpp/src/tests/run_cluster_test b/qpid/cpp/src/tests/run_cluster_test new file mode 100755 index 0000000000..c022eea1fe --- /dev/null +++ b/qpid/cpp/src/tests/run_cluster_test @@ -0,0 +1,26 @@ +#!/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 tests +srcdir=`dirname $0` +. $srcdir/ais_check +with_ais_group $srcdir/run_test ./cluster_test diff --git a/qpid/cpp/src/tests/run_cluster_tests b/qpid/cpp/src/tests/run_cluster_tests index 8b039346db..d1a58f9f6a 100755 --- a/qpid/cpp/src/tests/run_cluster_tests +++ b/qpid/cpp/src/tests/run_cluster_tests @@ -22,45 +22,21 @@ # Check that top_builddir and srcdir are set # If not, assume local run from test dir if [ -z ${top_builddir} -o -z ${srcdir} ]; then - srcdir=`pwd` + srcdir=`dirname $0` top_builddir=${srcdir}/../../ fi TEST_DIR=${top_builddir}/src/tests -PYTHON_DIR=${srcdir}/../../../python +. $srcdir/python_env.sh if test -z $1; then - CLUSTER_TEST="${PYTHON_DIR}/qpid-python-test -m cluster_tests cluster_tests.ShortTests.\*" + CLUSTER_TEST="$PYTHON_COMMANDS/qpid-python-test -m cluster_tests cluster_tests.ShortTests.\*" else - CLUSTER_TEST="${PYTHON_DIR}/qpid-python-test -m cluster_tests cluster_tests.LongTests.\*" + CLUSTER_TEST="$PYTHON_COMMANDS/qpid-python-test -m cluster_tests cluster_tests.LongTests.\*" echo "Running $1..." fi - # Check AIS requirements -id -nG | grep '\<ais\>' > /dev/null || NOGROUP="You are not a member of the ais group." -ps -u root | grep 'aisexec\|corosync' > /dev/null || NOAISEXEC="The aisexec or corosync daemon is not running as root." -if ! test -d ${PYTHON_DIR}; then - NO_PYTHON_DIR="PYTHON_DIR=\"${PYTHON_DIR}\" not found or does not exist." -fi - -if test -n "${NOGROUP}" -o -n "${NOAISEXEC}" -o -n "${NO_PYTHON_DIR}"; then - cat <<EOF - - ======== WARNING: PYTHON CLUSTER TESTS DISABLED =========== - - Tests that depend on the openais library (used for clustering) - and python will not be run because: - - ${NOGROUP} - ${NOAISEXEC} - ${NO_PYTHON_DIR} - - =========================================================== - -EOF - exit 0 -fi - +. $srcdir/ais_check # Check XML exchange requirements XML_LIB=$srcdir/../.libs/xml.so @@ -103,7 +79,7 @@ export TMP_DATA_DIR # Run the test -sg ais -c "${CLUSTER_TEST}" +with_ais_group ${CLUSTER_TEST} RETCODE=$? if test x${RETCODE} != x0; then @@ -114,4 +90,4 @@ fi # Delete cluster store dir if test was successful. rm -rf ${TMP_DATA_DIR} -exit 0
\ No newline at end of file +exit 0 diff --git a/qpid/cpp/src/tests/run_failover_soak b/qpid/cpp/src/tests/run_failover_soak index 3c9a5589c4..8d5b37f008 100755 --- a/qpid/cpp/src/tests/run_failover_soak +++ b/qpid/cpp/src/tests/run_failover_soak @@ -19,29 +19,7 @@ # under the License. # -# Check AIS requirements and run tests if found. -id -ng | grep '\<ais\>' >/dev/null || \ - NOGROUP="The ais group is not your primary group." -ps -u root | grep 'aisexec\|corosync' >/dev/null || \ - NOAISEXEC="The aisexec/corosync daemon is not running as root" - -if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then - cat <<EOF - - =========== WARNING: NOT RUNNING AIS TESTS ============== - - Tests that depend on the openais library (used for clustering) - will not be run because: - - $NOGROUP - $NOAISEXEC - - ========================================================== - -EOF - exit 0; # A warning, not a failure. -fi - +. `dirname $0`/ais_check host=127.0.0.1 diff --git a/qpid/cpp/src/tests/run_federation_tests b/qpid/cpp/src/tests/run_federation_tests index 8640fb728f..3fe4bccb13 100755 --- a/qpid/cpp/src/tests/run_federation_tests +++ b/qpid/cpp/src/tests/run_federation_tests @@ -21,7 +21,7 @@ # Run the federation tests. MY_DIR=`dirname \`which $0\`` -PYTHON_DIR=${MY_DIR}/../../../python +. `dirname $0`/python_env.sh trap stop_brokers INT TERM QUIT @@ -42,7 +42,7 @@ if test -d ${PYTHON_DIR} ; then echo "Running federation tests using brokers on ports $LOCAL_PORT $REMOTE_PORT" PYTHONPATH=${PYTHON_DIR}:${MY_DIR} export PYTHONPATH - ${PYTHON_DIR}/qpid-python-test -m federation -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT $@ + $PYTHON_COMMANDS/qpid-python-test -m federation -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT $@ RETCODE=$? stop_brokers if test x$RETCODE != x0; then diff --git a/qpid/cpp/src/tests/run_federation_tests.ps1 b/qpid/cpp/src/tests/run_federation_tests.ps1 index db3dbf5a11..dd0ea2fe5b 100644 --- a/qpid/cpp/src/tests/run_federation_tests.ps1 +++ b/qpid/cpp/src/tests/run_federation_tests.ps1 @@ -18,42 +18,63 @@ # # Run the federation tests. -$srcdir = Split-Path $myInvocation.ScriptName -$PYTHON_DIR = $srcdir\..\..\..\python -trap stop_brokers INT TERM QUIT +$srcdir = Split-Path $myInvocation.InvocationName +$PYTHON_DIR = "$srcdir\..\..\..\python" +if (!(Test-Path $PYTHON_DIR -pathType Container)) { + "Skipping federation tests as python libs not found" + exit 1 +} -start_brokers() { +# Test runs from the tests directory but the broker executable is one level +# up, and most likely in a subdirectory from there based on what build type. +# Look around for it before trying to start it. +$subs = "Debug","Release","MinSizeRel","RelWithDebInfo" +foreach ($sub in $subs) { + $prog = "..\$sub\qpidd.exe" + if (Test-Path $prog) { + break + } +} +if (!(Test-Path $prog)) { + "Cannot locate qpidd.exe" + exit 1 +} +$cmdline = "$prog --auth=no --no-module-dir --port=0 --log-to-file qpidd.log $args | foreach { set-content qpidd.port `$_ }" +$cmdblock = $executioncontext.invokecommand.NewScriptBlock($cmdline) + +function start_brokers { # Start 2 brokers, saving the port numbers in LOCAL_PORT, REMOTE_PORT. - . $srcdir\background.ps1 { - ..\Debug\qpidd --auth=no --no-module-dir --port=0 --log-to-file qpidd.log $args | foreach { set-content qpidd.port $_ } } + . $srcdir\background.ps1 $cmdblock while (!(Test-Path qpidd.port)) { Start-Sleep 2 } set-item -path env:LOCAL_PORT -value (get-content -path qpidd.port -totalcount 1) Remove-Item qpidd.port - . $srcdir\background.ps1 { - ..\Debug\qpidd --auth=no --no-module-dir --port=0 --log-to-file qpidd.log $args | foreach { set-content qpidd.port $_ } } + . $srcdir\background.ps1 $cmdblock while (!(Test-Path qpidd.port)) { Start-Sleep 2 } set-item -path env:REMOTE_PORT -value (get-content -path qpidd.port -totalcount 1) } -stop_brokers() { - ..\Debug\qpidd -q --port $LOCAL_PORT | Out-Default - ..\Debug\qpidd -q --port $REMOTE_PORT | Out-Default +function stop_brokers { + Invoke-Expression "$prog -q --port $env:LOCAL_PORT" | Out-Default + Invoke-Expression "$prog -q --port $env:REMOTE_PORT" | Out-Default +} + +trap { + &stop_brokers + break } -if (Test-Path $PYTHON_DIR -pathType Container) { - start_brokers - "Running federation tests using brokers on ports $LOCAL_PORT $REMOTE_PORT" - $env:PYTHONPATH=$PYTHON_DIR - $srcdir/federation.py -v -s $srcdir\..\..\..\specs\amqp.0-10-qpid-errata.xml -b localhost:$LOCAL_PORT --remote-port $REMOTE_PORT $args - $RETCODE=$LASTEXITCODE - stop_brokers - if ($RETCODE != 0) { - "FAIL federation tests" - exit 1 - } +&start_brokers +"Running federation tests using brokers on ports $env:LOCAL_PORT $env:REMOTE_PORT" +$env:PYTHONPATH=$PYTHON_DIR +python $srcdir/federation.py -v -s $srcdir\..\..\..\specs\amqp.0-10-qpid-errata.xml -b localhost:$env:LOCAL_PORT --remote-port $env:REMOTE_PORT $args +$RETCODE=$LASTEXITCODE +&stop_brokers +if ($RETCODE -ne 0) { + "FAIL federation tests" + exit 1 } diff --git a/qpid/cpp/src/tests/run_header_test b/qpid/cpp/src/tests/run_header_test index 414fecd28f..1b5a3963db 100755 --- a/qpid/cpp/src/tests/run_header_test +++ b/qpid/cpp/src/tests/run_header_test @@ -24,7 +24,7 @@ # in both directions srcdir=`dirname $0` -PYTHON_DIR=$srcdir/../../../python +. `dirname $0`/python_env.sh test -f qpidd.port && QPID_PORT=`cat qpidd.port` if test -d ${PYTHON_DIR} ; then diff --git a/qpid/cpp/src/tests/run_header_test.ps1 b/qpid/cpp/src/tests/run_header_test.ps1 index add680f569..c7bc2d788e 100644 --- a/qpid/cpp/src/tests/run_header_test.ps1 +++ b/qpid/cpp/src/tests/run_header_test.ps1 @@ -21,20 +21,33 @@ # TODO: this should be expanded to cover a wider set of types and go # in both directions -$srcdir = Split-Path $myInvocation.ScriptName -$PYTHON_DIR = $srcdir\..\..\..\python +$srcdir = Split-Path $myInvocation.InvocationName +$PYTHON_DIR = "$srcdir\..\..\..\python" +if (!(Test-Path $PYTHON_DIR -pathType Container)) { + "Skipping header test as python libs not found" + exit 0 +} + if (Test-Path qpidd.port) { set-item -path env:QPID_PORT -value (get-content -path qpidd.port -totalcount 1) } -if (Test-Path $PYTHON_DIR -pathType Container) { - ./header_test -p $QPID_PORT - $env:PYTHONPATH="$PYTHON_DIR;$env:PYTHONPATH" - $srcdir/header_test.py "localhost" $QPID_PORT - exit $LASTEXITCODE +# Test runs from the tests directory but the test executables are in a +# subdirectory based on the build type. Look around for it before trying +# to start it. +$subs = "Debug","Release","MinSizeRel","RelWithDebInfo" +foreach ($sub in $subs) { + $prog = ".\$sub\header_test.exe" + if (Test-Path $prog) { + break + } } -else { - "Skipping header test as python libs not found" - exit 0 +if (!(Test-Path $prog)) { + "Cannot locate header_test.exe" + exit 1 } +Invoke-Expression "$prog -p $env:QPID_PORT" | Write-Output +$env:PYTHONPATH="$PYTHON_DIR;$env:PYTHONPATH" +Invoke-Expression "python $srcdir/header_test.py localhost $env:QPID_PORT" | Write-Output +exit $LASTEXITCODE diff --git a/qpid/cpp/src/tests/run_long_cluster_tests b/qpid/cpp/src/tests/run_long_cluster_tests index bc1ae8a0c1..cb9c6b219b 100755 --- a/qpid/cpp/src/tests/run_long_cluster_tests +++ b/qpid/cpp/src/tests/run_long_cluster_tests @@ -19,4 +19,5 @@ # under the License. # -./run_cluster_tests long_cluster_tests +srcdir=`dirname $0` +$srcdir/run_cluster_tests long_cluster_tests diff --git a/qpid/cpp/src/tests/run_ring_queue_test b/qpid/cpp/src/tests/run_ring_queue_test index fb90075458..9cd3775de1 100755 --- a/qpid/cpp/src/tests/run_ring_queue_test +++ b/qpid/cpp/src/tests/run_ring_queue_test @@ -22,9 +22,8 @@ #setup path to find qpid-config and sender/receiver test progs srcdir=`dirname $0` -PYTHON_DIR=$srcdir/../../../python -export PYTHONPATH=$PYTHON_DIR -export PATH=./:$PYTHON_DIR/commands:$PATH +. `dirname $0`/python_env.sh +export PATH=$PWD:$srcdir:$PYTHON_COMMANDS:$PATH #set port to connect to via env var test -s qpidd.port && QPID_PORT=`cat qpidd.port` diff --git a/qpid/cpp/src/tests/run_test.ps1 b/qpid/cpp/src/tests/run_test.ps1 index ebbef07f1d..551368bc9b 100644 --- a/qpid/cpp/src/tests/run_test.ps1 +++ b/qpid/cpp/src/tests/run_test.ps1 @@ -52,7 +52,6 @@ if (Test-Path qpidd.port) { set-item -path env:QPID_PORT -value (get-content -path qpidd.port -totalcount 1) } -#$p = new-object System.Diagnostics.Process $si = new-object System.Diagnostics.ProcessStartInfo $si.WorkingDirectory = $pwd $si.UseShellExecute = $true @@ -67,6 +66,6 @@ else { $si.Arguments = $args[1..$args.length-1] } } -$p = [diagnostics.process]::Start($si) +$p = [System.Diagnostics.Process]::Start($si) $p.WaitForExit() exit $? diff --git a/qpid/cpp/src/tests/start_broker.ps1 b/qpid/cpp/src/tests/start_broker.ps1 index f2aa20439a..9263262b9f 100644 --- a/qpid/cpp/src/tests/start_broker.ps1 +++ b/qpid/cpp/src/tests/start_broker.ps1 @@ -28,9 +28,26 @@ function Get-ScriptPath if (Test-Path qpidd.port) { Remove-Item qpidd.port } + +# Test runs from the tests directory but the broker executable is one level +# up, and most likely in a subdirectory from there based on what build type. +# Look around for it before trying to start it. +$subs = "Debug","Release","MinSizeRel","RelWithDebInfo" +foreach ($sub in $subs) { + $prog = "..\$sub\qpidd.exe" + if (Test-Path $prog) { + break + } +} +if (!(Test-Path $prog)) { + "Cannot locate qpidd.exe" + exit 1 +} +$cmdline = "$prog --auth=no --no-module-dir --port=0 --log-to-file qpidd.log $args | foreach { set-content qpidd.port `$_ }" +$cmdblock = $executioncontext.invokecommand.NewScriptBlock($cmdline) $srcdir = Get-ScriptPath -. $srcdir\background.ps1 { - ..\Debug\qpidd --auth=no --no-module-dir --port=0 --log-to-file qpidd.log $args | foreach { set-content qpidd.port $_ } } +. $srcdir\background.ps1 $cmdblock + $wait_time = 0 while (!(Test-Path qpidd.port) -and ($wait_time -lt 10)) { Start-Sleep 2 diff --git a/qpid/cpp/src/tests/start_cluster b/qpid/cpp/src/tests/start_cluster index 585ba082d5..fb3d27373a 100755 --- a/qpid/cpp/src/tests/start_cluster +++ b/qpid/cpp/src/tests/start_cluster @@ -23,20 +23,17 @@ # # Execute command with the ais group set. -with_ais_group() { - id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group." 1>&2; exit 1; } - echo $* | newgrp ais -} +. `dirname $0`/ais_check rm -f cluster*.log cluster.ports qpidd.port SIZE=${1:-3}; shift CLUSTER=`pwd` # Cluster name=pwd, avoid clashes. -OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --auth=no $@" +OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --auth=no --log-enable notice+ --log-enable debug+:cluster $@" for (( i=0; i<SIZE; ++i )); do DDIR=`mktemp -d /tmp/start_cluster.XXXXXXXXXX` - PORT=`with_ais_group ../qpidd -p0 --log-to-file=cluster$i.log $OPTS --data-dir=$DDIR` || exit 1 + PORT=`with_ais_group ../qpidd -p0 --log-to-file=cluster$i.log $OPTS --data-dir=$DDIR` || exit 1 echo $PORT >> cluster.ports done diff --git a/qpid/cpp/src/tests/stop_broker.ps1 b/qpid/cpp/src/tests/stop_broker.ps1 index 165c7a63b0..4fdeb26e2b 100644 --- a/qpid/cpp/src/tests/stop_broker.ps1 +++ b/qpid/cpp/src/tests/stop_broker.ps1 @@ -21,8 +21,23 @@ Get-Content -path qpidd.port -totalCount 1 | Set-Variable -name qpid_port Remove-Item qpidd.port +# Test runs from the tests directory but the broker executable is one level +# up, and most likely in a subdirectory from there based on what build type. +# Look around for it before trying to start it. +$subs = "Debug","Release","MinSizeRel","RelWithDebInfo" +foreach ($sub in $subs) { + $prog = "..\$sub\qpidd.exe" + if (Test-Path $prog) { + break + } +} +if (!(Test-Path $prog)) { + "Cannot locate qpidd.exe" + exit 1 +} + # Piping the output makes the script wait for qpidd to finish. -..\Debug\qpidd --quit --port $qpid_port | Write-Output +Invoke-Expression "$prog --quit --port $qpid_port" | Write-Output $stopped = $? # Check qpidd.log. diff --git a/qpid/cpp/src/tests/test_store.cpp b/qpid/cpp/src/tests/test_store.cpp index 64a96bf71a..f2d3aa65a3 100644 --- a/qpid/cpp/src/tests/test_store.cpp +++ b/qpid/cpp/src/tests/test_store.cpp @@ -140,7 +140,8 @@ struct TestStorePlugin : public Plugin { { Broker* broker = dynamic_cast<Broker*>(&target); if (!broker) return; - broker->setStore (new TestStore(options.name, *broker)); + boost::shared_ptr<MessageStore> p(new TestStore(options.name, *broker)); + broker->setStore (p); } void initialize(qpid::Plugin::Target&) {} diff --git a/qpid/cpp/src/tests/topictest.ps1 b/qpid/cpp/src/tests/topictest.ps1 index 04dae23ad9..58ae50c67c 100644 --- a/qpid/cpp/src/tests/topictest.ps1 +++ b/qpid/cpp/src/tests/topictest.ps1 @@ -19,9 +19,6 @@ # Run the C++ topic test -# Clean up old log files -Get-Item subscriber_*.log | Remove-Item - # Parameters with default values: s (subscribers) m (messages) b (batches) # h (host) t (false; use transactions) param ( @@ -32,23 +29,28 @@ param ( [switch] $t # transactional ) +# Clean up old log files +Get-Item subscriber_*.log | Remove-Item + +if ($t) { + $transactional = "--transactional --durable" +} + function subscribe { - "Start subscriber $args[0]" - $LOG = "subscriber_$args[0].log" - . $srcdir\background.ps1 { - $env:OUTDIR\topic_listener $TRANSACTIONAL > $LOG 2>&1 - if ($LastExitCode -ne 0) { Remove-Item $LOG } - } -inconsole + param ([int]$num) + "Start subscriber $num" + $LOG = "subscriber_$num.log" + $cmdline = "$env:OUTDIR\topic_listener $transactional > $LOG 2>&1 + if (`$LastExitCode -ne 0) { Remove-Item $LOG }" + $cmdblock = $executioncontext.invokecommand.NewScriptBlock($cmdline) + . $srcdir\background.ps1 $cmdblock } -publish() { - if ($t) { - $transactional = "--transactional --durable" - } - $env:OUTDIR\topic_publisher --messages $messages --batches $batches --subscribers $subscribers $host $transactional 2>&1 +function publish { + Invoke-Expression "$env:OUTDIR\topic_publisher --messages $messages --batches $batches --subscribers $subscribers $host $transactional" 2>&1 } -$srcdir = Split-Path $myInvocation.ScriptName +$srcdir = Split-Path $MyInvocation.MyCommand.Path if ($broker.length) { $broker = "-h$broker" } diff --git a/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp b/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp index d51ed90758..a0b665db73 100644 --- a/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp +++ b/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp @@ -28,9 +28,23 @@ #include <crtdbg.h> #include <windows.h> +#include <iostream> namespace { +// Instead of popping up a window for exceptions, just print something out +LONG _stdcall UnhandledExceptionFilter (PEXCEPTION_POINTERS pExceptionInfo) +{ + DWORD dwExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode; + + if (dwExceptionCode == EXCEPTION_ACCESS_VIOLATION) + std::cerr << "\nERROR: ACCESS VIOLATION\n" << std::endl; + else + std::cerr << "\nERROR: UNHANDLED EXCEPTION\n" << std::endl; + + return EXCEPTION_EXECUTE_HANDLER; +} + struct redirect_errors_to_stderr { redirect_errors_to_stderr (); }; @@ -50,6 +64,9 @@ redirect_errors_to_stderr::redirect_errors_to_stderr() // and can't-open-file message boxes. SetErrorMode(SEM_FAILCRITICALERRORS); SetErrorMode(SEM_NOOPENFILEERRORBOX); + + // And this will catch all unhandled exceptions. + SetUnhandledExceptionFilter (&UnhandledExceptionFilter); } } // namespace |