summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKari Oikarinen <kari.oikarinen@qt.io>2016-12-08 13:11:36 +0200
committerKari Oikarinen <kari.oikarinen@qt.io>2016-12-22 08:43:03 +0000
commit7e1e1889736a5c0f6f6324d0ad8173ff0a8679a8 (patch)
treecf36d5a059dd76444daa801bcf0df93cf3809054
parentdb61153547cb8aafaf374f43932047ea400bd482 (diff)
Handle host-device version mismatches forward-compatibly
There is no support for multiple versions, but the behavior changes in this commit should allow adding that in the future. Device responds with a new Refuse message, if it does not support the requested version. Change-Id: I8a747654edb1c6efab485808b2692cd9689bd100 Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
-rw-r--r--libqdb/protocol/protocol.h12
-rw-r--r--libqdb/protocol/qdbmessage.cpp5
-rw-r--r--libqdb/protocol/qdbmessage.h2
-rw-r--r--qdb/server/connection.cpp74
-rw-r--r--qdb/server/connection.h4
-rw-r--r--qdb/server/handshakeservice.cpp15
-rw-r--r--qdb/server/handshakeservice.h3
-rw-r--r--qdbd/server.cpp89
-rw-r--r--qdbd/server.h7
-rw-r--r--tests/servicetest.cpp38
-rw-r--r--tests/streamtest.cpp69
11 files changed, 265 insertions, 53 deletions
diff --git a/libqdb/protocol/protocol.h b/libqdb/protocol/protocol.h
index 4f50ab2..c42c17f 100644
--- a/libqdb/protocol/protocol.h
+++ b/libqdb/protocol/protocol.h
@@ -21,11 +21,21 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
+#include <QtCore/qbytearray.h>
+#include <QtCore/qdatastream.h>
+
#include <cstdint>
const int qdbHeaderSize = 4*sizeof(uint32_t);
const int qdbMessageSize = 16*1024;
const int qdbMaxPayloadSize = qdbMessageSize - qdbHeaderSize;
-const uint32_t qdbProtocolVersion = 0;
+const uint32_t qdbProtocolVersion = 1;
+
+enum class RefuseReason : uint32_t
+{
+ Invalid = 0, // Never used except for deserialization failure
+ NotConnected,
+ UnknownVersion,
+};
#endif
diff --git a/libqdb/protocol/qdbmessage.cpp b/libqdb/protocol/qdbmessage.cpp
index 7f30808..42e48da 100644
--- a/libqdb/protocol/qdbmessage.cpp
+++ b/libqdb/protocol/qdbmessage.cpp
@@ -114,6 +114,8 @@ QdbMessage::CommandType toCommandType(uint32_t command)
switch (command) {
case static_cast<uint32_t>(QdbMessage::Connect):
return QdbMessage::Connect;
+ case static_cast<uint32_t>(QdbMessage::Refuse):
+ return QdbMessage::Refuse;
case static_cast<uint32_t>(QdbMessage::Open):
return QdbMessage::Open;
case static_cast<uint32_t>(QdbMessage::Write):
@@ -167,6 +169,9 @@ QDebug &operator<<(QDebug &stream, ::QdbMessage::CommandType command)
case QdbMessage::Connect:
stream << "Connect";
break;
+ case QdbMessage::Refuse:
+ stream << "Refuse";
+ break;
case QdbMessage::Open:
stream << "Open";
break;
diff --git a/libqdb/protocol/qdbmessage.h b/libqdb/protocol/qdbmessage.h
index 99c57bb..56e6dd9 100644
--- a/libqdb/protocol/qdbmessage.h
+++ b/libqdb/protocol/qdbmessage.h
@@ -42,6 +42,7 @@ public:
{
Invalid = 0, // never sent
Connect = 0x434e584e, // CNXN
+ Refuse = 0x52465345, // RFSE
Open = 0x4f50454e, // OPEN
Write = 0x57525445, // WRTE
Close = 0x434c5345, // CLSE
@@ -75,6 +76,7 @@ private:
Q_DECLARE_METATYPE(QdbMessage::CommandType)
QT_BEGIN_NAMESPACE
+QDebug &operator<<(QDebug &stream, ::QdbMessage::CommandType command);
QDebug &operator<<(QDebug &stream, const ::QdbMessage &message);
QDataStream &operator<<(QDataStream &stream, const ::QdbMessage &message);
diff --git a/qdb/server/connection.cpp b/qdb/server/connection.cpp
index c2d7edd..03f2693 100644
--- a/qdb/server/connection.cpp
+++ b/qdb/server/connection.cpp
@@ -30,6 +30,17 @@
Q_LOGGING_CATEGORY(connectionC, "qdb.connection");
+RefuseReason toRefuseReason(uint32_t data)
+{
+ switch (data) {
+ case static_cast<uint32_t>(RefuseReason::NotConnected):
+ return RefuseReason::NotConnected;
+ case static_cast<uint32_t>(RefuseReason::UnknownVersion):
+ return RefuseReason::UnknownVersion;
+ }
+ return RefuseReason::Invalid;
+}
+
Connection::Connection(QdbTransport *transport, QObject *parent)
: AbstractConnection{transport, parent},
m_state{ConnectionState::Disconnected},
@@ -115,15 +126,20 @@ void Connection::handleMessage()
resetConnection(true);
break;
case ConnectionState::WaitingForConnection:
- if (message.command() != QdbMessage::Connect) {
- qCWarning(connectionC) << "Connection got a non-Connect message in WaitingForConnection state";
+ if (message.command() != QdbMessage::Connect && message.command() != QdbMessage::Refuse) {
+ qCWarning(connectionC) << "Connection got an unexpected message in WaitingForConnection state" << message;
resetConnection(true);
break;
}
- if (checkVersion(message))
- m_state = ConnectionState::Connected;
- else
- m_state = ConnectionState::Disconnected;
+
+ if (message.command() == QdbMessage::Connect) {
+ if (checkVersion(message))
+ m_state = ConnectionState::Connected;
+ else
+ m_state = ConnectionState::Disconnected;
+ } else if (message.command() == QdbMessage::Refuse) {
+ handleRefuse(message.data());
+ }
break;
case ConnectionState::Connected:
switch (message.command()) {
@@ -131,6 +147,9 @@ void Connection::handleMessage()
qCWarning(connectionC) << "Connection received QdbMessage::Connect while already connected. Reconnecting.";
resetConnection(true);
break;
+ case QdbMessage::Refuse:
+ handleRefuse(message.data());
+ break;
case QdbMessage::Write:
handleWrite(message);
break;
@@ -153,6 +172,9 @@ void Connection::handleMessage()
qCWarning(connectionC) << "Connection received QdbMessage::Connect while already connected and waiting. Reconnecting.";
resetConnection(true);
break;
+ case QdbMessage::Refuse:
+ handleRefuse(message.data());
+ break;
case QdbMessage::Write:
handleWrite(message);
break;
@@ -197,12 +219,12 @@ void Connection::processQueue()
}
if (m_state == ConnectionState::Waiting) {
- qCDebug(connectionC) << "Connection::processQueue() skipping to wait for QdbMessage::Ok";
+ qCDebug(connectionC) << "Delaying sending outgoing message to wait for Ok from device";
return;
}
if (m_state == ConnectionState::WaitingForConnection) {
- qCDebug(connectionC) << "Connection::processQueue() skipping to wait for QdbMessage::Connect";
+ qCDebug(connectionC) << "Delaying sending outgoing message due to waiting for Connect or Refuse from device";
return;
}
@@ -210,6 +232,8 @@ void Connection::processQueue()
Q_ASSERT_X(message.command() != QdbMessage::Invalid, "Connection::processQueue()",
"Tried to send invalid message");
+ Q_ASSERT_X(message.command() != QdbMessage::Refuse, "Connection::processQueue()",
+ "Tried to send Refuse message from host");
if (!m_transport->send(message)) {
qCCritical(connectionC) << "Connection could not send" << message;
@@ -239,6 +263,8 @@ void Connection::processQueue()
case QdbMessage::Ok:
// 'Ok's are sent via acknowledge()
//[[fallthrough]]
+ case QdbMessage::Refuse:
+ //[[fallthrough]]
case QdbMessage::Invalid:
Q_UNREACHABLE();
break;
@@ -254,6 +280,8 @@ void Connection::resetConnection(bool reconnect)
if (reconnect)
connect();
+ else
+ emit disconnected();
}
void Connection::closeStream(StreamId id)
@@ -280,6 +308,32 @@ void Connection::finishCreateStream(StreamId hostId, StreamId deviceId)
callback(m_streams[hostId].get());
}
+void Connection::handleRefuse(const QByteArray &payload)
+{
+ QDataStream dataStream{payload};
+ uint32_t rawReason;
+ dataStream >> rawReason;
+
+ const auto reason = toRefuseReason(rawReason);
+ switch (reason) {
+ case RefuseReason::NotConnected:
+ qCWarning(connectionC) << "Received Refuse due to not being connected, reconnecting";
+ resetConnection(true);
+ break;
+ case RefuseReason::UnknownVersion:
+ uint32_t version;
+ dataStream >> version;
+ qCCritical(connectionC) << "Device does not recognize version" << qdbProtocolVersion
+ << "and requested for unknown version" << version << ". Can not connect.";
+ resetConnection(false);
+ break;
+ case RefuseReason::Invalid:
+ qCCritical(connectionC) << "Received Refuse with an invalid reason. Disconnected.";
+ resetConnection(false);
+ break;
+ }
+}
+
void Connection::handleWrite(const QdbMessage &message)
{
if (m_streams.find(message.hostStream()) == m_streams.end()) {
@@ -301,8 +355,8 @@ bool Connection::checkVersion(const QdbMessage &message)
dataStream >> protocolVersion;
if (protocolVersion != qdbProtocolVersion) {
- qCCritical(connectionC) << "Device offered protocol version" << protocolVersion
- << ", but only version" << qdbProtocolVersion << "is supported";
+ qCCritical(connectionC) << "Device responded with protocol version" << protocolVersion
+ << ", but version" << qdbProtocolVersion << "was requested";
return false;
}
return true;
diff --git a/qdb/server/connection.h b/qdb/server/connection.h
index 451a4da..c71b590 100644
--- a/qdb/server/connection.h
+++ b/qdb/server/connection.h
@@ -56,6 +56,9 @@ public:
void enqueueMessage(const QdbMessage &message) override;
+signals:
+ void disconnected();
+
public slots:
void close();
void handleMessage() override;
@@ -66,6 +69,7 @@ private:
void resetConnection(bool reconnect);
void closeStream(StreamId id);
void finishCreateStream(StreamId hostId, StreamId deviceId);
+ void handleRefuse(const QByteArray &payload);
void handleWrite(const QdbMessage &message);
bool checkVersion(const QdbMessage &message);
diff --git a/qdb/server/handshakeservice.cpp b/qdb/server/handshakeservice.cpp
index c9f3df1..be766f9 100644
--- a/qdb/server/handshakeservice.cpp
+++ b/qdb/server/handshakeservice.cpp
@@ -44,6 +44,7 @@ HandshakeService::~HandshakeService()
void HandshakeService::initialize()
{
+ connect(m_connection, &Connection::disconnected, this, &HandshakeService::handleDisconnected);
m_connection->createStream(tagBuffer(HandshakeTag), [=](Stream *stream) {
this->streamCreated(stream);
});
@@ -85,6 +86,18 @@ void HandshakeService::receive(StreamPacket packet)
void HandshakeService::onStreamClosed()
{
Service::onStreamClosed();
- if (!m_responded)
+ failedResponse();
+}
+
+void HandshakeService::handleDisconnected()
+{
+ failedResponse();
+}
+
+void HandshakeService::failedResponse()
+{
+ if (!m_responded) {
emit response("", "", "");
+ m_responded = true;
+ }
}
diff --git a/qdb/server/handshakeservice.h b/qdb/server/handshakeservice.h
index c99e6ce..09fe03f 100644
--- a/qdb/server/handshakeservice.h
+++ b/qdb/server/handshakeservice.h
@@ -50,6 +50,9 @@ protected slots:
void onStreamClosed() override;
private:
+ void handleDisconnected();
+ void failedResponse();
+
Connection *m_connection;
bool m_responded;
};
diff --git a/qdbd/server.cpp b/qdbd/server.cpp
index 9e47528..ea28699 100644
--- a/qdbd/server.cpp
+++ b/qdbd/server.cpp
@@ -23,7 +23,6 @@
#include "createexecutor.h"
#include "echoexecutor.h"
#include "libqdb/make_unique.h"
-#include "libqdb/protocol/protocol.h"
#include "libqdb/protocol/qdbmessage.h"
#include "libqdb/protocol/qdbtransport.h"
#include "libqdb/stream.h"
@@ -49,24 +48,26 @@ void Server::handleMessage()
{
QdbMessage message = m_transport->receive();
- Q_ASSERT_X(message.command() != QdbMessage::Invalid, "Server::handleMessage()", "Received invalid message");
+ if (message.command() == QdbMessage::Invalid)
+ qFatal("Server received Invalid message, which is not supported");
+
+ if (message.command() == QdbMessage::Refuse)
+ qFatal("Server received Refuse message, which is not supported");
switch (m_state) {
case ServerState::Disconnected:
if (message.command() != QdbMessage::Connect) {
- qCWarning(connectionC) << "Server got non-Connect message in Disconnected state. Resetting.";
- resetServer(false);
+ qCWarning(connectionC) << "Server got non-Connect message in Disconnected state. Refusing.";
+ refuse(RefuseReason::NotConnected);
break;
}
- checkVersion(message);
- resetServer(true);
+ handleConnect(message.data());
break;
case ServerState::Connected:
switch (message.command()) {
case QdbMessage::Connect:
- qCWarning(connectionC()) << "Server received QdbMessage::Connect while already connected. Resetting.";
- checkVersion(message);
- resetServer(true);
+ qCWarning(connectionC) << "Server received QdbMessage::Connect while already connected. Resetting.";
+ handleConnect(message.data());
break;
case QdbMessage::Open:
handleOpen(message.hostStream(), message.data());
@@ -80,6 +81,8 @@ void Server::handleMessage()
case QdbMessage::Ok:
qCWarning(connectionC) << "Server received QdbMessage::Ok in connected state";
break;
+ case QdbMessage::Refuse:
+ //[[fallthrough]]
case QdbMessage::Invalid:
Q_UNREACHABLE();
break;
@@ -88,8 +91,8 @@ void Server::handleMessage()
case ServerState::Waiting:
switch (message.command()) {
case QdbMessage::Connect:
- qCWarning(connectionC()) << "Server received QdbMessage::Connect while already connected and waiting. Resetting.";
- resetServer(true);
+ qCWarning(connectionC) << "Server received QdbMessage::Connect while already connected and waiting. Resetting.";
+ handleConnect(message.data());
break;
case QdbMessage::Open:
handleOpen(message.hostStream(), message.data());
@@ -104,6 +107,8 @@ void Server::handleMessage()
case QdbMessage::Ok:
m_state = ServerState::Connected;
break;
+ case QdbMessage::Refuse:
+ //[[fallthrough]]
case QdbMessage::Invalid:
Q_UNREACHABLE();
break;
@@ -123,9 +128,8 @@ void Server::enqueueMessage(const QdbMessage &message)
void Server::processQueue()
{
- if (m_outgoingMessages.isEmpty()) {
+ if (m_outgoingMessages.isEmpty())
return;
- }
if (m_state == ServerState::Waiting) {
qCDebug(connectionC) << "Server::processQueue() skipping to wait for QdbMessage::Ok";
@@ -144,6 +148,9 @@ void Server::processQueue()
}
switch (message.command()) {
+ case QdbMessage::Refuse:
+ m_state = ServerState::Disconnected;
+ break;
case QdbMessage::Open:
qFatal("Server sending QdbMessage::Open is not supported");
break;
@@ -171,6 +178,23 @@ void Server::processQueue()
}
}
+void Server::handleConnect(const QByteArray &payload)
+{
+ if (!checkVersion(payload)) {
+ refuse(RefuseReason::UnknownVersion);
+ return;
+ }
+
+ resetServer();
+ m_state = ServerState::Connected;
+
+ QByteArray buffer{};
+ QDataStream dataStream{&buffer, QIODevice::WriteOnly};
+ dataStream << qdbProtocolVersion;
+
+ enqueueMessage(QdbMessage{QdbMessage::Connect, 0, 0, buffer});
+}
+
void Server::handleOpen(StreamId hostId, const QByteArray &tag)
{
StreamId deviceId = m_nextStreamId++;
@@ -179,18 +203,25 @@ void Server::handleOpen(StreamId hostId, const QByteArray &tag)
m_executors[deviceId] = createExecutor(m_streams[deviceId].get(), tag);
}
-void Server::resetServer(bool hostConnected)
+void Server::refuse(RefuseReason reason)
+{
+ resetServer();
+ QByteArray buffer{};
+ QDataStream stream{&buffer, QIODevice::WriteOnly};
+ stream << static_cast<uint32_t>(reason);
+
+ if (reason == RefuseReason::UnknownVersion)
+ stream << qdbProtocolVersion;
+
+ m_state = ServerState::Disconnected;
+ enqueueMessage(QdbMessage{QdbMessage::Refuse, 0, 0, buffer});
+}
+
+void Server::resetServer()
{
m_outgoingMessages.clear();
m_executors.clear();
m_streams.clear();
- m_state = hostConnected ? ServerState::Connected : ServerState::Disconnected;
-
- QByteArray buffer{};
- QDataStream dataStream{&buffer, QIODevice::WriteOnly};
- dataStream << qdbProtocolVersion;
-
- enqueueMessage(QdbMessage{QdbMessage::Connect, 0, 0, buffer});
}
void Server::handleWrite(const QdbMessage &message)
@@ -224,18 +255,22 @@ void Server::closeStream(StreamId id)
// Closes are not acknowledged
}
-void Server::checkVersion(const QdbMessage &message)
+bool Server::checkVersion(const QByteArray &payload)
{
- Q_ASSERT(message.command() == QdbMessage::Connect);
- Q_ASSERT(message.data().size() == sizeof(qdbProtocolVersion));
+ if (static_cast<size_t>(payload.size()) < sizeof(qdbProtocolVersion)) {
+ qCCritical(connectionC) << "Connection request did not contain a protocol version";
+ return false;
+ };
- QDataStream dataStream{message.data()};
+ QDataStream dataStream{payload};
uint32_t protocolVersion;
dataStream >> protocolVersion;
if (protocolVersion != qdbProtocolVersion) {
- qCCritical(connectionC()) << "Protocol version" << protocolVersion << "requested, but only version"
- << qdbProtocolVersion << "is known";
+ qCWarning(connectionC) << "Protocol version" << protocolVersion << "requested, but only version"
+ << qdbProtocolVersion << "is known";
+ return false;
}
+ return true;
}
diff --git a/qdbd/server.h b/qdbd/server.h
index 8f8bf09..097d286 100644
--- a/qdbd/server.h
+++ b/qdbd/server.h
@@ -22,6 +22,7 @@
#define SERVER_H
#include "libqdb/abstractconnection.h"
+#include "libqdb/protocol/protocol.h"
class Executor;
class QdbMessage;
class QdbTransport;
@@ -52,11 +53,13 @@ public slots:
private:
void processQueue();
+ void handleConnect(const QByteArray &payload);
void handleOpen(StreamId hostId, const QByteArray &tag);
- void resetServer(bool hostConnected);
+ void refuse(RefuseReason reason);
+ void resetServer();
void handleWrite(const QdbMessage &message);
void closeStream(StreamId id);
- void checkVersion(const QdbMessage &message);
+ bool checkVersion(const QByteArray &payload);
ServerState m_state;
std::unordered_map<StreamId, std::unique_ptr<Executor>> m_executors;
diff --git a/tests/servicetest.cpp b/tests/servicetest.cpp
index a895257..76af6cf 100644
--- a/tests/servicetest.cpp
+++ b/tests/servicetest.cpp
@@ -34,18 +34,39 @@
const int testTimeout = 500; // in milliseconds
// Helper to initialize Connection in testcases
-struct ConnectionContext
+class ConnectionContext
{
+public:
ConnectionContext()
- : deviceEnumerator{},
- connection{new QdbTransport{new UsbConnection{deviceEnumerator.listUsbDevices()[0]}}}
+ : m_connection{nullptr},
+ m_valid{false}
{
- QVERIFY(connection.initialize());
+ UsbDeviceEnumerator deviceEnumerator;
+ const auto devices = deviceEnumerator.listUsbDevices();
+ if (devices.empty())
+ QFAIL("Could not find QDB USB device to run the test against");
- connection.connect();
+ m_connection = make_unique<Connection>(new QdbTransport{new UsbConnection{devices[0]}});
+
+ QVERIFY(m_connection->initialize());
+ m_valid = true;
+
+ m_connection->connect();
+ }
+
+ Connection *connection()
+ {
+ return m_connection.get();
}
- UsbDeviceEnumerator deviceEnumerator;
- Connection connection;
+
+ bool isValid()
+ {
+ return m_valid;
+ }
+
+private:
+ std::unique_ptr<Connection> m_connection;
+ bool m_valid;
};
class ServiceTest : public QObject
@@ -58,8 +79,9 @@ private slots:
void ServiceTest::echo()
{
ConnectionContext ctx;
+ QVERIFY(ctx.isValid());
- EchoService echo{&ctx.connection};
+ EchoService echo{ctx.connection()};
connect(&echo, &EchoService::initialized, [&]() {
echo.send("ABCD");
});
diff --git a/tests/streamtest.cpp b/tests/streamtest.cpp
index 0e3068b..67ff33c 100644
--- a/tests/streamtest.cpp
+++ b/tests/streamtest.cpp
@@ -46,7 +46,11 @@ public slots:
void run()
{
UsbDeviceEnumerator deviceManager;
- m_transport = make_unique<QdbTransport>(new UsbConnection{deviceManager.listUsbDevices()[0]});
+ const auto devices = deviceManager.listUsbDevices();
+ if (devices.empty())
+ QFAIL("Could not find QDB USB device to run the test against");
+
+ m_transport = make_unique<QdbTransport>(new UsbConnection{devices[0]});
if (m_transport->open()) {
qDebug() << "opened transport";
connect(m_transport.get(), &QdbTransport::messageAvailable, this, &TestCase::testPhases);
@@ -179,7 +183,7 @@ public slots:
{
switch (m_phase) {
case 0: {
- QByteArray unsupported{};
+ QByteArray unsupported;
QDataStream dataStream{&unsupported, QIODevice::WriteOnly};
dataStream << (qdbProtocolVersion + 1);
QdbMessage connect{QdbMessage::Connect, 0, 0, unsupported};
@@ -188,10 +192,16 @@ public slots:
}
case 1: {
QdbMessage response = m_transport->receive();
- QCOMPARE(response.command(), QdbMessage::Connect);
+ QCOMPARE(response.command(), QdbMessage::Refuse);
QCOMPARE(response.hostStream(), 0u);
QCOMPARE(response.deviceStream(), 0u);
- QCOMPARE(response.data(), m_versionBuffer);
+ QDataStream dataStream{response.data()};
+ uint32_t reason;
+ dataStream >> reason;
+ QCOMPARE(reason, static_cast<uint32_t>(RefuseReason::UnknownVersion));
+ uint32_t version;
+ dataStream >> version;
+ QCOMPARE(version, qdbProtocolVersion);
emit passed();
break;
@@ -464,6 +474,51 @@ private:
StreamId m_deviceId2 = 0;
};
+class WriteWithoutConnectingTest : public TestCase
+{
+ Q_OBJECT
+public slots:
+ void testPhases() override
+ {
+ switch (m_phase) {
+ case 0: {
+ // Send Connect with unknown version to ensure not connected state.
+ // Otherwise the device will still be connected due to previous
+ // tests establishing the connection.
+ QByteArray unsupported;
+ QDataStream dataStream{&unsupported, QIODevice::WriteOnly};
+ dataStream << (qdbProtocolVersion + 1);
+ QdbMessage connect{QdbMessage::Connect, 0, 0, unsupported};
+ QVERIFY(m_transport->send(connect));
+ break;
+ }
+ case 1: {
+ QdbMessage response = m_transport->receive();
+ QCOMPARE(response.command(), QdbMessage::Refuse);
+
+ QByteArray data{"ABCD"};
+ QdbMessage write{QdbMessage::Write, 1, 1, data};
+ QVERIFY(m_transport->send(write));
+ break;
+ }
+ case 2: {
+ QdbMessage response = m_transport->receive();
+ QCOMPARE(response.command(), QdbMessage::Refuse);
+ QCOMPARE(response.hostStream(), 0u);
+ QCOMPARE(response.deviceStream(), 0u);
+ QByteArray expectedReason;
+ QDataStream dataStream{&expectedReason, QIODevice::WriteOnly};
+ dataStream << static_cast<uint32_t>(RefuseReason::NotConnected);
+ QCOMPARE(response.data(), expectedReason);
+
+ emit passed();
+ break;
+ }
+ }
+ ++m_phase;
+ }
+};
+
void testCase(TestCase *test)
{
QSignalSpy spy{test, &TestCase::passed};
@@ -511,6 +566,12 @@ private slots:
TwoEchoStreamsTest test;
testCase(&test);
}
+
+ void writeWithoutConnecting()
+ {
+ WriteWithoutConnectingTest test;
+ testCase(&test);
+ }
};
QTEST_GUILESS_MAIN(StreamTest)