Skip to content

Commit

Permalink
Merge pull request #11 from embassy-rs/ci-extra
Browse files Browse the repository at this point in the history
ci extra
  • Loading branch information
Dirbaio committed May 2, 2024
2 parents 4996ae7 + 63da25e commit 818d8df
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 170 deletions.
117 changes: 113 additions & 4 deletions fuzz/fuzz_targets/ops.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![no_main]

use std::collections::HashMap;
use std::collections::BTreeMap;
use std::ops::Bound;

use ekv::config::MAX_VALUE_SIZE;
use ekv::config::{MAX_KEY_SIZE, MAX_VALUE_SIZE};
use ekv::flash::MemFlash;
use ekv::{Config, Database, WriteError};
use ekv::{Config, Database, ReadError, WriteError};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use libfuzzer_sys::arbitrary::Arbitrary;
use libfuzzer_sys::fuzz_target;
Expand All @@ -19,6 +20,9 @@ struct Input {
#[derive(Arbitrary, Debug)]
enum Op {
Insert(InsertOp),
Delete(DeleteOp),
Read(ReadOp),
ReadRange(ReadRangeOp),
}

#[derive(Arbitrary, Debug)]
Expand All @@ -27,6 +31,22 @@ struct InsertOp {
value_len: usize,
}

#[derive(Arbitrary, Debug)]
struct DeleteOp {
key: u16,
}

#[derive(Arbitrary, Debug)]
struct ReadOp {
key: u16,
}

#[derive(Arbitrary, Debug)]
struct ReadRangeOp {
lower_bound: Bound<u16>,
upper_bound: Bound<u16>,
}

fn fuzz(ops: Input) {
if std::env::var_os("RUST_LOG").is_some() {
env_logger::init();
Expand All @@ -46,8 +66,9 @@ async fn fuzz_inner(ops: Input, dump: bool) {
db.format().await.unwrap();

// Mirror hashmap. Should always match F
let mut m = HashMap::new();
let mut m = BTreeMap::new();

let mut kbuf = [0; MAX_KEY_SIZE];
let mut buf = [0; MAX_VALUE_SIZE];

for (i, op) in ops.ops.into_iter().enumerate() {
Expand Down Expand Up @@ -75,6 +96,94 @@ async fn fuzz_inner(ops: Input, dump: bool) {
// Write to mirror
m.insert(key.to_vec(), val);
}
Op::Delete(op) => {
let key = op.key.to_be_bytes();

// Write to DB
let mut wtx = db.write_transaction().await;
match wtx.delete(&key).await {
Ok(()) => {}
Err(WriteError::Full) => continue,
Err(e) => panic!("write error: {:?}", e),
}
wtx.commit().await.unwrap();

// Write to mirror
m.remove(&key[..]);
}
Op::Read(op) => {
let key = op.key.to_be_bytes();

// Read from DB
let rtx = db.read_transaction().await;
let got_val = match rtx.read(&key, &mut buf).await {
Ok(n) => Some(&buf[..n]),
Err(ReadError::KeyNotFound) => None,
Err(e) => panic!("write error: {:?}", e),
};

// Write to mirror
let want_val = m.get(&key[..]).map(|v| &v[..]);

assert_eq!(got_val, want_val);
}
Op::ReadRange(op) => {
// ignore reversed ranges, otherwise BTreeMap::range panics.
if let (Bound::Excluded(l) | Bound::Included(l), Bound::Excluded(u) | Bound::Included(u)) =
(op.lower_bound, op.upper_bound)
{
if l > u {
continue;
}
}
// Tis also panics....
if let (Bound::Excluded(l), Bound::Excluded(u)) = (op.lower_bound, op.upper_bound) {
if l == u {
continue;
}
}

let mut lower_buf = [0; 2];
let lower_bound = op.lower_bound.map(|k| {
lower_buf = k.to_be_bytes();
&lower_buf[..]
});
let mut upper_buf = [0; 2];
let upper_bound = op.upper_bound.map(|k| {
upper_buf = k.to_be_bytes();
&upper_buf[..]
});

// Get cursor from DB
let rtx = db.read_transaction().await;
let mut cur = match rtx.read_range((lower_bound, upper_bound)).await {
Ok(cur) => cur,
Err(e) => panic!("read_range error: {:?}", e),
};

// iterate the mirror map.
for (want_k, want_v) in m.range((
op.lower_bound.map(|k| k.to_be_bytes().to_vec()),
op.upper_bound.map(|k| k.to_be_bytes().to_vec()),
)) {
match cur.next(&mut kbuf, &mut buf).await {
Err(e) => panic!("Cursor::next error: {:?}", e),
Ok(None) => panic!("Cursor returned None too early."),
Ok(Some((klen, vlen))) => {
let got_k = &kbuf[..klen];
let got_v = &buf[..vlen];
assert_eq!(want_k, got_k);
assert_eq!(want_v, got_v);
}
}
}

match cur.next(&mut kbuf, &mut buf).await {
Err(e) => panic!("Cursor::next error: {:?}", e),
Ok(None) => {}
Ok(Some(_)) => panic!("Cursor::next didn't return None when it should."),
}
}
}

if dump {
Expand Down
16 changes: 2 additions & 14 deletions fuzz/fuzz_targets/read.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![no_main]
use ekv::flash::MemFlash;
use ekv::{Bound, Config, Database};
use ekv::{Config, Database};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use libfuzzer_sys::fuzz_target;

Expand Down Expand Up @@ -57,19 +57,7 @@ async fn fuzz_inner(data: &[u8], dump: bool) {
drop(rtx);

let rtx = db.read_transaction().await;
if let Ok(mut cursor) = rtx
.read_range(
Some(Bound {
key: b"foo",
allow_equal: false,
}),
Some(Bound {
key: b"poo",
allow_equal: false,
}),
)
.await
{
if let Ok(mut cursor) = rtx.read_range(&b"foo"[..]..&b"poo"[..]).await {
let mut kbuf = [0; 64];
let mut vbuf = [0; 64];
while let Ok(Some((klen, vlen))) = cursor.next(&mut kbuf, &mut vbuf).await {
Expand Down
Loading

0 comments on commit 818d8df

Please sign in to comment.