From 26267ef57eedd0ee9dc4bfa13200fdae22777084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 14 Dec 2021 12:07:36 +0100 Subject: [PATCH] tst_QHash: Update the erase_edge_case test By using the bucketForHash function we can loop through and find some appropriate keys to test the edge-case. This will then automatically keep the test working even if some internals of QHash changes. We do this because certain changes which change the bucket the pre-selected keys would end up in could make the test a no-op, without warning. And recent and upcoming changes have changed both this and erase(). We limit the search-space to the minimum numBuckets * 4, where minimum numBuckets is current 128. Change-Id: I13b0bce15ee884144e3248846be34667fb5d35cc Reviewed-by: Marc Mutz --- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 32 ++++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 50c2b0d84e..bab22c454a 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -577,14 +577,40 @@ void tst_QHash::erase() */ void tst_QHash::erase_edge_case() { + QHashSeed::setDeterministicGlobalSeed(); + auto resetSeed = qScopeGuard([&]() { + QHashSeed::resetRandomGlobalSeed(); + }); + QHash h1; h1.reserve(2); - h1.d->seed = 10230148258692185509ull; - h1.insert(3, 4); - h1.insert(5, 6); + qsizetype capacity = h1.capacity(); + // Beholden to QHash internals: + qsizetype numBuckets = capacity << 1; + + // Find some keys which will both be slotted into the last bucket: + int keys[2]; + int index = 0; + for (qsizetype i = 0; i < numBuckets * 4 && index < 2; ++i) { + const size_t hash = qHash(i, QHashSeed::globalSeed()); + const size_t bucketForHash = QHashPrivate::GrowthPolicy::bucketForHash(numBuckets, hash); + if (bucketForHash == numBuckets - 1) + keys[index++] = i; + } + QCOMPARE(index, 2); // Sanity check. If this fails then the test needs an update! + + // As mentioned earlier these are both calculated to be in the last bucket: + h1.insert(keys[0], 4); + h1.insert(keys[1], 6); + // As a sanity-check, make sure that the key we inserted last is the first one (because its + // allocation to the last bucket would make it wrap around): + // NOTE: If this fails this then this test may need an update!!! + QCOMPARE(h1.constBegin().key(), keys[1]); + // Then we delete the last entry: QHash::iterator it1 = h1.begin(); ++it1; it1 = h1.erase(it1); + // Now, since we deleted the last entry, the iterator should be at the end(): QVERIFY(it1 == h1.end()); }