mirror of
https://github.com/qt/qtmqtt.git
synced 2026-10-25 16:16:26 +00:00
Add tests for websocket support for mqtt
For at least one platform run the twelve combinations of: Transport: [Tcp,Ssl,Ws,Wss] Protocol: [3.1, 3.1.1, 5.0] This happens if the following defines are present: MQTT_TEST_BROKER MQTT_TEST_TYPE MQTT_TEST_PROTOCOL If these are not defined, the old test behavior is kept The logic is that we are replacing the type of VersionClient to homegrown logic that replaces connectToHost with the correct function: connectToHost connectToHostEncrypted, connectToHostWebSocket connectToHostWebSocketEncrypted For this to work it is important that the VersionClient macro is used everywhere. Also, DefaultVersionTestData has been changed to return version(0) if MQTT_TEST_PROTOCOL is defined, we will now run one protocol at the time instead. This is Change Request 2 of 2 wrt testing. Task-number: QTBUG-129171 Change-Id: I4f68d7c2ea226a1107f009c80f87f8b749d9f120 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
This commit is contained in:
parent
967c70f1d5
commit
8316766cec
@ -1,6 +1,109 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# Copyright (C) 2025 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# This function adds the test 12 times if run on a computer where the
|
||||
# mosquitto broker has been provisioned by running the corresponding
|
||||
# script located qt6/coin/provisioning/*/*mosquitto*
|
||||
#
|
||||
# The script adds the file /etc/mosquitto/conf.d/mqtt.conf on unix-like
|
||||
# systems, and the file C:\\Program Files\\mosquitto\\conf.d\\mqtt.conf
|
||||
# on windows like systems. So this is what we test for.
|
||||
#
|
||||
# If we are on a provisioned system as detected by the two files above
|
||||
# we define these variables which the test use
|
||||
# MQTT_TEST_TYPE= selection from; 3, 4, 5
|
||||
# 3 -> Vers 3.1
|
||||
# 4 -> Vers 3.1.1
|
||||
# 5 -> Vers 5.0
|
||||
# MQTT_TEST_PROTOCOL= selection from; Tcp,Ssl,Ws,Wss
|
||||
# MQTT_TEST_BROKER="localhost"
|
||||
#
|
||||
# If neither of these files are present, we use the existing
|
||||
# design which is to run for tcp,3.1.1 by default.
|
||||
# In this case set the environment variable MQTT_TEST_BROKER
|
||||
# to localhost
|
||||
#
|
||||
# Finally, we allow the test to override for individual test
|
||||
# cases, if wanted. This is mostly used for MQTT_TEST_TYPE
|
||||
#
|
||||
function(qtmqtt_add_test)
|
||||
|
||||
set(options)
|
||||
set(oneValueArgs TARGET)
|
||||
set(multiValueArgs SOURCES DEFINES INCLUDE_DIRECTORIES LIBRARIES)
|
||||
|
||||
cmake_parse_arguments(
|
||||
arg_mqtt
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
set(TYPES)
|
||||
set(PROTOCOLS)
|
||||
|
||||
if((EXISTS "/etc/mosquitto/conf.d/mqtt.conf") OR
|
||||
(EXISTS "C:\\Program Files\\mosquitto\\conf.d\\mqtt.conf"))
|
||||
if(WASM)
|
||||
if(TARGET Qt::WebSockets)
|
||||
set(TYPES Ws Wss)
|
||||
set(PROTOCOLS 3 4 5)
|
||||
endif()
|
||||
elseif(QT_FEATURE_ssl)
|
||||
if(TARGET Qt::WebSockets)
|
||||
set(TYPES Tcp Ssl Ws Wss)
|
||||
else()
|
||||
set(TYPES Tcp Ssl)
|
||||
endif()
|
||||
set(PROTOCOLS 3 4 5)
|
||||
else()
|
||||
if(TARGET Qt::WebSockets)
|
||||
set(TYPES Tcp Ws)
|
||||
else()
|
||||
set(TYPES Tcp)
|
||||
endif()
|
||||
set(PROTOCOLS 3 4 5)
|
||||
endif()
|
||||
elseif(NOT WASM)
|
||||
set(TYPES Tcp)
|
||||
set(PROTOCOLS 4)
|
||||
endif()
|
||||
|
||||
foreach(TYPE ${TYPES})
|
||||
foreach(PROTOCOL ${PROTOCOLS})
|
||||
set(EXTRA_DEFINES)
|
||||
set(EXTRA_LIBS)
|
||||
if(EXISTS "/etc/mosquitto/conf.d/mqtt.conf" OR
|
||||
EXISTS "C:\\Program Files\\mosquitto\\conf.d\\mqtt.conf")
|
||||
set(EXTRA_DEFINES MQTT_TEST_TYPE="${TYPE}" MQTT_TEST_PROTOCOL=${PROTOCOL} MQTT_TEST_BROKER="localhost")
|
||||
endif()
|
||||
|
||||
if(TARGET Qt::WebSockets)
|
||||
set(EXTRA_DEFINES ${EXTRA_DEFINES} QT_MQTT_WITH_WEBSOCKETS)
|
||||
set(EXTRA_LIBS Qt::WebSockets)
|
||||
endif()
|
||||
|
||||
qt_internal_add_test(
|
||||
${arg_mqtt_TARGET}_${TYPE}_${PROTOCOL}
|
||||
SOURCES
|
||||
${arg_mqtt_SOURCES}
|
||||
DEFINES
|
||||
${arg_mqtt_DEFINES} ${EXTRA_DEFINES}
|
||||
INCLUDE_DIRECTORIES
|
||||
${arg_mqtt_INCLUDE_DIRECTORIES}
|
||||
LIBRARIES
|
||||
${arg_mqtt_LIBRARIES} ${EXTRA_LIBS}
|
||||
TESTDATA
|
||||
"../../certificate/cert.crt"
|
||||
"../../certificate/cert.key"
|
||||
BUILTIN_TESTDATA
|
||||
)
|
||||
|
||||
endforeach()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
if(QT_BUILD_STANDALONE_TESTS)
|
||||
# Add qt_find_package calls for extra dependencies that need to be found when building
|
||||
# the standalone tests here.
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_conformance Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_conformance
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_conformance
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_conformance.cpp
|
||||
|
||||
@ -42,7 +42,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
Tst_MqttConformance::Tst_MqttConformance()
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttclient Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttclient
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttclient
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_qmqttclient.cpp
|
||||
|
||||
@ -51,10 +51,11 @@ private Q_SLOTS:
|
||||
void subscriptionIdsOverlap();
|
||||
void keepAlive_data();
|
||||
void keepAlive();
|
||||
void reconnect();
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
Tst_QMqttClient::Tst_QMqttClient()
|
||||
@ -185,7 +186,7 @@ void Tst_QMqttClient::sendReceive()
|
||||
QSKIP("The MQTT 5 test broker does not support huge packages.", SkipOnce);
|
||||
publisher.publish(testTopic, data, 1);
|
||||
|
||||
QTRY_VERIFY2(received, "Subscriber did not receive message");
|
||||
QTRY_VERIFY2_WITH_TIMEOUT(received, "Subscriber did not receive message", std::chrono::seconds(180));
|
||||
QVERIFY2(verified, "Subscriber received different message");
|
||||
}
|
||||
|
||||
@ -270,6 +271,9 @@ void Tst_QMqttClient::willMessage()
|
||||
client1.connectToHost();
|
||||
QTRY_COMPARE(client1.state(), QMqttClient::Connected);
|
||||
|
||||
if (!client1.isTcp())
|
||||
QSKIP("This test is only for tcp");
|
||||
|
||||
auto client1Sub = client1.subscribe(willTopic, 1);
|
||||
connect(client1Sub, &QMqttSubscription::messageReceived, [=](QMqttMessage message) {
|
||||
Q_UNUSED(message);
|
||||
@ -282,7 +286,7 @@ void Tst_QMqttClient::willMessage()
|
||||
|
||||
// Client B connects (via TcpSocket)
|
||||
QTcpSocket sock;
|
||||
sock.connectToHost(m_testBroker, m_port);
|
||||
sock.connectToHost(client1.hostname(), client1.port());
|
||||
QVERIFY(sock.waitForConnected());
|
||||
|
||||
for (int i = 1; i > 0; --i) {
|
||||
@ -507,6 +511,9 @@ void Tst_QMqttClient::reconnect_QTBUG65726()
|
||||
client.setHostname(QLatin1String("localhost"));
|
||||
client.setPort(5726);
|
||||
|
||||
if (!client.isTcp())
|
||||
QSKIP("This test is only for tcp");
|
||||
|
||||
server.version = client.protocolVersion();
|
||||
|
||||
client.connectToHost();
|
||||
@ -569,6 +576,9 @@ void Tst_QMqttClient::staticProperties_QTBUG_67176()
|
||||
client.setHostname(m_testBroker);
|
||||
client.setPort(m_port);
|
||||
|
||||
auto clientVersion = client.protocolVersion();
|
||||
const QString hostname = client.hostname();
|
||||
const int port = client.port();
|
||||
const QString clientId = client.clientId();
|
||||
const quint16 keepAlive = client.keepAlive();
|
||||
const bool clean = client.cleanSession();
|
||||
@ -580,16 +590,16 @@ void Tst_QMqttClient::staticProperties_QTBUG_67176()
|
||||
QCOMPARE(client.clientId(), clientId);
|
||||
|
||||
client.setHostname(QLatin1String("some.domain.foo"));
|
||||
QCOMPARE(client.hostname(), m_testBroker);
|
||||
QCOMPARE(client.hostname(), hostname);
|
||||
|
||||
client.setPort(1234);
|
||||
QCOMPARE(client.port(), m_port);
|
||||
QCOMPARE(client.port(), port);
|
||||
|
||||
client.setKeepAlive(keepAlive + 10);
|
||||
QCOMPARE(client.keepAlive(), keepAlive);
|
||||
|
||||
client.setProtocolVersion(QMqttClient::MQTT_3_1);
|
||||
QCOMPARE(client.protocolVersion(), mqttVersion);
|
||||
QCOMPARE(client.protocolVersion(), clientVersion);
|
||||
|
||||
client.setUsername(QLatin1String("someUser"));
|
||||
QCOMPARE(client.username(), QLatin1String());
|
||||
@ -651,6 +661,7 @@ void Tst_QMqttClient::messageStatus()
|
||||
client.setPort(m_port);
|
||||
|
||||
client.connectToHost();
|
||||
|
||||
QTRY_VERIFY2(client.state() == QMqttClient::Connected, "Could not connect to broker.");
|
||||
|
||||
const QString topic = QLatin1String("Qt/client/statusCheck");
|
||||
@ -881,6 +892,76 @@ void Tst_QMqttClient::keepAlive()
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Disconnected);
|
||||
}
|
||||
|
||||
void Tst_QMqttClient::reconnect()
|
||||
{
|
||||
VersionClient(QMqttClient::ProtocolVersion(0), client);
|
||||
client.setHostname(m_testBroker);
|
||||
client.setPort(m_port);
|
||||
client.connectToHost();
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Connected);
|
||||
|
||||
client.disconnectFromHost();
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Disconnected);
|
||||
|
||||
/* The rest requires a mosquitto installation that runs
|
||||
on multiple ports.
|
||||
*/
|
||||
#if defined(MQTT_TEST_BROKER)
|
||||
client.setPort(client.port() + 1000);
|
||||
client.connectToHost();
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Connected);
|
||||
|
||||
client.disconnectFromHost();
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Disconnected);
|
||||
|
||||
QMqttClient client2;
|
||||
client2.setHostname(client.hostname());
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
#if defined(QT_MQTT_WITH_WEBSOCKETS)
|
||||
client2.setPort(9080);
|
||||
client2.connectToHostWebSocket();
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Connected);
|
||||
|
||||
client2.disconnectFromHost();
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Disconnected);
|
||||
#endif
|
||||
|
||||
#if defined(QT_MQTT_WITH_WEBSOCKETS) && !defined(QT_NO_SSL)
|
||||
client2.setPort(9081);
|
||||
QUrl url(QString(u"wss://") + client2.hostname() + QString(u":") + QString::number(client2.port()));
|
||||
QWebSocketHandshakeOptions options;
|
||||
options.setSubprotocols(QStringList{ QString::fromUtf8("mqttv3.1") });
|
||||
QWebSocket socket;
|
||||
socket.setSslConfiguration(makeConfig(QString::fromUtf8(getenv("MQTT_TEST_BROKER_CERTIFICATE"))));
|
||||
socket.open(url, options);
|
||||
|
||||
client2.connectToHostWebSocketEncrypted(&socket);
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Connected);
|
||||
|
||||
client2.disconnectFromHost();
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Disconnected);
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_SSL)
|
||||
client2.setPort(9883);
|
||||
client2.connectToHostEncrypted(makeConfig(QString::fromUtf8(getenv("MQTT_TEST_BROKER_CERTIFICATE"))));
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Connected);
|
||||
|
||||
client2.disconnectFromHost();
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Disconnected);
|
||||
#endif
|
||||
|
||||
client2.setPort(2883);
|
||||
client2.connectToHost();
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Connected);
|
||||
|
||||
client2.disconnectFromHost();
|
||||
QTRY_COMPARE(client2.state(), QMqttClient::Disconnected);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(Tst_QMqttClient)
|
||||
|
||||
#include "tst_qmqttclient.moc"
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttconnectionproperties Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttconnectionproperties
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttconnectionproperties
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_qmqttconnectionproperties.cpp
|
||||
|
||||
@ -31,7 +31,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
tst_QMqttConnectionProperties::tst_QMqttConnectionProperties()
|
||||
@ -239,7 +239,7 @@ void tst_QMqttConnectionProperties::maximumTopicAlias()
|
||||
client.publish(topic, msgContent, 1);
|
||||
QTRY_VERIFY(publishSpy.size() == 1);
|
||||
|
||||
QVERIFY(transportSpy.size() == 1);
|
||||
QTRY_VERIFY(transportSpy.size() == 1);
|
||||
const int dataSize = transportSpy.at(0).at(0).toInt();
|
||||
if (publishTransportSize == 0) {
|
||||
publishTransportSize = dataSize;
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttcontrolpacket Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttcontrolpacket
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttcontrolpacket
|
||||
SOURCES
|
||||
tst_qmqttcontrolpacket.cpp
|
||||
DEFINES
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttlastwillproperties Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttlastwillproperties
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttlastwillproperties
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_qmqttlastwillproperties.cpp
|
||||
|
||||
@ -27,7 +27,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
tst_QMqttLastWillProperties::tst_QMqttLastWillProperties()
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttpublishproperties Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttpublishproperties
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttpublishproperties
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_qmqttpublishproperties.cpp
|
||||
|
||||
@ -26,7 +26,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
tst_QMqttPublishProperties::tst_QMqttPublishProperties()
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttsubscription Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttsubscription
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttsubscription
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_qmqttsubscription.cpp
|
||||
|
||||
@ -36,7 +36,7 @@ private:
|
||||
void createAndSubscribe(Client *c, QMqttSubscription **sub, const QString &topic);
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
Tst_QMqttSubscription::Tst_QMqttSubscription()
|
||||
@ -149,6 +149,9 @@ void Tst_QMqttSubscription::reconnect()
|
||||
client.connectToHost();
|
||||
QTRY_VERIFY2(client.state() == QMqttClient::Connected, "Could not connect to broker.");
|
||||
|
||||
if (!client.isTcp() && !client.isSsl())
|
||||
QSKIP("This test only runs for tcp and ssl");
|
||||
|
||||
// - Subscribe to topic A
|
||||
const QString subscription("Qt/subscription/topics/resub");
|
||||
auto sub = client.subscribe(subscription, 1);
|
||||
@ -384,6 +387,8 @@ void Tst_QMqttSubscription::noLocal()
|
||||
client.setPort(m_port);
|
||||
client.connectToHost();
|
||||
|
||||
const auto clientVersion = client.protocolVersion();
|
||||
|
||||
QTRY_VERIFY2(client.state() == QMqttClient::Connected, "Could not connect to broker.");
|
||||
|
||||
QMqttSubscriptionProperties subProps;
|
||||
@ -400,7 +405,7 @@ void Tst_QMqttSubscription::noLocal()
|
||||
client.publish(topic, "content", 1);
|
||||
QTRY_VERIFY(publishSpy.size() == 1);
|
||||
|
||||
if (version == QMqttClient::MQTT_3_1_1 || !non) { // 3.1.1 does not know NoLocal and sends to subscription
|
||||
if (clientVersion == QMqttClient::MQTT_3_1_1 || !non) { // 3.1.1 does not know NoLocal and sends to subscription
|
||||
QTRY_VERIFY(receivalSpy.size() == 1);
|
||||
} else {
|
||||
QTest::qWait(3000);
|
||||
@ -483,8 +488,8 @@ void Tst_QMqttSubscription::qtbug_104478()
|
||||
client.publish(topic, "Wildcard checks", 1);
|
||||
QTRY_VERIFY2(pubSpy.size() == 1, "Could not publish message.");
|
||||
|
||||
QTRY_VERIFY2(singleSpy.count() == 1, "Did not receive message");
|
||||
QTRY_VERIFY2(mixedSpy.count() == 1, "Did not receive message");
|
||||
QTRY_VERIFY2(singleSpy.count() >= 1, "Did not receive message");
|
||||
QTRY_VERIFY2(mixedSpy.count() >= 1, "Did not receive message");
|
||||
|
||||
client.disconnectFromHost();
|
||||
QTRY_VERIFY2(client.state() == QMqttClient::Disconnected, "Could not disconnect from broker.");
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqttsubscriptionproperties Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqttsubscriptionproperties
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqttsubscriptionproperties
|
||||
SOURCES
|
||||
../../common/broker_connection.h
|
||||
tst_qmqttsubscriptionproperties.cpp
|
||||
|
||||
@ -26,7 +26,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
tst_QMqttSubscriptionProperties::tst_QMqttSubscriptionProperties()
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqtttopicfilter Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqtttopicfilter
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqtttopicfilter
|
||||
SOURCES
|
||||
tst_qmqtttopicfilter.cpp
|
||||
DEFINES
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
## tst_qmqtttopicname Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmqtttopicname
|
||||
qtmqtt_add_test(
|
||||
TARGET
|
||||
tst_qmqtttopicname
|
||||
SOURCES
|
||||
tst_qmqtttopicname.cpp
|
||||
DEFINES
|
||||
|
||||
@ -25,7 +25,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
quint16 m_port{1883};
|
||||
quint16 m_port{0};
|
||||
};
|
||||
|
||||
Tst_QMqttClient::Tst_QMqttClient()
|
||||
@ -54,8 +54,8 @@ void Tst_QMqttClient::stressTest_data()
|
||||
void Tst_QMqttClient::stressTest()
|
||||
{
|
||||
QFETCH(int, qos);
|
||||
VersionClient(QMqttClient::MQTT_3_1_1, subscriber);
|
||||
VersionClient(QMqttClient::MQTT_3_1_1, publisher);
|
||||
VersionClient(0, subscriber);
|
||||
VersionClient(0, publisher);
|
||||
|
||||
subscriber.setHostname(m_testBroker);
|
||||
subscriber.setPort(m_port);
|
||||
@ -109,7 +109,7 @@ void Tst_QMqttClient::stressTest2()
|
||||
QSet<qint32> msgIds;
|
||||
msgIds.reserve(msgCount);
|
||||
|
||||
VersionClient(QMqttClient::MQTT_3_1_1, publisher);
|
||||
VersionClient(0, publisher);
|
||||
publisher.setHostname(m_testBroker);
|
||||
publisher.setPort(m_port);
|
||||
|
||||
|
||||
27
tests/certificate/cert.crt
Normal file
27
tests/certificate/cert.crt
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2025 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID6zCCAtOgAwIBAgIUbbY+pKEPOOytRZ3RujmmdriEAKcwDQYJKoZIhvcNAQEL
|
||||
BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
|
||||
MQswCQYDVQQKDAJRdDELMAkGA1UECwwCUXQxEjAQBgNVBAMMCWxvY2FsaG9zdDEo
|
||||
MCYGCSqGSIb3DQEJARYZZXZlbi5vc2Nhci5hbmRlcnNlbkBxdC5pbzAgFw0yNDEw
|
||||
MzExMTMyNDdaGA8yMTI0MTAwNzExMzI0N1owgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
|
||||
VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMQswCQYDVQQKDAJRdDELMAkGA1UECwwC
|
||||
UXQxEjAQBgNVBAMMCWxvY2FsaG9zdDEoMCYGCSqGSIb3DQEJARYZZXZlbi5vc2Nh
|
||||
ci5hbmRlcnNlbkBxdC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AJzWmpWU9f/baRi/Fhn362W488HzC2/MUdbTZGIQUqt1TwTLyYMEqkr6WMy/NdYL
|
||||
8X5oXW0uz8LttbFp98wJTkNirYBMxowxwWWePnqbK0iKaZTBvBzUh0vWvmtFzHUW
|
||||
E93K1NtKyL76Zj/EZv0I0CpkWMobpzEW/zquPj83Wxki0xp2rr/HHynqFv8KFMoJ
|
||||
pR1A6uWtly12V1aQyXZIyMoIUPgDPmsHtNZKBCcz7IsAYHjjfvEIJ+r4lOOsgTXj
|
||||
cdMU+0hHfyNCy1/6xmBwnchSqDZf3bTyFRu6GK+zzFKBSyt4MB7zQ2P29qYwoNJO
|
||||
buJkPRfqiQJJRLkwyu59TB0CAwEAAaNTMFEwHQYDVR0OBBYEFGGxHowwihBbJlM5
|
||||
2wzicQa2sCfwMB8GA1UdIwQYMBaAFGGxHowwihBbJlM52wzicQa2sCfwMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACf4lUaBpw65tOZk32EpMD0D
|
||||
M0ilx1AwfUqliKdhVvkFJ6jN5h17YhVjFoGtSzE7ry5Rg5J07tUK5Xkjcfk39UWV
|
||||
RofVnRhrtiticXs0eXQkDXqao0aMjUjsWiokr4/cTNT5R3h9jmjzyjA6pWf2oSjT
|
||||
GTzZAHdcuBTUfvPy/Ff4M5AVNsI6geUqrUd6XzFwQsDWTT86sdWQIC8j+FMghhss
|
||||
9XRNOmhWtWGSRbP0HqlWOz5hFRPP/faI/FGTknzkkVYoWaB1CR+ThFK9jYi0FnFL
|
||||
2fIcJPt+6g6d01Ws5cb9HpL9joUloCjsZ+w6PXYNVyHTaG3Lg5o4nT1Oizvrq1k=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
32
tests/certificate/cert.key
Normal file
32
tests/certificate/cert.key
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright (C) 2025 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCc1pqVlPX/22kY
|
||||
vxYZ9+tluPPB8wtvzFHW02RiEFKrdU8Ey8mDBKpK+ljMvzXWC/F+aF1tLs/C7bWx
|
||||
affMCU5DYq2ATMaMMcFlnj56mytIimmUwbwc1IdL1r5rRcx1FhPdytTbSsi++mY/
|
||||
xGb9CNAqZFjKG6cxFv86rj4/N1sZItMadq6/xx8p6hb/ChTKCaUdQOrlrZctdldW
|
||||
kMl2SMjKCFD4Az5rB7TWSgQnM+yLAGB4437xCCfq+JTjrIE143HTFPtIR38jQstf
|
||||
+sZgcJ3IUqg2X9208hUbuhivs8xSgUsreDAe80Nj9vamMKDSTm7iZD0X6okCSUS5
|
||||
MMrufUwdAgMBAAECggEAKs2u9q/my2M4NZbBE2lEB0kIzZ/lOSfMFhMvTEwkI8Mq
|
||||
Q6bSYj19tGTKo2Zz7OzphZQ6GzgxX4O8mKTRChBoGZ/uths9/Lj/jRo49wEuOOf9
|
||||
lKmjC0M9gYckBObRvArAdUGMAiVQ0D5KdZDGgrxLA6bLTK1rXcxm777qIhqbdCpN
|
||||
i9RwW9wp9rMV53J8mmWWUDVpfbIKHAmp50JknXj07onPEqN6IKdZY7sYACfYiz/8
|
||||
l31rKfR/P5j/aRBOFwBnq7Z3JGfOEQPmE8bxQ2Vt3ZXPK2ekreDx4j2Tz+gSZmF3
|
||||
Ee8DonQtA1DTOlhMyb6FhJrEFmDr38jGQqDK4qV8iQKBgQDLoOSYzX0xcyK2dPMD
|
||||
woPGcKymI+XYx0Q6cVZo1GttNarhBN0w0ms9a4SYoTMhAI9tzjJw/sU5t9kLan6n
|
||||
m11PqQVK+Vbh1v2YICJW89LcOFYwyO6IAiMN1LUdy8las4GwcXRwBWWnXAnE+YJK
|
||||
AiXcmB1ZX3j8pgStCF9VApC50wKBgQDFLP87pGtWW3nvkxoDpgVb1CwpO1T1EsFF
|
||||
Yzv7eIkFQGUkqF7OlslhMCOERE8pj4dr4CoTIvVsYW+lYfBnFPpQ0pQ+BZ2meZ0u
|
||||
GfWBDYpNGTGrxEDBc923glb2oegQQirHpiWtlinp5nciOn/rqpUwJR3b46drFlNy
|
||||
26CTKA+8TwKBgQDKv8qdMo2i/QblMRD+/2CB55KgYkHrVI1ku5DUFB1awgMAxf0P
|
||||
LZRFtZZy+p6UD6DALn0e8S2jSKE9sq2laRbByINSoW2WtKAQJn7KoT+kshtvu8F1
|
||||
fts0XERyBITaYL2S14SePWF4ADZiACVwVy8ns/YVFPC8bvlc6Gczl7hOrQKBgQCP
|
||||
BUmJSIT3GdlDlq7q8JS4fBkgO0IvldAM9aL/j/nLjl8PDPXf4e3mihVpDmdhXRO8
|
||||
gtfiE5xzZeWmz3iiPMworeYLauVkaJhDZV73ogusStcFoY/bAqFTR76unNgIWwZO
|
||||
1MxFskNqvtmxQT+igJRAXNvgsKuyeHpFONurggaP7wKBgCj25sAxVcOuOcANQGcO
|
||||
wCNvt1pHDJengrzaKooCJqm5YxNhrcKlJsdQcQ1Mu+KyhcMY/WF/0UaJZytlHMWf
|
||||
aDlF7zKqhQFqFY7nk/C7+fED7Kg3XJR54qtweVNzD6k4yTeSsvBeTd2aaepzZvJI
|
||||
IOQ3RPVQNsdgjn3VTGs/rmrR
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
@ -8,8 +8,16 @@
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#include <QtTest/QTest>
|
||||
|
||||
#ifdef QT_MQTT_WITH_WEBSOCKETS
|
||||
#include <QWebSocket>
|
||||
#include <QWebSocketHandshakeOptions>
|
||||
#endif
|
||||
|
||||
QString invokeOrInitializeBroker(QProcess *gBrokerProcess)
|
||||
{
|
||||
#if defined(MQTT_TEST_BROKER)
|
||||
return QString::fromLatin1(MQTT_TEST_BROKER);
|
||||
#endif
|
||||
const QString broker = qgetenv("MQTT_TEST_BROKER");
|
||||
if (broker.size()) {
|
||||
qDebug("Overwriting default test broker");
|
||||
@ -65,13 +73,256 @@ QString invokeOrInitializeBroker(QProcess *gBrokerProcess)
|
||||
return QString();
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_SSL)
|
||||
QSslConfiguration makeConfig(QString certificateFile)
|
||||
{
|
||||
if (certificateFile.isEmpty())
|
||||
certificateFile=QString(u":/certificate/cert.crt");
|
||||
|
||||
QSslConfiguration config;
|
||||
QFile file(certificateFile);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << " Could not open certificate file " << certificateFile;
|
||||
} else {
|
||||
const auto bytes = file.readAll();
|
||||
const QSslCertificate certificate(bytes);
|
||||
|
||||
config.addCaCertificate(certificate);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
#endif /* !QT_NO_SSL */
|
||||
|
||||
int getBrokerPort(int defaultPort)
|
||||
{
|
||||
if (getenv("MQTT_TEST_BROKER_PORT"))
|
||||
return atoi(getenv("MQTT_TEST_BROKER_PORT"));
|
||||
|
||||
#if defined (MQTT_TEST_PROTOCOL)
|
||||
return defaultPort;
|
||||
#else
|
||||
return defaultPort - 1000; /* evaluates to 1883 for the old system */
|
||||
#endif
|
||||
}
|
||||
|
||||
QMqttClient::ProtocolVersion getProtocolVersion(int version)
|
||||
{
|
||||
#if defined (MQTT_TEST_PROTOCOL)
|
||||
if (version == 0)
|
||||
version=MQTT_TEST_PROTOCOL;
|
||||
#else
|
||||
if ((version == 0) && getenv("MQTT_TEST_PROTOCOL_VERSION")) {
|
||||
switch (atoi(getenv("MQTT_TEST_PROTOCOL_VERSION"))) {
|
||||
case 3: version = QMqttClient::MQTT_3_1; break;
|
||||
case 4: version = QMqttClient::MQTT_3_1_1; break;
|
||||
case 5: version = QMqttClient::MQTT_5_0; break;
|
||||
}
|
||||
}
|
||||
if (version == 0)
|
||||
version = QMqttClient::MQTT_5_0;
|
||||
#endif
|
||||
return (QMqttClient::ProtocolVersion)version;
|
||||
}
|
||||
|
||||
class MqTTTestClientBase : public QMqttClient
|
||||
{
|
||||
public:
|
||||
virtual bool isTcp() const { return false; }
|
||||
virtual bool isSsl() const { return false; }
|
||||
virtual bool isWs() const { return false; }
|
||||
virtual bool isWss() const { return false; }
|
||||
public:
|
||||
virtual void setPort(quint16 port) = 0;
|
||||
virtual void connectToHost() = 0;
|
||||
|
||||
void setTransport(QIODevice *device, TransportType transport)
|
||||
{
|
||||
m_transportSet = true;
|
||||
QMqttClient::setTransport(device, transport);
|
||||
}
|
||||
void disconnectFromHost()
|
||||
{
|
||||
m_transportSet = false;
|
||||
QMqttClient::disconnectFromHost();
|
||||
}
|
||||
protected:
|
||||
bool m_transportSet = false;
|
||||
};
|
||||
|
||||
class MqTTClientTcp : public MqTTTestClientBase
|
||||
{
|
||||
public:
|
||||
MqTTClientTcp() = default;
|
||||
|
||||
virtual bool isTcp() const override { return true; }
|
||||
void setPort(quint16 port) override
|
||||
{
|
||||
if (port == 0)
|
||||
port = getBrokerPort(2883);
|
||||
QMqttClient::setPort(port);
|
||||
}
|
||||
void connectToHost() override
|
||||
{
|
||||
QMqttClient::connectToHost();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef QT_MQTT_WITH_WEBSOCKETS
|
||||
class MqTTClientWs : public MqTTTestClientBase
|
||||
{
|
||||
public:
|
||||
MqTTClientWs() = default;
|
||||
|
||||
virtual bool isWs() const override { return true; }
|
||||
|
||||
void setPort(quint16 port) override
|
||||
{
|
||||
if (port == 0)
|
||||
port = getBrokerPort(9080);
|
||||
QMqttClient::setPort(port);
|
||||
}
|
||||
|
||||
void connectToHost() override
|
||||
{
|
||||
if (m_transportSet)
|
||||
QMqttClient::connectToHost();
|
||||
else
|
||||
QMqttClient::connectToHostWebSocket();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef QT_MQTT_WITH_WEBSOCKETS
|
||||
class MqTTClientWss : public MqTTTestClientBase
|
||||
{
|
||||
public:
|
||||
MqTTClientWss()
|
||||
{
|
||||
#ifndef QT_NO_SSL
|
||||
const QString origin;
|
||||
const QWebSocketProtocol::Version version = QWebSocketProtocol::VersionLatest;
|
||||
socket = new QWebSocket(origin, version, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool isWss() const override { return true; }
|
||||
|
||||
void setPort(quint16 port) override
|
||||
{
|
||||
if (port == 0)
|
||||
port = getBrokerPort(9081);
|
||||
QMqttClient::setPort(port);
|
||||
}
|
||||
|
||||
void connectToHost() override
|
||||
{
|
||||
if (m_transportSet)
|
||||
QMqttClient::connectToHost();
|
||||
else {
|
||||
#ifndef QT_NO_SSL
|
||||
QUrl url(QString(u"wss://") + QMqttClient::hostname() + QString(u":") + QString::number(QMqttClient::port()));
|
||||
QWebSocketHandshakeOptions options;
|
||||
options.setSubprotocols(QStringList{ QString::fromUtf8("mqttv3.1") });
|
||||
socket->setSslConfiguration(makeConfig(QString::fromUtf8(getenv("MQTT_TEST_BROKER_CERTIFICATE"))));
|
||||
socket->open(url, options);
|
||||
#endif
|
||||
QMqttClient::connectToHostWebSocketEncrypted(socket);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QWebSocket *socket = nullptr;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
class MqTTClientSsl : public MqTTTestClientBase
|
||||
{
|
||||
public:
|
||||
MqTTClientSsl() = default;
|
||||
|
||||
virtual bool isSsl() const override { return true; }
|
||||
|
||||
void setPort(quint16 port) override
|
||||
{
|
||||
if (port == 0)
|
||||
port = getBrokerPort(9883);
|
||||
QMqttClient::setPort(port);
|
||||
}
|
||||
|
||||
void connectToHost() override
|
||||
{
|
||||
if (m_transportSet)
|
||||
QMqttClient::connectToHost();
|
||||
else {
|
||||
QMqttClient::connectToHostEncrypted(makeConfig(QString::fromUtf8(getenv("MQTT_TEST_BROKER_CERTIFICATE"))));
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif /* !QT_NO_SSL */
|
||||
|
||||
Q_DECLARE_METATYPE(QMqttClient::ProtocolVersion)
|
||||
#define VersionClient(MQTTVERSION, CLIENTNAME) QMqttClient CLIENTNAME; CLIENTNAME.setProtocolVersion(MQTTVERSION)
|
||||
|
||||
#if !defined(QT_NO_SSL) && defined(QT_MQTT_WITH_WEBSOCKETS)
|
||||
#define VersionClientBase(MQTTVERSION, CLIENTNAME, TestType) \
|
||||
std::shared_ptr<MqTTTestClientBase> p##CLIENTNAME; \
|
||||
if (TestType == QString(u"Tcp")) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
if (TestType == QString(u"Ws")) p##CLIENTNAME = std::make_shared<MqTTClientWs>(); \
|
||||
if (TestType == QString(u"Wss")) p##CLIENTNAME = std::make_shared<MqTTClientWss>(); \
|
||||
if (TestType == QString(u"Ssl")) p##CLIENTNAME = std::make_shared<MqTTClientSsl>(); \
|
||||
if (!p##CLIENTNAME) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
MqTTTestClientBase &CLIENTNAME = *p##CLIENTNAME; \
|
||||
CLIENTNAME.setProtocolVersion(getProtocolVersion(MQTTVERSION))
|
||||
#endif
|
||||
|
||||
#if defined(QT_NO_SSL) && defined(QT_MQTT_WITH_WEBSOCKETS)
|
||||
#define VersionClientBase(MQTTVERSION, CLIENTNAME, TestType) \
|
||||
std::shared_ptr<MqTTTestClientBase> p##CLIENTNAME; \
|
||||
if (TestType == QString(u"Tcp")) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
if (TestType == QString(u"Ws")) p##CLIENTNAME = std::make_shared<MqTTClientWs>(); \
|
||||
if (TestType == QString(u"Wss")) p##CLIENTNAME = std::make_shared<MqTTClientWss>(); \
|
||||
if (!p##CLIENTNAME) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
MqTTTestClientBase &CLIENTNAME = *p##CLIENTNAME; \
|
||||
CLIENTNAME.setProtocolVersion(getProtocolVersion(MQTTVERSION))
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_SSL) && !defined(QT_MQTT_WITH_WEBSOCKETS)
|
||||
#define VersionClientBase(MQTTVERSION, CLIENTNAME, TestType) \
|
||||
std::shared_ptr<MqTTTestClientBase> p##CLIENTNAME; \
|
||||
if (TestType == QString(u"Tcp")) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
if (TestType == QString(u"Ssl")) p##CLIENTNAME = std::make_shared<MqTTClientSsl>(); \
|
||||
if (!p##CLIENTNAME) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
MqTTTestClientBase &CLIENTNAME = *p##CLIENTNAME; \
|
||||
CLIENTNAME.setProtocolVersion(getProtocolVersion(MQTTVERSION))
|
||||
#endif
|
||||
|
||||
#if defined(QT_NO_SSL) && !defined(QT_MQTT_WITH_WEBSOCKETS)
|
||||
#define VersionClientBase(MQTTVERSION, CLIENTNAME, TestType) \
|
||||
std::shared_ptr<MqTTTestClientBase> p##CLIENTNAME; \
|
||||
if (TestType == QString(u"Tcp")) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
if (!p##CLIENTNAME) p##CLIENTNAME = std::make_shared<MqTTClientTcp>(); \
|
||||
MqTTTestClientBase &CLIENTNAME = *p##CLIENTNAME; \
|
||||
CLIENTNAME.setProtocolVersion(getProtocolVersion(MQTTVERSION))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MQTT_TEST_TYPE)
|
||||
#define VersionClient(MQTTVERSION, CLIENTNAME) \
|
||||
VersionClientBase(MQTTVERSION, CLIENTNAME, MQTT_TEST_TYPE)
|
||||
#else
|
||||
#define VersionClient(MQTTVERSION, CLIENTNAME) \
|
||||
VersionClientBase(MQTTVERSION, CLIENTNAME, qgetenv("MQTT_TEST_BROKER_TYPE"))
|
||||
#endif
|
||||
|
||||
|
||||
#define DefaultVersionTestData(FUNCTION) \
|
||||
void FUNCTION() \
|
||||
{ \
|
||||
QTest::addColumn<QMqttClient::ProtocolVersion>("mqttVersion"); \
|
||||
QTest::newRow("V3.1.1") << QMqttClient::MQTT_3_1_1; \
|
||||
QTest::newRow("V5.0.0") << QMqttClient::MQTT_5_0; \
|
||||
if (getenv("MQTT_TEST_PROTOCOL_VERSION"))\
|
||||
QTest::newRow("V0") << QMqttClient::ProtocolVersion(0); \
|
||||
else { \
|
||||
QTest::newRow("V3.1.1") << QMqttClient::MQTT_3_1_1; \
|
||||
QTest::newRow("V5.0.0") << QMqttClient::MQTT_5_0; \
|
||||
} \
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user