summaryrefslogtreecommitdiff
path: root/bindgen-tests/tests/quickchecking/src/bin.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bindgen-tests/tests/quickchecking/src/bin.rs')
-rw-r--r--bindgen-tests/tests/quickchecking/src/bin.rs112
1 files changed, 112 insertions, 0 deletions
diff --git a/bindgen-tests/tests/quickchecking/src/bin.rs b/bindgen-tests/tests/quickchecking/src/bin.rs
new file mode 100644
index 00000000..f2b52e82
--- /dev/null
+++ b/bindgen-tests/tests/quickchecking/src/bin.rs
@@ -0,0 +1,112 @@
+//! 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::<usize>() {
+ 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::<usize>() {
+ 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::<usize>().unwrap();
+ let tests: usize =
+ matches.value_of("count").unwrap().parse::<usize>().unwrap();
+
+ quickchecking::test_bindgen(generate_range, tests, output_path)
+}