xref: /aosp_15_r20/external/pigweed/pw_fuzzer/domain_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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