fuzzing: Add initial API call fuzzer

We only generate *valid* sequences of API calls. To do this, we keep track of
what objects we've already created in earlier API calls via the `Scope` struct.

To generate even-more-pathological sequences of API calls, we use [swarm
testing]:

> In swarm testing, the usual practice of potentially including all features
> in every test case is abandoned. Rather, a large “swarm” of randomly
> generated configurations, each of which omits some features, is used, with
> configurations receiving equal resources.

[swarm testing]: https://www.cs.utah.edu/~regehr/papers/swarm12.pdf

There are more public APIs and instance introspection APIs that we have than
this fuzzer exercises right now. We will need a better generator of valid Wasm
than `wasm-opt -ttf` to really get the most out of those currently-unexercised
APIs, since the Wasm modules generated by `wasm-opt -ttf` don't import and
export a huge variety of things.
This commit is contained in:
Nick Fitzgerald
2019-12-06 15:48:46 -08:00
parent 7d415df209
commit 0cde30197d
6 changed files with 360 additions and 4 deletions

View File

@@ -8,15 +8,28 @@
//! wrapper over an external tool, such that the wrapper implements the
//! `Arbitrary` trait for the wrapped external tool.
pub mod api;
use arbitrary::{Arbitrary, Unstructured};
use std::fmt;
/// A Wasm test case generator that is powered by Binaryen's `wasm-opt -ttf`.
#[derive(Debug)]
#[derive(Clone)]
pub struct WasmOptTtf {
/// The raw, encoded Wasm bytes.
pub wasm: Vec<u8>,
}
impl fmt::Debug for WasmOptTtf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"WasmOptTtf {{ wasm: wat::parse_str(r###\"\n{}\n\"###).unwrap() }}",
wasmprinter::print_bytes(&self.wasm).expect("valid wasm should always disassemble")
)
}
}
impl Arbitrary for WasmOptTtf {
fn arbitrary<U>(input: &mut U) -> Result<Self, U::Error>
where