blob: 213e66aa3c594a5de488db98ee57515150254ee8 [file] [edit]
// 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
//
// 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.
use super::domains::GenericCorpusValue;
use super::domains::GenericDomain;
use std::collections::HashMap;
use std::sync::LazyLock;
/// A trait implemented by types used to Fuzz a given property function.
///
/// When a test is annotated with the `fuzztest` macro attribute, that test will be wrapped in a
/// FuzzTestObject that implements this trait. The FuzzTestObject is created by the macro and holds,
/// among others, the property function and the domains of its arguments.
/// The FuzzTestObject is then manipulated by Fuzzing Test Engine through the APIs of this trait.
pub trait FuzzTest {
// TODO(tinmar): refine arguments as we get a clearer picture of
// what the dispatcher interface looks like
fn name(&self) -> &'static str;
fn activate(&mut self);
fn mutate(&mut self);
/// Executes the property function with the given arguments
/// (will attempt to downcast to actual user values).
///
/// Returns `true` if the property function holds, `false` if it crashes.
fn execute(&self, args: &GenericCorpusValue) -> bool;
fn print_finding_report(&self);
fn domains(&self) -> &dyn GenericDomain;
}
/// Identifies the property function of a fuzz test.
///
/// `FuzzTestInfo` is instantiated by the `fuzztest` macro which populates the fields with the
/// appropriate values.
pub struct FuzzTestInfo {
pub name: &'static str,
pub file: &'static str,
pub line: u32,
}
pub type BoxedFuzzTest = Box<dyn FuzzTest + Send + Sync>;
pub struct FuzzTestRegistration {
pub info: &'static FuzzTestInfo,
pub factory: fn() -> BoxedFuzzTest,
}
inventory::collect!(FuzzTestRegistration);
#[allow(clippy::type_complexity)]
pub static FUZZ_TEST_NAME_TO_FACTORY: LazyLock<HashMap<&str, fn() -> BoxedFuzzTest>> =
LazyLock::new(|| {
inventory::iter
.into_iter()
.map(|&FuzzTestRegistration { info, factory }| (info.name, factory))
.collect()
});
pub struct InputStateAndDomain<I, D> {
pub input_state: Option<I>,
pub domain: D,
}