// 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. #ifndef FUZZTEST_FUZZTEST_INTERNAL_DOMAINS_VALUE_MUTATION_HELPERS_H_ #define FUZZTEST_FUZZTEST_INTERNAL_DOMAINS_VALUE_MUTATION_HELPERS_H_ #include <cstddef> #include <limits> #include <optional> #include "absl/numeric/bits.h" #include "absl/numeric/int128.h" #include "absl/random/bit_gen_ref.h" #include "absl/random/random.h" #include "./fuzztest/internal/coverage.h" #include "./fuzztest/internal/meta.h" #include "./fuzztest/internal/table_of_recent_compares.h" namespace fuzztest::internal { // Random bit flip: minimal mutation to a field, it will converge // the hamming distance of a value to its target in constant steps. template <typename T> void RandomBitFlip(absl::BitGenRef prng, T& val, size_t range) { … } // BitWidth of the value of val, specially handle uint12 and int128, because // they don't have overloads in absl::bit_width. template <typename T> size_t BitWidth(T val) { … } // Given a parameter pack of functions `f`, run exactly one of the functions. template <typename... F> void RunOne(absl::BitGenRef prng, F... f) { … } template <typename T, size_t N, typename F> T ChooseOneOr(const T (&values)[N], absl::BitGenRef prng, F f) { … } template <typename T> T SampleFromUniformRange(absl::BitGenRef prng, T min, T max) { … } // Randomly apply Randomwalk or Uniform distribution or dictionary to mutate // the val: // RandomWalk: converge the absolute distance of a value to its target // more efficiently. // Uniform Distribution: go across some non-linear boundary that cannot // be solved by bit flipping or randomwalk. // Dictionary: if applicable, choose randomly from the dictionary. if // dictionary fails to mutate, fall back to uniform. template <unsigned char RANGE, typename T, typename IntegerDictionaryT> void RandomWalkOrUniformOrDict(absl::BitGenRef prng, T& val, T min, T max, const IntegerDictionaryT& temporary_dict, const IntegerDictionaryT& permanent_dict, std::optional<T>& permanent_dict_candidate) { … } // REQUIRES: |target| < |val| template <typename T> T ShrinkTowards(absl::BitGenRef prng, T val, T target) { … } } // namespace fuzztest::internal #endif // FUZZTEST_FUZZTEST_INTERNAL_DOMAINS_VALUE_MUTATION_HELPERS_H_