测试: bypass 标志测试统一串行闸
途经 is_authorized 的测试统一持锁,消除并行偶发红
This commit is contained in:
@@ -893,6 +893,8 @@ mod tests {
|
||||
/// 锁定此差异:grep 与 read_file 同款授权弹窗语义。
|
||||
#[test]
|
||||
fn test_grep_unauthorized_path_triggers_auth_not_denied() {
|
||||
// 途经 is_authorized 读进程级 bypass 标志,持串行闸防与写标志的测试并行互踩
|
||||
let _guard = BLACKLIST_BYPASS_TEST_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
// 空白名单(不含 workspace_root 的目录):任何路径都未授权 → NeedsAuth
|
||||
let allowed = crate::state::AllowedDirs::default();
|
||||
let args = serde_json::json!({ "pattern": "foo", "path": "C:/some/unauthorized/dir" });
|
||||
@@ -916,6 +918,8 @@ mod tests {
|
||||
/// grep 黑名单路径(.ssh 等)直接 Denied(不申请授权),对齐 read_file。
|
||||
#[test]
|
||||
fn test_grep_blacklisted_path_denied() {
|
||||
// 途经 is_authorized 读进程级 bypass 标志,持串行闸防与写标志的测试并行互踩
|
||||
let _guard = BLACKLIST_BYPASS_TEST_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let allowed = crate::state::AllowedDirs::default_with_root();
|
||||
// .ssh 命中系统黑名单(is_in_system_blacklist)
|
||||
let args = serde_json::json!({ "pattern": "foo", "path": "/home/user/.ssh/config" });
|
||||
|
||||
@@ -181,6 +181,8 @@ mod tests {
|
||||
/// bypass 关:黑名单行为不变(Denied 基线,与改造前一致)。
|
||||
#[test]
|
||||
fn test_bypass_off_blacklist_still_denied() {
|
||||
// 途经 is_authorized 读进程级 bypass 标志,持串行闸防与写标志的测试并行互踩
|
||||
let _guard = BLACKLIST_BYPASS_TEST_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let allowed = crate::state::AllowedDirs::default_with_root();
|
||||
let args = serde_json::json!({ "path": "/home/user/.ssh/config" });
|
||||
match check_file_tool_auth("read_file", &args, &allowed, false) {
|
||||
|
||||
@@ -276,9 +276,18 @@ mod tests {
|
||||
.unwrap_or_else(|| PathBuf::from("."))
|
||||
}
|
||||
|
||||
/// 途经 is_authorized 的用例统一持此串行闸:is_authorized 首行读进程级 bypass 标志,
|
||||
/// 与写标志的测试并行运行会互踩误判(path_auth::BLACKLIST_BYPASS_TEST_LOCK 全局单例)。
|
||||
fn bypass_test_lock() -> std::sync::MutexGuard<'static, ()> {
|
||||
crate::commands::ai::audit::path_auth::BLACKLIST_BYPASS_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
}
|
||||
|
||||
/// 显式授权目录后命中(模拟用户在 Settings 页添加目录)
|
||||
#[test]
|
||||
fn test_allowed_dirs_workspace_root_authorized() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut set = HashSet::new();
|
||||
set.insert(workspace_root_path());
|
||||
let allowed = AllowedDirs { persistent: set, session: HashSet::new(), once: HashSet::new() };
|
||||
@@ -292,6 +301,7 @@ mod tests {
|
||||
/// 自定义授权目录命中放行(模拟用户授权 E:/some/external/dir)
|
||||
#[test]
|
||||
fn test_allowed_dirs_custom_authorized() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut set = HashSet::new();
|
||||
let custom = PathBuf::from("E:/wk-test-external-dir");
|
||||
set.insert(custom.clone());
|
||||
@@ -304,6 +314,7 @@ mod tests {
|
||||
/// 未授权目录被拒绝
|
||||
#[test]
|
||||
fn test_allowed_dirs_unauthorized_rejected() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut set = HashSet::new();
|
||||
set.insert(PathBuf::from("E:/wk-test-authorized"));
|
||||
let allowed = AllowedDirs { persistent: set, session: HashSet::new(), once: HashSet::new() };
|
||||
@@ -314,6 +325,7 @@ mod tests {
|
||||
/// 默认(空 persistent)只授权 workspace_root
|
||||
#[test]
|
||||
fn test_allowed_dirs_default_empty_persistent() {
|
||||
let _guard = bypass_test_lock();
|
||||
let allowed = AllowedDirs::default();
|
||||
// 空 persistent,无 workspace_root → 任何路径都不授权
|
||||
// (default_with_root 才含 workspace_root;Default 不含,用于边界测试)
|
||||
@@ -333,6 +345,7 @@ mod tests {
|
||||
/// Phase B: session 命中放行(persistent 未命中但 session 命中)
|
||||
#[test]
|
||||
fn test_allowed_dirs_session_authorized() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut session = HashSet::new();
|
||||
session.insert(PathBuf::from("E:/wk-temp-session"));
|
||||
let allowed = AllowedDirs { persistent: HashSet::new(), session, once: HashSet::new() };
|
||||
@@ -342,6 +355,7 @@ mod tests {
|
||||
/// Phase B: persistent + session 任一命中即放行
|
||||
#[test]
|
||||
fn test_allowed_dirs_persistent_or_session() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut persistent = HashSet::new();
|
||||
persistent.insert(PathBuf::from("E:/wk-persist"));
|
||||
let mut session = HashSet::new();
|
||||
@@ -359,6 +373,7 @@ mod tests {
|
||||
/// Phase C: Windows System32 黑名单命中(即使在白名单内也拒)
|
||||
#[test]
|
||||
fn test_blacklist_windows_system32() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut persistent = HashSet::new();
|
||||
// 用户误把整个 C:\ 加入白名单
|
||||
persistent.insert(PathBuf::from("C:\\"));
|
||||
@@ -370,6 +385,7 @@ mod tests {
|
||||
/// Phase C: Windows Program Files 黑名单命中
|
||||
#[test]
|
||||
fn test_blacklist_windows_program_files() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut persistent = HashSet::new();
|
||||
persistent.insert(PathBuf::from("C:\\"));
|
||||
let allowed = AllowedDirs { persistent, session: HashSet::new(), once: HashSet::new() };
|
||||
@@ -403,6 +419,7 @@ mod tests {
|
||||
/// Phase B/C: 显式授权 workspace_root 后,内路径 → Authorized(方案①:不再默认)
|
||||
#[test]
|
||||
fn test_check_path_authorized_workspace() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut set = HashSet::new();
|
||||
set.insert(workspace_root_path());
|
||||
let allowed = AllowedDirs { persistent: set, session: HashSet::new(), once: HashSet::new() };
|
||||
@@ -416,6 +433,7 @@ mod tests {
|
||||
/// Phase B/C: 未授权路径 → NeedsAuthorization(附父目录)
|
||||
#[test]
|
||||
fn test_check_path_needs_auth() {
|
||||
let _guard = bypass_test_lock();
|
||||
let allowed = AllowedDirs::default(); // 空,无 workspace_root
|
||||
match check_path_authorization("E:/wk-external/file.txt", &allowed) {
|
||||
PathAuthDecision::NeedsAuthorization { dir } => {
|
||||
@@ -428,6 +446,7 @@ mod tests {
|
||||
/// Phase B: session 命中 → Authorized(check_path_authorization 读 session 字段)
|
||||
#[test]
|
||||
fn test_check_path_session_hit() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut session = HashSet::new();
|
||||
session.insert(PathBuf::from("E:/wk-session"));
|
||||
let allowed = AllowedDirs { persistent: HashSet::new(), session, once: HashSet::new() };
|
||||
@@ -440,6 +459,7 @@ mod tests {
|
||||
/// Phase C: 黑名单路径 → Denied(不弹窗直接拒)
|
||||
#[test]
|
||||
fn test_check_path_denied_blacklist() {
|
||||
let _guard = bypass_test_lock();
|
||||
let allowed = AllowedDirs::default_with_root();
|
||||
match check_path_authorization("C:/Windows/System32/config/sam", &allowed) {
|
||||
PathAuthDecision::Denied { .. } => {}
|
||||
@@ -455,6 +475,7 @@ mod tests {
|
||||
/// 此测试锁死该修复:空 persistent + Unix 风格 .ssh 路径 → 必 Denied。
|
||||
#[test]
|
||||
fn test_check_path_blacklist_unix_style_ssh_on_windows() {
|
||||
let _guard = bypass_test_lock();
|
||||
let allowed = AllowedDirs::default_with_root();
|
||||
match check_path_authorization("/home/user/.ssh/config", &allowed) {
|
||||
PathAuthDecision::Denied { .. } => {}
|
||||
@@ -471,6 +492,7 @@ mod tests {
|
||||
/// 修复黑名单提前后,需确认非黑名单相对路径行为不变。
|
||||
#[test]
|
||||
fn test_check_path_non_blacklist_relative_still_needs_auth() {
|
||||
let _guard = bypass_test_lock();
|
||||
let allowed = AllowedDirs::default_with_root();
|
||||
match check_path_authorization("some/regular/path", &allowed) {
|
||||
PathAuthDecision::NeedsAuthorization { .. } => {}
|
||||
@@ -489,6 +511,7 @@ mod tests {
|
||||
/// persistent 用动态 workspace_root_path(非硬编码开发机路径),candidate 拼 verbatim 前缀。
|
||||
#[test]
|
||||
fn test_is_authorized_strips_verbatim_prefix() {
|
||||
let _guard = bypass_test_lock();
|
||||
let mut set = HashSet::new();
|
||||
set.insert(workspace_root_path());
|
||||
let allowed = AllowedDirs { persistent: set, session: HashSet::new(), once: HashSet::new() };
|
||||
@@ -535,9 +558,7 @@ mod tests {
|
||||
/// 先取结果再复位再断言,防 panic 泄漏标志污染并行测试。
|
||||
#[test]
|
||||
fn test_bypass_on_is_authorized_allows_all() {
|
||||
let _guard = crate::commands::ai::audit::path_auth::BLACKLIST_BYPASS_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
let _guard = bypass_test_lock();
|
||||
crate::commands::ai::audit::path_auth::set_blacklist_bypass(true);
|
||||
let allowed = AllowedDirs::default();
|
||||
let outside = PathBuf::from("E:/wk-test-bypass-outside/file.txt");
|
||||
@@ -552,9 +573,7 @@ mod tests {
|
||||
/// 总开关关:黑名单拒且白名单外拒,与接入旁路前行为一致。
|
||||
#[test]
|
||||
fn test_bypass_off_is_authorized_unchanged() {
|
||||
let _guard = crate::commands::ai::audit::path_auth::BLACKLIST_BYPASS_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
let _guard = bypass_test_lock();
|
||||
crate::commands::ai::audit::path_auth::set_blacklist_bypass(false);
|
||||
let allowed = AllowedDirs::default();
|
||||
let outside_ok = allowed.is_authorized(&PathBuf::from("E:/wk-test-bypass-outside/file.txt"));
|
||||
|
||||
Reference in New Issue
Block a user