diff --git a/src/random.cpp b/src/random.cpp --- a/src/random.cpp +++ b/src/random.cpp @@ -11,6 +11,7 @@ #endif #include #include // for LogPrint() +#include #include #include // for WAIT_LOCK #include // for GetTime() @@ -25,8 +26,6 @@ #include #include -#include - #ifndef WIN32 #include #include @@ -542,8 +541,10 @@ ProcRand(nullptr, 0, RNGLevel::SLEEP); } +bool g_mock_deterministic_tests{false}; + uint64_t GetRand(uint64_t nMax) noexcept { - return FastRandomContext().randrange(nMax); + return FastRandomContext(g_mock_deterministic_tests).randrange(nMax); } int GetRandInt(int nMax) noexcept { diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1195,6 +1195,9 @@ } BOOST_AUTO_TEST_CASE(rolling_bloom) { + SeedInsecureRand(/* deterministic */ true); + g_mock_deterministic_tests = true; + // last-100-entry, 1% false positive: CRollingBloomFilter rb1(100, 0.01); @@ -1218,13 +1221,8 @@ for (int i = 0; i < 10000; i++) { if (rb1.contains(RandomData())) ++nHits; } - // Run test_bitcoin with --log_level=message to see BOOST_TEST_MESSAGEs: - BOOST_TEST_MESSAGE("RollingBloomFilter got " - << nHits << " false positives (~100 expected)"); - - // Insanely unlikely to get a fp count outside this range: - BOOST_CHECK(nHits > 25); - BOOST_CHECK(nHits < 175); + // Expect about 100 hits + BOOST_CHECK_EQUAL(nHits, 75); BOOST_CHECK(rb1.contains(data[DATASIZE - 1])); rb1.reset(); @@ -1249,11 +1247,8 @@ for (int i = 0; i < DATASIZE; i++) { if (rb1.contains(data[i])) ++nHits; } - // Expect about 5 false positives, more than 100 means - // something is definitely broken. - BOOST_TEST_MESSAGE("RollingBloomFilter got " - << nHits << " false positives (~5 expected)"); - BOOST_CHECK(nHits < 100); + // Expect about 5 false positives + BOOST_CHECK_EQUAL(nHits, 6); // last-1000-entry, 0.01% false positive: CRollingBloomFilter rb2(1000, 0.001); @@ -1264,6 +1259,7 @@ for (int i = 0; i < DATASIZE; i++) { BOOST_CHECK(rb2.contains(data[i])); } + g_mock_deterministic_tests = false; } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp --- a/src/test/random_tests.cpp +++ b/src/test/random_tests.cpp @@ -19,9 +19,16 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests) { // Check that deterministic FastRandomContexts are deterministic + g_mock_deterministic_tests = true; FastRandomContext ctx1(true); FastRandomContext ctx2(true); + for (int i = 10; i > 0; --i) { + BOOST_CHECK_EQUAL(GetRand(std::numeric_limits::max()), + uint64_t{10393729187455219830U}); + BOOST_CHECK_EQUAL(GetRandInt(std::numeric_limits::max()), + int{769702006}); + } BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32()); BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32()); BOOST_CHECK_EQUAL(ctx1.rand64(), ctx2.rand64()); @@ -36,6 +43,13 @@ BOOST_CHECK(ctx1.randbytes(50) == ctx2.randbytes(50)); // 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::max()) != + uint64_t{10393729187455219830U}); + BOOST_CHECK(GetRandInt(std::numeric_limits::max()) != + int{769702006}); + } { FastRandomContext ctx3, ctx4; // extremely unlikely to be equal diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -31,6 +31,11 @@ */ 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) { g_insecure_rand_ctx = FastRandomContext(deterministic); }