Skip to content

Commit

Permalink
Add fuzz tests for StorageVec::binary_search*
Browse files Browse the repository at this point in the history
  • Loading branch information
cmichi committed Jul 20, 2021
1 parent 4ff763c commit f5a7344
Showing 1 changed file with 103 additions and 1 deletion.
104 changes: 103 additions & 1 deletion crates/storage/src/collections/vec/fuzz_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
},
Pack,
};

use itertools::Itertools;
use quickcheck::{
Arbitrary,
Gen,
Expand Down Expand Up @@ -83,3 +83,105 @@ crate::fuzz_storage!("vec_1", StorageVec<u32>);
crate::fuzz_storage!("vec_2", StorageVec<Option<Pack<Option<u32>>>>);
crate::fuzz_storage!("vec_3", StorageVec<(bool, (u32, u128))>);
crate::fuzz_storage!("vec_4", StorageVec<(i128, u32, bool, Option<(u32, i128)>)>);

#[quickcheck]
fn fuzz_binary_search(mut std_vec: Vec<i32>) {
// given
if std_vec.len() == 0 {
return
}
let original_std_vec = std_vec.clone();
std_vec.sort();
let ink_vec = StorageVec::from_iter(std_vec.clone());

for x in original_std_vec {
// when
let index = std_vec
.binary_search(&x)
.expect("`x` must be found in `Vec`") as u32;
let index_sv = ink_vec
.binary_search(&x)
.expect("`x` must be found in `StorageVec`");
let index_sv_by = ink_vec
.binary_search_by(|by_x| by_x.cmp(&x))
.expect("`x` must be found in `StorageVec`");

// then
assert_eq!(index, index_sv);
assert_eq!(index, index_sv_by);
}
}

#[quickcheck]
fn fuzz_binary_search_nonexistent(std_vec: Vec<i32>) {
// given
if std_vec.len() == 0 {
return
}
let mut unique_std_vec: Vec<i32> = std_vec.into_iter().unique().collect();
let removed_el = unique_std_vec.pop().expect("first element must exist");
unique_std_vec.sort();
let ink_vec = StorageVec::from_iter(unique_std_vec.clone());

// when
let std_err_index = unique_std_vec
.binary_search(&removed_el)
.expect_err("element must not be found") as u32;
let ink_err_index = ink_vec
.binary_search(&removed_el)
.expect_err("element must not be found");
let ink_search_by_err_index = ink_vec
.binary_search_by(|by_x| by_x.cmp(&removed_el))
.expect_err("element must not be found");

// then
assert_eq!(std_err_index, ink_err_index);
assert_eq!(std_err_index, ink_search_by_err_index);
}

#[quickcheck]
fn fuzz_binary_search_by_key(mut std_vec: Vec<(i32, i32)>) {
// given
if std_vec.len() == 0 {
return
}
let original_std_vec = std_vec.clone();
std_vec.sort_by_key(|&(_a, b)| b);
let ink_vec = StorageVec::from_iter(std_vec.clone());

for (_x, y) in original_std_vec {
// when
let std_index = std_vec
.binary_search_by_key(&y, |&(_a, b)| b)
.expect("`y` must be found in `Vec`") as u32;
let ink_index = ink_vec
.binary_search_by_key(&y, |&(_a, b)| b)
.expect("`y` must be found in `StorageVec`");

// then
assert_eq!(std_index, ink_index);
}
}
#[quickcheck]
fn fuzz_binary_search_by_key_nonexistent(std_vec: Vec<(i32, i32)>) {
// given
if std_vec.len() == 0 {
return
}
let mut unique_std_vec: Vec<(i32, i32)> =
std_vec.into_iter().unique_by(|&(_a, b)| b).collect();
let removed_el = unique_std_vec.pop().expect("first element must exist");
unique_std_vec.sort_by_key(|&(_a, b)| b);
let ink_vec = StorageVec::from_iter(unique_std_vec.clone());

// when
let std_err_index = unique_std_vec
.binary_search_by_key(&removed_el.1, |&(_a, b)| b)
.expect_err("element must not be found in `Vec`") as u32;
let ink_err_index = ink_vec
.binary_search_by_key(&removed_el.1, |&(_a, b)| b)
.expect_err("element must not be found in `StorageVec`");

// then
assert_eq!(std_err_index, ink_err_index);
}

0 comments on commit f5a7344

Please sign in to comment.