Skip to content

Commit

Permalink
test: Make bloom tests deterministic
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoFalke authored and Fuzzbawls committed Apr 14, 2021
1 parent 7b33223 commit c82e359
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 11 deletions.
4 changes: 3 additions & 1 deletion src/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,9 +660,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 RandAddSeedSleep() { 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
Expand Down
18 changes: 8 additions & 10 deletions src/test/bloom_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ static std::vector<unsigned char> RandomData()

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);

Expand All @@ -487,12 +490,8 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
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();
Expand All @@ -516,10 +515,8 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
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);
Expand All @@ -530,6 +527,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
for (int i = 0; i < DATASIZE; i++) {
BOOST_CHECK(rb2.contains(data[i]));
}
g_mock_deterministic_tests = false;
}

BOOST_AUTO_TEST_SUITE_END()
10 changes: 10 additions & 0 deletions src/test/random_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ BOOST_AUTO_TEST_CASE(osrandom_tests)
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<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.rand64(), ctx2.rand64());
Expand All @@ -38,6 +43,11 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests)
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<uint64_t>::max()) != uint64_t{10393729187455219830U});
BOOST_CHECK(GetRandInt(std::numeric_limits<int>::max()) != int{769702006});
}
{
FastRandomContext ctx3, ctx4;
BOOST_CHECK(ctx3.rand64() != ctx4.rand64()); // extremely unlikely to be equal
Expand Down
5 changes: 5 additions & 0 deletions src/test/test_pivx.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

extern FastRandomContext 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)
{
insecure_rand_ctx = FastRandomContext(deterministic);
Expand Down

0 comments on commit c82e359

Please sign in to comment.