From bf2d461cf691c1d15f96b45546ac0d5176156fe4 Mon Sep 17 00:00:00 2001 From: Hai Shang Date: Fri, 30 Sep 2022 10:07:51 -0700 Subject: [PATCH] Add unit tests for prng to verify it's not generating duplicating values PiperOrigin-RevId: 478020355 --- internal/platform/prng_test.cc | 61 ++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/internal/platform/prng_test.cc b/internal/platform/prng_test.cc index 0f4e663e..e6287aa4 100644 --- a/internal/platform/prng_test.cc +++ b/internal/platform/prng_test.cc @@ -14,6 +14,11 @@ #include "internal/platform/prng.h" +#include +#include +#include // NOLINT(build/c++11) +#include + #include "gtest/gtest.h" namespace location { @@ -32,18 +37,74 @@ TEST(PrngTest, NextInt32) { EXPECT_GE(i, std::numeric_limits::min()); } +TEST(PrngTest, NextInt32GeneratesDifferentValues) { + Prng prng; + std::set values; + for (int i = 0; i < 100; ++i) { + auto value = prng.NextInt32(); + EXPECT_LE(value, std::numeric_limits::max()); + EXPECT_GE(value, std::numeric_limits::min()); + EXPECT_EQ(values.find(value), values.end()); + values.insert(value); + } +} + +TEST(PrngTest, NextInt32AcrossThreads) { + Prng prng; + std::set values; + auto func = [&prng, &values]() { + auto value = prng.NextInt32(); + EXPECT_LE(value, std::numeric_limits::max()); + EXPECT_GE(value, std::numeric_limits::min()); + EXPECT_EQ(values.find(value), values.end()); + values.insert(value); + }; + std::vector threads; + for (int i = 0; i < 10; ++i) { + threads.push_back(std::thread(func)); + } + for (auto &thread : threads) { + thread.join(); + } + EXPECT_EQ(values.size(), 10); +} + TEST(PrngTest, NextUInt32) { std::uint32_t i = Prng().NextUint32(); EXPECT_LE(i, std::numeric_limits::max()); EXPECT_GE(i, std::numeric_limits::min()); } +TEST(PrngTest, NextUint32GeneratesDifferentValues) { + Prng prng; + std::set values; + for (int i = 0; i < 100; ++i) { + auto value = prng.NextUint32(); + EXPECT_LE(value, std::numeric_limits::max()); + EXPECT_GE(value, std::numeric_limits::min()); + EXPECT_EQ(values.find(value), values.end()); + values.insert(value); + } +} + TEST(PrngTest, NextInt64) { std::int64_t i = Prng().NextInt64(); EXPECT_LE(i, std::numeric_limits::max()); EXPECT_GE(i, std::numeric_limits::min()); } +TEST(PrngTest, NextInt64GeneratesDifferentValues) { + Prng prng; + std::set values; + for (int i = 0; i < 100; ++i) { + auto value = prng.NextInt64(); + EXPECT_LE(i, std::numeric_limits::max()); + EXPECT_GE(i, std::numeric_limits::min()); + EXPECT_EQ(values.find(value), values.end()); + values.insert(value); + } +} + void ValidateRandom(TestMode mode) { int count_all_zeros = 0; int count_all_ones = 0;