test: Make bloom tests deterministic

This commit is contained in:
MarcoFalke 2019-02-01 17:06:32 -05:00
parent 3e38d40873
commit fae169c95e
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
4 changed files with 26 additions and 11 deletions

View file

@ -514,9 +514,11 @@ void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNG
void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); } void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
void RandAddSeedSleep() { ProcRand(nullptr, 0, RNGLevel::SLEEP); } void RandAddSeedSleep() { ProcRand(nullptr, 0, RNGLevel::SLEEP); }
bool g_mock_deterministic_tests{false};
uint64_t GetRand(uint64_t nMax) noexcept uint64_t GetRand(uint64_t nMax) noexcept
{ {
return FastRandomContext().randrange(nMax); return FastRandomContext(g_mock_deterministic_tests).randrange(nMax);
} }
int GetRandInt(int nMax) noexcept int GetRandInt(int nMax) noexcept

View file

@ -461,6 +461,9 @@ static std::vector<unsigned char> RandomData()
BOOST_AUTO_TEST_CASE(rolling_bloom) BOOST_AUTO_TEST_CASE(rolling_bloom)
{ {
SeedInsecureRand(/* deterministic */ true);
g_mock_deterministic_tests = true;
// last-100-entry, 1% false positive: // last-100-entry, 1% false positive:
CRollingBloomFilter rb1(100, 0.01); CRollingBloomFilter rb1(100, 0.01);
@ -485,12 +488,8 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
if (rb1.contains(RandomData())) if (rb1.contains(RandomData()))
++nHits; ++nHits;
} }
// Run test_bitcoin with --log_level=message to see BOOST_TEST_MESSAGEs: // Expect about 100 hits
BOOST_TEST_MESSAGE("RollingBloomFilter got " << nHits << " false positives (~100 expected)"); BOOST_CHECK_EQUAL(nHits, 75);
// Insanely unlikely to get a fp count outside this range:
BOOST_CHECK(nHits > 25);
BOOST_CHECK(nHits < 175);
BOOST_CHECK(rb1.contains(data[DATASIZE-1])); BOOST_CHECK(rb1.contains(data[DATASIZE-1]));
rb1.reset(); rb1.reset();
@ -517,10 +516,8 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
if (rb1.contains(data[i])) if (rb1.contains(data[i]))
++nHits; ++nHits;
} }
// Expect about 5 false positives, more than 100 means // Expect about 5 false positives
// something is definitely broken. BOOST_CHECK_EQUAL(nHits, 6);
BOOST_TEST_MESSAGE("RollingBloomFilter got " << nHits << " false positives (~5 expected)");
BOOST_CHECK(nHits < 100);
// last-1000-entry, 0.01% false positive: // last-1000-entry, 0.01% false positive:
CRollingBloomFilter rb2(1000, 0.001); CRollingBloomFilter rb2(1000, 0.001);
@ -531,6 +528,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
for (int i = 0; i < DATASIZE; i++) { for (int i = 0; i < DATASIZE; i++) {
BOOST_CHECK(rb2.contains(data[i])); BOOST_CHECK(rb2.contains(data[i]));
} }
g_mock_deterministic_tests = false;
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -21,9 +21,14 @@ BOOST_AUTO_TEST_CASE(osrandom_tests)
BOOST_AUTO_TEST_CASE(fastrandom_tests) BOOST_AUTO_TEST_CASE(fastrandom_tests)
{ {
// Check that deterministic FastRandomContexts are deterministic // Check that deterministic FastRandomContexts are deterministic
g_mock_deterministic_tests = true;
FastRandomContext ctx1(true); FastRandomContext ctx1(true);
FastRandomContext ctx2(true); FastRandomContext ctx2(true);
for (int i = 10; i > 0; --i) {
BOOST_CHECK_EQUAL(GetRand(std::numeric_limits<uint64_t>::max()), uint64_t{10393729187455219830U});
BOOST_CHECK_EQUAL(GetRandInt(std::numeric_limits<int>::max()), int{769702006});
}
BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32()); BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32());
BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32()); BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32());
BOOST_CHECK_EQUAL(ctx1.rand64(), ctx2.rand64()); BOOST_CHECK_EQUAL(ctx1.rand64(), ctx2.rand64());
@ -38,6 +43,11 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests)
BOOST_CHECK(ctx1.randbytes(50) == ctx2.randbytes(50)); BOOST_CHECK(ctx1.randbytes(50) == ctx2.randbytes(50));
// Check that a nondeterministic ones are not // Check that a nondeterministic ones are not
g_mock_deterministic_tests = false;
for (int i = 10; i > 0; --i) {
BOOST_CHECK(GetRand(std::numeric_limits<uint64_t>::max()) != uint64_t{10393729187455219830U});
BOOST_CHECK(GetRandInt(std::numeric_limits<int>::max()) != int{769702006});
}
{ {
FastRandomContext ctx3, ctx4; FastRandomContext ctx3, ctx4;
BOOST_CHECK(ctx3.rand64() != ctx4.rand64()); // extremely unlikely to be equal BOOST_CHECK(ctx3.rand64() != ctx4.rand64()); // extremely unlikely to be equal

View file

@ -35,6 +35,11 @@ std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::os
*/ */
extern FastRandomContext g_insecure_rand_ctx; extern FastRandomContext g_insecure_rand_ctx;
/**
* Flag to make GetRand in random.h return the same number
*/
extern bool g_mock_deterministic_tests;
static inline void SeedInsecureRand(bool deterministic = false) static inline void SeedInsecureRand(bool deterministic = false)
{ {
g_insecure_rand_ctx = FastRandomContext(deterministic); g_insecure_rand_ctx = FastRandomContext(deterministic);