From ecab786d75eaf3ab6a110f1d6b47c1b1d7e2ec01 Mon Sep 17 00:00:00 2001 From: chenjiayi Date: Tue, 21 Nov 2023 15:17:23 +0800 Subject: [PATCH 076/103] fix(devmaster): avoid potential test case failures Sharing the same temporary rules directory in multiple test cases may lead to weird and occasional failures. --- exts/devmaster/src/lib/rules/rules_load.rs | 123 ++++++++++++--------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/exts/devmaster/src/lib/rules/rules_load.rs b/exts/devmaster/src/lib/rules/rules_load.rs index e9dd2259..999c9692 100644 --- a/exts/devmaster/src/lib/rules/rules_load.rs +++ b/exts/devmaster/src/lib/rules/rules_load.rs @@ -1736,14 +1736,24 @@ mod tests { use std::panic::catch_unwind; use std::{fs, path::Path}; - fn create_tmp_rules(dir: &'static str, file: &str, content: &str) { + fn create_tmp_rules(dir: &'static str, file: &str, content: &str, truncate: bool) { assert!(fs::create_dir_all(dir).is_ok()); - assert!(fs::write(format!("{}/{}", dir, file), content,).is_ok()); + let s = format!("{}/{}", dir, file); + let p = Path::new(&s); + assert!(fs::write(p, content,).is_ok()); + let mut f = fs::OpenOptions::new() + .write(true) + .truncate(truncate) + .open(p) + .unwrap(); + f.write_all(content.as_bytes()).unwrap(); + f.flush().unwrap(); + while !p.exists() {} } fn clear_tmp_rules(dir: &'static str) { if Path::new(dir).exists() { - assert!(fs::remove_dir_all(dir).is_ok()); + fs::remove_dir_all(dir).unwrap(); } } @@ -1758,7 +1768,7 @@ mod tests { 0, false, ); - clear_tmp_rules("/tmp/devmaster/rules"); + clear_tmp_rules("/tmp/devmaster/test_load_rules"); let legal_rule = vec![ "ACTION == \"change\", SYMLINK += \"test1\"", // Test legal rules. @@ -1810,23 +1820,21 @@ mod tests { "SECLABEL{x}:=\"$hello\"", // Illegal placeholder in value will throw warning rather than panic. ]; - create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", ""); - for &content in legal_rule.iter() { - let mut f = fs::OpenOptions::new() - .write(true) - .truncate(true) - .open("/tmp/devmaster/rules/00-test.rules") - .unwrap(); - f.write_all(content.as_bytes()).unwrap(); + create_tmp_rules( + "/tmp/devmaster/test_load_rules", + "00-test.rules", + content, + true, + ); let _ = Rules::load_rules( - vec!["/tmp/devmaster/rules".to_string()], + vec!["/tmp/devmaster/test_load_rules".to_string()], ResolveNameTime::Early, ); } - clear_tmp_rules("/tmp/devmaster/rules"); + clear_tmp_rules("/tmp/devmaster/test_load_rules"); } #[test] @@ -1840,7 +1848,7 @@ mod tests { 0, false, ); - clear_tmp_rules("/tmp/devmaster/rules"); + clear_tmp_rules("/tmp/devmaster/test_load_rules_panic"); let illegal_rule = vec![ "action==\"change\"", // Error in State::Pre @@ -1945,26 +1953,24 @@ mod tests { "XXX=\"xxx\"", // Invalid token key. ]; - create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", ""); - for content in illegal_rule.iter() { - let mut f = fs::OpenOptions::new() - .write(true) - .truncate(true) - .open("/tmp/devmaster/rules/00-test.rules") - .unwrap(); - f.write_all(content.as_bytes()).unwrap(); + create_tmp_rules( + "/tmp/devmaster/test_load_rules_panic", + "00-test.rules", + content, + true, + ); assert!(catch_unwind(|| { let _ = Rules::load_rules( - vec!["/tmp/devmaster/rules".to_string()], + vec!["/tmp/devmaster/test_load_rules_panic".to_string()], ResolveNameTime::Early, ); }) .is_err()); } - clear_tmp_rules("/tmp/devmaster/rules"); + clear_tmp_rules("/tmp/devmaster/test_load_rules_panic"); } #[test] @@ -1978,50 +1984,48 @@ mod tests { 0, false, ); - clear_tmp_rules("/tmp/devmaster/rules"); + clear_tmp_rules("/tmp/devmaster/test_resolve_name_time"); let legal = vec!["OWNER=\"root\"", "GROUP=\"root\""]; let illegal = vec!["OWNER=\"xxxx\"", "GROUP=\"xxxx\""]; - create_tmp_rules("/tmp/devmaster/rules", "00-test.rules", ""); - for &content in legal.iter() { - let mut f = fs::OpenOptions::new() - .write(true) - .truncate(true) - .open("/tmp/devmaster/rules/00-test.rules") - .unwrap(); - f.write_all(content.as_bytes()).unwrap(); + create_tmp_rules( + "/tmp/devmaster/test_resolve_name_time", + "00-test.rules", + content, + true, + ); let _ = Rules::load_rules( - vec!["/tmp/devmaster/rules".to_string()], + vec!["/tmp/devmaster/test_resolve_name_time".to_string()], ResolveNameTime::Early, ); } for &content in illegal.iter() { - let mut f = fs::OpenOptions::new() - .write(true) - .truncate(true) - .open("/tmp/devmaster/rules/00-test.rules") - .unwrap(); - f.write_all(content.as_bytes()).unwrap(); + create_tmp_rules( + "/tmp/devmaster/test_resolve_name_time", + "00-test.rules", + content, + true, + ); let _ = Rules::load_rules( - vec!["/tmp/devmaster/rules".to_string()], + vec!["/tmp/devmaster/test_resolve_name_time".to_string()], ResolveNameTime::Late, ); assert!(catch_unwind(|| { let _ = Rules::load_rules( - vec!["/tmp/devmaster/rules".to_string()], + vec!["/tmp/devmaster/test_resolve_name_time".to_string()], ResolveNameTime::Early, ); }) .is_err()); } - clear_tmp_rules("/tmp/devmaster/rules"); + clear_tmp_rules("/tmp/devmaster/test_resolve_name_time"); } #[test] @@ -2330,11 +2334,11 @@ mod tests { #[test] fn test_parse_rules() { - create_dir_all("/tmp/devmaster/rules").unwrap(); + create_dir_all("/tmp/devmaster/test_parse_rules").unwrap(); /* Normal rule file. */ touch_file( - "/tmp/devmaster/rules/00-a.rules", + "/tmp/devmaster/test_parse_rules/00-a.rules", false, Some(0o777), None, @@ -2342,10 +2346,17 @@ mod tests { ) .unwrap(); /* Skip parsing the file with invalid suffix. */ - touch_file("/tmp/devmaster/rules/01-b", false, Some(0o777), None, None).unwrap(); + touch_file( + "/tmp/devmaster/test_parse_rules/01-b", + false, + Some(0o777), + None, + None, + ) + .unwrap(); /* Failed to parse the file as it is not readable. */ touch_file( - "/tmp/devmaster/rules/02-c.rules", + "/tmp/devmaster/test_parse_rules/02-c.rules", false, Some(0o000), None, @@ -2354,21 +2365,25 @@ mod tests { .unwrap(); let rules = Arc::new(RwLock::new(Rules::new( - vec!["/tmp/devmaster/rules".to_string()], + vec!["/tmp/devmaster/test_parse_rules".to_string()], ResolveNameTime::Never, ))); - // Rules::parse_rules(Arc::new(RwLock::new(rules))); - - RuleFile::load_file("/tmp/devmaster/rules/00-a.rules".to_string(), rules.clone()); + RuleFile::load_file( + "/tmp/devmaster/test_parse_rules/00-a.rules".to_string(), + rules.clone(), + ); if nix::unistd::getuid().as_raw() != 0 { assert!(catch_unwind(|| { - RuleFile::load_file("/tmp/devmaster/rules/02-c.rules".to_string(), rules.clone()); + RuleFile::load_file( + "/tmp/devmaster/test_parse_rules/02-c.rules".to_string(), + rules.clone(), + ); }) .is_err()); } - remove_dir_all("/tmp/devmaster").unwrap(); + remove_dir_all("/tmp/devmaster/test_parse_rules").unwrap(); } } -- 2.33.0