diff options
author | Justin Bassett <jbassett@google.com> | 2024-05-20 10:44:01 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-05-20 10:45:19 -0700 |
commit | 254b3a5326932026fd23923fd367619d2837f0ad (patch) | |
tree | ae7b15f8c6462ed407c89ef5144fdbf5a5a91e2b /absl/random/mocking_bit_gen_test.cc | |
parent | 93ac3a4f9ee7792af399cebd873ee99ce15aed08 (diff) | |
download | abseil-254b3a5326932026fd23923fd367619d2837f0ad.tar.gz abseil-254b3a5326932026fd23923fd367619d2837f0ad.tar.bz2 abseil-254b3a5326932026fd23923fd367619d2837f0ad.zip |
Add (unused) validation to absl::MockingBitGen
`absl::Uniform(tag, rng, a, b)` has some restrictions on the values it can produce in that it will always be in the range specified by `a` and `b`, but these restrictions can be violated by `absl::MockingBitGen`. This makes it easier than necessary to introduce a bug in tests using a mock RNG.
We can fix this by making `MockingBitGen` emit a runtime error if the value produced is out of bounds.
Immediately fixing all the internal buggy uses of `MockingBitGen` is currently infeasible, so the plan is this:
1. Add turned-off validation to `MockingBitGen` to avoid the costs of maintaining unsubmitted code.
2. Temporarily migrate the internal buggy use cases to keep the current behavior, to be fixed later.
3. Turn on validation for `MockingBitGen`.
4. Fix the internal buggy use cases over time.
---
A few of the different categories of errors I found:
- `Call(tag, rng, a, b) -> a or b`, for open/half-open intervals (i.e. incorrect boundary condition). This case happens quite a lot, e.g. by specifying `absl::Uniform<double>(rng, 0, 1)` to return `1.0`.
- `Call(tag, rng, 0, 1) -> 42` (i.e. return an arbitrary value). These may be straightforward to fix by just returning an in-range value, or sometimes they are difficult to fix because other data structures depend on those values.
PiperOrigin-RevId: 635503223
Change-Id: I9293ab78e79450e2b7b682dcb05149f238ecc550
Diffstat (limited to 'absl/random/mocking_bit_gen_test.cc')
-rw-r--r-- | absl/random/mocking_bit_gen_test.cc | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/absl/random/mocking_bit_gen_test.cc b/absl/random/mocking_bit_gen_test.cc index 9ccdf568..26e673ac 100644 --- a/absl/random/mocking_bit_gen_test.cc +++ b/absl/random/mocking_bit_gen_test.cc @@ -16,9 +16,11 @@ #include "absl/random/mocking_bit_gen.h" #include <cmath> +#include <cstddef> #include <cstdint> +#include <iterator> #include <numeric> -#include <random> +#include <vector> #include "gmock/gmock.h" #include "gtest/gtest-spi.h" @@ -246,33 +248,33 @@ TEST(WillOnce, DistinctCounters) { absl::MockingBitGen gen; EXPECT_CALL(absl::MockUniform<int>(), Call(gen, 1, 1000000)) .Times(3) - .WillRepeatedly(Return(0)); + .WillRepeatedly(Return(1)); EXPECT_CALL(absl::MockUniform<int>(), Call(gen, 1000001, 2000000)) .Times(3) - .WillRepeatedly(Return(1)); - EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1); - EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 0); - EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1); - EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 0); - EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1); - EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 0); + .WillRepeatedly(Return(1000001)); + EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1000001); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 1); + EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1000001); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 1); + EXPECT_EQ(absl::Uniform(gen, 1000001, 2000000), 1000001); + EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 1); } TEST(TimesModifier, ModifierSaturatesAndExpires) { EXPECT_NONFATAL_FAILURE( []() { absl::MockingBitGen gen; - EXPECT_CALL(absl::MockUniform<int>(), Call(gen, 1, 1000000)) + EXPECT_CALL(absl::MockUniform<int>(), Call(gen, 0, 1000000)) .Times(3) .WillRepeatedly(Return(15)) .RetiresOnSaturation(); - EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 15); - EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 15); - EXPECT_EQ(absl::Uniform(gen, 1, 1000000), 15); + EXPECT_EQ(absl::Uniform(gen, 0, 1000000), 15); + EXPECT_EQ(absl::Uniform(gen, 0, 1000000), 15); + EXPECT_EQ(absl::Uniform(gen, 0, 1000000), 15); // Times(3) has expired - Should get a different value now. - EXPECT_NE(absl::Uniform(gen, 1, 1000000), 15); + EXPECT_NE(absl::Uniform(gen, 0, 1000000), 15); }(), ""); } @@ -394,7 +396,7 @@ TEST(MockingBitGen, StrictMock_TooMany) { EXPECT_EQ(absl::Uniform(gen, 1, 1000), 145); EXPECT_NONFATAL_FAILURE( - [&]() { EXPECT_EQ(absl::Uniform(gen, 10, 1000), 0); }(), + [&]() { EXPECT_EQ(absl::Uniform(gen, 0, 1000), 0); }(), "over-saturated and active"); } |