1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include <cctype>
16
17 #include "pw_fuzzer/fuzztest.h"
18 #include "pw_result/result.h"
19 #include "pw_unit_test/framework.h"
20
21 // Most of the tests in this file only validate that the domains provided by
22 // Pigweed build, both with and without FuzzTest. Each domain comprises one or
23 // more FuzzTest domains, so the validation of the distribution of values
24 // produced by domains is left to and assumed from FuzzTest's own domain tests.
25
26 namespace pw::fuzzer {
27 namespace {
28
29 ////////////////////////////////////////////////////////////////
30 // Constants, macros, and types used by the domain tests below.
31
32 constexpr size_t kSize = 8;
33 constexpr char kMin = 4;
34 constexpr char kMax = 16;
35
36 /// Generates a target function and fuzz test for a specific type.
37 ///
38 /// The generated test simply checks that the provided domain can produce values
39 /// of the appropriate type. Generally, explicitly providing a target function
40 /// is preferred for readability, but this macro can be useful for templated
41 /// domains that are tested for many repetitive numerical types.
42 ///
43 /// This macro should not be used directly. Instead, use
44 /// `FUZZ_TEST_FOR_INTEGRAL`, `FUZZ_TEST_FOR_FLOATING_POINT`, or
45 /// `FUZZ_TEST_FOR_ARITHMETIC`.
46 #define FUZZ_TEST_FOR_TYPE(Suite, Target, Domain, Type, ...) \
47 void Target(Type t) { Take##Domain<Type>(t); } \
48 FUZZ_TEST(Suite, Target).WithDomains(Domain<Type>(__VA_ARGS__))
49
50 /// Generates target functions and fuzz tests for a integral types.
51 #define FUZZ_TEST_FOR_INTEGRAL(Suite, Target, Domain, ...) \
52 FUZZ_TEST_FOR_TYPE(Suite, Target##_Char, Domain, char, __VA_ARGS__); \
53 FUZZ_TEST_FOR_TYPE( \
54 Suite, Target##_UChar, Domain, unsigned char, __VA_ARGS__); \
55 FUZZ_TEST_FOR_TYPE(Suite, Target##_Short, Domain, short, __VA_ARGS__); \
56 FUZZ_TEST_FOR_TYPE( \
57 Suite, Target##_UShort, Domain, unsigned short, __VA_ARGS__); \
58 FUZZ_TEST_FOR_TYPE(Suite, Target##_Int, Domain, int, __VA_ARGS__); \
59 FUZZ_TEST_FOR_TYPE(Suite, Target##_UInt, Domain, unsigned int, __VA_ARGS__); \
60 FUZZ_TEST_FOR_TYPE(Suite, Target##_Long, Domain, long, __VA_ARGS__); \
61 FUZZ_TEST_FOR_TYPE(Suite, Target##_ULong, Domain, unsigned long, __VA_ARGS__)
62
63 /// Generates target functions and fuzz tests for a floating point types.
64 #define FUZZ_TEST_FOR_FLOATING_POINT(Suite, Target, Domain, ...) \
65 FUZZ_TEST_FOR_TYPE(Suite, Target##_Float, Domain, float, __VA_ARGS__); \
66 FUZZ_TEST_FOR_TYPE(Suite, Target##_Double, Domain, double, __VA_ARGS__)
67
68 /// Generates target functions and fuzz tests for a all arithmetic types.
69 #define FUZZ_TEST_FOR_ARITHMETIC(Suite, Target, Domain, ...) \
70 FUZZ_TEST_FOR_INTEGRAL(Suite, Target, Domain, __VA_ARGS__); \
71 FUZZ_TEST_FOR_FLOATING_POINT(Suite, Target, Domain, __VA_ARGS__)
72
73 // Test struct that can be produced by FuzzTest.
74 struct StructForTesting {
75 int a;
76 long b;
77 };
78
79 // Test class that can be produced by FuzzTest.
80 class ClassForTesting {
81 public:
ClassForTesting(unsigned char c,short d)82 ClassForTesting(unsigned char c, short d) : c_(c), d_(d) {}
c() const83 unsigned char c() const { return c_; }
d() const84 short d() const { return d_; }
85
86 private:
87 unsigned char c_;
88 short d_;
89 };
90
91 ////////////////////////////////////////////////////////////////
92 // Arbitrary domains forwarded or stubbed from FuzzTest
93
94 template <typename T>
TakeArbitrary(T)95 void TakeArbitrary(T) {}
96
TakeArbitraryBool(bool b)97 void TakeArbitraryBool(bool b) { TakeArbitrary<bool>(b); }
98 FUZZ_TEST(ArbitraryTest, TakeArbitraryBool).WithDomains(Arbitrary<bool>());
99
100 FUZZ_TEST_FOR_ARITHMETIC(ArbitraryTest, TakeArbitrary, Arbitrary);
101
TakeArbitraryStruct(const StructForTesting & s)102 void TakeArbitraryStruct(const StructForTesting& s) {
103 TakeArbitrary<StructForTesting>(s);
104 }
105 FUZZ_TEST(ArbitraryTest, TakeArbitraryStruct)
106 .WithDomains(Arbitrary<StructForTesting>());
107
TakeArbitraryTuple(const std::tuple<int,long> & t)108 void TakeArbitraryTuple(const std::tuple<int, long>& t) {
109 TakeArbitrary<std::tuple<int, long>>(t);
110 }
111 FUZZ_TEST(ArbitraryTest, TakeArbitraryTuple)
112 .WithDomains(Arbitrary<std::tuple<int, long>>());
113
TakeArbitraryOptional(const std::optional<int> & o)114 void TakeArbitraryOptional(const std::optional<int>& o) {
115 TakeArbitrary<std::optional<int>>(o);
116 }
117 FUZZ_TEST(ArbitraryTest, TakeArbitraryOptional)
118 .WithDomains(Arbitrary<std::optional<int>>());
119
120 ////////////////////////////////////////////////////////////////
121 // Numerical domains forwarded or stubbed from FuzzTest
122
123 template <typename Arithmetic>
TakeInRange(Arithmetic x)124 void TakeInRange(Arithmetic x) {
125 EXPECT_GE(x, Arithmetic(kMin));
126 EXPECT_LE(x, Arithmetic(kMax));
127 }
128 FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeInRange, InRange, kMin, kMax);
129
130 template <typename Arithmetic>
TakeNonZero(Arithmetic x)131 void TakeNonZero(Arithmetic x) {
132 EXPECT_NE(x, Arithmetic(0));
133 }
134 FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonZero, NonZero);
135
136 template <typename Arithmetic>
TakePositive(Arithmetic x)137 void TakePositive(Arithmetic x) {
138 EXPECT_GT(x, Arithmetic(0));
139 }
140 FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakePositive, Positive);
141
142 template <typename Arithmetic>
TakeNonNegative(Arithmetic x)143 void TakeNonNegative(Arithmetic x) {
144 EXPECT_GE(x, Arithmetic(0));
145 }
146 FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonNegative, NonNegative);
147
148 template <typename Arithmetic>
TakeNegative(Arithmetic x)149 void TakeNegative(Arithmetic x) {
150 EXPECT_LT(x, Arithmetic(0));
151 }
152 FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNegative, Positive);
153
154 template <typename Arithmetic>
TakeNonPositive(Arithmetic x)155 void TakeNonPositive(Arithmetic x) {
156 EXPECT_LE(x, Arithmetic(0));
157 }
158 FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonPositive, NonNegative);
159
160 template <typename FloatingPoint>
TakeFinite(FloatingPoint f)161 void TakeFinite(FloatingPoint f) {
162 EXPECT_TRUE(std::isfinite(f));
163 }
164 FUZZ_TEST_FOR_FLOATING_POINT(DomainTest, TakeFinite, Finite);
165
166 ////////////////////////////////////////////////////////////////
167 // Character domains forwarded or stubbed from FuzzTest
168
TakeNonZeroChar(char c)169 void TakeNonZeroChar(char c) { EXPECT_NE(c, 0); }
170 FUZZ_TEST(DomainTest, TakeNonZeroChar).WithDomains(NonZeroChar());
171
TakeNumericChar(char c)172 void TakeNumericChar(char c) { EXPECT_TRUE(std::isdigit(c)); }
173 FUZZ_TEST(DomainTest, TakeNumericChar).WithDomains(NumericChar());
174
TakeLowerChar(char c)175 void TakeLowerChar(char c) { EXPECT_TRUE(std::islower(c)); }
176 FUZZ_TEST(DomainTest, TakeLowerChar).WithDomains(LowerChar());
177
TakeUpperChar(char c)178 void TakeUpperChar(char c) { EXPECT_TRUE(std::isupper(c)); }
179 FUZZ_TEST(DomainTest, TakeUpperChar).WithDomains(UpperChar());
180
TakeAlphaChar(char c)181 void TakeAlphaChar(char c) { EXPECT_TRUE(std::isalpha(c)); }
182 FUZZ_TEST(DomainTest, TakeAlphaChar).WithDomains(AlphaChar());
183
TakeAlphaNumericChar(char c)184 void TakeAlphaNumericChar(char c) { EXPECT_TRUE(std::isalnum(c)); }
185 FUZZ_TEST(DomainTest, TakeAlphaNumericChar).WithDomains(AlphaNumericChar());
186
TakePrintableAsciiChar(char c)187 void TakePrintableAsciiChar(char c) { EXPECT_TRUE(std::isprint(c)); }
188 FUZZ_TEST(DomainTest, TakePrintableAsciiChar).WithDomains(PrintableAsciiChar());
189
TakeAsciiChar(char c)190 void TakeAsciiChar(char c) {
191 EXPECT_GE(c, 0);
192 EXPECT_LE(c, 127);
193 }
194 FUZZ_TEST(DomainTest, TakeAsciiChar).WithDomains(AsciiChar());
195
196 ////////////////////////////////////////////////////////////////
197 // Regular expression domains forwarded or stubbed from FuzzTest
198
199 // TODO: b/285775246 - Add support for `fuzztest::InRegexp`.
200 // void TakeMatch(std::string_view sv) {
201 // ASSERT_EQ(sv.size(), 3U);
202 // EXPECT_EQ(sv[0], 'a');
203 // EXPECT_EQ(sv[2], 'c');
204 // }
205 // FUZZ_TEST(DomainTest, TakeMatch).WithDomains(InRegexp("a.c"));
206
207 ////////////////////////////////////////////////////////////////
208 // Enumerated domains forwarded or stubbed from FuzzTest
209
TakeSingleDigitEvenNumber(int n)210 void TakeSingleDigitEvenNumber(int n) {
211 EXPECT_LT(n, 10);
212 EXPECT_EQ(n % 2, 0);
213 }
214 FUZZ_TEST(DomainTest, TakeSingleDigitEvenNumber)
215 .WithDomains(ElementOf({0, 2, 4, 6, 8}));
216
217 enum Flags : uint8_t {
218 kFlag1 = 1 << 0,
219 kFlag2 = 1 << 1,
220 kFlag3 = 1 << 2,
221 };
TakeFlagCombination(uint8_t flags)222 void TakeFlagCombination(uint8_t flags) { EXPECT_FALSE(flags & Flags::kFlag2); }
223 FUZZ_TEST(DomainTest, TakeFlagCombination)
224 .WithDomains(BitFlagCombinationOf({Flags::kFlag1, Flags::kFlag3}));
225
226 ////////////////////////////////////////////////////////////////
227 // Aggregate domains forwarded or stubbed from FuzzTest
228
TakeStructForTesting(const StructForTesting & obj)229 void TakeStructForTesting(const StructForTesting& obj) {
230 EXPECT_NE(obj.a, 0);
231 EXPECT_LT(obj.b, 0);
232 }
233 FUZZ_TEST(DomainTest, TakeStructForTesting)
234 .WithDomains(StructOf<StructForTesting>(NonZero<int>(), Negative<long>()));
235
TakeClassForTesting(const ClassForTesting & obj)236 void TakeClassForTesting(const ClassForTesting& obj) {
237 EXPECT_GE(obj.c(), kMin);
238 EXPECT_LE(obj.c(), kMax);
239 EXPECT_GE(obj.d(), 0);
240 }
241 FUZZ_TEST(DomainTest, TakeClassForTesting)
242 .WithDomains(ConstructorOf<ClassForTesting>(InRange<unsigned char>(kMin,
243 kMax),
244 NonNegative<short>()));
245
TakePair(const std::pair<char,float> & p)246 void TakePair(const std::pair<char, float>& p) {
247 EXPECT_TRUE(std::islower(p.first));
248 EXPECT_TRUE(std::isfinite(p.second));
249 }
250 FUZZ_TEST(DomainTest, TakePair)
251 .WithDomains(PairOf(LowerChar(), Finite<float>()));
252
TakeTuple(std::tuple<short,int> a,long b)253 void TakeTuple(std::tuple<short, int> a, long b) {
254 EXPECT_NE(std::get<short>(a), 0);
255 EXPECT_NE(std::get<int>(a), 0);
256 EXPECT_NE(b, 0);
257 }
258 FUZZ_TEST(DomainTest, TakeTuple)
259 .WithDomains(TupleOf(NonZero<short>(), NonZero<int>()), NonZero<long>());
260
TakeVariant(const std::variant<int,long> &)261 void TakeVariant(const std::variant<int, long>&) {}
262 FUZZ_TEST(DomainTest, TakeVariant)
263 .WithDomains(VariantOf(Arbitrary<int>(), Arbitrary<long>()));
264
TakeOptional(const std::optional<int> &)265 void TakeOptional(const std::optional<int>&) {}
266 FUZZ_TEST(DomainTest, TakeOptional).WithDomains(OptionalOf(Arbitrary<int>()));
267
TakeNullOpt(const std::optional<int> & option)268 void TakeNullOpt(const std::optional<int>& option) { EXPECT_FALSE(option); }
269 FUZZ_TEST(DomainTest, TakeNullOpt).WithDomains(NullOpt<int>());
270
TakeNonNull(const std::optional<int> & option)271 void TakeNonNull(const std::optional<int>& option) { EXPECT_TRUE(option); }
272 FUZZ_TEST(DomainTest, TakeNonNull)
273 .WithDomains(NonNull(OptionalOf(Arbitrary<int>())));
274
275 ////////////////////////////////////////////////////////////////
276 // Other miscellaneous domains forwarded or stubbed from FuzzTest
277
TakePositiveOrMinusOne(int n)278 void TakePositiveOrMinusOne(int n) {
279 if (n != -1) {
280 EXPECT_GT(n, 0);
281 }
282 }
283 FUZZ_TEST(DomainTest, TakePositiveOrMinusOne)
284 .WithDomains(OneOf(Just(-1), Positive<int>()));
285
TakePackedValue(uint32_t value)286 void TakePackedValue(uint32_t value) {
287 EXPECT_GE(value & 0xFFFF, 1000U);
288 EXPECT_LT(value >> 16, 2048U);
289 }
290 FUZZ_TEST(DomainTest, TakePackedValue)
291 .WithDomains(
292 Map([](uint16_t lower,
__anon5cadf3610202(uint16_t lower, uint16_t upper) 293 uint16_t upper) { return (uint32_t(upper) << 16) | lower; },
294 InRange<uint16_t>(1000U, std::numeric_limits<uint16_t>::max()),
295 InRange<uint16_t>(0U, 2047U)));
296
TakeOrdered(size_t x,size_t y)297 void TakeOrdered(size_t x, size_t y) { EXPECT_LT(x, y); }
FlatMapAdapter(const std::pair<size_t,size_t> & p)298 void FlatMapAdapter(const std::pair<size_t, size_t>& p) {
299 TakeOrdered(p.first, p.second);
300 }
301 FUZZ_TEST(DomainTest, FlatMapAdapter)
302 .WithDomains(FlatMap(
__anon5cadf3610302(size_t x) 303 [](size_t x) {
304 return PairOf(
305 Just(x),
306 InRange<size_t>(x + 1, std::numeric_limits<size_t>::max()));
307 },
308 InRange<size_t>(0, std::numeric_limits<size_t>::max() - 1)));
309
TakeEven(unsigned int n)310 void TakeEven(unsigned int n) { EXPECT_EQ(n % 2, 0U); }
311 FUZZ_TEST(DomainTest, TakeEven)
__anon5cadf3610402(unsigned int n) 312 .WithDomains(Filter([](unsigned int n) { return n % 2 == 0; },
313 Arbitrary<unsigned int>()));
314
315 ////////////////////////////////////////////////////////////////
316 // pw_status-related types
317
TakeStatus(const Status &)318 void TakeStatus(const Status&) {}
319 FUZZ_TEST(ArbitraryTest, TakeStatus).WithDomains(Arbitrary<Status>());
320
TakeStatusWithSize(const StatusWithSize &)321 void TakeStatusWithSize(const StatusWithSize&) {}
322 FUZZ_TEST(ArbitraryTest, TakeStatusWithSize)
323 .WithDomains(Arbitrary<StatusWithSize>());
324
TakeNonOkStatus(const Status & status)325 void TakeNonOkStatus(const Status& status) { EXPECT_FALSE(status.ok()); }
326 FUZZ_TEST(FilterTest, TakeNonOkStatus).WithDomains(NonOkStatus());
327
328 ////////////////////////////////////////////////////////////////
329 // pw_result-related types
330
TakeResult(const Result<int> &)331 void TakeResult(const Result<int>&) {}
332 FUZZ_TEST(DomainTest, TakeResult).WithDomains(ResultOf(Arbitrary<int>()));
333 FUZZ_TEST(ArbitraryTest, TakeResult).WithDomains(Arbitrary<Result<int>>());
334
335 ////////////////////////////////////////////////////////////////
336 // pw_containers-related types
337
TakeVector(const Vector<int> & vector)338 void TakeVector(const Vector<int>& vector) {
339 EXPECT_EQ(vector.max_size(), kSize);
340 }
341 FUZZ_TEST(DomainTest, TakeVector)
342 .WithDomains(VectorOf<kSize>(Arbitrary<int>()));
343 FUZZ_TEST(ArbitraryTest, TakeVector)
344 .WithDomains(Arbitrary<Vector<int, kSize>>());
345
TakeVectorAsContainer(const Vector<int> &)346 void TakeVectorAsContainer(const Vector<int>&) {}
347 FUZZ_TEST(ContainerTest, TakeVectorAsContainer)
348 .WithDomains(ContainerOf<Vector<int, kSize>>(Arbitrary<int>()));
349
TakeVectorNonEmpty(const Vector<int> & vector)350 void TakeVectorNonEmpty(const Vector<int>& vector) {
351 EXPECT_FALSE(vector.empty());
352 }
353 FUZZ_TEST(ContainerTest, TakeVectorNonEmpty)
354 .WithDomains(NonEmpty(ContainerOf<Vector<int, kSize>>(Arbitrary<int>())));
355
TakeVectorLessThan3(const Vector<int> & vector)356 void TakeVectorLessThan3(const Vector<int>& vector) {
357 EXPECT_LT(vector.size(), 3U);
358 }
359 FUZZ_TEST(ContainerTest, TakeVectorLessThan3)
360 .WithDomains(
361 ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithMaxSize(2));
362
TakeVectorAtLeast3(const Vector<int> & vector)363 void TakeVectorAtLeast3(const Vector<int>& vector) {
364 EXPECT_GE(vector.size(), 3U);
365 }
366 FUZZ_TEST(ContainerTest, TakeVectorAtLeast3)
367 .WithDomains(
368 ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithMinSize(3));
369
TakeVectorExactly3(const Vector<int> & vector)370 void TakeVectorExactly3(const Vector<int>& vector) {
371 EXPECT_EQ(vector.size(), 3U);
372 }
373 FUZZ_TEST(ContainerTest, TakeVectorExactly3)
374 .WithDomains(ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithSize(3));
375
TakeVectorUnique(const Vector<int> & vector)376 void TakeVectorUnique(const Vector<int>& vector) {
377 for (auto i = vector.begin(); i != vector.end(); ++i) {
378 for (auto j = i + 1; j != vector.end(); ++j) {
379 EXPECT_NE(*i, *j);
380 }
381 }
382 }
383 FUZZ_TEST(ContainerTest, TakeVectorUnique)
384 .WithDomains(
385 UniqueElementsContainerOf<Vector<int, kSize>>(Arbitrary<int>()));
386 FUZZ_TEST(DomainTest, TakeVectorUnique)
387 .WithDomains(UniqueElementsVectorOf<kSize>(Arbitrary<int>()));
388
TakeFlatMap(const containers::FlatMap<int,size_t,kSize> &)389 void TakeFlatMap(const containers::FlatMap<int, size_t, kSize>&) {}
390 FUZZ_TEST(DomainTest, TakeFlatMap)
391 .WithDomains(FlatMapOf<kSize>(Arbitrary<int>(), Arbitrary<size_t>()));
392 FUZZ_TEST(ArbitraryTest, TakeFlatMap)
393 .WithDomains(Arbitrary<containers::FlatMap<int, size_t, kSize>>());
394 FUZZ_TEST(ContainerTest, TakeFlatMap)
395 .WithDomains(ContainerOf<containers::FlatMap<int, size_t, kSize>>(
396 FlatMapPairOf(Arbitrary<int>(), Arbitrary<size_t>())));
397 FUZZ_TEST(MapToTest, TakeFlatMap)
398 .WithDomains(MapToFlatMap<kSize>(
399 UniqueElementsVectorOf<kSize>(Arbitrary<int>()).WithSize(kSize),
400 ArrayOf<kSize>(Arbitrary<size_t>())));
401
TakeDeque(const InlineDeque<int,kSize> & deque)402 void TakeDeque(const InlineDeque<int, kSize>& deque) {
403 EXPECT_EQ(deque.max_size(), kSize);
404 }
405 FUZZ_TEST(DomainTest, TakeDeque).WithDomains(DequeOf<kSize>(Arbitrary<int>()));
406 FUZZ_TEST(ArbitraryTest, TakeDeque)
407 .WithDomains(Arbitrary<InlineDeque<int, kSize>>());
408
TakeBasicDeque(const BasicInlineDeque<int,unsigned short,kSize> & deque)409 void TakeBasicDeque(const BasicInlineDeque<int, unsigned short, kSize>& deque) {
410 EXPECT_EQ(deque.max_size(), kSize);
411 }
412 FUZZ_TEST(DomainTest, TakeBasicDeque)
413 .WithDomains(BasicDequeOf<unsigned short, kSize>(Arbitrary<int>()));
414 FUZZ_TEST(ArbitraryTest, TakeBasicDeque)
415 .WithDomains(Arbitrary<BasicInlineDeque<int, unsigned short, kSize>>());
416
TakeQueue(const InlineQueue<int,kSize> & queue)417 void TakeQueue(const InlineQueue<int, kSize>& queue) {
418 EXPECT_EQ(queue.max_size(), kSize);
419 }
420 FUZZ_TEST(DomainTest, TakeQueue).WithDomains(QueueOf<kSize>(Arbitrary<int>()));
421 FUZZ_TEST(ArbitraryTest, TakeQueue)
422 .WithDomains(Arbitrary<InlineQueue<int, kSize>>());
423
TakeBasicQueue(const BasicInlineQueue<int,unsigned short,kSize> & queue)424 void TakeBasicQueue(const BasicInlineQueue<int, unsigned short, kSize>& queue) {
425 EXPECT_EQ(queue.max_size(), kSize);
426 }
427 FUZZ_TEST(DomainTest, TakeBasicQueue)
428 .WithDomains(BasicQueueOf<unsigned short, kSize>(Arbitrary<int>()));
429 FUZZ_TEST(ArbitraryTest, TakeBasicQueue)
430 .WithDomains(Arbitrary<BasicInlineQueue<int, unsigned short, kSize>>());
431
432 // Test item that can be added to an intrusive list.
433 class TestItem : public IntrusiveList<TestItem>::Item {
434 private:
435 public:
TestItem(long value)436 constexpr explicit TestItem(long value) : value_(value) {}
value() const437 long value() const { return value_; }
438
TestItem(TestItem && other)439 TestItem(TestItem&& other) { *this = std::move(other); }
operator =(TestItem && other)440 TestItem& operator=(TestItem&& other) {
441 value_ = other.value_;
442 return *this;
443 }
444
445 private:
446 long value_;
447 };
448
449 // IntrusiveLists cannot be generated directly, but ScopedLists can.
TakeIntrusiveList(const IntrusiveList<TestItem> & list)450 void TakeIntrusiveList(const IntrusiveList<TestItem>& list) {
451 EXPECT_LE(list.size(), kSize);
452 }
ScopedListAdapter(const ScopedList<TestItem,kSize> & scoped)453 void ScopedListAdapter(const ScopedList<TestItem, kSize>& scoped) {
454 TakeIntrusiveList(scoped.list());
455 }
456 FUZZ_TEST(DomainTest, ScopedListAdapter)
457 .WithDomains(ScopedListOf<TestItem, kSize>(Arbitrary<long>()));
458
459 ////////////////////////////////////////////////////////////////
460 // pw_string-related types
461
TakeString(const InlineString<> & string)462 void TakeString(const InlineString<>& string) {
463 EXPECT_EQ(string.max_size(), kSize);
464 }
465 FUZZ_TEST(DomainTest, TakeString)
466 .WithDomains(StringOf<kSize>(Arbitrary<char>()));
467 FUZZ_TEST(ArbitraryTest, TakeString)
468 .WithDomains(Arbitrary<InlineString<kSize>>());
469 FUZZ_TEST(FilterTest, TakeString).WithDomains(String<kSize>());
470
TakeStringAsContainer(const InlineString<> &)471 void TakeStringAsContainer(const InlineString<>&) {}
472 FUZZ_TEST(ContainerTest, TakeStringAsContainer)
473 .WithDomains(ContainerOf<InlineString<kSize>>(Arbitrary<char>()));
474
TakeStringNonEmpty(const InlineString<> & string)475 void TakeStringNonEmpty(const InlineString<>& string) {
476 EXPECT_FALSE(string.empty());
477 }
478 FUZZ_TEST(ContainerTest, TakeStringNonEmpty)
479 .WithDomains(NonEmpty(ContainerOf<InlineString<kSize>>(Arbitrary<char>())));
480
TakeStringLessThan3(const InlineString<> & string)481 void TakeStringLessThan3(const InlineString<>& string) {
482 EXPECT_LT(string.size(), 3U);
483 }
484 FUZZ_TEST(ContainerTest, TakeStringLessThan3)
485 .WithDomains(
486 ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithMaxSize(2));
487
TakeStringAtLeast3(const InlineString<> & string)488 void TakeStringAtLeast3(const InlineString<>& string) {
489 EXPECT_GE(string.size(), 3U);
490 }
491 FUZZ_TEST(ContainerTest, TakeStringAtLeast3)
492 .WithDomains(
493 ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithMinSize(3));
494
TakeStringExactly3(const InlineString<> & string)495 void TakeStringExactly3(const InlineString<>& string) {
496 EXPECT_EQ(string.size(), 3U);
497 }
498 FUZZ_TEST(ContainerTest, TakeStringExactly3)
499 .WithDomains(
500 ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithSize(3));
501
TakeAsciiString(const InlineString<> & string)502 void TakeAsciiString(const InlineString<>& string) {
503 EXPECT_TRUE(std::all_of(
504 string.begin(), string.end(), [](int c) { return c < 0x80; }));
505 }
506 FUZZ_TEST(FilterTest, TakeAsciiString).WithDomains(AsciiString<kSize>());
507
TakePrintableAsciiString(const InlineString<> & string)508 void TakePrintableAsciiString(const InlineString<>& string) {
509 EXPECT_TRUE(std::all_of(string.begin(), string.end(), isprint));
510 }
511 FUZZ_TEST(FilterTest, TakePrintableAsciiString)
512 .WithDomains(PrintableAsciiString<kSize>());
513
514 } // namespace
515 } // namespace pw::fuzzer
516