Struct AllocationSensor

Source
pub struct AllocationSensor { /* private fields */ }
Expand description

A Sensor that records the allocations made by the test function.

It can only be used when the #[global_allocator] is a value of type CountingAllocator<A>.

Its observations are a tuple (u64, u64) where the first element is the number of allocations performed and the second element is the amount of bytes that were allocated.

§Example

use std::alloc::System;
use fuzzcheck::{Arguments, ReasonForStopping, PoolExt};
use fuzzcheck::sensors_and_pools::{CountingAllocator, AllocationSensor, MaximiseObservationPool, DifferentObservations};

// set the global allocator to CountingAllocator so that the allocation sensor
// can retrieve allocation data
#[global_allocator]
static alloc: CountingAllocator<System> = CountingAllocator(System);

// This function fails on the very specific input `[98, 18, 9, 203, 45, 165]`.
// For every matching element, an integer is allocated on the heap and pushed to a vector.
// By trying to maximise the number of allocations, the fuzzer can incrementally find the failing input.
fn test_function(xs: &[u8]) -> bool {
    if xs.len() == 6 {
        let mut v = vec![];

        if xs[0] == 98  { v.push(Box::new(0)) }
        if xs[1] == 18  { v.push(Box::new(1)) }
        if xs[2] == 9   { v.push(Box::new(2)) }
        if xs[3] == 203 { v.push(Box::new(3)) }
        if xs[4] == 45  { v.push(Box::new(4)) }
        if xs[5] == 165 { v.push(Box::new(5)) }

        v.len() != 6
    } else {
        true
    }
}
let sensor = AllocationSensor::default();

// The sensor can be paired with any pool which is compatible with
// observations of type `(u64, u64)`. For example, we can use the following
// pool to maximise both elements of the tuple.
let pool =
    MaximiseObservationPool::<u64>::new("alloc_blocks")
    .and(
        MaximiseObservationPool::<u64>::new("alloc_bytes"),
        None,
        DifferentObservations
    );

// then launch fuzzcheck with this sensor and pool
let result = fuzzcheck::fuzz_test(test_function)
    .default_mutator()
    .serde_serializer()
    .sensor_and_pool(sensor, pool)
    .arguments(Arguments::for_internal_documentation_test())
    .stop_after_first_test_failure(true)
    .launch();

assert!(matches!(
    result.reason_for_stopping,
    ReasonForStopping::TestFailure(x)
        if matches!(
            x.as_slice(),
            [98, 18, 9, 203, 45, 165]
        )
));

Trait Implementations§

Source§

impl Default for AllocationSensor

Source§

fn default() -> AllocationSensor

Returns the “default value” for a type. Read more
Source§

impl SaveToStatsFolder for AllocationSensor

Source§

fn save_to_stats_folder(&self) -> Vec<(PathBuf, Vec<u8>)>

Save information about self to the stats folder Read more
Source§

impl Sensor for AllocationSensor

Source§

type Observations = (u64, u64)

Source§

fn start_recording(&mut self)

Signal to the sensor that it should prepare to record observations
Source§

fn stop_recording(&mut self)

Signal to the sensor that it should stop recording observations
Source§

fn get_observations(&mut self) -> Self::Observations

Access the sensor’s observations

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> SensorExt for T
where T: Sensor,

Source§

fn map<ToObservations, F>(self, map_f: F) -> MapSensor<Self, ToObservations, F>
where Self: Sized, F: Fn(Self::Observations) -> ToObservations,

Maps the observations of the sensor using the given closure. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.