14 releases (8 breaking)
0.11.0 | Jun 8, 2024 |
---|---|
0.10.0 | Sep 28, 2023 |
0.9.2 | May 15, 2023 |
0.9.1 | Mar 30, 2023 |
0.3.0 | Dec 5, 2019 |
#23 in #property
26,363 downloads per month
Used in 33 crates
(via bolero-generator)
27KB
549 lines
bolero-generator
value generator for testing and fuzzing
Installation
bolero-generator
is on crates.io
and can be added to a project like so:
$ cargo add --dev bolero-generator
Usage
Simple type generator
use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator};
let input = &[1, 2, 3, 4, 5];
let driver = FuzzDriver::new(&input);
let value = gen::<u8>().generate(&mut driver).unwrap();
Parameterized value generator
use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator};
let input = &[1, 2, 3, 4, 5];
let driver = FuzzDriver::new(&input);
let value = gen::<u8>().with().bounds(5..=42).generate(&mut driver).unwrap();
Nested parameterized value generator
use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator};
let input = &[1, 2, 3, 4, 5];
let driver = FuzzDriver::new(&input);
let value = (
gen::<u8>(),
gen::<u8>()
.with()
.bounds(5..=42), // between 5 and including 42
gen::<Vec<u32>>()
.with()
.len(6usize) // always have 6 values
.values(7..500), // between 7 and 500
).generate(&mut driver).unwrap();
Value modifications with map
and and_then
use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator};
let input = &[1, 2, 3, 4, 5];
let driver = FuzzDriver::new(&input);
let value = gen::<u8>()
.map(|value| value / 2)
.and_then(|value| gen::<Vec<u8>>().with().len(value as usize))
.generate(&mut driver)
.unwrap()
Prior work
arbitrary
While bolero
draws a lot of inspiration from the rust_arbitrary
crate, several improvements were added:
Parameterized generation
Arbitrary supports basic value generation, given a type:
let driver = RingBuffer::new(input, 20).unwrap();
let value: u8 = Arbitrary::arbitrary(&mut driver).unwrap();
This can be limiting when constraints need to be applied to the type:
let driver = RingBuffer::new(input, 20).unwrap();
let value: u8 = Arbitrary::arbitrary(&mut driver).unwrap();
// make sure `value` in between 8 and 20
let value = (value % (20 - 8)) + 8;
The same issue arises from container sizes being limited to 0-255:
let driver = RingBuffer::new(input, 20).unwrap();
let mut value: Vec<u8> = Arbitrary::arbitrary(&mut driver).unwrap();
// make sure `value` has at least 3 items
while value.len() < 3 {
value.push(Arbitrary::arbitrary(&mut driver).unwrap());
}
// make sure `value` has no more than 42 items
while value.len() > 42 {
value.pop();
}
bolero
supports value generation, given a type:
let driver = FuzzDriver::new(&[1, 2, 3, 4, 5]);
let value = gen::<u8>().generate(&mut driver).unwrap();
Parameterized generators can be created by calling with()
let driver = FuzzDriver::new(&[1, 2, 3, 4, 5]);
let value = gen::<u8>().with().bounds(8..=20).generate(&mut driver).unwrap();
Container sizes can be specified as well:
let driver = FuzzDriver::new(&[1, 2, 3, 4, 5]);
let value = gen::<Vec<u8>>().with().len(3usize..=42).generate(&mut driver).unwrap();
#![no_std]
compatibility
bolero
supports environments that require #![no_std]
.
Dependencies
~3.5MB
~77K SLoC