-
Notifications
You must be signed in to change notification settings - Fork 10
#41: Make unit tests of update_one
and update_all
method
#71
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ pub struct ResourceIndex { | |
root: PathBuf, | ||
} | ||
|
||
#[derive(Debug)] | ||
#[derive(PartialEq, Debug)] | ||
pub struct IndexUpdate { | ||
pub deleted: HashSet<ResourceId>, | ||
pub added: HashMap<CanonicalPathBuf, ResourceId>, | ||
|
@@ -352,6 +352,10 @@ impl ResourceIndex { | |
return self.forget_id(old_id); | ||
} | ||
|
||
let deleted: HashSet<ResourceId> = HashSet::new(); | ||
let added: HashMap<CanonicalPathBuf, ResourceId> = HashMap::new(); | ||
let mut update = IndexUpdate { deleted, added }; | ||
|
||
let canonical_path_buf = CanonicalPathBuf::canonicalize(path)?; | ||
let canonical_path = canonical_path_buf.as_canonical_path(); | ||
|
||
|
@@ -365,33 +369,42 @@ impl ResourceIndex { | |
Err(_) => { | ||
// updating the index after resource removal is a correct | ||
// scenario | ||
self.forget_path(canonical_path, old_id) | ||
return self.forget_path(canonical_path, old_id); | ||
} | ||
Ok(metadata) => { | ||
match scan_entry(canonical_path, metadata) { | ||
Err(_) => { | ||
// a directory or empty file exists by the path | ||
self.forget_path(canonical_path, old_id) | ||
return self.forget_path(canonical_path, old_id); | ||
} | ||
Ok(new_entry) => { | ||
// valid resource exists by the path | ||
let curr_entry = &self.path2id[canonical_path]; | ||
|
||
if curr_entry.id == new_entry.id { | ||
// in rare cases we are here due to hash collision | ||
// in rare cases we are here due to hash collision | ||
funnyVOLT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if let Some(curr_entry) = | ||
self.path2id.get(canonical_path) | ||
{ | ||
if curr_entry.id == new_entry.id { | ||
if curr_entry.modified == new_entry.modified { | ||
log::warn!("path {:?} does not modified but not its content", &canonical_path); | ||
return Ok(update); | ||
} | ||
|
||
if curr_entry.modified == new_entry.modified { | ||
log::warn!("path {:?} was modified but not its content", &canonical_path); | ||
//in cases Resourceid' didn't modify and 'SystemTime' was modified | ||
// updated | ||
log::warn!("Resourceid didn't modify but SystemTime was modified"); | ||
// update.added.insert( | ||
// canonical_path_buf.clone(), | ||
// new_entry.id, | ||
// ); | ||
// self.insert_entry( | ||
// canonical_path_buf.clone(), | ||
// new_entry, | ||
// ); | ||
// update.deleted.insert(old_id); | ||
Comment on lines
+394
to
+402
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Commented-out code should be removed before merging. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@Kirill I would like to ask you:
#kirill I would like to ask you: Why do you want to return "Err" when a file has been modified? |
||
return Ok(update); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to keep returning |
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth to write something into the log in |
||
|
||
// the caller must have ensured that the path was | ||
// updated | ||
return Err(ArklibError::Collision( | ||
"New content has the same id".into(), | ||
)); | ||
} | ||
|
||
// new resource exists by the path | ||
//new resource exists by the path | ||
self.forget_path(canonical_path, old_id).map( | ||
|mut update| { | ||
update.added.insert( | ||
|
@@ -605,7 +618,7 @@ fn is_hidden(entry: &DirEntry) -> bool { | |
#[cfg(test)] | ||
mod tests { | ||
use crate::id::ResourceId; | ||
use crate::index::{discover_paths, IndexEntry}; | ||
use crate::index::{discover_paths, scan_entries, IndexEntry, IndexUpdate}; | ||
use crate::initialize; | ||
use crate::ResourceIndex; | ||
use canonical_path::CanonicalPathBuf; | ||
|
@@ -619,6 +632,10 @@ mod tests { | |
use std::time::SystemTime; | ||
use uuid::Uuid; | ||
|
||
use std::collections::{HashMap, HashSet}; | ||
type Paths = HashSet<CanonicalPathBuf>; | ||
use walkdir::DirEntry; | ||
|
||
const FILE_SIZE_1: u64 = 10; | ||
const FILE_SIZE_2: u64 = 11; | ||
|
||
|
@@ -629,6 +646,8 @@ mod tests { | |
const CRC32_1: u32 = 3817498742; | ||
const CRC32_2: u32 = 1804055020; | ||
|
||
use crate::{ArklibError, Result}; | ||
|
||
fn get_temp_dir() -> PathBuf { | ||
create_dir_at(std::env::temp_dir()) | ||
} | ||
|
@@ -984,4 +1003,198 @@ mod tests { | |
assert!(new2 > old2); | ||
assert!(new2 > new1); | ||
} | ||
|
||
#[test] | ||
fn should_correctly_update_one_resource() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test case is not correct. See test case |
||
run_test_and_clean_up(|path| { | ||
create_file_at(path.clone(), Some(FILE_SIZE_2), Some(FILE_NAME_2)); | ||
let mut actual = ResourceIndex::build(path.clone()); | ||
|
||
println!("==🌹🌹=update_one unit tests start=="); | ||
|
||
for (key, value) in &actual.path2id { | ||
println!( | ||
"===❤❤========update_one_new_entry Resource ID: {}", | ||
&actual.path2id[key].id | ||
); | ||
} | ||
|
||
create_file_at(path.clone(), Some(FILE_SIZE_1), Some(FILE_NAME_1)); | ||
let mut file_path = path.clone(); | ||
file_path.push(FILE_NAME_1); | ||
let old_id = ResourceId { | ||
data_size: FILE_SIZE_1, | ||
crc32: CRC32_1, | ||
}; | ||
let path_buf: CanonicalPathBuf = | ||
CanonicalPathBuf::canonicalize(&file_path).unwrap(); | ||
let update = actual | ||
.update_one(&path_buf.clone(), old_id) | ||
.expect("Should update one resource correctly"); | ||
|
||
for (key, value) in &actual.path2id { | ||
println!( | ||
"===😂😂========update_after_entry Resource ID: {}", | ||
&actual.path2id[key].id | ||
); | ||
} | ||
|
||
println!( | ||
"===✔✔==added=:{} deleted={}", | ||
update.added.len().to_string(), | ||
update.deleted.len().to_string() | ||
); | ||
|
||
assert_eq!(update.added.len(), 1); | ||
assert_eq!(actual.path2id.len(), 2); | ||
}) | ||
} | ||
|
||
#[test] | ||
fn should_correctly_update_all_resource() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test case is a duplicate. See |
||
run_test_and_clean_up(|path| { | ||
create_file_at(path.clone(), Some(FILE_SIZE_2), Some(FILE_NAME_2)); | ||
let mut actual = ResourceIndex::build(path.clone()); | ||
|
||
println!("==🌹🌹=update_all unit tests start=="); | ||
for (key, value) in &actual.path2id { | ||
println!( | ||
"===❤❤========update_one_new_entry Resource ID: {}", | ||
&actual.path2id[key].id | ||
); | ||
} | ||
|
||
create_file_at(path.clone(), Some(FILE_SIZE_1), Some(FILE_NAME_1)); | ||
|
||
let update = actual | ||
.update_all() | ||
.expect("Should update index correctly"); | ||
|
||
for (key, value) in &actual.path2id { | ||
println!( | ||
"===😂😂========update_after_entry Resource ID: {}", | ||
&actual.path2id[key].id | ||
); | ||
} | ||
|
||
println!( | ||
"===✔✔==added=:{} deleted={}", | ||
update.added.len().to_string(), | ||
update.deleted.len().to_string() | ||
); | ||
|
||
assert_eq!(update.deleted.len(), 0); | ||
assert_eq!(update.added.len(), 1); | ||
}) | ||
} | ||
|
||
#[test] | ||
fn should_correctly_update_all_using_update_one_resource() { | ||
run_test_and_clean_up(|path| { | ||
create_file_at(path.clone(), Some(FILE_SIZE_2), Some(FILE_NAME_2)); | ||
let mut actual = ResourceIndex::build(path.clone()); | ||
|
||
let mut all_deleted: HashSet<ResourceId> = HashSet::new(); | ||
let mut all_added: HashMap<CanonicalPathBuf, ResourceId> = | ||
HashMap::new(); | ||
|
||
println!("==🌹🌹=update_all using update_one unit tests start=="); | ||
for (key, value) in &actual.path2id { | ||
println!( | ||
"===❤❤========update_one_new_entry Resource ID: {}", | ||
value.id | ||
); | ||
} | ||
|
||
create_file_at(path.clone(), Some(FILE_SIZE_1), Some(FILE_NAME_1)); | ||
|
||
for (old_path, old_index_enry) in &actual.path2id { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just 1 iteration, at this moment. |
||
let one_index_update = actual | ||
.clone() | ||
.update_one(&old_path.clone(), old_index_enry.id) | ||
.expect("Should update one resource correctly"); | ||
|
||
for (add_path, &add_id) in one_index_update.added.iter() { | ||
all_added.insert(add_path.clone(), add_id.clone()); | ||
} | ||
|
||
for delete_id in one_index_update.deleted { | ||
all_deleted.insert(delete_id); | ||
} | ||
} | ||
|
||
let curr_paths: HashMap<CanonicalPathBuf, DirEntry> = | ||
discover_paths(path.clone()); | ||
let curr_entries = scan_entries(curr_paths); | ||
|
||
for (cur_path, cur_entry) in curr_entries { | ||
let one_index_update = actual | ||
.update_one(&cur_path.clone(), cur_entry.id) | ||
.expect("Should update one resource correctly"); | ||
|
||
for (add_path, &add_id) in one_index_update.added.iter() { | ||
all_added.insert(add_path.clone(), add_id.clone()); | ||
} | ||
|
||
for delete_id in one_index_update.deleted { | ||
all_deleted.insert(delete_id); | ||
} | ||
} | ||
Comment on lines
+1130
to
+1142
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test case contains no assertion, what is your expectation of the final state? Also, please don't commit debugging prints ( |
||
|
||
for (key, entry) in &actual.path2id { | ||
println!( | ||
"===😂😂========update_after_entry Resource ID: {}", | ||
entry.id | ||
); | ||
} | ||
|
||
println!( | ||
"===✔✔==added=:{} deleted={}", | ||
all_added.len().to_string(), | ||
all_deleted.len().to_string() | ||
); | ||
}) | ||
} | ||
|
||
#[test] | ||
fn should_correctly_update_all_compare_update_one_resource() { | ||
run_test_and_clean_up(|path| { | ||
create_file_at(path.clone(), Some(FILE_SIZE_2), Some(FILE_NAME_2)); | ||
let mut actual = ResourceIndex::build(path.clone()); | ||
create_file_at(path.clone(), Some(FILE_SIZE_1), Some(FILE_NAME_1)); | ||
|
||
let updated_using_update_all_result = actual.clone().update_all(); | ||
|
||
let mut all_deleted: HashSet<ResourceId> = HashSet::new(); | ||
let mut all_added: HashMap<CanonicalPathBuf, ResourceId> = | ||
HashMap::new(); | ||
|
||
let curr_paths: HashMap<CanonicalPathBuf, DirEntry> = | ||
discover_paths(path.clone()); | ||
let curr_entries = scan_entries(curr_paths); | ||
|
||
for (cur_path, cur_entry) in curr_entries { | ||
let one_index_update = actual | ||
.update_one(&cur_path.clone(), cur_entry.id) | ||
.expect("Should update one resource correctly"); | ||
|
||
for (add_path, &add_id) in one_index_update.added.iter() { | ||
all_added.insert(add_path.clone(), add_id.clone()); | ||
} | ||
|
||
for delete_id in one_index_update.deleted { | ||
all_deleted.insert(delete_id); | ||
} | ||
} | ||
|
||
let updated_using_update_one = IndexUpdate { | ||
deleted: all_deleted, | ||
added: all_added, | ||
}; | ||
Comment on lines
+1190
to
+1193
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a good idea to compare There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something like this is easier to start with:
|
||
let updated_using_update_all = | ||
updated_using_update_all_result.unwrap(); | ||
|
||
assert_eq!(updated_using_update_all, updated_using_update_one); | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These structures seem to be unused.