// Copyright 2022 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 // // http://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. // Tests of DomainBuilder. #include #include #include #include #include #include #include #include #include #include #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/random/random.h" #include "./fuzztest/domain_core.h" #include "./domain_tests/domain_testing.h" namespace fuzztest { namespace { struct Tree { int value; std::vector children; }; Domain ArbitraryTree() { DomainBuilder builder; builder.Set( "tree", StructOf(InRange(0, 10), ContainerOf>( builder.Get("tree")))); return std::move(builder).Finalize("tree"); } TEST(DomainBuilder, DomainForRecursiveDataStructureCreatesUniqueObjects) { // The domain should outlive the builder. Domain domain = ArbitraryTree(); absl::BitGen bitgen; Value tree(domain, bitgen); while (true) { tree.Mutate(domain, bitgen, {}, false); if (tree.user_value.children.empty()) continue; if (tree.user_value.children[0].children.empty()) continue; if (tree.user_value.children[0].children[0].children.empty()) continue; break; } } struct RedTree; struct BlackTree { int value; std::vector children; }; struct RedTree { int value; std::vector children; }; Domain ArbitraryRedBlackTree() { DomainBuilder builder; builder.Set( "redtree", StructOf(InRange(0, 10), ContainerOf>( builder.Get("blacktree")))); builder.Set( "blacktree", StructOf(InRange(0, 10), ContainerOf>( builder.Get("redtree")))); return std::move(builder).Finalize("redtree"); } TEST(DomainBuilder, DomainForMutuallyRecursiveDataStructureCreatesUniqueObjects) { Domain domain_redtree = ArbitraryRedBlackTree(); absl::BitGen bitgen; Value redtree(domain_redtree, bitgen); while (true) { redtree.Mutate(domain_redtree, bitgen, {}, false); if (redtree.user_value.children.empty()) continue; if (redtree.user_value.children[0].children.empty()) continue; if (redtree.user_value.children[0].children[0].children.empty()) continue; break; } } TEST(DomainBuilder, DiesOnInvalidFinalize) { DomainBuilder builder; builder.Set("example", Just(0)); EXPECT_DEATH_IF_SUPPORTED( std::move(builder).Finalize("typo"), "Finalize\\(\\) has been called with an unknown name: typo"); } } // namespace } // namespace fuzztest