Skip to content

Commit

Permalink
Merge pull request #71 from srlabs/integration-tests
Browse files Browse the repository at this point in the history
Add integration tests and CI workflow
  • Loading branch information
louismerlin authored Oct 11, 2023
2 parents 67d75ce + cd0ce7d commit f44530c
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 11 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Cargo Build & Test

on:
push:
pull_request:

env:
CARGO_TERM_COLOR: always

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cargo sort
run: cargo install cargo-sort && cargo sort --check
- name: Format
run: cargo fmt --check
- name: Clippy
run: cargo clippy --all-targets -- -D warnings
build_and_test:
name: Rust project - latest
runs-on: ubuntu-latest
strategy:
matrix:
toolchain:
- stable
- beta
- nightly
steps:
- uses: actions/checkout@v3
- run: sudo apt-get install binutils-dev libunwind-dev gnuplot
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- run: cargo install cargo-afl honggfuzz grcov
- run: cargo install --path . --verbose
- run: cargo test --verbose
60 changes: 58 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 23 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,38 @@ members = [
]

[dependencies]
afl = { version = "0.14.1", default-features = false, optional = true }
anyhow = { version = "1.0.75", optional = true }
cargo_metadata = { version = "0.18.0", optional = true }
clap = { version = "4.4.6", features = ["cargo", "derive", "env"], optional = true }
console = { version = "0.15.7", optional = true }
env_logger = { version = "0.10.0", optional = true }
glob = { version = "0.3.1", optional = true }
toml = { version = "0.7.6", optional = true }
anyhow = { version = "1.0.75", optional = true }
afl = { version = "0.14.1", default-features = false, optional = true }
# We use our own fork of honggfuzz to use the tool's latest release
# https://github.com/rust-fuzz/honggfuzz-rs/pull/85
honggfuzz = { package = "ziggy-honggfuzz-2", version = "0.5.55", optional = true }
serde_json = { version = "1.0.105", optional = true }
libc = { version = "0.2.147", optional = true }
log = { version = "0.4.20", optional = true }
env_logger = { version = "0.10.0", optional = true }
strip-ansi-escapes = { version = "0.2.0", optional = true }
rand = { version = "0.8", optional = true }
libc = { version = "0.2.147", optional = true }
serde_json = { version = "1.0.105", optional = true }
strip-ansi-escapes = { version = "0.2.0", optional = true }
time-humanize = { version = "0.1.3", optional = true }
toml = { version = "0.7.6", optional = true }

[features]
default = ["cli"]
cli = ["clap", "console", "glob", "toml", "anyhow", "serde_json", "log", "env_logger", "strip-ansi-escapes", "rand", "libc", "time-humanize"]
cli = [
"clap",
"console",
"glob",
"toml",
"anyhow",
"serde_json",
"log",
"env_logger",
"strip-ansi-escapes",
"rand",
"libc",
"time-humanize",
"cargo_metadata",
]
2 changes: 1 addition & 1 deletion src/bin/cargo-ziggy/plot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl Plot {
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));

let fuzzer_data_dir = format!(
"./{}/{}/afl/{}/",
"{}/{}/afl/{}/",
&self.ziggy_output.display(),
&self.target,
&self.input
Expand Down
98 changes: 98 additions & 0 deletions tests/arbitrary_fuzz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use std::{
env, fs,
path::PathBuf,
process, thread,
time::{Duration, SystemTime, UNIX_EPOCH},
};

fn kill_subprocesses_recursively(pid: &str) {
let subprocesses = process::Command::new("pgrep")
.arg(&format!("-P{pid}"))
.output()
.unwrap();

for subprocess in std::str::from_utf8(&subprocesses.stdout)
.unwrap()
.split('\n')
{
if subprocess.is_empty() {
continue;
}

kill_subprocesses_recursively(subprocess);
}

println!("Killing pid {pid}");
unsafe {
libc::kill(pid.parse::<i32>().unwrap(), libc::SIGTERM);
}
}

#[test]
fn integration() {
let unix_time = format!(
"{}",
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
);
let temp_dir_path = env::temp_dir().join(unix_time);
let metadata = cargo_metadata::MetadataCommand::new().exec().unwrap();
let workspace_root: PathBuf = metadata.workspace_root.into();
let target_directory: PathBuf = metadata.target_directory.into();
let cargo_ziggy = target_directory.join("debug").join("cargo-ziggy");
let fuzzer_directory = workspace_root.join("examples").join("arbitrary");

// TODO Custom target path

// cargo ziggy build
let build_status = process::Command::new(cargo_ziggy.clone())
.arg("ziggy")
.arg("build")
.current_dir(fuzzer_directory.clone())
.status()
.expect("failed to run `cargo ziggy build`");

assert!(build_status.success(), "`cargo ziggy build` failed");

// cargo ziggy fuzz -j 2 -t 5 -o temp_dir
let fuzzer = process::Command::new(cargo_ziggy)
.arg("ziggy")
.arg("fuzz")
.arg("-j2")
.arg("-t5")
.env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display()))
.env("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "1")
.env("AFL_SKIP_CPUFREQ", "1")
.current_dir(fuzzer_directory)
.spawn()
.expect("failed to run `cargo ziggy fuzz`");
thread::sleep(Duration::from_secs(10));
kill_subprocesses_recursively(&format!("{}", fuzzer.id()));

assert!(temp_dir_path
.join("arbitrary-fuzz")
.join("afl")
.join("mainaflfuzzer")
.join("fuzzer_stats")
.is_file());
assert!(
fs::read_dir(
temp_dir_path
.join("arbitrary-fuzz")
.join("afl")
.join("mainaflfuzzer")
.join("crashes")
)
.unwrap()
.count()
!= 0
);
assert!(temp_dir_path
.join("arbitrary-fuzz")
.join("honggfuzz")
.join("arbitrary-fuzz")
.join("input")
.is_dir());
}
Loading

0 comments on commit f44530c

Please sign in to comment.