summaryrefslogtreecommitdiff
path: root/tests/quickchecking/src
diff options
context:
space:
mode:
Diffstat (limited to 'tests/quickchecking/src')
-rw-r--r--tests/quickchecking/src/bin.rs110
-rw-r--r--tests/quickchecking/src/fuzzers.rs637
-rw-r--r--tests/quickchecking/src/lib.rs126
3 files changed, 0 insertions, 873 deletions
diff --git a/tests/quickchecking/src/bin.rs b/tests/quickchecking/src/bin.rs
deleted file mode 100644
index d2774eb0..00000000
--- a/tests/quickchecking/src/bin.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-//! 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)
-}
diff --git a/tests/quickchecking/src/fuzzers.rs b/tests/quickchecking/src/fuzzers.rs
deleted file mode 100644
index 7c764425..00000000
--- a/tests/quickchecking/src/fuzzers.rs
+++ /dev/null
@@ -1,637 +0,0 @@
-use quickcheck::{Arbitrary, Gen, StdGen};
-use std::fmt;
-use rand::thread_rng;
-
-/// BaseTypeC is used in generation of C headers to represent the C language's
-/// primitive types as well as `void*`.
-#[derive(Debug, Clone)]
-pub struct BaseTypeC {
- /// String representation of C type.
- pub def: String,
-}
-
-/// TypeQualifierC is used in generation of C headers to represent qualifiers
-/// such as `const`.
-#[derive(Debug, Clone)]
-pub struct TypeQualifierC {
- /// String representation of C type qualifier.
- pub def: String,
-}
-
-/// PointerLevelC is used in generation of C headers to represent number of
-/// `*` for pointer types.
-#[derive(Debug, Clone)]
-pub struct PointerLevelC {
- /// String representation of C declaration's pointer level.
- pub def: String,
-}
-
-/// ArrayDimensionC is used in generation of C headers to represent number of
-/// `[]` used to define array types.
-#[derive(Debug, Clone)]
-pub struct ArrayDimensionC {
- /// String representation of C declaration's array dimension.
- pub def: String,
-}
-
-/// BasicTypeDeclarationC is used in generation of C headers to represent
-/// declarations outside of function pointers that take the form
-/// `BaseTypeC` + `TypeQualifierC` + `PointerLevelC` + `ident_id`.
-#[derive(Debug, Clone)]
-pub struct BasicTypeDeclarationC {
- /// The declaration's base type, i.e. `int`.
- pub type_name: BaseTypeC,
- /// The declaration's type qualifier, i.e. `const`.
- pub type_qualifier: TypeQualifierC,
- /// The declaration's pointer level, i.e. `***`.
- pub pointer_level: PointerLevelC,
- /// The declaration's array dimension, i.e. [][][].
- pub array_dimension: ArrayDimensionC,
- /// The declaration's identifier, i.e. ident_N.
- pub ident_id: String,
-}
-
-/// StructDeclarationC is used in generation of C headers to represent the
-/// definition of a struct type.
-#[derive(Debug, Clone)]
-pub struct StructDeclarationC {
- /// The declaration's fields.
- pub fields: DeclarationListC,
- /// The declaration's array dimension, i.e. [][][].
- pub array_dimension: ArrayDimensionC,
- /// The declaration's identifier, i.e. struct_N.
- pub ident_id: String,
-}
-
-/// UnionDeclarationC is used in generation of C headers to represent the
-/// definition of a union type.
-#[derive(Debug, Clone)]
-pub struct UnionDeclarationC {
- /// The declaration's fields.
- pub fields: DeclarationListC,
- /// The declaration's array dimension, i.e. [][][].
- pub array_dimension: ArrayDimensionC,
- /// The declaration's identifier, i.e. union_N.
- pub ident_id: String,
-}
-
-/// FunctionPointerDeclarationC is used in generation of C headers to represent
-/// the definition of a function pointer type.
-#[derive(Debug, Clone)]
-pub struct FunctionPointerDeclarationC {
- /// The function's type qualifier, i.e. `const`.
- pub type_qualifier: TypeQualifierC,
- /// The function's return type, i.e. `int`.
- pub type_name: BaseTypeC,
- /// The function's pointer level, i.e. `***`.
- pub pointer_level: PointerLevelC,
- /// The function's parameters.
- pub params: ParameterListC,
- /// The declaration's identifier, i.e. func_ptr_N.
- pub ident_id: String,
-}
-
-/// FunctionPrototypeC is used in generation of C headers to represent the
-/// definition of a function prototype.
-#[derive(Debug, Clone)]
-pub struct FunctionPrototypeC {
- /// The function's type qualifier, i.e. `const`.
- pub type_qualifier: TypeQualifierC,
- /// The function's return type, i.e. `int`.
- pub type_name: BaseTypeC,
- /// The function's pointer level, i.e. `***`.
- pub pointer_level: PointerLevelC,
- /// The function's parameters.
- pub params: ParameterListC,
- /// The prototype's identifier, i.e. `func_N`.
- pub ident_id: String,
-}
-
-/// ParameterC is used in generation of C headers to represent the
-/// definition function parameters.
-#[derive(Debug, Clone)]
-pub struct ParameterC {
- /// The parameter's type qualifier, i.e. `const`.
- pub type_qualifier: TypeQualifierC,
- /// The parameter's base type, i.e. `int`.
- pub type_name: BaseTypeC,
- /// The parameter's pointer level, i.e. `***`.
- pub pointer_level: PointerLevelC,
-}
-
-/// ParameterListC is used in generation of C headers to represent a list of
-/// definitions of function parameters.
-#[derive(Debug, Clone)]
-pub struct ParameterListC {
- /// Parameters that define a C function signature.
- pub params: Vec<ParameterC>,
-}
-
-/// DeclarationC is used in generation of C headers to represent all supported
-/// C type declarations allowed in the generated header.
-#[derive(Debug, Clone)]
-pub enum DeclarationC {
- /// Function prototype declaration kind.
- FunctionDecl(FunctionPrototypeC),
- /// Function pointer declaration kind.
- FunctionPtrDecl(FunctionPointerDeclarationC),
- /// Struct declaration kind.
- StructDecl(StructDeclarationC),
- /// Union declaration kind.
- UnionDecl(UnionDeclarationC),
- /// Basic type declaration kind.
- VariableDecl(BasicTypeDeclarationC),
-}
-
-/// DeclarationListC is used in generation of C headers to represent a list of
-/// declarations.
-#[derive(Debug, Clone)]
-pub struct DeclarationListC {
- /// Grouping of C declarations.
- pub decls: Vec<DeclarationC>,
-}
-
-/// HeaderC is used in generation of C headers to represent a collection of
-/// declarations.
-#[derive(Clone)]
-pub struct HeaderC {
- /// The header's declarations.
- pub def: DeclarationListC,
-}
-
-/// MakeUnique is used in generation of C headers to make declaration
-/// identifiers unique by incorporating the `stamp` parameter into it's name.
-trait MakeUnique {
- fn make_unique(&mut self, stamp: usize);
-}
-
-/// MakeUnique is used in generation of C headers to make DeclarationC
-/// identifiers unique.
-impl MakeUnique for DeclarationC {
- fn make_unique(&mut self, stamp: usize) {
- match *self {
- DeclarationC::FunctionDecl(ref mut d) => d.make_unique(stamp),
- DeclarationC::FunctionPtrDecl(ref mut d) => d.make_unique(stamp),
- DeclarationC::StructDecl(ref mut d) => d.make_unique(stamp),
- DeclarationC::UnionDecl(ref mut d) => d.make_unique(stamp),
- DeclarationC::VariableDecl(ref mut d) => d.make_unique(stamp),
- }
- }
-}
-
-/// A qucickcheck trait for describing how DeclarationC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for DeclarationC {
- fn arbitrary<G: Gen>(g: &mut G) -> DeclarationC {
- match g.gen_range(0, 5) {
- 0 => DeclarationC::FunctionDecl(FunctionPrototypeC::arbitrary(g)),
- 1 => DeclarationC::FunctionPtrDecl(FunctionPointerDeclarationC::arbitrary(g)),
- 2 => DeclarationC::StructDecl(StructDeclarationC::arbitrary(g)),
- 3 => DeclarationC::UnionDecl(UnionDeclarationC::arbitrary(g)),
- 4 => DeclarationC::VariableDecl(BasicTypeDeclarationC::arbitrary(g)),
- _ => unreachable!(),
- }
- }
-}
-
-/// Enables to string and format for DeclarationC types.
-impl fmt::Display for DeclarationC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match *self {
- DeclarationC::FunctionPtrDecl(ref d) => write!(f, "{}", d),
- DeclarationC::StructDecl(ref d) => write!(f, "{}", d),
- DeclarationC::UnionDecl(ref d) => write!(f, "{}", d),
- DeclarationC::VariableDecl(ref d) => write!(f, "{}", d),
- DeclarationC::FunctionDecl(ref d) => write!(f, "{}", d),
- }
- }
-}
-
-/// A qucickcheck trait for describing how DeclarationListC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for DeclarationListC {
- fn arbitrary<G: Gen>(g: &mut G) -> DeclarationListC {
- DeclarationListC {
- decls: Arbitrary::arbitrary(g),
- }
- }
-}
-
-/// Enables to string and format for DeclarationListC types.
-impl fmt::Display for DeclarationListC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut display = String::new();
- for decl in &self.decls {
- display += &format!("{}", decl);
- }
- write!(f, "{}", display)
- }
-}
-
-/// A qucickcheck trait for describing how BaseTypeC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for BaseTypeC {
- fn arbitrary<G: Gen>(g: &mut G) -> BaseTypeC {
- // Special case `long double` until issue #550 is resolved.
- let base_type = vec![
- "char",
- "signed char",
- "unsigned char",
- "short",
- "short int",
- "signed short",
- "signed short int",
- "unsigned short",
- "unsigned short int",
- "int",
- "signed",
- "signed int",
- "unsigned",
- "unsigned int",
- "long",
- "long int",
- "signed long",
- "signed long int",
- "unsigned long",
- "unsigned long int",
- "long long",
- "long long int",
- "signed long long",
- "signed long long int",
- "unsigned long long",
- "unsigned long long int",
- "float",
- "double",
- #[cfg(feature = "long-doubles")]
- "long double",
- "void*",
- ];
- BaseTypeC {
- def: String::from(*g.choose(&base_type).unwrap()),
- }
- }
-}
-
-/// Enables to string and format for BaseTypeC types,
-impl fmt::Display for BaseTypeC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.def)
- }
-}
-
-/// A qucickcheck trait for describing how TypeQualifierC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for TypeQualifierC {
- fn arbitrary<G: Gen>(g: &mut G) -> TypeQualifierC {
- let qualifier = vec!["const", ""];
- TypeQualifierC {
- def: String::from(*g.choose(&qualifier).unwrap()),
- }
- }
-}
-
-/// Enables to string and format for TypeQualifierC types.
-impl fmt::Display for TypeQualifierC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.def)
- }
-}
-
-/// A qucickcheck trait for describing how PointerLevelC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for PointerLevelC {
- fn arbitrary<G: Gen>(g: &mut G) -> PointerLevelC {
- PointerLevelC {
- // 16 is an arbitrary "not too big" number for capping pointer level.
- def: (0..g.gen_range(0, 16)).map(|_| "*").collect::<String>(),
- }
- }
-}
-
-/// Enables to string and format for PointerLevelC types.
-impl fmt::Display for PointerLevelC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.def)
- }
-}
-
-/// A qucickcheck trait for describing how ArrayDimensionC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for ArrayDimensionC {
- fn arbitrary<G: Gen>(g: &mut G) -> ArrayDimensionC {
- // Keep these small, clang complains when they get too big.
- let dimensions = g.gen_range(0, 5);
- let mut def = String::new();
-
- let lower_bound;
- if cfg!(feature = "zero-sized-arrays") {
- lower_bound = 0;
- } else {
- lower_bound = 1;
- }
-
- for _ in 1..dimensions {
- // 16 is an arbitrary "not too big" number for capping array size.
- def += &format!("[{}]", g.gen_range(lower_bound, 16));
- }
- ArrayDimensionC { def }
- }
-}
-
-/// Enables to string and format for ArrayDimensionC types.
-impl fmt::Display for ArrayDimensionC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.def)
- }
-}
-
-/// MakeUnique is used in generation of C headers to make BasicTypeDeclarationC
-/// identifiers unique.
-impl MakeUnique for BasicTypeDeclarationC {
- fn make_unique(&mut self, stamp: usize) {
- self.ident_id += &format!("_{}", stamp);
- }
-}
-
-/// A qucickcheck trait for describing how BasicTypeDeclarationC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for BasicTypeDeclarationC {
- fn arbitrary<G: Gen>(g: &mut G) -> BasicTypeDeclarationC {
- BasicTypeDeclarationC {
- type_qualifier: Arbitrary::arbitrary(g),
- type_name: Arbitrary::arbitrary(g),
- pointer_level: Arbitrary::arbitrary(g),
- array_dimension: Arbitrary::arbitrary(g),
- ident_id: format!("{}", usize::arbitrary(g)),
- }
- }
-}
-
-/// Enables to string and format for BasicTypeDeclarationC types.
-impl fmt::Display for BasicTypeDeclarationC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{} {} {} ident_{}{};",
- self.type_qualifier,
- self.type_name,
- self.pointer_level,
- self.ident_id,
- self.array_dimension
- )
- }
-}
-
-/// MakeUnique is used in generation of C headers to make StructDeclarationC
-/// identifiers unique.
-impl MakeUnique for StructDeclarationC {
- fn make_unique(&mut self, stamp: usize) {
- self.ident_id += &format!("_{}", stamp);
- }
-}
-
-/// A qucickcheck trait for describing how StructDeclarationC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for StructDeclarationC {
- fn arbitrary<G: Gen>(g: &mut G) -> StructDeclarationC {
- // Reduce generator size as a method of putting a bound on recursion.
- // When size < 1 the empty list is generated.
- let reduced_size: usize = (g.size() / 2) as usize + 1;
- let mut decl_list: DeclarationListC =
- Arbitrary::arbitrary(&mut StdGen::new(thread_rng(), reduced_size));
- let mut fields: DeclarationListC = DeclarationListC { decls: vec![] };
-
- for (i, decl) in decl_list.decls.iter_mut().enumerate() {
- match *decl {
- DeclarationC::FunctionDecl(_) => {}
- ref mut decl => {
- decl.make_unique(i);
- fields.decls.push(decl.clone());
- }
- }
- }
-
- StructDeclarationC {
- fields,
- ident_id: format!("{}", usize::arbitrary(g)),
- array_dimension: Arbitrary::arbitrary(g),
- }
- }
-}
-
-/// Enables to string and format for StructDeclarationC types.
-impl fmt::Display for StructDeclarationC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "struct {{ {} }} struct_{}{};",
- self.fields,
- self.ident_id,
- self.array_dimension
- )
- }
-}
-
-/// MakeUnique is used in generation of C headers to make UnionDeclarationC
-/// identifiers unique.
-impl MakeUnique for UnionDeclarationC {
- fn make_unique(&mut self, stamp: usize) {
- self.ident_id += &format!("_{}", stamp);
- }
-}
-
-/// A qucickcheck trait for describing how UnionDeclarationC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for UnionDeclarationC {
- fn arbitrary<G: Gen>(g: &mut G) -> UnionDeclarationC {
- // Reduce generator size as a method of putting a bound on recursion.
- // When size < 1 the empty list is generated.
- let reduced_size: usize = (g.size() / 2) as usize + 1;
- let mut decl_list: DeclarationListC =
- Arbitrary::arbitrary(&mut StdGen::new(thread_rng(), reduced_size));
- let mut fields: DeclarationListC = DeclarationListC { decls: vec![] };
-
- for (i, decl) in decl_list.decls.iter_mut().enumerate() {
- match *decl {
- DeclarationC::FunctionDecl(_) => {}
- ref mut decl => {
- decl.make_unique(i);
- fields.decls.push(decl.clone());
- }
- }
- }
-
- UnionDeclarationC {
- fields,
- ident_id: format!("{}", usize::arbitrary(g)),
- array_dimension: Arbitrary::arbitrary(g),
- }
- }
-}
-
-/// Enables to string and format for UnionDeclarationC types.
-impl fmt::Display for UnionDeclarationC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "union {{ {} }} union_{}{};",
- self.fields,
- self.ident_id,
- self.array_dimension
- )
- }
-}
-
-/// MakeUnique is used in generation of C headers to make
-/// FunctionPointerDeclarationC identifiers unique.
-impl MakeUnique for FunctionPointerDeclarationC {
- fn make_unique(&mut self, stamp: usize) {
- self.ident_id += &format!("_{}", stamp);
- }
-}
-
-/// A qucickcheck trait for describing how FunctionPointerDeclarationC types can
-/// be randomly generated and shrunk.
-impl Arbitrary for FunctionPointerDeclarationC {
- fn arbitrary<G: Gen>(g: &mut G) -> FunctionPointerDeclarationC {
- FunctionPointerDeclarationC {
- type_qualifier: Arbitrary::arbitrary(g),
- type_name: Arbitrary::arbitrary(g),
- pointer_level: Arbitrary::arbitrary(g),
- params: Arbitrary::arbitrary(g),
- ident_id: format!("{}", usize::arbitrary(g)),
- }
- }
-}
-
-/// Enables to string and format for FunctionPointerDeclarationC types.
-impl fmt::Display for FunctionPointerDeclarationC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{} {} {} (*func_ptr_{})({});",
- self.type_qualifier,
- self.type_name,
- self.pointer_level,
- self.ident_id,
- self.params
- )
- }
-}
-
-/// MakeUnique is used in generation of C headers to make FunctionPrototypeC
-/// identifiers unique.
-impl MakeUnique for FunctionPrototypeC {
- fn make_unique(&mut self, stamp: usize) {
- self.ident_id += &format!("_{}", stamp);
- }
-}
-
-/// A qucickcheck trait for describing how FunctionPrototypeC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for FunctionPrototypeC {
- fn arbitrary<G: Gen>(g: &mut G) -> FunctionPrototypeC {
- FunctionPrototypeC {
- type_qualifier: Arbitrary::arbitrary(g),
- type_name: Arbitrary::arbitrary(g),
- pointer_level: Arbitrary::arbitrary(g),
- params: Arbitrary::arbitrary(g),
- ident_id: format!("{}", usize::arbitrary(g)),
- }
- }
-}
-
-/// Enables to string and format for FunctionPrototypeC types.
-impl fmt::Display for FunctionPrototypeC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{} {} {} func_{}({});",
- self.type_qualifier,
- self.type_name,
- self.pointer_level,
- self.ident_id,
- self.params
- )
- }
-}
-
-/// A qucickcheck trait for describing how ParameterC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for ParameterC {
- fn arbitrary<G: Gen>(g: &mut G) -> ParameterC {
- ParameterC {
- type_qualifier: Arbitrary::arbitrary(g),
- type_name: Arbitrary::arbitrary(g),
- pointer_level: Arbitrary::arbitrary(g),
- }
- }
-}
-
-/// Enables to string and format for ParameterC types.
-impl fmt::Display for ParameterC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{} {} {}",
- self.type_qualifier,
- self.type_name,
- self.pointer_level
- )
- }
-}
-
-/// A qucickcheck trait for describing how ParameterListC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for ParameterListC {
- fn arbitrary<G: Gen>(g: &mut G) -> ParameterListC {
- ParameterListC {
- params: Arbitrary::arbitrary(g),
- }
- }
-}
-
-/// Enables to string and format for ParameterListC types.
-impl fmt::Display for ParameterListC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut display = String::new();
- for (i, p) in self.params.iter().enumerate() {
- match i {
- 0 => display += &format!("{}", p),
- _ => display += &format!(",{}", p),
- }
- }
- write!(f, "{}", display)
- }
-}
-
-/// A qucickcheck trait for describing how HeaderC types can be
-/// randomly generated and shrunk.
-impl Arbitrary for HeaderC {
- fn arbitrary<G: Gen>(g: &mut G) -> HeaderC {
- let mut decl_list: DeclarationListC = Arbitrary::arbitrary(g);
- for (i, decl) in decl_list.decls.iter_mut().enumerate() {
- decl.make_unique(i);
- }
- HeaderC { def: decl_list }
- }
-}
-
-/// Enables to string and format for HeaderC types.
-impl fmt::Display for HeaderC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut display = String::new();
- for decl in &self.def.decls {
- display += &format!("{}", decl);
- }
- write!(f, "{}", display)
- }
-}
-
-/// Use Display trait for Debug so that any failing property tests report
-/// generated C code rather than the data structures that contain it.
-impl fmt::Debug for HeaderC {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self)
- }
-}
diff --git a/tests/quickchecking/src/lib.rs b/tests/quickchecking/src/lib.rs
deleted file mode 100644
index d8633dfb..00000000
--- a/tests/quickchecking/src/lib.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-//! A library to generate __fuzzed__ C headers for use with `quickcheck`
-//!
-//! ## Example
-//!
-//! ```rust
-//! extern crate quickcheck;
-//! extern crate quickchecking;
-//! extern crate rand;
-//! use quickcheck::{Arbitrary, Gen, StdGen};
-//! use quickchecking::fuzzers;
-//! use rand::thread_rng;
-//!
-//! fn main() {
-//! let generate_range: usize = 10; // Determines things like the length of
-//! // arbitrary vectors generated.
-//! let header = fuzzers::HeaderC::arbitrary(
-//! &mut StdGen::new(thread_rng(), generate_range));
-//! println!("{}", header);
-//! }
-//! ```
-//!
-#![deny(missing_docs)]
-#[macro_use]
-extern crate lazy_static;
-extern crate quickcheck;
-extern crate rand;
-extern crate tempdir;
-
-use std::sync::Mutex;
-use quickcheck::{QuickCheck, StdGen, TestResult};
-use std::fs::File;
-use std::io::Write;
-use tempdir::TempDir;
-use std::process::{Command, Output};
-use std::path::PathBuf;
-use std::error::Error;
-use rand::thread_rng;
-
-/// Contains definitions of and impls for types used to fuzz C declarations.
-pub mod fuzzers;
-
-// Global singleton, manages context across tests. For now that context is
-// only the output_path for inspecting fuzzed headers (if specified).
-struct Context {
- output_path: Option<String>,
-}
-
-// Initialize global context.
-lazy_static! {
- static ref CONTEXT: Mutex<Context> = Mutex::new(Context { output_path: None });
-}
-
-// Passes fuzzed header to the `csmith-fuzzing/predicate.py` script, returns
-// output of the associated command.
-fn run_predicate_script(header: fuzzers::HeaderC) -> Result<Output, Box<Error>> {
- let dir = TempDir::new("bindgen_prop")?;
- let header_path = dir.path().join("prop_test.h");
-
- let mut header_file = File::create(&header_path)?;
- header_file.write_all(header.to_string().as_bytes())?;
- header_file.sync_all()?;
-
- let header_path_string;
- match header_path.into_os_string().into_string() {
- Ok(s) => header_path_string = s,
- Err(_) => return Err(From::from("error converting path into String")),
- }
-
- let mut predicate_script_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
- predicate_script_path.push("../../csmith-fuzzing/predicate.py");
-
- let predicate_script_path_string;
- match predicate_script_path.into_os_string().into_string() {
- Ok(s) => predicate_script_path_string = s,
- Err(_) => return Err(From::from("error converting path into String")),
- }
-
- // Copy generated temp files to output_path directory for inspection.
- // If `None`, output path not specified, don't copy.
- match CONTEXT.lock().unwrap().output_path {
- Some(ref path) => {
- Command::new("cp")
- .arg("-a")
- .arg(&dir.path().to_str().unwrap())
- .arg(&path)
- .output()?;
- }
- None => {}
- }
-
- Ok(Command::new(&predicate_script_path_string)
- .arg(&header_path_string)
- .output()?)
-}
-
-// Generatable property. Pass generated headers off to run through the
-// `csmith-fuzzing/predicate.py` script. Success is measured by the success
-// status of that command.
-fn bindgen_prop(header: fuzzers::HeaderC) -> TestResult {
- match run_predicate_script(header) {
- Ok(o) => return TestResult::from_bool(o.status.success()),
- Err(e) => {
- println!("{:?}", e);
- return TestResult::from_bool(false);
- }
- }
-}
-
-/// Instantiate a Quickcheck object and use it to run property tests using
-/// fuzzed C headers generated with types defined in the `fuzzers` module.
-/// Success/Failure is dictated by the result of passing the fuzzed headers
-/// to the `csmith-fuzzing/predicate.py` script.
-pub fn test_bindgen(generate_range: usize, tests: usize, output_path: Option<&str>) {
- match output_path {
- Some(path) => {
- CONTEXT.lock().unwrap().output_path =
- Some(String::from(PathBuf::from(path).to_str().unwrap()));
- }
- None => {} // Path not specified, don't provide output.
- }
-
- QuickCheck::new()
- .tests(tests)
- .gen(StdGen::new(thread_rng(), generate_range))
- .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult)
-}