• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! An application to run property tests for `bindgen` with _fuzzed_ C headers
2 //! using `quickcheck`
3 //!
4 //! ## Usage
5 //!
6 //! Print help
7 //! ```bash
8 //! $ cargo run --bin=quickchecking -- -h
9 //! ```
10 //!
11 //! Run with default values
12 //! ```bash
13 //! $ cargo run --bin=quickchecking
14 //! ```
15 //!
16 #![deny(missing_docs)]
17 extern crate clap;
18 extern crate quickchecking;
19 
20 use clap::{App, Arg};
21 use std::path::Path;
22 
23 // Validate CLI argument input for generation range.
validate_generate_range(v: String) -> Result<(), String>24 fn validate_generate_range(v: String) -> Result<(), String> {
25     match v.parse::<usize>() {
26         Ok(_) => Ok(()),
27         Err(_) => Err(String::from(
28             "Generate range could not be converted to a usize.",
29         )),
30     }
31 }
32 
33 // Validate CLI argument input for tests count.
validate_tests_count(v: String) -> Result<(), String>34 fn validate_tests_count(v: String) -> Result<(), String> {
35     match v.parse::<usize>() {
36         Ok(_) => Ok(()),
37         Err(_) => Err(String::from(
38             "Tests count could not be converted to a usize.",
39         )),
40     }
41 }
42 
43 // Validate CLI argument input for fuzzed headers output path.
validate_path(v: String) -> Result<(), String>44 fn validate_path(v: String) -> Result<(), String> {
45     match Path::new(&v).is_dir() {
46         true => Ok(()),
47         false => Err(String::from("Provided directory path does not exist.")),
48     }
49 }
50 
main()51 fn main() {
52     let matches = App::new("quickchecking")
53         .version("0.2.0")
54         .about(
55             "Bindgen property tests with quickcheck. \
56              Generate random valid C code and pass it to the \
57              csmith/predicate.py script",
58         )
59         .arg(
60             Arg::with_name("path")
61                 .short("p")
62                 .long("path")
63                 .value_name("PATH")
64                 .help(
65                     "Optional. Preserve generated headers for inspection, \
66                      provide directory path for header output. [default: None] ",
67                 )
68                 .takes_value(true)
69                 .validator(validate_path),
70         )
71         .arg(
72             Arg::with_name("range")
73                 .short("r")
74                 .long("range")
75                 .value_name("RANGE")
76                 .help(
77                     "Sets the range quickcheck uses during generation. \
78                      Corresponds to things like arbitrary usize and \
79                      arbitrary vector length. This number doesn't have \
80                      to grow much for execution time to increase \
81                      significantly.",
82                 )
83                 .takes_value(true)
84                 .default_value("32")
85                 .validator(validate_generate_range),
86         )
87         .arg(
88             Arg::with_name("count")
89                 .short("c")
90                 .long("count")
91                 .value_name("COUNT")
92                 .help(
93                     "Count / number of tests to run. Running a fuzzed \
94                      header through the predicate.py script can take a \
95                      long time, especially if the generation range is \
96                      large. Increase this number if you're willing to \
97                      wait a while.",
98                 )
99                 .takes_value(true)
100                 .default_value("2")
101                 .validator(validate_tests_count),
102         )
103         .get_matches();
104 
105     let output_path: Option<&str> = matches.value_of("path");
106     let generate_range: usize =
107         matches.value_of("range").unwrap().parse::<usize>().unwrap();
108     let tests: usize =
109         matches.value_of("count").unwrap().parse::<usize>().unwrap();
110 
111     quickchecking::test_bindgen(generate_range, tests, output_path)
112 }
113