summaryrefslogtreecommitdiffstats
path: root/tests/manual/corelib/qdatastream/tst_manualqdatastream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/corelib/qdatastream/tst_manualqdatastream.cpp')
-rw-r--r--tests/manual/corelib/qdatastream/tst_manualqdatastream.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/tests/manual/corelib/qdatastream/tst_manualqdatastream.cpp b/tests/manual/corelib/qdatastream/tst_manualqdatastream.cpp
new file mode 100644
index 0000000000..37e5b80950
--- /dev/null
+++ b/tests/manual/corelib/qdatastream/tst_manualqdatastream.cpp
@@ -0,0 +1,234 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QDataStream>
+#include <QHash>
+#include <QList>
+#include <QMap>
+#include <QScopeGuard>
+#include <QSet>
+#include <QTest>
+
+// These tests are way too slow to be part of automatic unit tests
+class tst_QDataStream : public QObject
+{
+ Q_OBJECT
+
+ template <class T>
+ void fill(T &input);
+
+ void fill(QSet<qsizetype> &input);
+ void fill(QMap<qsizetype, qsizetype> &input);
+ void fill(QHash<qsizetype, qsizetype> &input);
+
+ template <class T>
+ void stream_big();
+
+public slots:
+ void initTestCase();
+
+private slots:
+ void stream_bigQString();
+ void stream_bigQByteArray();
+ void stream_bigQList();
+ void stream_bigQSet();
+ void stream_bigQMap();
+ void stream_bigQHash();
+ void stream_bigCString();
+};
+
+void tst_QDataStream::initTestCase()
+{
+ qputenv("QTEST_FUNCTION_TIMEOUT", "9000000");
+
+ QTest::addColumn<QDataStream::Version>("streamVersion");
+ QTest::addRow("current") << QDataStream::Qt_DefaultCompiledVersion;
+ QTest::addRow("Qt_6_6") << QDataStream::Qt_6_6;
+}
+
+template <class T>
+void tst_QDataStream::fill(T &input)
+{
+ constexpr qsizetype GiB = 1024 * 1024 * 1024;
+ constexpr qsizetype BaseSize = 4 * GiB + 1;
+ qDebug("Filling container with %lld entries", qint64(BaseSize));
+ QElapsedTimer timer;
+ timer.start();
+ try {
+ input.reserve(BaseSize);
+ input.resize(BaseSize, 'a');
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4 GiB of RAM.");
+ }
+ qDebug("Created dataset in %lld ms", timer.elapsed());
+}
+
+void tst_QDataStream::fill(QSet<qsizetype> &input)
+{
+ constexpr qsizetype GiB = 1024 * 1024 * 1024;
+ constexpr qsizetype BaseSize = 4 * GiB + 1;
+ qDebug("Filling container with %lld entries", qint64(BaseSize));
+ QElapsedTimer timer;
+ timer.start();
+ try {
+ input.reserve(BaseSize);
+ for (qsizetype i = 0; i < BaseSize; ++i)
+ input.insert(i);
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4 Gi entries.");
+ }
+ qDebug("Created dataset in %lld ms", timer.elapsed());
+}
+
+void tst_QDataStream::fill(QMap<qsizetype, qsizetype> &input)
+{
+ constexpr qsizetype GiB = 1024 * 1024 * 1024;
+ constexpr qsizetype BaseSize = 4 * GiB + 1;
+ qDebug("Filling container with %lld entries", qint64(BaseSize));
+ QElapsedTimer timer;
+ timer.start();
+ try {
+ for (qsizetype i = 0; i < BaseSize; ++i)
+ input.insert(i, i);
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4 Gi entries.");
+ }
+ qDebug("Created dataset in %lld ms", timer.elapsed());
+}
+
+void tst_QDataStream::fill(QHash<qsizetype, qsizetype> &input)
+{
+ constexpr qsizetype GiB = 1024 * 1024 * 1024;
+ constexpr qsizetype BaseSize = 4 * GiB + 1;
+ qDebug("Filling container with %lld entries", qint64(BaseSize));
+ QElapsedTimer timer;
+ timer.start();
+ try {
+ input.reserve(BaseSize);
+ for (qsizetype i = 0; i < BaseSize; ++i)
+ input.emplace(i, i);
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4 Gi entries.");
+ }
+ qDebug("Created dataset in %lld ms", timer.elapsed());
+}
+
+template <class T>
+void tst_QDataStream::stream_big()
+{
+#if QT_POINTER_SIZE > 4
+ QFETCH_GLOBAL(const QDataStream::Version, streamVersion);
+ QElapsedTimer timer;
+ T input;
+ fill(input);
+ QByteArray ba;
+ QDataStream inputstream(&ba, QIODevice::WriteOnly);
+ inputstream.setVersion(streamVersion);
+ timer.start();
+ try {
+ inputstream << input;
+ } catch (const std::bad_alloc &) {
+ QSKIP("Not enough memory to copy into QDataStream.");
+ }
+ qDebug("Streamed into QDataStream in %lld ms", timer.elapsed());
+ if (streamVersion < QDataStream::Qt_6_7) {
+ // old versions do not support data size more than 4 GiB
+ QCOMPARE(inputstream.status(), QDataStream::SizeLimitExceeded);
+ QVERIFY(ba.isEmpty());
+ } else {
+ T output;
+ QDataStream outputstream(ba);
+ timer.start();
+ try {
+ outputstream >> output;
+ } catch (const std::bad_alloc &) {
+ QSKIP("Not enough memory to copy out of QDataStream.");
+ }
+ qDebug("Streamed out of QDataStream in %lld ms", timer.elapsed());
+ QCOMPARE(input.size(), output.size());
+ QCOMPARE(input, output);
+ }
+#else
+ QSKIP("This test is 64-bit only.");
+#endif
+}
+
+void tst_QDataStream::stream_bigQString()
+{
+ stream_big<QString>();
+}
+
+void tst_QDataStream::stream_bigQByteArray()
+{
+ stream_big<QByteArray>();
+}
+void tst_QDataStream::stream_bigQList()
+{
+ stream_big<QList<char>>();
+}
+
+void tst_QDataStream::stream_bigQSet()
+{
+ stream_big<QSet<qsizetype>>();
+}
+
+void tst_QDataStream::stream_bigQMap()
+{
+ stream_big<QMap<qsizetype, qsizetype>>();
+}
+void tst_QDataStream::stream_bigQHash()
+{
+ stream_big<QHash<qsizetype, qsizetype>>();
+}
+
+void tst_QDataStream::stream_bigCString()
+{
+ if constexpr (sizeof(void*) == sizeof(int))
+ QSKIP("This test is 64-bit only.");
+
+ QFETCH_GLOBAL(const QDataStream::Version, streamVersion);
+ constexpr qint64 GiB = 1024 * 1024 * 1024;
+ constexpr qint64 BaseSize = 4 * GiB + 1;
+ std::string input;
+ qDebug("Creating an array with %lld entries", BaseSize);
+ QElapsedTimer timer;
+ timer.start();
+ try {
+ input.resize(BaseSize, 'a');
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4 Gi + 2 entries.");
+ }
+ qDebug("Created dataset in %lld ms", timer.elapsed());
+ QByteArray ba;
+ QDataStream inputstream(&ba, QIODevice::WriteOnly);
+ inputstream.setVersion(streamVersion);
+ timer.start();
+ try {
+ inputstream << input.data();
+ } catch (const std::bad_alloc &) {
+ QSKIP("Not enough memory to copy into QDataStream.");
+ }
+ qDebug("Streamed into QDataStream in %lld ms", timer.elapsed());
+ if (streamVersion < QDataStream::Qt_6_7) {
+ // old versions do not support data size more than 4 GiB
+ QCOMPARE(inputstream.status(), QDataStream::SizeLimitExceeded);
+ QVERIFY(ba.isEmpty());
+ } else {
+ char *output = nullptr;
+ auto cleanup = qScopeGuard([&output] { delete [] output; });
+ QDataStream outputstream(ba);
+ timer.start();
+ try {
+ outputstream >> output;
+ } catch (const std::bad_alloc &) {
+ QSKIP("Not enough memory to copy out of QDataStream.");
+ }
+ qDebug("Streamed out of QDataStream in %lld ms", timer.elapsed());
+ QCOMPARE(qstrlen(output), input.size());
+ QVERIFY(memcmp(input.data(), output, BaseSize + 1) == 0);
+ }
+}
+
+QTEST_MAIN(tst_QDataStream)
+
+#include "tst_manualqdatastream.moc"