Skip to content

Commit 4f88aec

Browse files
authored
implement kani integration (#73)
1 parent 2993d32 commit 4f88aec

File tree

17 files changed

+359
-44
lines changed

17 files changed

+359
-44
lines changed

.github/workflows/main.yml

+25-1
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ jobs:
4242
test:
4343
runs-on: ${{ matrix.os }}
4444
strategy:
45+
fail-fast: false
4546
matrix:
46-
rust: [1.52.0, stable, beta, nightly]
47+
rust: [1.56.1, stable, beta, nightly]
4748
os: [ubuntu-latest, macOS-latest]
4849
# TODO add honggfuzz back
4950
test: [unit-tests, libfuzzer, afl, examples-tests]
@@ -115,3 +116,26 @@ jobs:
115116
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
116117
AFL_SKIP_CPUFREQ: 1
117118
SANITIZER: ${{ matrix.sanitizer }}
119+
120+
kani:
121+
runs-on: ubuntu-latest
122+
123+
steps:
124+
- uses: actions/[email protected]
125+
126+
- uses: actions-rs/[email protected]
127+
id: toolchain
128+
with:
129+
toolchain: stable
130+
profile: minimal
131+
override: true
132+
133+
- name: Setup
134+
run: |
135+
cargo install kani-verifier
136+
cargo-kani setup
137+
138+
- name: Test
139+
working-directory: examples/basic
140+
run: |
141+
cargo kani

.rustfmt.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
edition = "2018"
22
format_macro_matchers = true
3-
merge_imports = true
4-
reorder_impl_items = true
3+
imports_granularity = "Crate"
54
use_field_init_shorthand = true

bolero-engine/Cargo.toml

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ license = "MIT"
1010
edition = "2018"
1111
readme = "../README.md"
1212

13-
[features]
14-
default = ["rng"]
15-
rng = ["rand"]
16-
1713
[dependencies]
18-
anyhow = "1.0"
19-
backtrace = "0.3"
14+
anyhow = "1"
2015
bolero-generator = { version = "0.6", path = "../bolero-generator", default-features = false }
2116
lazy_static = "1"
2217
pretty-hex = "0.2.1"
23-
rand = { version = "^0.8", optional = true }
18+
19+
[target.'cfg(not(kani))'.dependencies]
20+
backtrace = { version = "0.3" }
21+
22+
[target.'cfg(not(any(fuzzing, kani)))'.dependencies]
23+
rand = { version = "^0.8" }
2424

2525
[dev-dependencies]
2626
bolero-generator = { version = "0.6", path = "../bolero-generator", features = ["std"] }

bolero-engine/src/lib.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ pub use bolero_generator::{
55
};
66
use core::time::Duration;
77

8+
#[cfg(not(kani))]
89
pub mod panic;
9-
#[cfg(feature = "rng")]
10+
#[cfg(kani)]
11+
#[path = "./noop/panic.rs"]
12+
pub mod panic;
13+
14+
#[cfg(not(any(fuzzing, kani)))]
1015
pub mod rng;
1116
pub mod shrink;
1217
mod test;

bolero-engine/src/noop/panic.rs

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use core::fmt::{self, Debug, Display};
2+
use std::panic::RefUnwindSafe;
3+
4+
#[derive(Debug)]
5+
#[allow(dead_code)]
6+
pub struct PanicError {
7+
pub(crate) message: String,
8+
pub(crate) location: Option<String>,
9+
pub(crate) backtrace: Option<Backtrace>,
10+
pub(crate) thread_name: String,
11+
}
12+
13+
impl Display for PanicError {
14+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15+
writeln!(f, "PANIC")?;
16+
Ok(())
17+
}
18+
}
19+
20+
impl std::error::Error for PanicError {}
21+
22+
impl PanicError {
23+
pub(crate) fn new(message: String) -> Self {
24+
Self {
25+
message,
26+
location: None,
27+
backtrace: None,
28+
thread_name: thread_name(),
29+
}
30+
}
31+
}
32+
33+
pub fn catch<F: RefUnwindSafe + FnOnce() -> Output, Output>(fun: F) -> Result<Output, PanicError> {
34+
Ok(fun())
35+
}
36+
37+
pub fn take_panic() -> Option<PanicError> {
38+
None
39+
}
40+
41+
pub fn capture_backtrace(_value: bool) -> bool {
42+
false
43+
}
44+
45+
pub fn forward_panic(_value: bool) -> bool {
46+
false
47+
}
48+
49+
pub fn set_hook() {
50+
// no-op
51+
}
52+
53+
pub fn rust_backtrace() -> bool {
54+
false
55+
}
56+
57+
pub fn thread_name() -> String {
58+
String::from("main")
59+
}
60+
61+
#[derive(Debug)]
62+
pub struct Backtrace(());
63+
64+
impl Display for Backtrace {
65+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66+
writeln!(f, "backtrace")?;
67+
Ok(())
68+
}
69+
}
70+
71+
#[derive(Debug)]
72+
pub struct BacktraceFrame(());

bolero-engine/src/target_location.rs

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ pub struct TargetLocation {
2828

2929
impl TargetLocation {
3030
pub fn should_run(&self) -> bool {
31+
if cfg!(kani) {
32+
return true;
33+
}
34+
3135
// cargo-bolero needs to resolve information about the target
3236
if let Ok(mode) = ::std::env::var("CARGO_BOLERO_SELECT") {
3337
match mode.as_str() {
@@ -61,6 +65,10 @@ impl TargetLocation {
6165
}
6266

6367
pub fn abs_path(&self) -> Option<PathBuf> {
68+
if cfg!(kani) {
69+
return None;
70+
}
71+
6472
let file = Path::new(self.file);
6573

6674
#[cfg(not(miri))] // miri does not currently support this call
@@ -83,6 +91,10 @@ impl TargetLocation {
8391
}
8492

8593
pub fn work_dir(&self) -> Option<PathBuf> {
94+
if cfg!(kani) {
95+
return None;
96+
}
97+
8698
let mut work_dir = self.abs_path()?;
8799
work_dir.pop();
88100

@@ -101,6 +113,10 @@ impl TargetLocation {
101113
}
102114

103115
pub fn is_harnessed(&self) -> bool {
116+
if cfg!(kani) {
117+
return false;
118+
}
119+
104120
is_harnessed(self.item_path)
105121
}
106122

bolero-engine/src/test.rs

+9
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ where
133133
}
134134

135135
/// Lazily generates a new value for the given driver
136+
#[cfg(not(kani))]
136137
macro_rules! generate_value {
137138
($self:ident, $driver:ident) => {{
138139
let forward_panic = crate::panic::forward_panic(true);
@@ -154,6 +155,14 @@ macro_rules! generate_value {
154155
value
155156
}};
156157
}
158+
#[cfg(kani)]
159+
macro_rules! generate_value {
160+
($self:ident, $driver:ident) => {{
161+
$self.value = $self.gen.generate($driver);
162+
kani::assume($self.value.is_some());
163+
$self.value.as_ref().unwrap()
164+
}};
165+
}
157166

158167
pub struct BorrowedGeneratorTest<F, G, V> {
159168
fun: F,

bolero-generator/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ alloc = ["rand_core/alloc"]
1717

1818
[dependencies]
1919
bolero-generator-derive = { version = "0.6.0", path = "../bolero-generator-derive" }
20-
byteorder = { version = "1.3", default-features = false }
2120
either = { version = "1.5", default-features = false, optional = true }
2221
rand_core = { version = "^0.6", default-features = false }
2322

bolero-kani/Cargo.toml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "bolero-kani"
3+
version = "0.6.0"
4+
authors = ["Cameron Bytheway <[email protected]>"]
5+
description = "kani plugin for bolero"
6+
homepage = "https://github.com/camshaft/bolero"
7+
repository = "https://github.com/camshaft/bolero"
8+
keywords = ["testing", "model", "proof"]
9+
license = "MIT"
10+
edition = "2018"
11+
readme = "../README.md"
12+
13+
[features]
14+
default = ["lib"]
15+
bin = []
16+
lib = ["bolero-engine"]
17+
18+
[dependencies]
19+
bolero-engine = { version = "0.6", path = "../bolero-engine", optional = true }

0 commit comments

Comments
 (0)