mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-05 00:35:27 +08:00
qt 6.5.1 original
This commit is contained in:
17
tests/auto/corelib/tools/qhashseed/CMakeLists.txt
Normal file
17
tests/auto/corelib/tools/qhashseed/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qhashseed Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qhashseed
|
||||
SOURCES
|
||||
tst_qhashseed.cpp
|
||||
)
|
||||
|
||||
qt_internal_add_executable(tst_qhashseed_helper
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
SOURCES
|
||||
tst_qhashseed_helper.cpp
|
||||
)
|
186
tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp
Normal file
186
tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
// Copyright (C) 2021 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <qhashfunctions.h>
|
||||
#if QT_CONFIG(process)
|
||||
#include <qprocess.h>
|
||||
#endif
|
||||
|
||||
class tst_QHashSeed : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static void initMain();
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void environmentVariable_data();
|
||||
void environmentVariable();
|
||||
void deterministicSeed();
|
||||
void reseeding();
|
||||
void quality();
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
||||
void compatibilityApi();
|
||||
void deterministicSeed_compat();
|
||||
#endif
|
||||
};
|
||||
|
||||
void tst_QHashSeed::initMain()
|
||||
{
|
||||
qunsetenv("QT_HASH_SEED");
|
||||
}
|
||||
|
||||
void tst_QHashSeed::initTestCase()
|
||||
{
|
||||
// in case the qunsetenv above didn't work
|
||||
if (qEnvironmentVariableIsSet("QT_HASH_SEED"))
|
||||
QSKIP("QT_HASH_SEED environment variable is set, please don't do that");
|
||||
}
|
||||
|
||||
void tst_QHashSeed::environmentVariable_data()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
QSKIP("This test needs a helper binary, so is excluded from this platform.");
|
||||
#endif
|
||||
|
||||
QTest::addColumn<QByteArray>("envVar");
|
||||
QTest::addColumn<bool>("isZero");
|
||||
QTest::newRow("unset-environment") << QByteArray() << false;
|
||||
QTest::newRow("empty-environment") << QByteArray("") << false;
|
||||
QTest::newRow("zero-seed") << QByteArray("0") << true;
|
||||
}
|
||||
|
||||
void tst_QHashSeed::environmentVariable()
|
||||
{
|
||||
#if QT_CONFIG(process)
|
||||
QFETCH(QByteArray, envVar);
|
||||
QFETCH(bool, isZero);
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
if (envVar.isNull())
|
||||
env.remove("QT_HASH_SEED");
|
||||
else
|
||||
env.insert("QT_HASH_SEED", envVar);
|
||||
|
||||
QProcess helper;
|
||||
helper.setProcessEnvironment(env);
|
||||
helper.setProgram("./tst_qhashseed_helper");
|
||||
helper.start();
|
||||
QVERIFY2(helper.waitForStarted(5000), qPrintable(helper.errorString()));
|
||||
QVERIFY2(helper.waitForFinished(5000), qPrintable(helper.errorString()));
|
||||
QCOMPARE(helper.exitStatus(), 0);
|
||||
|
||||
QByteArray line1 = helper.readLine().trimmed();
|
||||
QByteArray line2 = helper.readLine().trimmed();
|
||||
QCOMPARE(line2, line1);
|
||||
QCOMPARE(line1 == "0", isZero);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QHashSeed::deterministicSeed()
|
||||
{
|
||||
QHashSeed::setDeterministicGlobalSeed();
|
||||
QCOMPARE(size_t(QHashSeed::globalSeed()), size_t(0));
|
||||
|
||||
// now reset
|
||||
QHashSeed::resetRandomGlobalSeed();
|
||||
QVERIFY(QHashSeed::globalSeed() != 0);
|
||||
}
|
||||
|
||||
void tst_QHashSeed::reseeding()
|
||||
{
|
||||
constexpr int Iterations = 4;
|
||||
size_t seeds[Iterations];
|
||||
for (int i = 0; i < Iterations; ++i) {
|
||||
seeds[i] = QHashSeed::globalSeed();
|
||||
QHashSeed::resetRandomGlobalSeed();
|
||||
}
|
||||
|
||||
// verify that they are all different
|
||||
QString fmt = QStringLiteral("seeds[%1] = 0x%3, seeds[%2] = 0x%4");
|
||||
for (int i = 0; i < Iterations; ++i) {
|
||||
for (int j = i + 1; j < Iterations; ++j) {
|
||||
QVERIFY2(seeds[i] != seeds[j],
|
||||
qPrintable(fmt.arg(i).arg(j).arg(seeds[i], 16).arg(seeds[j], 16)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHashSeed::quality()
|
||||
{
|
||||
// this "bad seed" is used internally in qhash.cpp and should never leak!
|
||||
constexpr size_t BadSeed = size_t(Q_UINT64_C(0x5555'5555'5555'5555));
|
||||
|
||||
constexpr int Iterations = 24; // nicely divisible by 3
|
||||
int oneThird = 0;
|
||||
int badSeeds = 0;
|
||||
int seedsToMinus1 = 0;
|
||||
size_t ored = 0;
|
||||
|
||||
for (int i = 0; i < Iterations; ++i) {
|
||||
size_t seed = QHashSeed::globalSeed();
|
||||
ored |= seed;
|
||||
int bits = qPopulationCount(quintptr(seed));
|
||||
QVERIFY2(bits > 0, QByteArray::number(bits)); // mandatory
|
||||
|
||||
if (bits >= std::numeric_limits<size_t>::digits / 3)
|
||||
++oneThird;
|
||||
if (seed == BadSeed)
|
||||
++badSeeds;
|
||||
if (ored != size_t(-1))
|
||||
++seedsToMinus1;
|
||||
|
||||
QHashSeed::resetRandomGlobalSeed();
|
||||
}
|
||||
|
||||
// report out
|
||||
qInfo() << "Number of seeds until all bits became set:" << seedsToMinus1 << '/' << Iterations;
|
||||
qInfo() << "Number of seeds with at least one third of the bits set:"
|
||||
<< oneThird << '/' << Iterations;
|
||||
|
||||
// we must have set all bits after all the iterations
|
||||
QCOMPARE(ored, size_t(-1));
|
||||
|
||||
// at least one third of the seeds must have one third of all the bits set
|
||||
QVERIFY(oneThird > (Iterations/3));
|
||||
|
||||
// at most one seed can be the bad seed, if 32-bit, none on 64-bit
|
||||
if (std::numeric_limits<size_t>::digits > 32)
|
||||
QCOMPARE(badSeeds, 0);
|
||||
else
|
||||
QVERIFY2(badSeeds <= 1, "badSeeds = " + QByteArray::number(badSeeds));
|
||||
|
||||
// we must have taken at most two thirds of the iterations to have set each
|
||||
// bit at least once
|
||||
QVERIFY2(seedsToMinus1 < 2*Iterations/3,
|
||||
"seedsToMinus1 = " + QByteArray::number(seedsToMinus1));
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
void tst_QHashSeed::compatibilityApi()
|
||||
{
|
||||
int oldSeed = qGlobalQHashSeed();
|
||||
size_t newSeed = QHashSeed::globalSeed();
|
||||
|
||||
QCOMPARE(size_t(oldSeed), newSeed & size_t(INT_MAX));
|
||||
}
|
||||
|
||||
void tst_QHashSeed::deterministicSeed_compat()
|
||||
{
|
||||
// same as above, but using the compat API
|
||||
qSetGlobalQHashSeed(0);
|
||||
QCOMPARE(size_t(QHashSeed::globalSeed()), size_t(0));
|
||||
QCOMPARE(qGlobalQHashSeed(), 0);
|
||||
|
||||
// now reset
|
||||
qSetGlobalQHashSeed(-1);
|
||||
QVERIFY(QHashSeed::globalSeed() != 0);
|
||||
QVERIFY(qGlobalQHashSeed() != 0);
|
||||
QVERIFY(qGlobalQHashSeed() != -1); // possible, but extremely unlikely
|
||||
}
|
||||
#endif // Qt 7
|
||||
|
||||
QTEST_MAIN(tst_QHashSeed)
|
||||
#include "tst_qhashseed.moc"
|
14
tests/auto/corelib/tools/qhashseed/tst_qhashseed_helper.cpp
Normal file
14
tests/auto/corelib/tools/qhashseed/tst_qhashseed_helper.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2021 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <qhashfunctions.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
// appless:
|
||||
QHashSeed seed1 = QHashSeed::globalSeed();
|
||||
QHashSeed seed2 = QHashSeed::globalSeed();
|
||||
printf("%zu\n%zu\n", size_t(seed1), size_t(seed2));
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user