eprint problematic folders

This commit is contained in:
n4n5
2024-05-12 21:28:58 +02:00
committed by andy.boot
parent 4f6255971b
commit 028ca1fdc7
4 changed files with 105 additions and 55 deletions
+12 -5
View File
@@ -142,7 +142,8 @@ fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
.into_iter() .into_iter()
.par_bridge() .par_bridge()
.filter_map(|entry| { .filter_map(|entry| {
if let Ok(ref entry) = entry { match entry {
Ok(ref entry) => {
// uncommenting the below line gives simpler code but // uncommenting the below line gives simpler code but
// rayon doesn't parallelize as well giving a 3X performance drop // rayon doesn't parallelize as well giving a 3X performance drop
// hence we unravel the recursion a bit // hence we unravel the recursion a bit
@@ -171,15 +172,19 @@ fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
prog_data.num_files.fetch_add(1, ORDERING); prog_data.num_files.fetch_add(1, ORDERING);
if let Some(ref file) = node { if let Some(ref file) = node {
prog_data.total_file_size.fetch_add(file.size, ORDERING); prog_data
.total_file_size
.fetch_add(file.size, ORDERING);
} }
return node; return node;
} }
} }
} else { }
Err(ref failed) => {
let mut editable_error = errors.lock().unwrap(); let mut editable_error = errors.lock().unwrap();
editable_error.no_permissions = true editable_error.no_permissions.insert(failed.to_string());
}
} }
None None
}) })
@@ -189,7 +194,9 @@ fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
let mut editable_error = errors.lock().unwrap(); let mut editable_error = errors.lock().unwrap();
match failed.kind() { match failed.kind() {
std::io::ErrorKind::PermissionDenied => { std::io::ErrorKind::PermissionDenied => {
editable_error.no_permissions = true; editable_error
.no_permissions
.insert(dir.to_string_lossy().into());
} }
std::io::ErrorKind::NotFound => { std::io::ErrorKind::NotFound => {
editable_error.file_not_found.insert(failed.to_string()); editable_error.file_not_found.insert(failed.to_string());
+8 -3
View File
@@ -252,7 +252,6 @@ fn main() {
} }
let final_errors = walk_data.errors.lock().unwrap(); let final_errors = walk_data.errors.lock().unwrap();
let failed_permissions = final_errors.no_permissions;
if !final_errors.file_not_found.is_empty() { if !final_errors.file_not_found.is_empty() {
let err = final_errors let err = final_errors
.file_not_found .file_not_found
@@ -262,8 +261,14 @@ fn main() {
.join(", "); .join(", ");
eprintln!("No such file or directory: {}", err); eprintln!("No such file or directory: {}", err);
} }
if failed_permissions { if !final_errors.no_permissions.is_empty() {
eprintln!("Did not have permissions for all directories"); let err = final_errors
.no_permissions
.iter()
.map(|a| a.as_ref())
.collect::<Vec<&str>>()
.join(", ");
eprintln!("Did not have permissions for directories: {}", err);
} }
if !final_errors.unknown_error.is_empty() { if !final_errors.unknown_error.is_empty() {
let err = final_errors let err = final_errors
+1 -1
View File
@@ -70,7 +70,7 @@ impl PAtomicInfo {
#[derive(Default)] #[derive(Default)]
pub struct RuntimeErrors { pub struct RuntimeErrors {
pub no_permissions: bool, pub no_permissions: HashSet<String>,
pub file_not_found: HashSet<String>, pub file_not_found: HashSet<String>,
pub unknown_error: HashSet<String>, pub unknown_error: HashSet<String>,
pub abort: bool, pub abort: bool,
+51 -13
View File
@@ -41,7 +41,11 @@ fn initialize() {
}); });
} }
fn exact_output_test<T: AsRef<OsStr>>(valid_outputs: Vec<String>, command_args: Vec<T>) { fn exact_output_test<T: AsRef<OsStr>>(
command_args: Vec<T>,
valid_outputs: Vec<String>,
error_outputs: Vec<String>,
) {
initialize(); initialize();
let mut a = &mut Command::cargo_bin("dust").unwrap(); let mut a = &mut Command::cargo_bin("dust").unwrap();
@@ -50,17 +54,32 @@ fn exact_output_test<T: AsRef<OsStr>>(valid_outputs: Vec<String>, command_args:
a = a.arg(p); a = a.arg(p);
} }
let output = str::from_utf8(&a.unwrap().stdout).unwrap().to_owned(); if !valid_outputs.is_empty() {
let stdout_output = str::from_utf8(&a.unwrap().stdout).unwrap().to_owned();
let will_fail = valid_outputs.iter().any(|i| output.contains(i)); let will_fail = valid_outputs.iter().any(|i| stdout_output.contains(i));
if !will_fail { if !will_fail {
eprintln!( eprintln!(
"output:\n{}\ndoes not contain any of:\n{}", "output(stdout):\n{}\ndoes not contain any of:\n{}",
output, stdout_output,
valid_outputs.join("\n\n") valid_outputs.join("\n\n")
); );
} }
assert!(will_fail) assert!(will_fail);
}
// check stderr
if !error_outputs.is_empty() {
let stderr_output = str::from_utf8(&a.unwrap().stderr).unwrap().to_owned();
let will_fail = error_outputs.iter().any(|i| stderr_output.contains(i));
if !will_fail {
eprintln!(
"output(stderr):\n{}\ndoes not contain any of:\n{}",
stderr_output,
valid_outputs.join("\n\n")
);
}
assert!(will_fail);
}
} }
// "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable // "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
@@ -68,7 +87,7 @@ fn exact_output_test<T: AsRef<OsStr>>(valid_outputs: Vec<String>, command_args:
#[test] #[test]
pub fn test_main_basic() { pub fn test_main_basic() {
// -c is no color mode - This makes testing much simpler // -c is no color mode - This makes testing much simpler
exact_output_test(main_output(), vec!["-c", "-B", "/tmp/test_dir/"]) exact_output_test(vec!["-c", "-B", "/tmp/test_dir/"], main_output(), vec![]);
} }
#[cfg_attr(target_os = "windows", ignore)] #[cfg_attr(target_os = "windows", ignore)]
@@ -81,7 +100,7 @@ pub fn test_main_multi_arg() {
"/tmp/test_dir", "/tmp/test_dir",
"/tmp/test_dir", "/tmp/test_dir",
]; ];
exact_output_test(main_output(), command_args); exact_output_test(command_args, main_output(), vec![]);
} }
fn main_output() -> Vec<String> { fn main_output() -> Vec<String> {
@@ -112,7 +131,7 @@ fn main_output() -> Vec<String> {
#[test] #[test]
pub fn test_main_long_paths() { pub fn test_main_long_paths() {
let command_args = vec!["-c", "-p", "-B", "/tmp/test_dir/"]; let command_args = vec!["-c", "-p", "-B", "/tmp/test_dir/"];
exact_output_test(main_output_long_paths(), command_args); exact_output_test(command_args, main_output_long_paths(), vec![]);
} }
fn main_output_long_paths() -> Vec<String> { fn main_output_long_paths() -> Vec<String> {
@@ -140,7 +159,7 @@ fn main_output_long_paths() -> Vec<String> {
#[test] #[test]
pub fn test_substring_of_names_and_long_names() { pub fn test_substring_of_names_and_long_names() {
let command_args = vec!["-c", "-B", "/tmp/test_dir2"]; let command_args = vec!["-c", "-B", "/tmp/test_dir2"];
exact_output_test(no_substring_of_names_output(), command_args); exact_output_test(command_args, no_substring_of_names_output(), vec![]);
} }
fn no_substring_of_names_output() -> Vec<String> { fn no_substring_of_names_output() -> Vec<String> {
@@ -174,7 +193,7 @@ fn no_substring_of_names_output() -> Vec<String> {
#[test] #[test]
pub fn test_unicode_directories() { pub fn test_unicode_directories() {
let command_args = vec!["-c", "-B", "/tmp/test_dir_unicode"]; let command_args = vec!["-c", "-B", "/tmp/test_dir_unicode"];
exact_output_test(unicode_dir(), command_args); exact_output_test(command_args, unicode_dir(), vec![]);
} }
fn unicode_dir() -> Vec<String> { fn unicode_dir() -> Vec<String> {
@@ -201,7 +220,7 @@ fn unicode_dir() -> Vec<String> {
#[test] #[test]
pub fn test_apparent_size() { pub fn test_apparent_size() {
let command_args = vec!["-c", "-s", "-b", "/tmp/test_dir"]; let command_args = vec!["-c", "-s", "-b", "/tmp/test_dir"];
exact_output_test(apparent_size_output(), command_args); exact_output_test(command_args, apparent_size_output(), vec![]);
} }
fn apparent_size_output() -> Vec<String> { fn apparent_size_output() -> Vec<String> {
@@ -222,3 +241,22 @@ fn apparent_size_output() -> Vec<String> {
vec![one_space_before, two_space_before] vec![one_space_before, two_space_before]
} }
#[cfg_attr(target_os = "windows", ignore)]
#[test]
pub fn test_permission() {
Command::new("sh")
.arg("-c")
.arg("mkdir -p /tmp/unreadable_folder && chmod 000 /tmp/unreadable_folder")
.output()
.unwrap();
let command_args = vec!["/tmp/unreadable_folder"];
let permission_msg = r#"Did not have permissions"#.trim().to_string();
exact_output_test(command_args, vec![], vec![permission_msg]);
Command::new("sh")
.arg("-c")
.arg("chmod 555 /tmp/unreadable_folder")
.output()
.unwrap();
}