diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2021-07-04 23:44:01 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2021-07-06 01:17:26 +0200 |
commit | 35453446a511366e1250858b249e36c80b6ad044 (patch) | |
tree | 72c94cd17caa6f6d69d611b4f265db82375dff7a /tests/auto/corelib/tools | |
parent | 6832789bbd1a19499bffd05b1cac400db2bdd948 (diff) |
QCryptographicHash: don't present the same data over and over again
Need to decrement 'remaining' (check), but also increment data (meep).
Testing is a bit complicated, as most algorithms are just too slow to
fit into the 5min QTestLib timeout. Picked the fast ones and Sha512
(which completes here in < 17s, with threads), at least.
Amends e12577b56396cca0df05f88f8787706a3a12c82d.
[ChangeLog][QtCore][QCryptographicHash] Fixed a bug where presenting
more than 4GiB in a single addData() call would calculate the wrong
result().
Pick-to: 6.1 6.2
Change-Id: Ic72916ebc33ba087d58225af6d8240e46e41f434
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools')
-rw-r--r-- | tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp index c819f02d70..92a2c3516c 100644 --- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp @@ -29,9 +29,14 @@ #include <QtCore/QCoreApplication> #include <QTest> +#include <QScopeGuard> #include <QCryptographicHash> #include <QtCore/QMetaEnum> +#if QT_CONFIG(cxx11_future) +# include <thread> +#endif + Q_DECLARE_METATYPE(QCryptographicHash::Algorithm) class tst_QCryptographicHash : public QObject @@ -51,6 +56,11 @@ private slots: void files(); void hashLength_data(); void hashLength(); + // keep last + void moreThan4GiBOfData_data(); + void moreThan4GiBOfData(); +private: + std::vector<char> large; }; void tst_QCryptographicHash::repeated_result_data() @@ -419,5 +429,79 @@ void tst_QCryptographicHash::hashLength() QCOMPARE(QCryptographicHash::hashLength(algorithm), output.length()); } +void tst_QCryptographicHash::moreThan4GiBOfData_data() +{ +#if QT_POINTER_SIZE > 4 + QElapsedTimer timer; + timer.start(); + const size_t GiB = 1024 * 1024 * 1024; + try { + large.resize(4 * GiB + 1, '\0'); + } catch (const std::bad_alloc &) { + QSKIP("Could not allocate 4GiB plus one byte of RAM."); + } + QCOMPARE(large.size(), 4 * GiB + 1); + large.back() = '\1'; + qDebug("created dataset in %lld ms", timer.elapsed()); + + QTest::addColumn<QCryptographicHash::Algorithm>("algorithm"); + auto me = QMetaEnum::fromType<QCryptographicHash::Algorithm>(); + auto row = [me] (QCryptographicHash::Algorithm algo) { + QTest::addRow("%s", me.valueToKey(int(algo))) << algo; + }; + // these are reasonably fast (O(secs)) + row(QCryptographicHash::Md4); + row(QCryptographicHash::Md5); + row(QCryptographicHash::Sha1); + // this is already significantly slower, but important (O(min) + row(QCryptographicHash::Sha512); + // the rest is just too slow +#else + QSKIP("This test is 64-bit only."); +#endif +} + +void tst_QCryptographicHash::moreThan4GiBOfData() +{ + QFETCH(const QCryptographicHash::Algorithm, algorithm); + +# if QT_CONFIG(cxx11_future) + using MaybeThread = std::thread; +# else + struct MaybeThread { + std::function<void()> func; + void join() { func(); } + }; +# endif + + QElapsedTimer timer; + timer.start(); + const auto sg = qScopeGuard([&] { + qDebug() << algorithm << "test finished in" << timer.restart() << "ms"; + }); + + const auto begin = large.data(); + const auto mid = begin + large.size() / 2; + const auto end = begin + large.size(); + + QByteArray single; + QByteArray chunked; + + auto t = MaybeThread{[&] { + QCryptographicHash h(algorithm); + h.addData(begin, end - begin); + single = h.result(); + }}; + { + QCryptographicHash h(algorithm); + h.addData(begin, mid - begin); + h.addData(mid, end - mid); + chunked = h.result(); + } + t.join(); + + QCOMPARE(single, chunked); +} + QTEST_MAIN(tst_QCryptographicHash) #include "tst_qcryptographichash.moc" |