chromium/third_party/fuzztest/src/fuzztest/internal/registration.h

// 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_REGISTRATION_H_
#define FUZZTEST_FUZZTEST_INTERNAL_REGISTRATION_H_

#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/types/span.h"
#include "./fuzztest/domain_core.h"
#include "./fuzztest/internal/domains/aggregate_of_impl.h"
#include "./fuzztest/internal/domains/domain.h"
#include "./fuzztest/internal/meta.h"
#include "./fuzztest/internal/printer.h"
#include "./fuzztest/internal/type_support.h"

namespace fuzztest {
namespace internal {

struct BasicTestInfo {};

// Use base classes to progressively add members/behavior to the registerer
// object. This way we can statically assert that certain functions are called
// in the right order.

struct NoFixture {};

// Initial base class. No custom domain, no seeds.
template <typename... Args>
struct DefaultRegistrationBase {};

template <typename Fixture, typename BaseFixture, typename... Args>
DefaultRegistrationBase<std::decay_t<Args>...> DefaultRegistrationBaseImpl(
    Fixture*, void (BaseFixture::*)(Args...));

template <typename... Args>
DefaultRegistrationBase<std::decay_t<Args>...> DefaultRegistrationBaseImpl(
    NoFixture*, void (*)(Args...));

DefaultRegistrationBaseT;

// A custom domain was specified.
template <typename... Args>
struct RegistrationWithDomainsBase {};

// Seeds were specified. It derived from the existing base to augment it.
template <typename Base>
struct RegistrationWithSeedsBase : Base {};

template <typename Base, typename SeedProvider>
struct RegistrationWithSeedProviderBase : Base {};

class PerIterationFixture;
struct RegistrationToken;

template <typename Fixture, typename TargetFunction,
          typename Base = DefaultRegistrationBaseT<Fixture, TargetFunction>,
          typename SeedProvider = void*>
class Registration : private Base {};

}  // namespace internal

// Returns a registration for a fuzz test based on `Fixture` and
// `target_function`. `target_function` must be a pointer to a member function
// of `Fixture` or its base class.
//
// This is an advanced API; in almost all cases you should prefer registring
// your fixture-based fuzz tests with the FUZZ_TEST_F macro. Unlike the macro,
// this function allows customizing `suite_name`, `test_name`, `file`, and
// `line`. For example, it is suitable when you want to register fuzz tests with
// dynamically generated test names.
//
// Note: If `Fixture` is a GoogleTest fixture, make sure that all fuzz tests
// registered with `suite_name` also use `Fixture`. Otherwise, you may encounter
// undefined behavior when it comes to test suite setup and teardown.
template <typename Fixture, typename TargetFunction>
auto GetRegistrationWithFixture(std::string suite_name, std::string test_name,
                                std::string file, int line,
                                TargetFunction target_function) {}

// Returns a registration for a fuzz test based on `target_function`, which
// should be a function pointer.
//
// This is an advanced API; in almost all cases you should prefer registring
// your fuzz tests with the FUZZ_TEST macro. Unlike the macro, this function
// allows customizing `suite_name`, `test_name`, `file`, and `line`. For
// example, it is suitable when you want to register fuzz tests with dynamically
// generated test names.
template <typename TargetFunction>
auto GetRegistration(std::string suite_name, std::string test_name,
                     std::string file, int line,
                     TargetFunction target_function) {}

}  // namespace fuzztest

#endif  // FUZZTEST_FUZZTEST_INTERNAL_REGISTRATION_H_