#include #include "signalspy.h" #include "qamqptestcase.h" #include "qamqpclient.h" #include "qamqpexchange.h" #include "qamqpqueue.h" class tst_QAMQPExchange : public TestCase { Q_OBJECT private Q_SLOTS: void init(); void cleanup(); void standardTypes_data(); void standardTypes(); void invalidStandardDeclaration_data(); void invalidStandardDeclaration(); void invalidDeclaration(); void invalidRedeclaration(); void removeIfUnused(); void invalidMandatoryRouting(); void invalidImmediateRouting(); void confirmsSupport(); void confirmDontLoseMessages(); void passiveDeclareNotFound(); void cleanupOnDeletion(); void testQueuedPublish(); private: QScopedPointer client; }; void tst_QAMQPExchange::init() { client.reset(new QAmqpClient); client->connectToHost(); QVERIFY(waitForSignal(client.data(), SIGNAL(connected()))); } void tst_QAMQPExchange::cleanup() { if (client->isConnected()) { client->disconnectFromHost(); QVERIFY(waitForSignal(client.data(), SIGNAL(disconnected()))); } } void tst_QAMQPExchange::standardTypes_data() { QTest::addColumn("type"); QTest::addColumn("delayedDeclaration"); QTest::newRow("direct") << QAmqpExchange::Direct << false; QTest::newRow("direct-delayed") << QAmqpExchange::Direct << true; QTest::newRow("fanout") << QAmqpExchange::FanOut << false; QTest::newRow("fanout-delayed") << QAmqpExchange::FanOut << true; QTest::newRow("topic") << QAmqpExchange::Topic << false; QTest::newRow("topic-delayed") << QAmqpExchange::Topic << true; QTest::newRow("headers") << QAmqpExchange::Headers << false; QTest::newRow("headers-delayed") << QAmqpExchange::Headers << true; } void tst_QAMQPExchange::standardTypes() { QFETCH(QAmqpExchange::ExchangeType, type); QFETCH(bool, delayedDeclaration); QAmqpExchange *exchange = client->createExchange("test"); if (!delayedDeclaration) QVERIFY(waitForSignal(exchange, SIGNAL(opened()))); exchange->declare(type); QVERIFY(waitForSignal(exchange, SIGNAL(declared()))); exchange->remove(QAmqpExchange::roForce); QVERIFY(waitForSignal(exchange, SIGNAL(removed()))); } void tst_QAMQPExchange::invalidStandardDeclaration_data() { QTest::addColumn("exchangeName"); QTest::addColumn("type"); QTest::addColumn("error"); QTest::newRow("amq.direct") << "amq.direct" << QAmqpExchange::Direct << QAMQP::PreconditionFailedError; QTest::newRow("amq.fanout") << "amq.fanout" << QAmqpExchange::FanOut << QAMQP::PreconditionFailedError; QTest::newRow("amq.headers") << "amq.headers" << QAmqpExchange::Headers << QAMQP::PreconditionFailedError; QTest::newRow("amq.match") << "amq.match" << QAmqpExchange::Headers << QAMQP::PreconditionFailedError; QTest::newRow("amq.topic") << "amq.topic" << QAmqpExchange::Topic << QAMQP::PreconditionFailedError; QTest::newRow("amq.reserved") << "amq.reserved" << QAmqpExchange::Direct << QAMQP::AccessRefusedError; } void tst_QAMQPExchange::invalidStandardDeclaration() { QFETCH(QString, exchangeName); QFETCH(QAmqpExchange::ExchangeType, type); QFETCH(QAMQP::Error, error); QAmqpExchange *exchange = client->createExchange(exchangeName); exchange->declare(type); QVERIFY(waitForSignal(exchange, SIGNAL(error(QAMQP::Error)))); QCOMPARE(exchange->error(), error); } void tst_QAMQPExchange::invalidDeclaration() { QAmqpExchange *exchange = client->createExchange("test-invalid-declaration"); exchange->declare("invalidExchangeType"); QVERIFY(waitForSignal(client.data(), SIGNAL(error(QAMQP::Error)))); QCOMPARE(client->error(), QAMQP::CommandInvalidError); } void tst_QAMQPExchange::invalidRedeclaration() { QAmqpExchange *exchange = client->createExchange("test-invalid-redeclaration"); exchange->declare(QAmqpExchange::Direct); QVERIFY(waitForSignal(exchange, SIGNAL(declared()))); QAmqpExchange *redeclared = client->createExchange("test-invalid-redeclaration"); redeclared->declare(QAmqpExchange::FanOut); QVERIFY(waitForSignal(redeclared, SIGNAL(error(QAMQP::Error)))); // this is per spec: // QCOMPARE(redeclared->error(), QAMQP::NotAllowedError); // this is for rabbitmq: QCOMPARE(redeclared->error(), QAMQP::PreconditionFailedError); // Server has probably closed the channel on us, if so, re-open it. if (!exchange->isOpen()) { exchange->reopen(); QVERIFY(waitForSignal(exchange, SIGNAL(opened()))); } // cleanup exchange->remove(); QVERIFY(waitForSignal(exchange, SIGNAL(removed()))); } void tst_QAMQPExchange::removeIfUnused() { QAmqpExchange *exchange = client->createExchange("test-if-unused-exchange"); exchange->declare(QAmqpExchange::Direct, QAmqpExchange::AutoDelete); QVERIFY(waitForSignal(exchange, SIGNAL(declared()))); QAmqpQueue *queue = client->createQueue("test-if-unused-queue"); queue->declare(); QVERIFY(waitForSignal(queue, SIGNAL(declared()))); queue->bind("test-if-unused-exchange", "testRoutingKey"); QVERIFY(waitForSignal(queue, SIGNAL(bound()))); exchange->remove(QAmqpExchange::roIfUnused); QVERIFY(waitForSignal(exchange, SIGNAL(error(QAMQP::Error)))); QCOMPARE(exchange->error(), QAMQP::PreconditionFailedError); QVERIFY(!exchange->errorString().isEmpty()); // cleanup queue->remove(QAmqpQueue::roForce); QVERIFY(waitForSignal(queue, SIGNAL(removed()))); } void tst_QAMQPExchange::invalidMandatoryRouting() { QAmqpExchange *defaultExchange = client->createExchange(); defaultExchange->publish("some message", "unroutable-key", QAmqpMessage::PropertyHash(), QAmqpExchange::poMandatory); QVERIFY(waitForSignal(defaultExchange, SIGNAL(error(QAMQP::Error)))); QCOMPARE(defaultExchange->error(), QAMQP::NoRouteError); } void tst_QAMQPExchange::invalidImmediateRouting() { QAmqpExchange *defaultExchange = client->createExchange(); defaultExchange->publish("some message", "unroutable-key", QAmqpMessage::PropertyHash(), QAmqpExchange::poImmediate); QVERIFY(waitForSignal(client.data(), SIGNAL(error(QAMQP::Error)))); QCOMPARE(client->error(), QAMQP::NotImplementedError); } void tst_QAMQPExchange::confirmsSupport() { QAmqpExchange *exchange = client->createExchange("confirm-test"); exchange->enableConfirms(); QVERIFY(waitForSignal(exchange, SIGNAL(confirmsEnabled()))); } void tst_QAMQPExchange::confirmDontLoseMessages() { QAmqpExchange *defaultExchange = client->createExchange(); defaultExchange->enableConfirms(); QVERIFY(waitForSignal(defaultExchange, SIGNAL(confirmsEnabled()))); QAmqpMessage::PropertyHash properties; properties[QAmqpMessage::DeliveryMode] = "2"; // make message persistent for (int i = 0; i < 10000; ++i) defaultExchange->publish("noop", "confirms-test", properties); QVERIFY(defaultExchange->waitForConfirms()); } void tst_QAMQPExchange::passiveDeclareNotFound() { QAmqpExchange *nonExistentExchange = client->createExchange("this-does-not-exist"); nonExistentExchange->declare(QAmqpExchange::Direct, QAmqpExchange::Passive); QVERIFY(waitForSignal(nonExistentExchange, SIGNAL(error(QAMQP::Error)))); QCOMPARE(nonExistentExchange->error(), QAMQP::NotFoundError); } void tst_QAMQPExchange::cleanupOnDeletion() { // create, declare, and close the wrong way QAmqpExchange *exchange = client->createExchange("test-deletion"); exchange->declare(); QVERIFY(waitForSignal(exchange, SIGNAL(declared()))); exchange->close(); exchange->deleteLater(); QVERIFY(waitForSignal(exchange, SIGNAL(destroyed()))); // now create, declare, and close the right way exchange = client->createExchange("test-deletion"); exchange->declare(); QVERIFY(waitForSignal(exchange, SIGNAL(declared()))); exchange->close(); QVERIFY(waitForSignal(exchange, SIGNAL(closed()))); } void tst_QAMQPExchange::testQueuedPublish() { QAmqpExchange *defaultExchange = client->createExchange(); defaultExchange->enableConfirms(); QVERIFY(waitForSignal(defaultExchange, SIGNAL(confirmsEnabled()))); QAmqpMessage::PropertyHash properties; properties[QAmqpMessage::DeliveryMode] = "2"; // make message persistent for (int i = 0; i < 10000; ++i) { QMetaObject::invokeMethod(defaultExchange, "publish", Qt::QueuedConnection, Q_ARG(QString, "noop"), Q_ARG(QString, "confirms-test"), Q_ARG(QAmqpMessage::PropertyHash, properties)); } QVERIFY(defaultExchange->waitForConfirms()); } QTEST_MAIN(tst_QAMQPExchange) #include "tst_qamqpexchange.moc"