| commit | 02d30c2c360ea27b00dca8597852e9df638139b5 | [log] [tgz] |
|---|---|---|
| author | Android Build Coastguard Worker <[email protected]> | Fri Mar 10 04:19:20 2023 +0000 |
| committer | Automerger Merge Worker <[email protected]> | Fri Mar 10 04:19:20 2023 +0000 |
| tree | dc2692d0085b040a1674a3092cf72cedba7404ed | |
| parent | c3bc8900effa71b1ce9a09ae5bb902720b18a1dd [diff] | |
| parent | 39c38fdbd1fbad18ba3e6d9d00d6f36616cb2f9f [diff] |
Snap for 9719949 from d39159148f0f8bd6e409690cad63642932cf9d4a to udc-release am: 39c38fdbd1 Original change: https://googleplex-android-review.googlesource.com/c/platform/external/rust/crates/arbitrary/+/21946642 Change-Id: I9f6a55612fa7d705cd4751abdd8de27452a09c50 Signed-off-by: Automerger Merge Worker <[email protected]>
The Arbitrary crate lets you construct arbitrary instances of a type.
This crate is primarily intended to be combined with a fuzzer like libFuzzer and cargo-fuzz or AFL, and to help you turn the raw, untyped byte buffers that they produce into well-typed, valid, structured values. This allows you to combine structure-aware test case generation with coverage-guided, mutation-based fuzzers.
Read the API documentation on docs.rs!
Say you're writing a color conversion library, and you have an Rgb struct to represent RGB colors. You might want to implement Arbitrary for Rgb so that you could take arbitrary Rgb instances in a test function that asserts some property (for example, asserting that RGB converted to HSL and converted back to RGB always ends up exactly where we started).
ArbitraryAutomatically deriving the Arbitrary trait is the recommended way to implement Arbitrary for your types.
Automatically deriving Arbitrary requires you to enable the "derive" cargo feature:
# Cargo.toml [dependencies] arbitrary = { version = "1", features = ["derive"] }
And then you can simply add #[derive(Arbitrary)] annotations to your types:
// rgb.rs use arbitrary::Arbitrary; #[derive(Arbitrary)] pub struct Rgb { pub r: u8, pub g: u8, pub b: u8, }
This can be particular handy if your structure uses a type that does not implement Arbitrary or you want to have more customization for particular fields.
#[derive(Arbitrary)] pub struct Rgba { // set `r` to Default::default() #[arbitrary(default)] pub r: u8, // set `g` to 255 #[arbitrary(value = 255)] pub g: u8, // Generate `b` with a custom function of type // // fn(&mut Unstructured) -> arbitrary::Result<T> // // where `T` is the field's type. #[arbitrary(with = arbitrary_b)] pub b: u8, // Generate `a` with a custom closure (shortuct to avoid a custom funciton) #[arbitrary(with = |u: &mut Unstructured| u.int_in_range(0..=64))] pub a: u8, } fn arbitrary_b(u: &mut Unstructured) -> arbitrary::Result<u8> { u.int_in_range(64..=128) }
Arbitrary By HandAlternatively, you can write an Arbitrary implementation by hand:
// rgb.rs use arbitrary::{Arbitrary, Result, Unstructured}; #[derive(Copy, Clone, Debug)] pub struct Rgb { pub r: u8, pub g: u8, pub b: u8, } impl<'a> Arbitrary<'a> for Rgb { fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { let r = u8::arbitrary(u)?; let g = u8::arbitrary(u)?; let b = u8::arbitrary(u)?; Ok(Rgb { r, g, b }) } }
Licensed under dual MIT or Apache-2.0 at your choice.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.