add tests for proper uri validation

this is the missing component from PR #41, tests a number of example
amqp uri's provided by the RabbitMQ spec/documentation
This commit is contained in:
Matt Broadstone 2014-06-26 13:31:25 -04:00 committed by mbroadst
parent 12a03f959f
commit a89dbb3805
4 changed files with 108 additions and 48 deletions

View File

@ -34,7 +34,7 @@ ClientPrivate::~ClientPrivate()
{
}
void ClientPrivate::init(const QUrl &connectionString)
void ClientPrivate::init()
{
Q_Q(Client);
initSocket();
@ -43,11 +43,6 @@ void ClientPrivate::init(const QUrl &connectionString)
authenticator = QSharedPointer<Authenticator>(
new AMQPlainAuthenticator(QString::fromLatin1(AMQP_LOGIN), QString::fromLatin1(AMQP_PSWD)));
if (connectionString.isValid()) {
parseConnectionString(connectionString);
_q_connect();
}
}
void ClientPrivate::initSocket()
@ -61,24 +56,54 @@ void ClientPrivate::initSocket()
q, SLOT(_q_socketError(QAbstractSocket::SocketError)));
}
void ClientPrivate::parseConnectionString(const QUrl &connectionString)
void ClientPrivate::setUsername(const QString &username)
{
Q_Q(Client);
Authenticator *auth = authenticator.data();
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
a->setLogin(username);
}
}
void ClientPrivate::setPassword(const QString &password)
{
Authenticator *auth = authenticator.data();
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
a->setPassword(password);
}
}
void ClientPrivate::parseConnectionString(const QString &uri)
{
#if QT_VERSION > 0x040801
QUrl connectionString = QUrl::fromUserInput(uri);
#else
QUrl connectionString(uri, QUrl::TolerantMode);
#endif
if (connectionString.scheme() != AMQP_SCHEME &&
connectionString.scheme() != AMQP_SSCHEME) {
qAmqpDebug() << Q_FUNC_INFO << "invalid scheme: " << connectionString.scheme();
return;
}
q->setPassword(connectionString.password());
q->setUsername(connectionString.userName());
q->setPort(connectionString.port(AMQP_PORT));
q->setHost(connectionString.host());
port = connectionString.port(AMQP_PORT);
host = connectionString.host();
QString vhost = connectionString.path();
if (vhost.startsWith("/"))
vhost = vhost.mid(1);
q->setVirtualHost(vhost);
#if QT_VERSION <= 0x050200
virtualHost = QUrl::fromPercentEncoding(vhost.toUtf8());
setPassword(QUrl::fromPercentEncoding(connectionString.password().toUtf8()));
setUsername(QUrl::fromPercentEncoding(connectionString.userName().toUtf8()));
#else
virtualHost = vhost;
setPassword(connectionString.password());
setUsername(connectionString.userName());
#endif
}
void ClientPrivate::_q_connect()
@ -506,14 +531,6 @@ Client::Client(QObject *parent)
d->init();
}
Client::Client(const QUrl &connectionString, QObject *parent)
: QObject(parent),
d_ptr(new ClientPrivate(this))
{
Q_D(Client);
d->init(connectionString);
}
Client::Client(ClientPrivate *dd, QObject *parent)
: QObject(parent),
d_ptr(dd)
@ -583,12 +600,8 @@ QString Client::username() const
void Client::setUsername(const QString &username)
{
Q_D(const Client);
Authenticator *auth = d->authenticator.data();
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
a->setLogin(username);
}
Q_D(Client);
d->setUsername(username);
}
QString Client::password() const
@ -606,11 +619,7 @@ QString Client::password() const
void Client::setPassword(const QString &password)
{
Q_D(Client);
Authenticator *auth = d->authenticator.data();
if (auth && auth->type() == QLatin1String("AMQPLAIN")) {
AMQPlainAuthenticator *a = static_cast<AMQPlainAuthenticator*>(auth);
a->setPassword(password);
}
d->setPassword(password);
}
Exchange *Client::createExchange(int channelNumber)
@ -753,15 +762,15 @@ QString Client::errorString() const
return d->errorString;
}
void Client::connectToHost(const QString &connectionString)
void Client::connectToHost(const QString &uri)
{
Q_D(Client);
if (connectionString.isEmpty()) {
if (uri.isEmpty()) {
d->_q_connect();
return;
}
d->parseConnectionString(QUrl::fromUserInput(connectionString));
d->parseConnectionString(uri);
d->_q_connect();
}
@ -829,13 +838,6 @@ SslClient::SslClient(QObject *parent)
{
}
SslClient::SslClient(const QUrl &connectionString, QObject *parent)
: Client(new SslClientPrivate(this), parent)
{
Q_D(SslClient);
d->init(connectionString);
}
SslClient::~SslClient()
{
}

View File

@ -33,8 +33,7 @@ class QAMQP_EXPORT Client : public QObject
Q_PROPERTY(qint16 heartbeatDelay READ heartbeatDelay() WRITE setHeartbeatDelay)
public:
Client(QObject *parent = 0);
Client(const QUrl &connectionString, QObject *parent = 0);
explicit Client(QObject *parent = 0);
~Client();
// properties
@ -84,7 +83,7 @@ public:
Queue *createQueue(const QString &name, int channelNumber = -1);
// methods
void connectToHost(const QString &connectionString = QString());
void connectToHost(const QString &uri = QString());
void connectToHost(const QHostAddress &address, quint16 port = AMQP_PORT);
void disconnectFromHost();

View File

@ -35,9 +35,11 @@ public:
ClientPrivate(Client *q);
virtual ~ClientPrivate();
virtual void init(const QUrl &connectionString = QUrl());
virtual void init();
virtual void initSocket();
void parseConnectionString(const QUrl &connectionString);
void setUsername(const QString &username);
void setPassword(const QString &password);
void parseConnectionString(const QString &uri);
void sendFrame(const Frame::Base &frame);
// private slots
@ -69,7 +71,7 @@ public:
void close(const Frame::Method &frame);
void closeOk();
quint32 port;
quint16 port;
QString host;
QString virtualHost;

View File

@ -3,6 +3,7 @@
#include <QProcess>
#include "amqp_client.h"
#include "amqp_client_p.h"
#include "amqp_authenticator.h"
using namespace QAMQP;
@ -15,6 +16,9 @@ private Q_SLOTS:
void invalidAuthenticationMechanism();
void tune();
void validateUri_data();
void validateUri();
private:
void autoReconnect();
@ -85,5 +89,58 @@ void tst_QAMQPClient::tune()
QVERIFY(waitForSignal(&client, SIGNAL(disconnected())));
}
void tst_QAMQPClient::validateUri_data()
{
QTest::addColumn<QString>("uri");
QTest::addColumn<QString>("expectedUsername");
QTest::addColumn<QString>("expectedPassword");
QTest::addColumn<QString>("expectedHost");
QTest::addColumn<quint16>("expectedPort");
QTest::addColumn<QString>("expectedVirtualHost");
QTest::newRow("standard") << "amqp://user:pass@host:10000/vhost"
<< "user" << "pass" << "host" << quint16(10000) << "vhost";
#if QT_VERSION >= 0x040806
QTest::newRow("urlencoded") << "amqp://user%61:%61pass@ho%61st:10000/v%2fhost"
<< "usera" << "apass" << "hoast" << quint16(10000) << "v/host";
#endif
QTest::newRow("empty") << "amqp://" << "" << "" << "" << quint16(AMQP_PORT) << "";
QTest::newRow("empty2") << "amqp://:@/" << "" << "" << "" << quint16(AMQP_PORT) << "";
QTest::newRow("onlyuser") << "amqp://user@" << "user" << "" << "" << quint16(AMQP_PORT) << "";
QTest::newRow("userpass") << "amqp://user:pass@" << "user" << "pass" << "" << quint16(AMQP_PORT) << "";
QTest::newRow("onlyhost") << "amqp://host" << "" << "" << "host" << quint16(AMQP_PORT) << "";
QTest::newRow("onlyport") << "amqp://:10000" << "" << "" << "" << quint16(10000) << "";
QTest::newRow("onlyvhost") << "amqp:///vhost" << "" << "" << "" << quint16(AMQP_PORT) << "vhost";
QTest::newRow("urlencodedvhost") << "amqp://host/%2f"
<< "" << "" << "host" << quint16(AMQP_PORT) << "/";
QTest::newRow("ipv6") << "amqp://[::1]" << "" << "" << "::1" << quint16(AMQP_PORT) << "";
}
void tst_QAMQPClient::validateUri()
{
QFETCH(QString, uri);
QFETCH(QString, expectedUsername);
QFETCH(QString, expectedPassword);
QFETCH(QString, expectedHost);
QFETCH(quint16, expectedPort);
QFETCH(QString, expectedVirtualHost);
ClientPrivate clientPrivate(0);
// fake init
clientPrivate.authenticator = QSharedPointer<Authenticator>(
new AMQPlainAuthenticator(QString::fromLatin1(AMQP_LOGIN), QString::fromLatin1(AMQP_PSWD)));
// test parsing
clientPrivate.parseConnectionString(uri);
AMQPlainAuthenticator *auth =
static_cast<AMQPlainAuthenticator*>(clientPrivate.authenticator.data());
QCOMPARE(auth->login(), expectedUsername);
QCOMPARE(auth->password(), expectedPassword);
QCOMPARE(clientPrivate.host, expectedHost);
QCOMPARE(clientPrivate.port, expectedPort);
QCOMPARE(clientPrivate.virtualHost, expectedVirtualHost);
}
QTEST_MAIN(tst_QAMQPClient)
#include "tst_qamqpclient.moc"