diff options
Diffstat (limited to 'tests/auto/websockets/websocketframe/tst_websocketframe.cpp')
-rw-r--r-- | tests/auto/websockets/websocketframe/tst_websocketframe.cpp | 624 |
1 files changed, 624 insertions, 0 deletions
diff --git a/tests/auto/websockets/websocketframe/tst_websocketframe.cpp b/tests/auto/websockets/websocketframe/tst_websocketframe.cpp new file mode 100644 index 0000000..5db82d5 --- /dev/null +++ b/tests/auto/websockets/websocketframe/tst_websocketframe.cpp @@ -0,0 +1,624 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Kurt Pattyn <pattyn.kurt@gmail.com>. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> +#include <QtTest/qtestcase.h> +#include <QDebug> +#include <QByteArray> +#include <QtEndian> + +#include "private/qwebsocketframe_p.h" +#include "private/qwebsocketprotocol_p.h" +#include "qwebsocketprotocol.h" + +QT_USE_NAMESPACE + +Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode) +Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode) + +/*! + * \brief class FrameHelper is used to encode a single frame. + * + * \internal + */ +class FrameHelper +{ +public: + FrameHelper(); + + QByteArray wireRepresentation(); + + void setRsv1(int value) { m_rsv1 = value; } + void setRsv2(int value) { m_rsv2 = value; } + void setRsv3(int value) { m_rsv3 = value; } + void setMask(quint32 mask) { m_mask = mask; } + void setOpCode(QWebSocketProtocol::OpCode opCode) { m_opCode = opCode; } + void setPayload(const QByteArray &payload) { m_payload = payload; } + void setFinalFrame(bool isFinal) { m_isFinalFrame = isFinal; } + +private: + int m_rsv1; + int m_rsv2; + int m_rsv3; + quint32 m_mask; + QWebSocketProtocol::OpCode m_opCode; + QByteArray m_payload; + bool m_isFinalFrame; +}; + +FrameHelper::FrameHelper() : + m_rsv1(0), m_rsv2(0), m_rsv3(0), + m_mask(0), m_opCode(QWebSocketProtocol::OpCodeReserved3), + m_payload(), m_isFinalFrame(false) +{} + +QByteArray FrameHelper::wireRepresentation() +{ + quint8 byte = 0x00; + QByteArray wireRep; + quint64 payloadLength = m_payload.length(); + + //FIN, opcode + byte = static_cast<quint8>((m_opCode & 0x0F) | (m_isFinalFrame ? 0x80 : 0x00)); //FIN, opcode + //RSV1-3 + byte |= static_cast<quint8>(((m_rsv1 & 0x01) << 6) | ((m_rsv2 & 0x01) << 5) | + ((m_rsv3 & 0x01) << 4)); + wireRep.append(static_cast<char>(byte)); + + byte = 0x00; + if (m_mask != 0) + { + byte |= 0x80; + } + if (payloadLength <= 125) + { + byte |= static_cast<quint8>(payloadLength); + wireRep.append(static_cast<char>(byte)); + } + else if (payloadLength <= 0xFFFFU) + { + byte |= 126; + wireRep.append(static_cast<char>(byte)); + quint16 swapped = qToBigEndian<quint16>(static_cast<quint16>(payloadLength)); + wireRep.append(static_cast<const char *>(static_cast<const void *>(&swapped)), 2); + } + else + { + byte |= 127; + wireRep.append(static_cast<char>(byte)); + quint64 swapped = qToBigEndian<quint64>(payloadLength); + wireRep.append(static_cast<const char *>(static_cast<const void *>(&swapped)), 8); + } + //Write mask + if (m_mask != 0) + { + wireRep.append(static_cast<const char *>(static_cast<const void *>(&m_mask)), + sizeof(quint32)); + } + QByteArray tmpData = m_payload; + if (m_mask) + { + tmpData.detach(); + QWebSocketProtocol::mask(&tmpData, m_mask); + } + wireRep.append(tmpData); + return wireRep; +} + +class tst_WebSocketFrame : public QObject +{ + Q_OBJECT + +public: + tst_WebSocketFrame(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void tst_initialization(); + void tst_copyConstructorAndAssignment(); + + void tst_goodFrames_data(); + void tst_goodFrames(); + + void tst_invalidFrames_data(); + void tst_invalidFrames(); + + void tst_malformedFrames_data(); + void tst_malformedFrames(); +}; + +tst_WebSocketFrame::tst_WebSocketFrame() +{} + +void tst_WebSocketFrame::initTestCase() +{ +} + +void tst_WebSocketFrame::cleanupTestCase() +{} + +void tst_WebSocketFrame::init() +{ + qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode"); + qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode"); +} + +void tst_WebSocketFrame::cleanup() +{ +} + +void tst_WebSocketFrame::tst_initialization() +{ + QWebSocketFrame frame; + QVERIFY(!frame.isValid()); + QCOMPARE(frame.payload().length(), 0); +} + +void tst_WebSocketFrame::tst_copyConstructorAndAssignment() +{ + FrameHelper frameHelper; + frameHelper.setRsv1(0); + frameHelper.setRsv2(0); + frameHelper.setRsv3(0); + frameHelper.setFinalFrame(true); + frameHelper.setMask(1234u); + frameHelper.setOpCode(QWebSocketProtocol::OpCodeBinary); + frameHelper.setPayload(QByteArrayLiteral("12345")); + + QByteArray payload = frameHelper.wireRepresentation(); + QBuffer buffer(&payload); + buffer.open(QIODevice::ReadOnly); + + QWebSocketFrame frame = QWebSocketFrame::readFrame(&buffer); + buffer.close(); + + { + QWebSocketFrame other(frame); + QCOMPARE(other.closeCode(), frame.closeCode()); + QCOMPARE(other.closeReason(), frame.closeReason()); + QCOMPARE(other.hasMask(), frame.hasMask()); + QCOMPARE(other.isContinuationFrame(), frame.isContinuationFrame()); + QCOMPARE(other.isControlFrame(), frame.isControlFrame()); + QCOMPARE(other.isDataFrame(), frame.isDataFrame()); + QCOMPARE(other.isFinalFrame(), frame.isFinalFrame()); + QCOMPARE(other.isValid(), frame.isValid()); + QCOMPARE(other.mask(), frame.mask()); + QCOMPARE(other.opCode(), frame.opCode()); + QCOMPARE(other.payload(), frame.payload()); + QCOMPARE(other.rsv1(), frame.rsv1()); + QCOMPARE(other.rsv2(), frame.rsv2()); + QCOMPARE(other.rsv3(), frame.rsv3()); + } + { + QWebSocketFrame other; + other = frame; + QCOMPARE(other.closeCode(), frame.closeCode()); + QCOMPARE(other.closeReason(), frame.closeReason()); + QCOMPARE(other.hasMask(), frame.hasMask()); + QCOMPARE(other.isContinuationFrame(), frame.isContinuationFrame()); + QCOMPARE(other.isControlFrame(), frame.isControlFrame()); + QCOMPARE(other.isDataFrame(), frame.isDataFrame()); + QCOMPARE(other.isFinalFrame(), frame.isFinalFrame()); + QCOMPARE(other.isValid(), frame.isValid()); + QCOMPARE(other.mask(), frame.mask()); + QCOMPARE(other.opCode(), frame.opCode()); + QCOMPARE(other.payload(), frame.payload()); + QCOMPARE(other.rsv1(), frame.rsv1()); + QCOMPARE(other.rsv2(), frame.rsv2()); + QCOMPARE(other.rsv3(), frame.rsv3()); + } +} + +void tst_WebSocketFrame::tst_goodFrames_data() +{ + QTest::addColumn<int>("rsv1"); + QTest::addColumn<int>("rsv2"); + QTest::addColumn<int>("rsv3"); + QTest::addColumn<quint32>("mask"); + QTest::addColumn<QWebSocketProtocol::OpCode>("opCode"); + QTest::addColumn<bool>("isFinal"); + QTest::addColumn<QByteArray>("payload"); + QTest::addColumn<bool>("isControlFrame"); + QTest::addColumn<bool>("isDataFrame"); + QTest::addColumn<bool>("isContinuationFrame"); + + QTest::newRow("Non masked final text frame with small payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << false << true << false; + QTest::newRow("Non masked final binary frame with small payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeBinary + << true << QByteArrayLiteral("\x00\x01\x02\x03\x04") + << false << true << false; + QTest::newRow("Non masked final text frame with no payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeText + << true << QByteArray() + << false << true << false; + QTest::newRow("Non masked final binary frame with no payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeBinary + << true << QByteArray() + << false << true << false; + + QTest::newRow("Non masked final close frame with small payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeClose + << true << QStringLiteral("Hello world!").toUtf8() + << true << false << false; + QTest::newRow("Non masked final close frame with no payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeClose + << true << QByteArray() + << true << false << false; + QTest::newRow("Non masked final ping frame with small payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodePing + << true << QStringLiteral("Hello world!").toUtf8() + << true << false << false; + QTest::newRow("Non masked final pong frame with no payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodePong + << true << QByteArray() + << true << false << false; + + QTest::newRow("Non masked final continuation frame with small payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeContinue + << true << QStringLiteral("Hello world!").toUtf8() + << false << true << true; + QTest::newRow("Non masked non-final continuation frame with small payload") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeContinue + << false << QStringLiteral("Hello world!").toUtf8() + << false << true << true; +} + +void tst_WebSocketFrame::tst_goodFrames() +{ + QFETCH(int, rsv1); + QFETCH(int, rsv2); + QFETCH(int, rsv3); + QFETCH(quint32, mask); + QFETCH(QWebSocketProtocol::OpCode, opCode); + QFETCH(bool, isFinal); + QFETCH(QByteArray, payload); + QFETCH(bool, isControlFrame); + QFETCH(bool, isDataFrame); + QFETCH(bool, isContinuationFrame); + + FrameHelper helper; + helper.setRsv1(rsv1); + helper.setRsv2(rsv2); + helper.setRsv3(rsv3); + helper.setMask(mask); + helper.setOpCode(opCode); + helper.setFinalFrame(isFinal); + helper.setPayload(payload); + + QByteArray wireRepresentation = helper.wireRepresentation(); + QBuffer buffer; + buffer.setData(wireRepresentation); + buffer.open(QIODevice::ReadOnly); + QWebSocketFrame frame = QWebSocketFrame::readFrame(&buffer); + buffer.close(); + QVERIFY(frame.isValid()); + QCOMPARE(frame.rsv1(), rsv1); + QCOMPARE(frame.rsv2(), rsv2); + QCOMPARE(frame.rsv3(), rsv3); + QCOMPARE(frame.hasMask(), (mask != 0)); + QCOMPARE(frame.opCode(), opCode); + QCOMPARE(frame.isFinalFrame(), isFinal); + QCOMPARE(frame.isControlFrame(), isControlFrame); + QCOMPARE(frame.isDataFrame(), isDataFrame); + QCOMPARE(frame.isContinuationFrame(), isContinuationFrame); + QCOMPARE(frame.payload().length(), payload.length()); + QCOMPARE(frame.payload(), payload); +} + +void tst_WebSocketFrame::tst_invalidFrames_data() +{ + QTest::addColumn<int>("rsv1"); + QTest::addColumn<int>("rsv2"); + QTest::addColumn<int>("rsv3"); + QTest::addColumn<quint32>("mask"); + QTest::addColumn<QWebSocketProtocol::OpCode>("opCode"); + QTest::addColumn<bool>("isFinal"); + QTest::addColumn<QByteArray>("payload"); + QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedError"); + + QTest::newRow("RSV1 != 0") + << 1 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("RSV2 != 0") + << 0 << 1 << 0 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("RSV3 != 0") + << 0 << 0 << 1 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("RSV1 != 0 and RSV2 != 0") + << 1 << 1 << 0 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("RSV1 != 0 and RSV3 != 0") + << 1 << 0 << 1 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("RSV2 != 0 and RSV3 != 0") + << 0 << 1 << 1 + << 0U << QWebSocketProtocol::OpCodeText + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + + QTest::newRow("Reserved OpCode 3") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReserved3 + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode 4") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReserved4 + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode 5") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReserved5 + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode 6") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReserved6 + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode 7") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReserved7 + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode B") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReservedB + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode C") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReservedC + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode D") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReservedD + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode E") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReservedE + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Reserved OpCode F") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeReservedF + << true << QStringLiteral("Hello world!").toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + + QTest::newRow("Close Frame with payload > 125 bytes") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeClose + << true << QString(126, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Non-final Close Frame") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeClose + << false << QString(126, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Ping Frame with payload > 125 bytes") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodePing + << true << QString(126, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Non-final Ping Frame") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodePing + << false << QString(126, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Pong Frame with payload > 125 bytes") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodePong + << true << QString(126, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; + QTest::newRow("Non-final Pong Frame") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodePong + << false << QString(126, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeProtocolError; +} + +void tst_WebSocketFrame::tst_invalidFrames() +{ + QFETCH(int, rsv1); + QFETCH(int, rsv2); + QFETCH(int, rsv3); + QFETCH(quint32, mask); + QFETCH(QWebSocketProtocol::OpCode, opCode); + QFETCH(bool, isFinal); + QFETCH(QByteArray, payload); + QFETCH(QWebSocketProtocol::CloseCode, expectedError); + + FrameHelper helper; + helper.setRsv1(rsv1); + helper.setRsv2(rsv2); + helper.setRsv3(rsv3); + helper.setMask(mask); + helper.setOpCode(opCode); + helper.setFinalFrame(isFinal); + helper.setPayload(payload); + + QByteArray wireRepresentation = helper.wireRepresentation(); + QBuffer buffer; + buffer.setData(wireRepresentation); + buffer.open(QIODevice::ReadOnly); + QWebSocketFrame frame = QWebSocketFrame::readFrame(&buffer); + buffer.close(); + + QVERIFY(!frame.isValid()); + QCOMPARE(frame.closeCode(), expectedError); +} + + +/* + * Incomplete or overly large frames + * Payload must be crafted manually + * + QTest::newRow("Frame Too Big") + << 0 << 0 << 0 + << 0U << QWebSocketProtocol::OpCodeText + << true << QString(MAX_FRAME_SIZE_IN_BYTES + 1, 'a').toUtf8() + << QWebSocketProtocol::CloseCodeTooMuchData; + + */ +void tst_WebSocketFrame::tst_malformedFrames_data() +{ + QTest::addColumn<QByteArray>("payload"); + QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedError"); + + //too little data + QTest::newRow("No data") << QByteArray() << QWebSocketProtocol::CloseCodeGoingAway; + FrameHelper helper; + helper.setRsv1(0); + helper.setRsv2(0); + helper.setRsv3(0); + helper.setMask(0U); + helper.setOpCode(QWebSocketProtocol::OpCodeText); + helper.setFinalFrame(true); + helper.setPayload(QString(10, 'a').toUtf8()); + QByteArray wireRep = helper.wireRepresentation(); + + //too little data + //header + payload should be 12 bytes for non-masked payloads < 126 bytes + for (int i = 1; i < 12; ++i) + { + QTest::newRow(QStringLiteral("Header too small - %1 byte(s)").arg(i).toLatin1().constData()) + << wireRep.left(i) + << QWebSocketProtocol::CloseCodeGoingAway; + } + //too much data + { + const char bigpayloadIndicator = char(127); + const quint64 payloadSize = MAX_FRAME_SIZE_IN_BYTES + 1; + uchar swapped[8] = {0}; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Frame too big") + << wireRep.left(1).append(bigpayloadIndicator) + .append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CloseCodeTooMuchData; + } + //invalid size field + { + const char bigpayloadIndicator = char(127); + quint64 payloadSize = quint64(1) << 63; + uchar swapped[8] = {0}; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Highest bit of payload length is set") + << wireRep.left(1).append(bigpayloadIndicator) + .append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CloseCodeProtocolError; + + payloadSize = 256; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Overlong 64-bit size field; should be 16-bit") + << wireRep.left(1).append(bigpayloadIndicator) + .append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CloseCodeProtocolError; + } + //overlong size field + { + const char largepayloadIndicator = char(126); + const quint16 payloadSize = 120; + uchar swapped[2] = {0}; + qToBigEndian<quint16>(payloadSize, swapped); + QTest::newRow("Overlong 16-bit size field") + << wireRep.left(1).append(largepayloadIndicator) + .append(reinterpret_cast<char *>(swapped), 2) + << QWebSocketProtocol::CloseCodeProtocolError; + } + { + const char bigpayloadIndicator = char(127); + quint64 payloadSize = 120; + uchar swapped[8] = {0}; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Overlong 64-bit size field; should be 7-bit") + << wireRep.left(1).append(bigpayloadIndicator) + .append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CloseCodeProtocolError; + + payloadSize = 256; + qToBigEndian<quint64>(payloadSize, swapped); + QTest::newRow("Overlong 64-bit size field; should be 16-bit") + << wireRep.left(1).append(bigpayloadIndicator) + .append(reinterpret_cast<char *>(swapped), 8) + << QWebSocketProtocol::CloseCodeProtocolError; + } +} + +void tst_WebSocketFrame::tst_malformedFrames() +{ + QFETCH(QByteArray, payload); + QFETCH(QWebSocketProtocol::CloseCode, expectedError); + + QBuffer buffer; + buffer.setData(payload); + buffer.open(QIODevice::ReadOnly); + QWebSocketFrame frame = QWebSocketFrame::readFrame(&buffer); + buffer.close(); + + QVERIFY(!frame.isValid()); + QCOMPARE(frame.closeCode(), expectedError); +} + +QTEST_MAIN(tst_WebSocketFrame) + +#include "tst_websocketframe.moc" + |