//! An application to run property tests for `bindgen` with _fuzzed_ C headers //! using `quickcheck` //! //! ## Usage //! //! Print help //! ```bash //! $ cargo run --bin=quickchecking -- -h //! ``` //! //! Run with default values //! ```bash //! $ cargo run --bin=quickchecking //! ``` //! #![deny(missing_docs)] extern crate clap; extern crate quickchecking; use clap::{App, Arg}; use std::path::Path; // Validate CLI argument input for generation range. fn validate_generate_range(v: String) -> Result<(), String> { match v.parse::() { Ok(_) => Ok(()), Err(_) => Err(String::from( "Generate range could not be converted to a usize.", )), } } // Validate CLI argument input for tests count. fn validate_tests_count(v: String) -> Result<(), String> { match v.parse::() { Ok(_) => Ok(()), Err(_) => Err(String::from( "Tests count could not be converted to a usize.", )), } } // Validate CLI argument input for fuzzed headers output path. fn validate_path(v: String) -> Result<(), String> { match Path::new(&v).is_dir() { true => Ok(()), false => Err(String::from("Provided directory path does not exist.")), } } fn main() { let matches = App::new("quickchecking") .version("0.2.0") .about( "Bindgen property tests with quickcheck. \ Generate random valid C code and pass it to the \ csmith/predicate.py script", ) .arg( Arg::with_name("path") .short("p") .long("path") .value_name("PATH") .help( "Optional. Preserve generated headers for inspection, \ provide directory path for header output. [default: None] ", ) .takes_value(true) .validator(validate_path), ) .arg( Arg::with_name("range") .short("r") .long("range") .value_name("RANGE") .help( "Sets the range quickcheck uses during generation. \ Corresponds to things like arbitrary usize and \ arbitrary vector length. This number doesn't have \ to grow much for execution time to increase \ significantly.", ) .takes_value(true) .default_value("32") .validator(validate_generate_range), ) .arg( Arg::with_name("count") .short("c") .long("count") .value_name("COUNT") .help( "Count / number of tests to run. Running a fuzzed \ header through the predicate.py script can take a \ long time, especially if the generation range is \ large. Increase this number if you're willing to \ wait a while.", ) .takes_value(true) .default_value("2") .validator(validate_tests_count), ) .get_matches(); let output_path: Option<&str> = matches.value_of("path"); let generate_range: usize = matches.value_of("range").unwrap().parse::().unwrap(); let tests: usize = matches.value_of("count").unwrap().parse::().unwrap(); quickchecking::test_bindgen(generate_range, tests, output_path) }