diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2021-07-03 16:03:54 +0300 |
---|---|---|
committer | Alex Trotsenko <alex1973tr@gmail.com> | 2021-07-06 14:50:55 +0300 |
commit | 03272e601ce0b03c36717dac0a60c2fdd8987bee (patch) | |
tree | 37cef825c04c7029ec05f7f64213ddf83b05bf27 /tests/auto/network/socket/qlocalsocket | |
parent | d9a9eca54d72583ec03caedc10f83e080a20b031 (diff) |
Clarify readLine() behavior on sequential devices
QIODevice::readLine() can also return partial lines, which was not
properly documented. Add an autotest for QLocalSocket to illustrate
and test this behavior.
Pick-to: 6.2
Change-Id: Ia2c1c438cc68d2672d34881e11fdf7837232f3b4
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'tests/auto/network/socket/qlocalsocket')
-rw-r--r-- | tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index eebbf4ef24..8ec41a760a 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -34,6 +34,7 @@ #include <QWaitCondition> #include <QLoggingCategory> #include <QMutex> +#include <QList> #include <qtextstream.h> #include <qdatastream.h> @@ -64,6 +65,7 @@ class tst_QLocalSocket : public QObject Q_OBJECT public: + using ByteArrayList = QList<QByteArray>; tst_QLocalSocket(); private slots: @@ -90,6 +92,9 @@ private slots: void sendData_data(); void sendData(); + void readLine_data(); + void readLine(); + void readBufferOverflow(); void simpleCommandProtocol1(); @@ -704,6 +709,103 @@ void tst_QLocalSocket::sendData() QCOMPARE(spy.count(), (canListen ? 1 : 0)); } +void tst_QLocalSocket::readLine_data() +{ + QTest::addColumn<ByteArrayList>("input"); + QTest::addColumn<ByteArrayList>("output"); + QTest::addColumn<int>("maxSize"); + QTest::addColumn<bool>("wholeLinesOnly"); + + QTest::newRow("0") << ByteArrayList{ "\n", "A", "\n", "B", "B", "A", "\n" } + << ByteArrayList{ "\n", "", "", "A\n", "", "", "", "", + "BBA\n", "", "" } + << 80 << true; + QTest::newRow("1") << ByteArrayList{ "A", "\n", "\n", "B", "B", "\n", "A", "A" } + << ByteArrayList{ "", "A\n", "", "\n", "", "", "", "BB\n", + "", "", "", "AA", "" } + << 80 << true; + + QTest::newRow("2") << ByteArrayList{ "\nA\nA\n" } + << ByteArrayList{ "\n", "A", "\n", "A", "\n", "", "" } + << 1 << false; + QTest::newRow("3") << ByteArrayList{ "A\n\n\nA", "A" } + << ByteArrayList{ "A\n", "\n", "\n", "A", "", "A", "", "" } + << 2 << false; + + QTest::newRow("4") << ByteArrayList{ "He", "ll", "o\n", " \n", "wo", "rl", "d", "!\n" } + << ByteArrayList{ "", "Hel", "", "lo\n", "", " \n", "", "", "wor", + "", "", "ld!", "\n", "", "" } + << 3 << true; + QTest::newRow("5") << ByteArrayList{ "Hello\n world!" } + << ByteArrayList{ "Hello\n", "", " world!", "" } + << 80 << true; + + QTest::newRow("6") << ByteArrayList{ "\nHello", " \n", " wor", "ld!\n" } + << ByteArrayList{ "\n", "Hell", "o", "", " \n", "", " wor", "", + "ld!\n", "", "" } + << 4 << false; + QTest::newRow("7") << ByteArrayList{ "Hello\n world", "!" } + << ByteArrayList{ "Hello\n", " world", "", "!", "", "" } + << 80 << false; +} + +void tst_QLocalSocket::readLine() +{ + QFETCH(ByteArrayList, input); + QFETCH(ByteArrayList, output); + QFETCH(int, maxSize); + QFETCH(bool, wholeLinesOnly); + + const QString serverName = QLatin1String("tst_localsocket"); + LocalServer server; + QVERIFY(server.listen(serverName)); + + LocalSocket client; + client.connectToServer(serverName); + QVERIFY(server.waitForNewConnection()); + QLocalSocket *serverSocket = server.nextPendingConnection(); + QVERIFY(serverSocket); + QCOMPARE(client.state(), QLocalSocket::ConnectedState); + + ByteArrayList result; + qsizetype pos = 0; + do { + // This test assumes that such small chunks of data are synchronously + // delivered to the receiver on all supported platforms. + if (pos < input.size()) { + const QByteArray &chunk = input.at(pos); + QCOMPARE(serverSocket->write(chunk), qint64(chunk.size())); + QVERIFY(serverSocket->waitForBytesWritten()); + QCOMPARE(serverSocket->bytesToWrite(), qint64(0)); + QVERIFY(client.waitForReadyRead()); + } else { + serverSocket->close(); + QVERIFY(!client.waitForReadyRead()); + } + + while (!wholeLinesOnly || (client.bytesAvailable() >= qint64(maxSize)) + || client.canReadLine() || (pos == input.size())) { + const bool chunkEmptied = (client.bytesAvailable() == 0); + QByteArray line(maxSize, Qt::Uninitialized); + + const qint64 readResult = client.readLine(line.data(), maxSize + 1); + if (chunkEmptied) { + if (pos == input.size()) + QCOMPARE(readResult, qint64(-1)); + else + QCOMPARE(readResult, qint64(0)); + break; + } + QVERIFY((readResult > 0) && (readResult <= maxSize)); + line.resize(readResult); + result.append(line); + } + result.append(QByteArray()); + } while (++pos <= input.size()); + QCOMPARE(client.state(), QLocalSocket::UnconnectedState); + QCOMPARE(result, output); +} + void tst_QLocalSocket::readBufferOverflow() { const int readBufferSize = 128; |