blob: c1c2098cf1748d6b074c347cf02cdea8f5aaa6f3 [file] [log] [blame]
Austin Engcc2516a2023-10-17 20:57:54 +00001// Copyright 2021 The Dawn & Tint Authors
Ryan Harrisondbc13af2022-02-21 15:19:07 +00002//
Austin Engcc2516a2023-10-17 20:57:54 +00003// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions are met:
Ryan Harrisondbc13af2022-02-21 15:19:07 +00005//
Austin Engcc2516a2023-10-17 20:57:54 +00006// 1. Redistributions of source code must retain the above copyright notice, this
7// list of conditions and the following disclaimer.
Ryan Harrisondbc13af2022-02-21 15:19:07 +00008//
Austin Engcc2516a2023-10-17 20:57:54 +00009// 2. Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12//
13// 3. Neither the name of the copyright holder nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Ryan Harrisondbc13af2022-02-21 15:19:07 +000027
28#include "src/tint/fuzzers/random_generator.h"
29
30#include <memory>
31
32#include "gtest/gtest.h"
33
34#include "src/tint/fuzzers/mersenne_twister_engine.h"
35
dan sinclair62a1d712022-04-07 17:46:04 +000036namespace tint::fuzzers {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000037namespace {
38
39/// Implementation of RandomGeneratorEngine that just returns a stream of
40/// monotonically increasing numbers.
41class MonotonicEngine : public RandomGeneratorEngine {
dan sinclair41e4d9a2022-05-01 14:40:55 +000042 public:
43 uint32_t RandomUInt32(uint32_t, uint32_t) override { return next_++; }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000044
dan sinclair41e4d9a2022-05-01 14:40:55 +000045 uint64_t RandomUInt64(uint64_t, uint64_t) override { return next_++; }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000046
dan sinclair41e4d9a2022-05-01 14:40:55 +000047 void RandomNBytes(uint8_t*, size_t) override {
48 assert(false && "MonotonicDelegate does not implement RandomNBytes");
49 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000050
dan sinclair41e4d9a2022-05-01 14:40:55 +000051 private:
52 uint32_t next_ = 0;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000053};
54
55class RandomGeneratorTest : public testing::Test {
dan sinclair41e4d9a2022-05-01 14:40:55 +000056 public:
57 void SetUp() override { rng_ = std::make_unique<RandomGenerator>(0); }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000058
dan sinclair41e4d9a2022-05-01 14:40:55 +000059 void TearDown() override {}
Ryan Harrisondbc13af2022-02-21 15:19:07 +000060
dan sinclair41e4d9a2022-05-01 14:40:55 +000061 protected:
62 std::unique_ptr<RandomGenerator> rng_;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000063};
64
65#ifndef NDEBUG
66TEST_F(RandomGeneratorTest, GetUInt32ReversedBoundsCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +000067 EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt32(10, 5), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000068}
69
70TEST_F(RandomGeneratorTest, GetUInt32EmptyBoundsCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +000071 EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt32(5, 5), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000072}
73
74TEST_F(RandomGeneratorTest, GetUInt32ZeroBoundCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +000075 EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt32(0u), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000076}
77#endif // NDEBUG
78
79TEST_F(RandomGeneratorTest, GetUInt32SingularReturnsOneValue) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000080 {
81 uint32_t result = rng_->GetUInt32(5u, 6u);
82 ASSERT_EQ(5u, result);
83 }
84 {
85 uint32_t result = rng_->GetUInt32(1u);
86 ASSERT_EQ(0u, result);
87 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000088}
89
90TEST_F(RandomGeneratorTest, GetUInt32StaysInBounds) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000091 {
92 uint32_t result = rng_->GetUInt32(5u, 10u);
93 ASSERT_LE(5u, result);
94 ASSERT_GT(10u, result);
95 }
96 {
97 uint32_t result = rng_->GetUInt32(10u);
98 ASSERT_LE(0u, result);
99 ASSERT_GT(10u, result);
100 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000101}
102
103#ifndef NDEBUG
104TEST_F(RandomGeneratorTest, GetUInt64ReversedBoundsCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +0000105 EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt64(10, 5), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000106}
107
108TEST_F(RandomGeneratorTest, GetUInt64EmptyBoundsCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +0000109 EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt64(5, 5), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000110}
111
112TEST_F(RandomGeneratorTest, GetUInt64ZeroBoundCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +0000113 EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt64(0u), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000114}
115#endif // NDEBUG
116
117TEST_F(RandomGeneratorTest, GetUInt64SingularReturnsOneValue) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000118 {
119 uint64_t result = rng_->GetUInt64(5u, 6u);
120 ASSERT_EQ(5u, result);
121 }
122 {
123 uint64_t result = rng_->GetUInt64(1u);
124 ASSERT_EQ(0u, result);
125 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000126}
127
128TEST_F(RandomGeneratorTest, GetUInt64StaysInBounds) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000129 {
130 uint64_t result = rng_->GetUInt64(5u, 10u);
131 ASSERT_LE(5u, result);
132 ASSERT_GT(10u, result);
133 }
134 {
135 uint64_t result = rng_->GetUInt64(10u);
136 ASSERT_LE(0u, result);
137 ASSERT_GT(10u, result);
138 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000139}
140
141TEST_F(RandomGeneratorTest, GetByte) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000142 rng_->GetByte();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000143}
144
145#ifndef NDEBUG
146TEST_F(RandomGeneratorTest, GetNBytesNullDataBufferCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +0000147 EXPECT_DEATH_IF_SUPPORTED(rng_->GetNBytes(nullptr, 5), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000148}
149#endif // NDEBUG
150
151TEST_F(RandomGeneratorTest, GetNBytes) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000152 std::vector<uint8_t> data;
153 for (uint32_t i = 25; i < 1000u; i = i + 25) {
154 data.resize(i);
155 rng_->GetNBytes(data.data(), data.size());
156 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000157}
158
159TEST_F(RandomGeneratorTest, GetBool) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000160 rng_->GetBool();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000161}
162
163TEST_F(RandomGeneratorTest, GetWeightedBoolZeroAlwaysFalse) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000164 ASSERT_FALSE(rng_->GetWeightedBool(0));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000165}
166
167TEST_F(RandomGeneratorTest, GetWeightedBoolHundredAlwaysTrue) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000168 ASSERT_TRUE(rng_->GetWeightedBool(100));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000169}
170
171#ifndef NDEBUG
172TEST_F(RandomGeneratorTest, GetWeightedBoolAboveHundredCrashes) {
Ian Vollickc1187342023-07-05 17:39:02 +0000173 EXPECT_DEATH_IF_SUPPORTED(rng_->GetWeightedBool(101), ".*");
174 EXPECT_DEATH_IF_SUPPORTED(rng_->GetWeightedBool(500), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000175}
176#endif // NDEBUG
177
178TEST_F(RandomGeneratorTest, GetWeightedBool) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000179 for (uint32_t i = 0; i <= 100; i++) {
180 rng_ = std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
181 for (uint32_t j = 0; j <= 100; j++) {
182 if (j < i) {
183 ASSERT_TRUE(rng_->GetWeightedBool(i));
184 } else {
185 ASSERT_FALSE(rng_->GetWeightedBool(i));
186 }
187 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000188 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000189}
190
191#ifndef NDEBUG
192TEST_F(RandomGeneratorTest, GetRandomElementEmptyVectorCrashes) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000193 std::vector<uint8_t> v;
Ian Vollickc1187342023-07-05 17:39:02 +0000194 EXPECT_DEATH_IF_SUPPORTED(rng_->GetRandomElement(v), ".*");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000195}
196#endif // NDEBUG
197
198TEST_F(RandomGeneratorTest, GetRandomElement) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000199 std::vector<uint32_t> v;
200 for (uint32_t i = 25; i < 100u; i = i + 25) {
201 rng_ = std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
202 v.resize(i);
203 std::iota(v.begin(), v.end(), 0);
204 for (uint32_t j = 0; j < i; j++) {
205 EXPECT_EQ(j, rng_->GetRandomElement(v));
206 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000207 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000208}
209
210} // namespace
dan sinclair62a1d712022-04-07 17:46:04 +0000211} // namespace tint::fuzzers