From 0215817262687fa2d1b3901502fdcd50b2264eef Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 15 Jul 2017 00:05:05 +0200 Subject: [PATCH] Add quickcheck-based test for link removal --- libimagentrylink/Cargo.toml | 3 ++ libimagentrylink/src/internal.rs | 79 ++++++++++++++++++++++++++++++++ libimagentrylink/src/lib.rs | 4 ++ 3 files changed, 86 insertions(+) diff --git a/libimagentrylink/Cargo.toml b/libimagentrylink/Cargo.toml index 193f5108..67723efc 100644 --- a/libimagentrylink/Cargo.toml +++ b/libimagentrylink/Cargo.toml @@ -23,6 +23,9 @@ rust-crypto = "0.2" env_logger = "0.3" is-match = "0.1" +[dev-dependencies] +quickcheck = "0.3" + [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagentrylink/src/internal.rs b/libimagentrylink/src/internal.rs index 62003777..9507698f 100644 --- a/libimagentrylink/src/internal.rs +++ b/libimagentrylink/src/internal.rs @@ -1056,5 +1056,84 @@ mod test { assert_eq!(e3.get_internal_links().unwrap().collect::>().len(), 0); } + quickcheck! { + + // This creates `removals.len() * 10` entries in the store and links all of them to a + // test entry. + // After that, each entry from the to-link-entries list which is hit by an index from + // `removals` is unlinked again and a number of checks run for the testing entry: + // + // * Are all other entries still linked (two-way-check) + // * Is the number of links in the testing entry smaller than before + // * Is the just unlinked entry not linked + // + // I'm not sure whether using quickcheck is the right approach here, but it is the easiest + // way to create a random number of to-remove-entries where I don't know which ones get + // removed. + fn test_random_linking(removals: Vec) -> bool { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hash; + use std::hash::Hasher; + use itertools::Itertools; + + setup_logging(); + + let num_removals = removals.len(); + let num_tmp_entries = num_removals * 10; + let removals = removals + .into_iter() + .map(|r| r % num_tmp_entries) + .unique() + .collect::>(); + + let store = get_store(); + + let test_entry_name = { + let mut hasher = DefaultHasher::new(); + removals.hash(&mut hasher); + let name_ext : u64 = hasher.finish(); + format!("test-{}", name_ext) + }; + + let mut test_entry = store.retrieve(PathBuf::from(test_entry_name)).unwrap(); + + let mut tmp_entries = Vec::with_capacity(num_tmp_entries); + + for i in 0..num_tmp_entries { + let mut entry = store.retrieve(PathBuf::from(format!("tmp-{}", i))).unwrap(); + assert!(test_entry.add_internal_link(&mut entry).is_ok(), + format!("Adding entry did not work: {:?} -> {:?}", test_entry, entry)); + tmp_entries.push(entry); + } + + let link_count = test_entry.get_internal_links().unwrap().count(); + + assert_eq!(link_count, num_tmp_entries, + "Numbers of links in test_entry should be: {:?} but is {:?}: {:?}", + num_tmp_entries, link_count, + test_entry.get_internal_links().unwrap().collect::>()); + + for index in removals { + let num_links = test_entry.get_internal_links().unwrap().count(); + + debug!("Removing link: {:?}", tmp_entries[index]); + assert!(test_entry.remove_internal_link(&mut tmp_entries[index]).is_ok(), + format!("Removing link to test entry failed: {:?}", tmp_entries[index])); + + let link_count = test_entry.get_internal_links().unwrap().count(); + assert_eq!(link_count, num_links - 1, + "Numbers of links in test_entry should be: {:?} but is {:?}: {:?}", + num_links - 1, link_count, + test_entry.get_internal_links().unwrap().collect::>()); + + for internal_link in test_entry.get_internal_links().unwrap() { + assert!(tmp_entries.iter().any(|tmp| internal_link.eq_store_id(tmp.get_location()))); + } + } + + true + } + } + } diff --git a/libimagentrylink/src/lib.rs b/libimagentrylink/src/lib.rs index 2ed8b6ba..eab4ea9e 100644 --- a/libimagentrylink/src/lib.rs +++ b/libimagentrylink/src/lib.rs @@ -42,6 +42,10 @@ extern crate crypto; #[cfg(test)] extern crate env_logger; +#[cfg(test)] +#[macro_use] +extern crate quickcheck; + #[macro_use] extern crate libimagstore; #[macro_use] extern crate libimagerror; extern crate libimagutil;