No public description PiperOrigin-RevId: 953398853
diff --git a/domain_tests/BUILD b/domain_tests/BUILD index c4ecc87..0dfd652 100644 --- a/domain_tests/BUILD +++ b/domain_tests/BUILD
@@ -30,10 +30,12 @@ "@abseil-cpp//absl/random", "@abseil-cpp//absl/random:bit_gen_ref", "@abseil-cpp//absl/status", + "@abseil-cpp//absl/types:optional", + "@abseil-cpp//absl/types:span", + "@abseil-cpp//absl/types:variant", "@com_google_fuzztest//fuzztest:domain_core", "@com_google_fuzztest//fuzztest/internal:serialization", "@com_google_fuzztest//fuzztest/internal:type_support", - "@com_google_fuzztest//fuzztest/internal/domains:core_domains_impl", "@googletest//:gtest_main", ], ) @@ -135,7 +137,6 @@ "@abseil-cpp//absl/random", "@com_google_fuzztest//fuzztest:domain_core", "@com_google_fuzztest//fuzztest/internal:table_of_recent_compares", - "@com_google_fuzztest//fuzztest/internal/domains:core_domains_impl", "@googletest//:gtest_main", ], ) @@ -152,10 +153,8 @@ "@abseil-cpp//absl/random", "@abseil-cpp//absl/random:bit_gen_ref", "@abseil-cpp//absl/status", - "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", "@com_google_fuzztest//common:logging", - "@com_google_fuzztest//common:status_macros", "@com_google_fuzztest//fuzztest/internal:logging", "@com_google_fuzztest//fuzztest/internal:meta", "@com_google_fuzztest//fuzztest/internal:serialization", @@ -200,9 +199,7 @@ ":domain_testing", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/random", - "@abseil-cpp//absl/status", "@com_google_fuzztest//fuzztest:domain_core", - "@com_google_fuzztest//fuzztest/internal/domains:core_domains_impl", "@googletest//:gtest_main", ], ) @@ -259,7 +256,6 @@ ":domain_testing", "@abseil-cpp//absl/random", "@com_google_fuzztest//fuzztest:domain_core", - "@com_google_fuzztest//fuzztest/internal/domains:core_domains_impl", "@googletest//:gtest_main", ], )
diff --git a/domain_tests/CMakeLists.txt b/domain_tests/CMakeLists.txt index 2b09961..be59c47 100644 --- a/domain_tests/CMakeLists.txt +++ b/domain_tests/CMakeLists.txt
@@ -8,8 +8,10 @@ absl::flat_hash_set absl::random_bit_gen_ref absl::random_random + absl::optional + absl::span absl::status - fuzztest::core_domains_impl + absl::variant fuzztest::domain_core fuzztest::serialization fuzztest::type_support @@ -120,8 +122,6 @@ absl::flat_hash_map absl::flat_hash_set absl::random_random - absl::status - fuzztest::core_domains_impl fuzztest::domain_core fuzztest::table_of_recent_compares GTest::gmock_main @@ -138,11 +138,9 @@ absl::random_random absl::random_bit_gen_ref absl::status - absl::statusor absl::strings fuzztest::domain_core fuzztest::common_logging - fuzztest::status_macros fuzztest::meta fuzztest::serialization fuzztest::test_protobuf_cc_proto @@ -190,7 +188,6 @@ fuzztest::domain_testing absl::algorithm_container absl::random_random - fuzztest::core_domains_impl fuzztest::domain_core GTest::gmock_main ) @@ -250,7 +247,6 @@ DEPS fuzztest::domain_testing absl::random_random - fuzztest::core_domains_impl fuzztest::domain_core GTest::gmock_main ) @@ -285,5 +281,3 @@ fuzztest::table_of_recent_compares GTest::gmock_main ) - -
diff --git a/domain_tests/aggregate_combinators_test.cc b/domain_tests/aggregate_combinators_test.cc index c5e87ba..5ee180d 100644 --- a/domain_tests/aggregate_combinators_test.cc +++ b/domain_tests/aggregate_combinators_test.cc
@@ -30,7 +30,6 @@ #include "absl/status/status.h" #include "./fuzztest/domain_core.h" #include "./domain_tests/domain_testing.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/serialization.h" #include "./fuzztest/internal/type_support.h" @@ -491,63 +490,5 @@ EXPECT_TRUE(optional_corpus_tuple.has_value()); } -TEST(StructOf, InitWithTraversalCtxUpdatesInitBudget) { - struct Foo { - int a; - double b; - }; - auto domain = StructOf<Foo>(Arbitrary<int>(), Arbitrary<double>()); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.init_budget = 10; - - auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - ASSERT_OK(val.status()); - // 1 (root) + 2 (fields: int, double) = 3 decrements - EXPECT_EQ(state.init_budget, 7); -} - -TEST(StructOf, InitWithTraversalCtxPropagatesFailureFromInnerDomain) { - struct Foo { - int a; - std::vector<int> v; - }; - // Inner container cannot be empty. - auto domain = StructOf<Foo>(Arbitrary<int>(), - VectorOf(Arbitrary<int>()).WithMinSize(1)); - - absl::BitGen prng; - domain_implementor::TraversalState state; - // The parent init decrements to 0 and the inner vector init decrements to -1 - // and fails due to the min size constraint. - state.depth_budget = 1; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), - testing::HasSubstr("Traversal budget exceeded")); -} - -TEST(StructOf, InitWithTraversalCtxHandlesPreExistingFailure) { - auto domain = StructOf<MyStruct>(Arbitrary<int>(), Arbitrary<std::string>()); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.status = absl::CancelledError("Pre-existing failure"); - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_EQ(state.status.message(), "Pre-existing failure"); -} - } // namespace } // namespace fuzztest
diff --git a/domain_tests/container_test.cc b/domain_tests/container_test.cc index 98c6dea..c599fa4 100644 --- a/domain_tests/container_test.cc +++ b/domain_tests/container_test.cc
@@ -34,7 +34,6 @@ #include "absl/random/random.h" #include "./fuzztest/domain_core.h" #include "./domain_tests/domain_testing.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/table_of_recent_compares.h" namespace fuzztest { @@ -357,7 +356,8 @@ * 1.0 / 4 // to use cmp tables * 1.0 / 2 // to pick the memcmp table * 1.0 / 2 // to pick one of the entries - * 1.0 / 2; // to apply replacement + * 1.0 / 2 // to apply replacement + ; for (int i = 0; i < 1 * IterationsToHitAll(/*num_cases=*/2, hit_probability); ++i) { std::vector<uint8_t> mutant = {10, 11, 12, 13}; @@ -369,106 +369,5 @@ EXPECT_THAT(mutants, Not(Contains(std::vector<uint8_t>{129, 129, 129, 129}))); } -TEST(ContainerTest, - SequenceInitWithTraversalCtxDepthExhaustedWithMinSizeFails) { - auto domain = VectorOf(Arbitrary<int>()).WithMinSize(3); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.depth_budget = 0; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), - testing::HasSubstr("Traversal budget exceeded")); -} - -TEST(ContainerTest, - SequenceInitWithTraversalCtxDepthExhaustedNoMinSizeSucceeds) { - auto domain = VectorOf(Arbitrary<int>()); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.depth_budget = 0; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - ASSERT_OK(val.status()); - EXPECT_TRUE(val->user_value.empty()); - EXPECT_TRUE(state.status.ok()); -} - -TEST(ContainerTest, SequenceInitWithTraversalCtxUpdatesInitBudget) { - auto domain = VectorOf(Arbitrary<int>()).WithSize(3); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.init_budget = 10; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - ASSERT_OK(val.status()); - EXPECT_EQ(val->user_value.size(), 3); - // 1 (root) + 3 (elements) = 4 decrements - EXPECT_EQ(state.init_budget, 6); -} - -TEST(ContainerTest, - SequenceInitWithTraversalCtxInitBudgetExhaustedWithMinSizeFails) { - auto domain = VectorOf(Arbitrary<int>()).WithMinSize(3); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.init_budget = 0; // Enter() will decrement to -1 - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); -} - -TEST(ContainerTest, - SequenceInitWithTraversalCtxInitBudgetExhaustedNoMinSizeSucceeds) { - auto domain = VectorOf(Arbitrary<int>()); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.init_budget = 0; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - ASSERT_OK(val.status()); - EXPECT_TRUE(val->user_value.empty()); - EXPECT_TRUE(state.status.ok()); -} - -TEST(ContainerTest, - SequenceInitWithTraversalCtxPropagatesFailureFromInnerExhaustion) { - // Both the parent and inner vectors must not be empty. - auto domain = - VectorOf(VectorOf(Arbitrary<int>()).WithMinSize(1)).WithMinSize(1); - - absl::BitGen prng; - domain_implementor::TraversalState state; - // The parent init decrements to 0 and the inner init decrements to -1 - // and fails due to the min size constraint. - state.depth_budget = 1; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), - testing::HasSubstr("Traversal budget exceeded")); -} - } // namespace } // namespace fuzztest
diff --git a/domain_tests/domain_testing.h b/domain_tests/domain_testing.h index d5df74a..ca2aa3b 100644 --- a/domain_tests/domain_testing.h +++ b/domain_tests/domain_testing.h
@@ -33,13 +33,10 @@ #include "absl/random/bit_gen_ref.h" #include "absl/random/random.h" #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "./common/logging.h" -#include "./common/status_macros.h" #include "./fuzztest/internal/domains/mutation_metadata.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/logging.h" #include "./fuzztest/internal/meta.h" #include "./fuzztest/internal/serialization.h" @@ -84,12 +81,12 @@ template <typename T> size_t operator()(const T& v) const { if constexpr (internal::Requires<T>( - [](auto v) -> decltype(v&& v.get()) {})) { + [](auto v) -> decltype(v && v.get()) {})) { // Smart pointers. return v ? absl::HashOf(*v) : 0; } else if constexpr (internal::Requires<T>( - [](auto v) -> decltype(std::isnan(*std::optional( - v))) {})) { + [](auto v) -> decltype(std::isnan( + *std::optional(v))) {})) { auto o = std::optional(v); return !o || std::isnan(*o) ? 0 : absl::Hash<T>{}(*o); } else if constexpr (internal::Requires<T>( @@ -111,12 +108,12 @@ differencer.set_field_comparator(&cmp); return differencer.Compare(a, b); } else if constexpr (internal::Requires<T>( - [](auto v) -> decltype(v&& v.get()) {})) { + [](auto v) -> decltype(v && v.get()) {})) { // Smart pointers. return a ? b && *a == *b : !b; } else if constexpr (internal::Requires<T>( - [](auto v) -> decltype(std::isnan(*std::optional( - v))) {})) { + [](auto v) -> decltype(std::isnan( + *std::optional(v))) {})) { auto oa = std::optional(a), ob = std::optional(b); return a == b || (oa && ob && std::isnan(*oa) && std::isnan(*ob)); } else { @@ -130,7 +127,6 @@ // The Value class keeps the corpus and value types together throughout tests to // simplify their access and mutation. -// TODO(b/535145936): Update to a class and make the values private. template <typename Domain> struct Value { using T = internal::value_type_t<Domain>; @@ -156,17 +152,6 @@ }()), user_value(std::move(user_value)) {} - static absl::StatusOr<Value> BuildWithTraversalCtx( - Domain& domain, absl::BitGenRef prng, - domain_implementor::TraversalState& state) { - ASSIGN_OR_RETURN_IF_NOT_OK( - auto corpus, - domain.InitWithTraversalCtx( - prng, domain_implementor::InitTraversalContext<Domain>(state))); - auto user = domain.GetValue(corpus); - return Value{std::move(corpus), std::move(user)}; - } - void Mutate(Domain& domain, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) { @@ -237,9 +222,6 @@ } private: - Value(internal::corpus_type_t<Domain> corpus, T user) - : corpus_value(std::move(corpus)), user_value(std::move(user)) {} - // We don't test the printers here, just that we return one. // The printers themselves are tested in type_support_test.cc using Printer = decltype(std::declval<const Domain&>().GetPrinter());
diff --git a/domain_tests/map_filter_combinator_test.cc b/domain_tests/map_filter_combinator_test.cc index 82c80f9..ebf66ed 100644 --- a/domain_tests/map_filter_combinator_test.cc +++ b/domain_tests/map_filter_combinator_test.cc
@@ -26,10 +26,8 @@ #include "gtest/gtest.h" #include "absl/algorithm/container.h" #include "absl/random/random.h" -#include "absl/status/status.h" #include "./fuzztest/domain_core.h" #include "./domain_tests/domain_testing.h" -#include "./fuzztest/internal/domains/traversal_context.h" namespace fuzztest { namespace { @@ -410,72 +408,5 @@ HasSubstr("Invalid corpus value for the inner domain in Filter()"))); } -TEST(Filter, InitWithTraversalCtxConsumesBudgetOnPredicateFailure) { - int attempts = 0; - // Fails 5 times, then succeeds. - auto domain = - Filter([&attempts](int i) { return ++attempts > 5; }, Arbitrary<int>()); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.depth_budget = 100; - state.init_budget = 10; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - ASSERT_OK(val.status()); - EXPECT_TRUE(state.status.ok()); - // Start: 10 - // Filter wrapper enter: -1 (9) - // 5 failed attempts of Arbitrary: 5 * -1 (4) - // 1 successful attempt of Arbitrary: -1 (3) - EXPECT_EQ(state.init_budget, 3); - EXPECT_EQ(state.depth_budget, 100); -} - -TEST(Filter, InitWithTraversalCtxReturnsEarlyOnPreExistingFailure) { - auto domain = Filter( - [](int i) { - ADD_FAILURE() << "Predicate should not be called"; - return false; - }, - Arbitrary<int>()); - - absl::BitGen prng; - domain_implementor::TraversalState state; - state.status = absl::CancelledError("Pre-existing failure"); - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_EQ(state.status.message(), "Pre-existing failure"); -} - -TEST(Filter, InitWithTraversalCtxPropagatesFailureFromInnerDomain) { - auto domain = Filter( - [](const std::vector<int>& v) { - ADD_FAILURE() << "Predicate should not be called"; - return false; - }, - VectorOf(Arbitrary<int>()).WithMinSize(3)); - - absl::BitGen prng; - domain_implementor::TraversalState state; - // This causes the inner VectorOf initialization to fail due to budget - // exhaustion. - state.init_budget = 0; - - const auto val = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, prng, state); - - EXPECT_FALSE(val.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), - testing::HasSubstr("Traversal budget exceeded")); -} - } // namespace } // namespace fuzztest
diff --git a/domain_tests/recursive_domains_test.cc b/domain_tests/recursive_domains_test.cc index b2bba27..aa5a956 100644 --- a/domain_tests/recursive_domains_test.cc +++ b/domain_tests/recursive_domains_test.cc
@@ -18,20 +18,14 @@ #include <utility> #include <vector> -#include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/random/random.h" #include "./fuzztest/domain_core.h" #include "./domain_tests/domain_testing.h" -#include "./fuzztest/internal/domains/traversal_context.h" namespace fuzztest { namespace { -using ::testing::HasSubstr; -using ::testing::IsEmpty; -using ::testing::Not; - struct Tree { int value; std::vector<Tree> children; @@ -111,71 +105,5 @@ "Finalize\\(\\) has been called with an unknown name: typo"); } -TEST(DomainBuilder, RecursiveDomainReachesDepthLimit) { - DomainBuilder builder; - builder.Set<Tree>( - "tree", StructOf<Tree>(InRange(0, 10), ContainerOf<std::vector<Tree>>( - builder.Get<Tree>("tree")) - .WithSize(2))); - Domain<Tree> domain = std::move(builder).Finalize<Tree>("tree"); - - absl::BitGen bitgen; - domain_implementor::TraversalState state; - state.depth_budget = 5; - - const auto tree = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, bitgen, state); - - EXPECT_FALSE(tree.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), HasSubstr("Traversal budget exceeded")); - EXPECT_THAT(state.error_trace, Not(IsEmpty())); -} - -TEST(DomainBuilder, RecursiveDomainReachesInitBudgetLimit) { - DomainBuilder builder; - builder.Set<Tree>( - "tree", StructOf<Tree>(InRange(0, 10), ContainerOf<std::vector<Tree>>( - builder.Get<Tree>("tree")) - .WithSize(2))); - Domain<Tree> domain = std::move(builder).Finalize<Tree>("tree"); - - absl::BitGen bitgen; - domain_implementor::TraversalState state; - state.depth_budget = 100; - state.init_budget = 5; - - const auto tree = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, bitgen, state); - - EXPECT_FALSE(tree.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), HasSubstr("Traversal budget exceeded")); - EXPECT_THAT(state.error_trace, Not(IsEmpty())); -} - -TEST(DomainBuilder, RecursiveDomainWithFilterReachesDepthLimit) { - DomainBuilder builder; - builder.Set<Tree>( - "tree", - Filter([](const Tree& t) { return t.value % 2 == 0; }, - StructOf<Tree>(InRange(0, 10), ContainerOf<std::vector<Tree>>( - builder.Get<Tree>("tree")) - .WithSize(2)))); - Domain<Tree> domain = std::move(builder).Finalize<Tree>("tree"); - - absl::BitGen bitgen; - domain_implementor::TraversalState state; - state.depth_budget = 5; - - const auto tree = - Value<decltype(domain)>::BuildWithTraversalCtx(domain, bitgen, state); - - EXPECT_FALSE(tree.ok()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.message(), HasSubstr("Traversal budget exceeded")); - EXPECT_THAT(state.error_trace, Not(IsEmpty())); -} - } // namespace } // namespace fuzztest
diff --git a/fuzztest/domain_core.h b/fuzztest/domain_core.h index 4da59f3..f0a6a3d 100644 --- a/fuzztest/domain_core.h +++ b/fuzztest/domain_core.h
@@ -62,7 +62,6 @@ #include "./fuzztest/internal/domains/optional_of_impl.h" #include "./fuzztest/internal/domains/overlap_of_impl.h" #include "./fuzztest/internal/domains/smart_pointer_of_impl.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/domains/unique_elements_container_of_impl.h" #include "./fuzztest/internal/domains/utf.h" #include "./fuzztest/internal/domains/variant_of_impl.h" @@ -161,14 +160,6 @@ return GetInnerDomain().Init(prng); } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<IndirectDomain> ctx) { - using InnerCtx = domain_implementor::InitTraversalContext<Domain<T>>; - return GetInnerDomain().InitWithTraversalCtx(prng, - InnerCtx::Passthrough(ctx)); - } - void Mutate(corpus_type& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) { @@ -227,13 +218,6 @@ corpus_type Init(absl::BitGenRef prng) { return inner_.Init(prng); } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<OwningDomain> ctx) { - using InnerCtx = domain_implementor::InitTraversalContext<Domain<T>>; - return inner_.InitWithTraversalCtx(prng, InnerCtx::Passthrough(ctx)); - } - void Mutate(corpus_type& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) {
diff --git a/fuzztest/internal/domains/BUILD b/fuzztest/internal/domains/BUILD index 5d571dd..5682ffb 100644 --- a/fuzztest/internal/domains/BUILD +++ b/fuzztest/internal/domains/BUILD
@@ -13,7 +13,6 @@ # limitations under the License. load("@rules_cc//cc:cc_library.bzl", "cc_library") -load("@rules_cc//cc:cc_test.bzl", "cc_test") package(default_visibility = ["@com_google_fuzztest//:__subpackages__"]) @@ -53,7 +52,6 @@ "serialization_helpers.h", "smart_pointer_of_impl.h", "special_values.h", - "traversal_context.h", "unique_elements_container_of_impl.h", "value_mutation_helpers.h", "variant_of_impl.h", @@ -74,7 +72,6 @@ "@abseil-cpp//absl/time", "@abseil-cpp//absl/types:span", "@com_google_fuzztest//common:logging", - "@com_google_fuzztest//common:status_macros", "@com_google_fuzztest//fuzztest:fuzzing_bit_gen", "@com_google_fuzztest//fuzztest/internal:any", "@com_google_fuzztest//fuzztest/internal:enum_reflection", @@ -100,11 +97,9 @@ "@abseil-cpp//absl/random:bit_gen_ref", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/status", - "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:str_format", "@com_google_fuzztest//common:logging", - "@com_google_fuzztest//common:status_macros", "@com_google_fuzztest//fuzztest/internal:any", "@com_google_fuzztest//fuzztest/internal:logging", "@com_google_fuzztest//fuzztest/internal:meta", @@ -252,13 +247,3 @@ "@com_google_fuzztest//fuzztest/internal:serialization", ], ) - -cc_test( - name = "traversal_context_test", - srcs = ["traversal_context_test.cc"], - deps = [ - ":core_domains_impl", - "@abseil-cpp//absl/status", - "@googletest//:gtest_main", - ], -)
diff --git a/fuzztest/internal/domains/CMakeLists.txt b/fuzztest/internal/domains/CMakeLists.txt index 6fe4833..e9702ff 100644 --- a/fuzztest/internal/domains/CMakeLists.txt +++ b/fuzztest/internal/domains/CMakeLists.txt
@@ -52,7 +52,6 @@ "serialization_helpers.h" "smart_pointer_of_impl.h" "special_values.h" - "traversal_context.h" "unique_elements_container_of_impl.h" "value_mutation_helpers.h" "variant_of_impl.h" @@ -72,7 +71,6 @@ absl::time absl::span fuzztest::common_logging - fuzztest::status_macros fuzztest::fuzzing_bit_gen fuzztest::any fuzztest::logging @@ -112,7 +110,6 @@ fuzztest::domain_core fuzztest::any fuzztest::common_logging - fuzztest::status_macros fuzztest::meta fuzztest::printer fuzztest::serialization @@ -238,14 +235,3 @@ fuzztest::meta fuzztest::serialization ) - -fuzztest_cc_test( - NAME - traversal_context_test - SRCS - "traversal_context_test.cc" - DEPS - fuzztest::core_domains_impl - absl::status - GTest::gmock_main -)
diff --git a/fuzztest/internal/domains/aggregate_of_impl.h b/fuzztest/internal/domains/aggregate_of_impl.h index ac9159e..cd70ca1 100644 --- a/fuzztest/internal/domains/aggregate_of_impl.h +++ b/fuzztest/internal/domains/aggregate_of_impl.h
@@ -24,12 +24,8 @@ #include "absl/random/bit_gen_ref.h" #include "absl/random/distributions.h" -#include "absl/status/status.h" -#include "absl/status/statusor.h" -#include "./common/status_macros.h" #include "./fuzztest/internal/domains/domain_base.h" #include "./fuzztest/internal/domains/serialization_helpers.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/meta.h" #include "./fuzztest/internal/serialization.h" #include "./fuzztest/internal/status.h" @@ -68,32 +64,6 @@ inner_); } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<AggregateOfImpl> ctx) { - RETURN_IF_NOT_OK(ctx.status()); - if (auto seed = this->MaybeGetRandomSeed(prng)) return *std::move(seed); - return ApplyIndex<sizeof...(Inner)>( - [&](auto... Is) -> absl::StatusOr<corpus_type> { - std::tuple<std::optional<corpus_type_t<Inner>>...> results; - absl::Status status = absl::OkStatus(); - auto init_one = [&](auto I) { - auto res = std::get<I>(inner_).InitWithTraversalCtx(prng, ctx); - if (!res.ok()) { - status = std::move(res).status(); - return false; - } - std::get<I>(results) = *std::move(res); - return true; - }; - if (!(init_one(Is) && ...)) { - return status; - } - - return corpus_type{*std::move(std::get<Is>(results))...}; - }); - } - void Mutate(corpus_type& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) {
diff --git a/fuzztest/internal/domains/container_of_impl.h b/fuzztest/internal/domains/container_of_impl.h index 60be162..7a8cd45 100644 --- a/fuzztest/internal/domains/container_of_impl.h +++ b/fuzztest/internal/domains/container_of_impl.h
@@ -29,14 +29,11 @@ #include "absl/random/bit_gen_ref.h" #include "absl/random/distributions.h" #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "absl/types/span.h" #include "./common/logging.h" -#include "./common/status_macros.h" #include "./fuzztest/internal/domains/container_mutation_helpers.h" #include "./fuzztest/internal/domains/domain_base.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/logging.h" #include "./fuzztest/internal/meta.h" #include "./fuzztest/internal/serialization.h" @@ -586,34 +583,6 @@ return val; } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<Derived> ctx) { - RETURN_IF_NOT_OK(ctx.status()); - if (ctx.IsResourceExhausted()) { - if (this->min_size() > 0) { - ctx.FailWithBudgetExceeded(); - return ctx.status(); - } - return corpus_type{}; - } - - if (auto seed = this->MaybeGetRandomSeed(prng)) return *std::move(seed); - const size_t size = this->ChooseRandomInitialSize(prng); - corpus_type val; - while (val.size() < size) { - auto elem = this->inner_.InitWithTraversalCtx(prng, ctx); - if (!elem.ok()) { - if (val.size() >= this->min_size()) { - return val; - } - return std::move(elem).status(); - } - val.insert(val.end(), *std::move(elem)); - } - return val; - } - uint64_t CountNumberOfFields(corpus_type& val) { uint64_t total_weight = 0; for (auto& i : val) {
diff --git a/fuzztest/internal/domains/domain.h b/fuzztest/internal/domains/domain.h index c9aaeed..85425e2 100644 --- a/fuzztest/internal/domains/domain.h +++ b/fuzztest/internal/domains/domain.h
@@ -30,7 +30,6 @@ #include "absl/strings/string_view.h" #include "./fuzztest/internal/domains/domain_base.h" #include "./fuzztest/internal/domains/domain_type_erasure.h" // IWYU pragma: export -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/printer.h" #include "./fuzztest/internal/serialization.h" #include "./fuzztest/internal/table_of_recent_compares.h" @@ -166,14 +165,6 @@ // values). corpus_type Init(absl::BitGenRef prng) { return inner_->UntypedInit(prng); } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<Domain> ctx) { - return inner_->UntypedInitWithTraversalCtx( - prng, domain_implementor::InitTraversalContext< - internal::UntypedDomainConcept>::Passthrough(ctx)); - } - // Mutate() makes a relatively small modification on `val` of `corpus_type`. // // Used during coverage-guided fuzzing. When `only_shrink` is true, @@ -342,14 +333,6 @@ corpus_type Init(absl::BitGenRef prng) { return inner_->UntypedInit(prng); } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<UntypedDomain> ctx) { - return inner_->UntypedInitWithTraversalCtx( - prng, domain_implementor::InitTraversalContext< - internal::UntypedDomainConcept>::Passthrough(ctx)); - } - void Mutate(corpus_type& corpus_value, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) {
diff --git a/fuzztest/internal/domains/domain_base.h b/fuzztest/internal/domains/domain_base.h index 32199ad..704421b 100644 --- a/fuzztest/internal/domains/domain_base.h +++ b/fuzztest/internal/domains/domain_base.h
@@ -29,12 +29,9 @@ #include "absl/random/bit_gen_ref.h" #include "absl/random/distributions.h" #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/str_format.h" -#include "./common/status_macros.h" #include "./fuzztest/internal/domains/domain_type_erasure.h" #include "./fuzztest/internal/domains/mutation_metadata.h" // IWYU pragma: export -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/meta.h" #include "./fuzztest/internal/printer.h" #include "./fuzztest/internal/serialization.h" @@ -137,12 +134,6 @@ return derived().GetValue(derived().GetRandomCorpusValue(prng)); } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, InitTraversalContext<Derived> ctx) { - RETURN_IF_NOT_OK(ctx.status()); - return derived().Init(prng); - } - // Default GetValue and FromValue functions for !has_custom_corpus_type // domains. ValueType GetValue(const ValueType& v) const {
diff --git a/fuzztest/internal/domains/domain_type_erasure.h b/fuzztest/internal/domains/domain_type_erasure.h index 1377ae7..442af9d 100644 --- a/fuzztest/internal/domains/domain_type_erasure.h +++ b/fuzztest/internal/domains/domain_type_erasure.h
@@ -32,13 +32,10 @@ #include "absl/functional/function_ref.h" #include "absl/random/bit_gen_ref.h" #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "./common/logging.h" -#include "./common/status_macros.h" #include "./fuzztest/internal/any.h" #include "./fuzztest/internal/domains/mutation_metadata.h" -#include "./fuzztest/internal/domains/traversal_context.h" #include "./fuzztest/internal/logging.h" #include "./fuzztest/internal/meta.h" #include "./fuzztest/internal/printer.h" @@ -61,9 +58,6 @@ virtual std::unique_ptr<UntypedDomainConcept> UntypedClone() const = 0; virtual GenericDomainCorpusType UntypedInit(absl::BitGenRef) = 0; - virtual absl::StatusOr<GenericDomainCorpusType> UntypedInitWithTraversalCtx( - absl::BitGenRef, - domain_implementor::InitTraversalContext<UntypedDomainConcept>) = 0; virtual void UntypedMutate( GenericDomainCorpusType& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, @@ -146,19 +140,6 @@ domain_.Init(prng)); } - absl::StatusOr<GenericDomainCorpusType> UntypedInitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<UntypedDomainConcept> ctx) - final { - ASSIGN_OR_RETURN_IF_NOT_OK( - auto res, - domain_.InitWithTraversalCtx( - prng, - domain_implementor::InitTraversalContext<D>::Passthrough(ctx))); - return GenericDomainCorpusType(std::in_place_type<CorpusType>, - std::move(res)); - } - void UntypedMutate(GenericDomainCorpusType& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) final {
diff --git a/fuzztest/internal/domains/filter_impl.h b/fuzztest/internal/domains/filter_impl.h index 46978f2..f37b8f9 100644 --- a/fuzztest/internal/domains/filter_impl.h +++ b/fuzztest/internal/domains/filter_impl.h
@@ -21,13 +21,11 @@ #include "absl/random/bit_gen_ref.h" #include "absl/status/status.h" -#include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "./common/logging.h" -#include "./common/status_macros.h" #include "./fuzztest/internal/domains/domain.h" #include "./fuzztest/internal/domains/domain_base.h" -#include "./fuzztest/internal/domains/traversal_context.h" +#include "./fuzztest/internal/logging.h" #include "./fuzztest/internal/serialization.h" namespace fuzztest::internal { @@ -52,19 +50,6 @@ } } - absl::StatusOr<corpus_type> InitWithTraversalCtx( - absl::BitGenRef prng, - domain_implementor::InitTraversalContext<FilterImpl> ctx) { - RETURN_IF_NOT_OK(ctx.status()); - if (auto seed = this->MaybeGetRandomSeed(prng)) return *std::move(seed); - - while (true) { - ASSIGN_OR_RETURN_IF_NOT_OK(auto v, - inner_.InitWithTraversalCtx(prng, ctx)); - if (RunFilter(v)) return v; - } - } - void Mutate(corpus_type& val, absl::BitGenRef prng, const domain_implementor::MutationMetadata& metadata, bool only_shrink) {
diff --git a/fuzztest/internal/domains/traversal_context.h b/fuzztest/internal/domains/traversal_context.h deleted file mode 100644 index edaff80..0000000 --- a/fuzztest/internal/domains/traversal_context.h +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef FUZZTEST_FUZZTEST_INTERNAL_DOMAINS_TRAVERSAL_CONTEXT_H_ -#define FUZZTEST_FUZZTEST_INTERNAL_DOMAINS_TRAVERSAL_CONTEXT_H_ - -#include <limits> -#include <string> -#include <vector> - -#include "absl/status/status.h" -#include "absl/strings/str_format.h" -#include "./common/logging.h" -#include "./fuzztest/internal/type_support.h" - -namespace fuzztest::domain_implementor { - -struct TraversalState { - // The maximum node depth during domain initialization and mutation. - int depth_budget = 100; - // The maximum number of added nodes during domain initialization. - int init_budget = 1000; - absl::Status status = absl::OkStatus(); - std::vector<std::string> error_trace; -}; - -template <typename DomainType> -class TraversalContext { - public: - struct PassthroughTag {}; - TraversalContext(TraversalState& state, PassthroughTag) : state_{state} {} - - explicit TraversalContext(TraversalState& state) : state_{state} { Enter(); } - - template <typename OtherDomain> - TraversalContext(const TraversalContext<OtherDomain>& other) - : state_{other.state()} { - Enter(); - } - - TraversalContext(const TraversalContext& other) : state_{other.state_} { - Enter(); - } - - ~TraversalContext() { Exit(); } - - bool IsResourceExhausted() const { - return state_.depth_budget < 0 || state_.init_budget < 0; - } - - bool IsFailed() const { return !state_.status.ok(); } - - void FailWithBudgetExceeded() { - if (state_.status.ok()) { - state_.status = absl::ResourceExhaustedError( - absl::StrFormat("Traversal budget exceeded at %s", - fuzztest::internal::GetTypeName<DomainType>())); - } - } - - TraversalState& state() const { return state_; } - absl::Status status() const { return state_.status; } - - protected: - void Enter() { - entered_ = true; - enter_ok_ = state_.status.ok(); - FUZZTEST_CHECK_GT(state_.depth_budget, std::numeric_limits<int>::min()); - state_.depth_budget--; - } - - void Exit() { - if (entered_) { - state_.depth_budget++; - } - if (enter_ok_ && !state_.status.ok()) { - state_.error_trace.push_back( - std::string(fuzztest::internal::GetTypeName<DomainType>())); - } - } - - TraversalState& state_; - bool enter_ok_ = false; - bool entered_ = false; -}; - -template <typename DomainType> -class InitTraversalContext : public TraversalContext<DomainType> { - public: - using PassthroughTag = - typename InitTraversalContext::TraversalContext::PassthroughTag; - using InitTraversalContext::TraversalContext::TraversalContext; - - template <typename OtherDomain> - static InitTraversalContext Passthrough( - const InitTraversalContext<OtherDomain>& other) { - return InitTraversalContext(other.state(), PassthroughTag{}); - } - - template <typename OtherDomain> - static InitTraversalContext Passthrough( - const TraversalContext<OtherDomain>& other) { - return InitTraversalContext(other.state(), PassthroughTag{}); - } - - explicit InitTraversalContext(TraversalState& state) - : TraversalContext<DomainType>{state} { - Decrement(); - } - - template <typename OtherDomain> - InitTraversalContext(const InitTraversalContext<OtherDomain>& other) - : TraversalContext<DomainType>{other} { - Decrement(); - } - - template <typename OtherDomain> - InitTraversalContext(const TraversalContext<OtherDomain>& other) - : TraversalContext<DomainType>{other} { - Decrement(); - } - - InitTraversalContext(const InitTraversalContext& other) - : TraversalContext<DomainType>{other} { - Decrement(); - } - - private: - void Decrement() { - if (this->state_.init_budget >= 0) { - --this->state_.init_budget; - } - } -}; - -} // namespace fuzztest::domain_implementor - -#endif // FUZZTEST_FUZZTEST_INTERNAL_DOMAINS_TRAVERSAL_CONTEXT_H_
diff --git a/fuzztest/internal/domains/traversal_context_test.cc b/fuzztest/internal/domains/traversal_context_test.cc deleted file mode 100644 index e2c737d..0000000 --- a/fuzztest/internal/domains/traversal_context_test.cc +++ /dev/null
@@ -1,282 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "./fuzztest/internal/domains/traversal_context.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/status/status.h" - -namespace fuzztest::domain_implementor { -namespace { - -struct TestDomain {}; -struct AnotherTestDomain {}; - -TEST(TraversalContextTest, DepthTrackingDecrementsAndRestores) { - TraversalState state; - state.depth_budget = 1; - - EXPECT_TRUE(state.status.ok()); - EXPECT_EQ(state.depth_budget, 1); - - { - TraversalContext<TestDomain> ctx1(state); - EXPECT_EQ(state.depth_budget, 0); - EXPECT_FALSE(ctx1.IsResourceExhausted()); - - { - TraversalContext<TestDomain> ctx2(ctx1); - EXPECT_EQ(state.depth_budget, -1); - EXPECT_TRUE(ctx2.IsResourceExhausted()); - } - EXPECT_EQ(state.depth_budget, 0); - } - EXPECT_EQ(state.depth_budget, 1); -} - -TEST(TraversalContextTest, InitBudgetTrackingDecrementsAndDoesNotRestore) { - TraversalState state; - state.init_budget = 1; - - { - InitTraversalContext<TestDomain> ctx1(state); - EXPECT_EQ(state.init_budget, 0); - EXPECT_FALSE(ctx1.IsResourceExhausted()); - - { - InitTraversalContext<TestDomain> ctx2(ctx1); - EXPECT_EQ(state.init_budget, -1); - EXPECT_TRUE(ctx2.IsResourceExhausted()); - } - } - - EXPECT_EQ(state.init_budget, -1); -} - -TEST(TraversalContextTest, MixedTraversalContextsInitBudgetTracking) { - TraversalState state; - state.init_budget = 2; - - { - InitTraversalContext<TestDomain> ctx1(state); // Init: decrements to 1 - EXPECT_EQ(state.init_budget, 1); - - { - TraversalContext<TestDomain> ctx2(ctx1); // Mutate: does NOT decrement - EXPECT_EQ(state.init_budget, 1); - - { - InitTraversalContext<TestDomain> ctx3(ctx2); // Init: decrements to 0 - EXPECT_EQ(state.init_budget, 0); - } - } - } - EXPECT_EQ(state.init_budget, 0); -} - -TEST(TraversalContextTest, ExhaustedContextFailsOnlyOnExplicitFail) { - TraversalState state; - state.depth_budget = 0; // Next enter will exhaust it - - InitTraversalContext<TestDomain> ctx(state); // depth -1 - EXPECT_TRUE(ctx.IsResourceExhausted()); - EXPECT_FALSE(ctx.IsFailed()); - - // We can choose to fail: - ctx.FailWithBudgetExceeded(); - EXPECT_TRUE(ctx.IsFailed()); - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.status.ToString(), - testing::HasSubstr("Traversal budget exceeded")); -} - -TEST(TraversalContextTest, ExistingInitBudgetIsNotReset) { - TraversalState state; // init_budget defaults to 1000 - EXPECT_EQ(state.init_budget, 1000); - - { - InitTraversalContext<TestDomain> ctx1(state); - EXPECT_EQ(state.init_budget, 999); - - { - InitTraversalContext<AnotherTestDomain> ctx2(ctx1); - EXPECT_EQ(state.init_budget, 998); - } - // ctx2 destructed. No change to init_budget. - EXPECT_EQ(state.init_budget, 998); - } - // ctx1 destructed. No change to init_budget. - EXPECT_EQ(state.init_budget, 998); -} - -TEST(TraversalContextTest, TransitionToInitTraversalContext) { - TraversalState state; // init_budget = 1000, depth_budget = 100 - state.depth_budget = 5; - - TraversalContext<TestDomain> ctx_without_budget(state); - EXPECT_EQ(state.depth_budget, 4); - EXPECT_EQ(state.init_budget, 1000); // Not decremented by TraversalContext - - { - InitTraversalContext<AnotherTestDomain> ctx_with_budget(ctx_without_budget); - EXPECT_EQ(state.depth_budget, 3); // Decremented by TraversalContext base - EXPECT_EQ(state.init_budget, 999); // Decremented by InitTraversalContext - } - // ctx_with_budget destructed. depth_budget is restored, init_budget is NOT. - EXPECT_EQ(state.depth_budget, 4); - EXPECT_EQ(state.init_budget, 999); -} - -struct ExhaustionTestParam { - TraversalState state; - bool expected_exhausted; - bool expected_failed; -}; - -class TraversalContextExhaustionTest - : public testing::TestWithParam<ExhaustionTestParam> {}; - -TEST_P(TraversalContextExhaustionTest, ChecksIsResourceExhaustedAndIsFailed) { - const auto& param = GetParam(); - TraversalState state = param.state; - InitTraversalContext<TestDomain> ctx(state); - EXPECT_EQ(ctx.IsResourceExhausted(), param.expected_exhausted); - EXPECT_EQ(ctx.IsFailed(), param.expected_failed); -} - -INSTANTIATE_TEST_SUITE_P( - TraversalContextTests, TraversalContextExhaustionTest, - testing::Values(ExhaustionTestParam{TraversalState{1, 1}, false, false}, - ExhaustionTestParam{TraversalState{0, 1000}, true, false}, - ExhaustionTestParam{TraversalState{1, 0}, true, false}, - ExhaustionTestParam{ - TraversalState{1, 1, absl::CancelledError("cancelled")}, - false, true})); - -TEST(TraversalContextTest, ErrorTraceAccumulatesOnUnwinding) { - TraversalState state; - struct DomainC {}; - struct DomainB {}; - struct DomainA {}; - - { - TraversalContext<DomainA> ctxA(state); - { - TraversalContext<DomainB> ctxB(ctxA); - { - TraversalContext<DomainC> ctxC(ctxB); - ctxC.FailWithBudgetExceeded(); - } - } - } - - EXPECT_FALSE(state.status.ok()); - EXPECT_THAT(state.error_trace, - testing::ElementsAre(testing::HasSubstr("DomainC"), - testing::HasSubstr("DomainB"), - testing::HasSubstr("DomainA"))); -} - -TEST(TraversalContextTest, DepthGoesBelowMinusOneAndRestores) { - TraversalState state; - state.depth_budget = 1; - - { - // depth 0 - TraversalContext<TestDomain> ctx1(state); - EXPECT_EQ(state.depth_budget, 0); - { - // depth -1 - TraversalContext<TestDomain> ctx2(ctx1); - EXPECT_EQ(state.depth_budget, -1); - { - // depth goes to -2 (no longer capped) - TraversalContext<TestDomain> ctx3(ctx2); - EXPECT_EQ(state.depth_budget, -2); - } // exit ctx3 -> depth becomes -1 - EXPECT_EQ(state.depth_budget, -1); - } // exit ctx2 -> depth becomes 0 - EXPECT_EQ(state.depth_budget, 0); - } // exit ctx1 -> depth becomes 1 - EXPECT_EQ(state.depth_budget, 1); -} - -TEST(TraversalContextTest, InitBudgetCappedAtMinusOne) { - TraversalState state; - state.init_budget = 1; - - { - InitTraversalContext<TestDomain> ctx(state); - EXPECT_EQ(state.init_budget, 0); - } - { - InitTraversalContext<TestDomain> ctx(state); - EXPECT_EQ(state.init_budget, -1); - } - { - InitTraversalContext<TestDomain> ctx(state); - EXPECT_EQ(state.init_budget, -1); - } -} - -TEST(TraversalContextTest, PassthroughDoesNotDecrementBudgets) { - TraversalState state; - state.depth_budget = 5; - state.init_budget = 10; - - { - InitTraversalContext<TestDomain> ctx(state); - EXPECT_EQ(state.depth_budget, 4); - EXPECT_EQ(state.init_budget, 9); - - { - auto passthrough_ctx = - InitTraversalContext<AnotherTestDomain>::Passthrough(ctx); - EXPECT_EQ(state.depth_budget, 4); // Not decremented - EXPECT_EQ(state.init_budget, 9); // Not decremented - } - // passthrough_ctx destructed. No change. - EXPECT_EQ(state.depth_budget, 4); - EXPECT_EQ(state.init_budget, 9); - } - // ctx destructed. depth_budget restored. - EXPECT_EQ(state.depth_budget, 5); - EXPECT_EQ(state.init_budget, 9); -} - -TEST(TraversalContextTest, PassthroughDoesNotAddToErrorTrace) { - TraversalState state; - - { - InitTraversalContext<TestDomain> ctx(state); - - { - auto passthrough_ctx = - InitTraversalContext<AnotherTestDomain>::Passthrough(ctx); - - passthrough_ctx.FailWithBudgetExceeded(); - EXPECT_FALSE(state.status.ok()); - } - // passthrough_ctx destructed. It should not add "AnotherTestDomain" to - // error_trace. - EXPECT_TRUE(state.error_trace.empty()); - } - // ctx destructed. It was active (enter_ok_ is true). - // So it should add "TestDomain" to error_trace because status is now not ok. - EXPECT_THAT(state.error_trace, testing::ElementsAre("TestDomain")); -} - -} // namespace -} // namespace fuzztest::domain_implementor