Commit 502ffeec24b3df63887919aa3534348e5fe17288

Authored by Wiebe Cazemier
1 parent 0262ae00

Fix write buffer bug: wasn't increased enough

There still is a bug: writing a very big packet. I wrote the test case
already.
FlashMQTests/tst_maintests.cpp
... ... @@ -32,6 +32,9 @@ private slots:
32 32 void test_retained_changed();
33 33 void test_retained_removed();
34 34  
  35 + void test_packet_bigger_than_one_doubling();
  36 + void test_very_big_packet();
  37 +
35 38 };
36 39  
37 40 MainTests::MainTests()
... ... @@ -267,8 +270,8 @@ void MainTests::test_retained()
267 270 QString topic = "retaintopic";
268 271  
269 272 testContext.connectSender();
270   - testContext.publishRetained(topic, payload);
271   - testContext.publishRetained("dummy2", "Nobody sees this");
  273 + testContext.publish(topic, payload, true);
  274 + testContext.publish("dummy2", "Nobody sees this", true);
272 275  
273 276 testContext.connectReceiver();
274 277 testContext.subscribeReceiver("dummy");
... ... @@ -283,7 +286,7 @@ void MainTests::test_retained()
283 286  
284 287 testContext.receivedMessages.clear();
285 288  
286   - testContext.publishRetained(topic, payload);
  289 + testContext.publish(topic, payload, true);
287 290 testContext.waitReceiverReceived();
288 291  
289 292 QVERIFY2(testContext.receivedMessages.count() == 1, "There must be one message in the received list");
... ... @@ -300,11 +303,11 @@ void MainTests::test_retained_changed()
300 303 QString topic = "retaintopic";
301 304  
302 305 testContext.connectSender();
303   - testContext.publishRetained(topic, payload);
  306 + testContext.publish(topic, payload, true);
304 307  
305 308 payload = "Changed payload";
306 309  
307   - testContext.publishRetained(topic, payload);
  310 + testContext.publish(topic, payload, true);
308 311  
309 312 testContext.connectReceiver();
310 313 testContext.subscribeReceiver(topic);
... ... @@ -325,11 +328,11 @@ void MainTests::test_retained_removed()
325 328 QString topic = "retaintopic";
326 329  
327 330 testContext.connectSender();
328   - testContext.publishRetained(topic, payload);
  331 + testContext.publish(topic, payload, true);
329 332  
330 333 payload = "";
331 334  
332   - testContext.publishRetained(topic, payload);
  335 + testContext.publish(topic, payload, true);
333 336  
334 337 testContext.connectReceiver();
335 338 testContext.subscribeReceiver(topic);
... ... @@ -338,6 +341,49 @@ void MainTests::test_retained_removed()
338 341 QVERIFY2(testContext.receivedMessages.empty(), "We erased the retained message. We shouldn't have received any.");
339 342 }
340 343  
  344 +void MainTests::test_packet_bigger_than_one_doubling()
  345 +{
  346 + TwoClientTestContext testContext;
  347 +
  348 + QByteArray payload(8000, 3);
  349 + QString topic = "hugepacket";
  350 +
  351 + testContext.connectSender();
  352 + testContext.connectReceiver();
  353 + testContext.subscribeReceiver(topic);
  354 +
  355 + testContext.publish(topic, payload);
  356 + testContext.waitReceiverReceived();
  357 +
  358 + QVERIFY2(testContext.receivedMessages.count() == 1, "There must be one message in the received list");
  359 +
  360 + QMQTT::Message msg = testContext.receivedMessages.first();
  361 + QCOMPARE(msg.payload(), payload);
  362 + QVERIFY(!msg.retain());
  363 +}
  364 +
  365 +// This tests our write buffer, and that it's emptied during writing already.
  366 +void MainTests::test_very_big_packet()
  367 +{
  368 + TwoClientTestContext testContext;
  369 +
  370 + QByteArray payload(10*1024*1024, 3);
  371 + QString topic = "hugepacket";
  372 +
  373 + testContext.connectSender();
  374 + testContext.connectReceiver();
  375 + testContext.subscribeReceiver(topic);
  376 +
  377 + testContext.publish(topic, payload);
  378 + testContext.waitReceiverReceived();
  379 +
  380 + QVERIFY2(testContext.receivedMessages.count() == 1, "There must be one message in the received list");
  381 +
  382 + QMQTT::Message msg = testContext.receivedMessages.first();
  383 + QCOMPARE(msg.payload(), payload);
  384 + QVERIFY(!msg.retain());
  385 +}
  386 +
341 387 QTEST_GUILESS_MAIN(MainTests)
342 388  
343 389 #include "tst_maintests.moc"
... ...
FlashMQTests/twoclienttestcontext.cpp
... ... @@ -11,11 +11,11 @@ TwoClientTestContext::TwoClientTestContext(QObject *parent) : QObject(parent)
11 11 receiver.reset(new QMQTT::Client(targetHost));
12 12 }
13 13  
14   -void TwoClientTestContext::publishRetained(const QString &topic, const QByteArray &payload)
  14 +void TwoClientTestContext::publish(const QString &topic, const QByteArray &payload, bool retain)
15 15 {
16 16 QMQTT::Message msg;
17 17 msg.setTopic(topic);
18   - msg.setRetain(true);
  18 + msg.setRetain(retain);
19 19 msg.setQos(0);
20 20 msg.setPayload(payload);
21 21 sender->publish(msg);
... ...
FlashMQTests/twoclienttestcontext.h
... ... @@ -17,7 +17,7 @@ private slots:
17 17  
18 18 public:
19 19 explicit TwoClientTestContext(QObject *parent = nullptr);
20   - void publishRetained(const QString &topic, const QByteArray &payload);
  20 + void publish(const QString &topic, const QByteArray &payload, bool retain = false);
21 21 void connectSender();
22 22 void connectReceiver();
23 23 void disconnectReceiver();
... ...
client.cpp
... ... @@ -81,7 +81,7 @@ void Client::writeMqttPacket(const MqttPacket &packet)
81 81 {
82 82 std::lock_guard<std::mutex> locker(writeBufMutex);
83 83  
84   - if (packet.getSizeIncludingNonPresentHeader() > writebuf.freeSpace())
  84 + while (packet.getSizeIncludingNonPresentHeader() > writebuf.freeSpace())
85 85 {
86 86 if (packet.packetType == PacketType::PUBLISH && writebuf.getSize() >= CLIENT_MAX_BUFFER_SIZE)
87 87 return;
... ... @@ -99,6 +99,7 @@ void Client::writeMqttPacket(const MqttPacket &amp;packet)
99 99 while (len_left > 0)
100 100 {
101 101 const size_t len = std::min<int>(len_left, writebuf.maxWriteSize());
  102 + assert(len > 0);
102 103 std::memcpy(writebuf.headPtr(), &r.bytes[src_i], len);
103 104 writebuf.advanceHead(len);
104 105 src_i += len;
... ... @@ -113,6 +114,7 @@ void Client::writeMqttPacket(const MqttPacket &amp;packet)
113 114 while (len_left > 0)
114 115 {
115 116 const size_t len = std::min<int>(len_left, writebuf.maxWriteSize());
  117 + assert(len > 0);
116 118 std::memcpy(writebuf.headPtr(), &packet.getBites()[src_i], len);
117 119 writebuf.advanceHead(len);
118 120 src_i += len;
... ...
mqttpacket.cpp
... ... @@ -22,6 +22,7 @@ MqttPacket::MqttPacket(CirBuf &amp;buf, size_t packet_len, size_t fixed_header_lengt
22 22 while (_packet_len > 0)
23 23 {
24 24 int readlen = std::min<int>(buf.maxReadSize(), _packet_len);
  25 + assert(readlen > 0);
25 26 std::memcpy(&bites[i], buf.tailPtr(), readlen);
26 27 buf.advanceTail(readlen);
27 28 i += readlen;
... ...