aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2019-01-09 14:30:01 +0100
committerSona Kurazyan <sona.kurazyan@qt.io>2019-01-30 15:28:38 +0000
commit14b68fb394b0d02f672c2c8340c32580d007d2ba (patch)
treee3e53dcde5071d8048f06e68adc5441dba244025 /tests
parent214e0eeece8f0155ce16499a2097577e2d92bdaa (diff)
Add DTLS support to CoAP implementationv5.13.0-alpha1
Added transport layer security based on QDtls. This implementation supports authentication using pre-shared keys and X.509 certificates. Split the QCoapConnection class into a base class to be shared with other transports and a specialized class that relies on QUdpSocket using QDtls for security. Note, that raw public key mode (which is mandatory to implement according to RFC) is not implemented yet, since the underlying OpenSSL library does not support it yet. However, if we later decide to integrate another DTLS implementation, it can be done with minimal changes, by having the new implementations's connection type inherit the QCoapConnection class, which hides the implementation of the transport layer. Tests and examples will be added in a later commit. Change-Id: I14b34a9fd978e1993e86d47becbeed74397d1d6e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/qcoapclient/tst_qcoapclient.cpp28
-rw-r--r--tests/auto/qcoapqudpconnection/qcoapqudpconnection.pro (renamed from tests/auto/qcoapconnection/qcoapconnection.pro)3
-rw-r--r--tests/auto/qcoapqudpconnection/tst_qcoapqudpconnection.cpp (renamed from tests/auto/qcoapconnection/tst_qcoapconnection.cpp)47
-rw-r--r--tests/auto/qcoaprequest/tst_qcoaprequest.cpp52
5 files changed, 88 insertions, 44 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index a6f3a48..82c8af8 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -4,7 +4,7 @@ SUBDIRS += \
cmake \
# TODO: enable the tests below, when CI is configured properly
# qcoapclient \
-# qcoapconnection \
+# qcoapqudpconnection \
qcoapinternalreply \
qcoapinternalrequest \
qcoapmessage \
diff --git a/tests/auto/qcoapclient/tst_qcoapclient.cpp b/tests/auto/qcoapclient/tst_qcoapclient.cpp
index 7edbd52..8c4ae97 100644
--- a/tests/auto/qcoapclient/tst_qcoapclient.cpp
+++ b/tests/auto/qcoapclient/tst_qcoapclient.cpp
@@ -38,7 +38,7 @@
#include <QtCore/qbuffer.h>
#include <QtNetwork/qnetworkdatagram.h>
#include <private/qcoapclient_p.h>
-#include <private/qcoapconnection_p.h>
+#include <private/qcoapqudpconnection_p.h>
#include "../coapnetworksettings.h"
@@ -74,7 +74,7 @@ private Q_SLOTS:
void observe();
};
-class QCoapConnectionSocketTestsPrivate : public QCoapConnectionPrivate
+class QCoapQUdpConnectionSocketTestsPrivate : public QCoapQUdpConnectionPrivate
{
bool bind() override
{
@@ -85,30 +85,30 @@ class QCoapConnectionSocketTestsPrivate : public QCoapConnectionPrivate
}
};
-class QCoapConnectionSocketTests : public QCoapConnection
+class QCoapQUdpConnectionSocketTests : public QCoapQUdpConnection
{
public:
- QCoapConnectionSocketTests() :
- QCoapConnection(*new QCoapConnectionSocketTestsPrivate)
+ QCoapQUdpConnectionSocketTests() :
+ QCoapQUdpConnection(*new QCoapQUdpConnectionSocketTestsPrivate)
{
createSocket();
}
private:
- Q_DECLARE_PRIVATE(QCoapConnectionSocketTests)
+ Q_DECLARE_PRIVATE(QCoapQUdpConnectionSocketTests)
};
class QCoapClientForSocketErrorTests : public QCoapClient
{
public:
QCoapClientForSocketErrorTests() :
- QCoapClient(new QCoapProtocol, new QCoapConnectionSocketTests)
+ QCoapClient(new QCoapProtocol, new QCoapQUdpConnectionSocketTests)
{}
- QCoapConnection *connection()
+ QCoapQUdpConnection *connection()
{
QCoapClientPrivate *privateClient = static_cast<QCoapClientPrivate *>(d_func());
- return privateClient->connection;
+ return qobject_cast<QCoapQUdpConnection*>(privateClient->connection);
}
};
@@ -116,7 +116,7 @@ class QCoapClientForTests : public QCoapClient
{
public:
QCoapClientForTests() {}
- QCoapClientForTests(QCoapProtocol *protocol, QCoapConnection *connection) :
+ QCoapClientForTests(QCoapProtocol *protocol, QCoapQUdpConnection *connection) :
QCoapClient(protocol, connection)
{}
@@ -125,10 +125,10 @@ public:
QCoapClientPrivate *privateClient = static_cast<QCoapClientPrivate *>(d_func());
return privateClient->protocol;
}
- QCoapConnection *connection()
+ QCoapQUdpConnection *connection()
{
QCoapClientPrivate *privateClient = static_cast<QCoapClientPrivate *>(d_func());
- return privateClient->connection;
+ return qobject_cast<QCoapQUdpConnection*>(privateClient->connection);
}
};
@@ -409,7 +409,9 @@ void tst_QCoapClient::socketError()
QCoapClientForSocketErrorTests client;
QUrl url = QUrl(testServerResource());
- QUdpSocket *socket = client.connection()->socket();
+ const auto connection = client.connection();
+ QVERIFY2(connection, "Failed to get coap connection!");
+ QUdpSocket *socket = connection->socket();
QVERIFY2(socket, "Socket not properly created with connection");
QSignalSpy spySocketError(socket, SIGNAL(error(QAbstractSocket::SocketError)));
QScopedPointer<QCoapReply> reply(client.get(url));
diff --git a/tests/auto/qcoapconnection/qcoapconnection.pro b/tests/auto/qcoapqudpconnection/qcoapqudpconnection.pro
index 6c89a38..c10d6e6 100644
--- a/tests/auto/qcoapconnection/qcoapconnection.pro
+++ b/tests/auto/qcoapqudpconnection/qcoapqudpconnection.pro
@@ -5,4 +5,5 @@ include(../coaptestserver.pri)
HEADERS += ../coapnetworksettings.h
-SOURCES += tst_qcoapconnection.cpp
+SOURCES += \
+ tst_qcoapqudpconnection.cpp
diff --git a/tests/auto/qcoapconnection/tst_qcoapconnection.cpp b/tests/auto/qcoapqudpconnection/tst_qcoapqudpconnection.cpp
index 87d1d9f..e94ed6b 100644
--- a/tests/auto/qcoapconnection/tst_qcoapconnection.cpp
+++ b/tests/auto/qcoapqudpconnection/tst_qcoapqudpconnection.cpp
@@ -37,15 +37,15 @@
#include <QtNetwork/qudpsocket.h>
#include <QtNetwork/qnetworkdatagram.h>
#include <QtCoap/qcoapglobal.h>
-#include <QtCoap/qcoapconnection.h>
+#include <QtCoap/qcoapqudpconnection.h>
#include <QtCoap/qcoaprequest.h>
-#include <private/qcoapconnection_p.h>
+#include <private/qcoapqudpconnection_p.h>
#include <private/qcoapinternalrequest_p.h>
#include "../coapnetworksettings.h"
using namespace QtCoapNetworkSettings;
-class tst_QCoapConnection : public QObject
+class tst_QCoapQUdpConnection : public QObject
{
Q_OBJECT
@@ -56,45 +56,46 @@ private Q_SLOTS:
void sendRequest();
};
-class QCoapConnectionForTest : public QCoapConnection
+class QCoapQUdpConnectionForTest : public QCoapQUdpConnection
{
Q_OBJECT
public:
- QCoapConnectionForTest(QObject *parent = nullptr) :
- QCoapConnection(parent)
+ QCoapQUdpConnectionForTest(QObject *parent = nullptr) :
+ QCoapQUdpConnection(QtCoap::NoSec, parent)
{}
void bindSocketForTest() { d_func()->bindSocket(); }
};
-void tst_QCoapConnection::ctor()
+void tst_QCoapQUdpConnection::ctor()
{
- QCoapConnection connection;
+ QCoapQUdpConnection connection;
QVERIFY(connection.socket());
}
-void tst_QCoapConnection::connectToHost()
+void tst_QCoapQUdpConnection::connectToHost()
{
#ifdef QT_BUILD_INTERNAL
- QCoapConnectionForTest connection;
+ QCoapQUdpConnectionForTest connection;
QUdpSocket *socket = qobject_cast<QUdpSocket*>(connection.socket());
QSignalSpy spyConnectionBound(&connection, SIGNAL(bound()));
QSignalSpy spySocketStateChanged(socket , SIGNAL(stateChanged(QAbstractSocket::SocketState)));
- QCOMPARE(connection.state(), QCoapConnection::Unconnected);
+ QCOMPARE(connection.state(), QCoapQUdpConnection::Unconnected);
- connection.bindSocketForTest();
+ // This will trigger connection.bind()
+ connection.sendRequest(QByteArray(), QString(), 0);
QTRY_COMPARE(spySocketStateChanged.count(), 1);
QTRY_COMPARE(spyConnectionBound.count(), 1);
- QCOMPARE(connection.state(), QCoapConnection::Bound);
+ QCOMPARE(connection.state(), QCoapQUdpConnection::Bound);
#else
QSKIP("Not an internal build, skipping this test");
#endif
}
-void tst_QCoapConnection::sendRequest_data()
+void tst_QCoapQUdpConnection::sendRequest_data()
{
QTest::addColumn<QString>("protocol");
QTest::addColumn<QString>("host");
@@ -143,7 +144,7 @@ void tst_QCoapConnection::sendRequest_data()
<< "61626364";
}
-void tst_QCoapConnection::sendRequest()
+void tst_QCoapQUdpConnection::sendRequest()
{
#ifdef QT_BUILD_INTERNAL
QFETCH(QString, protocol);
@@ -154,10 +155,10 @@ void tst_QCoapConnection::sendRequest()
QFETCH(QString, dataHexaHeader);
QFETCH(QString, dataHexaPayload);
- QCoapConnectionForTest connection;
+ QCoapQUdpConnectionForTest connection;
QSignalSpy spySocketReadyRead(connection.socket(), &QUdpSocket::readyRead);
- QSignalSpy spyConnectionReadyRead(&connection, &QCoapConnection::readyRead);
+ QSignalSpy spyConnectionReadyRead(&connection, &QCoapQUdpConnection::readyRead);
QCoapRequest request(protocol + host + path);
request.setMessageId(24806);
@@ -170,16 +171,14 @@ void tst_QCoapConnection::sendRequest()
QTRY_COMPARE(spySocketReadyRead.count(), 1);
QTRY_COMPARE(spyConnectionReadyRead.count(), 1);
- QNetworkDatagram datagram = spyConnectionReadyRead.first()
- .first().value<QNetworkDatagram>();
-
- QVERIFY(QString(datagram.data().toHex()).startsWith(dataHexaHeader));
- QVERIFY(QString(datagram.data().toHex()).endsWith(dataHexaPayload));
+ QByteArray data = spyConnectionReadyRead.first().first().value<QByteArray>();
+ QVERIFY(QString(data.toHex()).startsWith(dataHexaHeader));
+ QVERIFY(QString(data.toHex()).endsWith(dataHexaPayload));
#else
QSKIP("Not an internal build, skipping this test");
#endif
}
-QTEST_MAIN(tst_QCoapConnection)
+QTEST_MAIN(tst_QCoapQUdpConnection)
-#include "tst_qcoapconnection.moc"
+#include "tst_qcoapqudpconnection.moc"
diff --git a/tests/auto/qcoaprequest/tst_qcoaprequest.cpp b/tests/auto/qcoaprequest/tst_qcoaprequest.cpp
index 98329fe..1a5c413 100644
--- a/tests/auto/qcoaprequest/tst_qcoaprequest.cpp
+++ b/tests/auto/qcoaprequest/tst_qcoaprequest.cpp
@@ -34,7 +34,6 @@
#include <QtCoap/qcoapglobal.h>
#include <QtCoap/qcoapnamespace.h>
#include <QtCoap/qcoaprequest.h>
-#include <QtCoap/qcoapconnection.h>
class tst_QCoapRequest : public QObject
{
@@ -43,6 +42,8 @@ class tst_QCoapRequest : public QObject
private Q_SLOTS:
void ctor_data();
void ctor();
+ void adjustUrl_data();
+ void adjustUrl();
void setUrl_data();
void setUrl();
void setMethod_data();
@@ -67,16 +68,57 @@ void tst_QCoapRequest::ctor()
QCOMPARE(request.url(), url);
}
+void tst_QCoapRequest::adjustUrl_data()
+{
+ QTest::addColumn<QUrl>("inputUrl");
+ QTest::addColumn<QUrl>("expectedUrl");
+ QTest::addColumn<bool>("secure");
+
+ QTest::newRow("empty") << QUrl() << QUrl() << false;
+ QTest::newRow("empty_secure") << QUrl() << QUrl() << true;
+ QTest::newRow("scheme_and_port_known") << QUrl("coap://10.11.12.13:1234/test")
+ << QUrl("coap://10.11.12.13:1234/test") << false;
+ QTest::newRow("scheme_and_port_known_secure") << QUrl("coaps://10.11.12.13:1234/test")
+ << QUrl("coaps://10.11.12.13:1234/test") << true;
+ QTest::newRow("no_port") << QUrl("coap://vs0.inf.ethz.ch/test")
+ << QUrl("coap://vs0.inf.ethz.ch:5683/test") << false;
+ QTest::newRow("no_port_secure") << QUrl("coaps://vs0.inf.ethz.ch/test")
+ << QUrl("coaps://vs0.inf.ethz.ch:5684/test") << true;
+ QTest::newRow("no_scheme_no_port") << QUrl("vs0.inf.ethz.ch/test")
+ << QUrl("coap://vs0.inf.ethz.ch:5683/test") << false;
+ QTest::newRow("no_scheme_no_port_secure") << QUrl("vs0.inf.ethz.ch/test")
+ << QUrl("coaps://vs0.inf.ethz.ch:5684/test") << true;
+}
+
+void tst_QCoapRequest::adjustUrl()
+{
+ QFETCH(QUrl, inputUrl);
+ QFETCH(QUrl, expectedUrl);
+ QFETCH(bool, secure);
+
+ QCoapRequest request(inputUrl);
+ request.adjustUrl(secure);
+ QCOMPARE(request.url(), expectedUrl);
+}
+
void tst_QCoapRequest::setUrl_data()
{
QTest::addColumn<QUrl>("inputUrl");
QTest::addColumn<QUrl>("expectedUrl");
QTest::newRow("empty") << QUrl() << QUrl();
- QTest::newRow("coap") << QUrl("coap://10.11.12.13:5683/test") << QUrl("coap://10.11.12.13:5683/test");
- QTest::newRow("other_port") << QUrl("coap://10.11.12.13:8888/test") << QUrl("coap://10.11.12.13:8888/test");
- QTest::newRow("no_port") << QUrl("coap://vs0.inf.ethz.ch/test") << QUrl("coap://vs0.inf.ethz.ch:5683/test");
- QTest::newRow("no_scheme_no_port") << QUrl("vs0.inf.ethz.ch/test") << QUrl("coap://vs0.inf.ethz.ch:5683/test");
+ QTest::newRow("coap") << QUrl("coap://10.11.12.13:5683/test")
+ << QUrl("coap://10.11.12.13:5683/test");
+ QTest::newRow("coaps") << QUrl("coaps://10.11.12.13:5683/test")
+ << QUrl("coaps://10.11.12.13:5683/test");
+ QTest::newRow("other_port") << QUrl("coap://10.11.12.13:8888/test")
+ << QUrl("coap://10.11.12.13:8888/test");
+ QTest::newRow("no_port") << QUrl("coap://vs0.inf.ethz.ch/test")
+ << QUrl("coap://vs0.inf.ethz.ch:5683/test");
+ QTest::newRow("no_port_scure") << QUrl("coaps://vs0.inf.ethz.ch/test")
+ << QUrl("coaps://vs0.inf.ethz.ch:5684/test");
+ QTest::newRow("no_scheme_no_port") << QUrl("vs0.inf.ethz.ch/test")
+ << QUrl("vs0.inf.ethz.ch/test");
QTest::newRow("incorrect_scheme") << QUrl("http://vs0.inf.ethz.ch:5683/test") << QUrl();
QTest::newRow("invalid") << QUrl("-coap://vs0.inf.ethz.ch:5683/test") << QUrl();
}