修正 CI 权限用例在 root 容器下的前提并补平台无关的分类判据
Project CI / Repository checks (pull_request) Successful in 3m5s
Project CI / Frontend tests (pull_request) Successful in 4m2s
Project CI / Backend tests (pull_request) Successful in 6m51s
Project CI / Native shell tests (pull_request) Successful in 19m16s

- project_write_lock_does_not_project_permission_denial_as_contention 不再用 expect_err 断言“只读目录必须挡住取锁”:CI 容器以 root 运行,0o500 不生效,取锁会正常成功;此时跳过端到端前提
- 新增平台无关用例 project_write_lock_classifies_by_whether_the_target_exists:目标存在才是争用、目标不存在却创建失败是权限拒绝、NotFound 归其它
- 让权限分类判据在不依赖 ACL 环境的条件下也有回归护栏,避免只靠会被 root 绕过的端到端用例
This commit is contained in:
2026-09-10 16:52:30 +08:00
parent 81c2389132
commit 4ecab19429
2 changed files with 34 additions and 2 deletions
@@ -485,6 +485,33 @@ fn project_write_lock_reports_acl_denial_without_an_existing_target() {
);
}
/// 分类判据本身与平台无关,两个平台都要盯住:目标存在才是争用,目标不存在却创建失败
/// 是权限拒绝。这条用例不依赖 ACL 环境,因此在 CI 容器以 root 运行时仍然有效。
#[test]
fn project_write_lock_classifies_by_whether_the_target_exists() {
assert_eq!(
project_write_lock_classify_open_error(
&std::io::Error::from(std::io::ErrorKind::AlreadyExists),
true
),
ProjectWriteLockOpenFailure::Contention
);
assert_eq!(
project_write_lock_classify_open_error(
&std::io::Error::from(std::io::ErrorKind::PermissionDenied),
false
),
ProjectWriteLockOpenFailure::Permission
);
assert_eq!(
project_write_lock_classify_open_error(
&std::io::Error::from(std::io::ErrorKind::NotFound),
false
),
ProjectWriteLockOpenFailure::Other
);
}
#[cfg(all(test, windows))]
#[test]
fn project_write_lock_hardens_space_containing_path_in_process() {
@@ -426,10 +426,15 @@ fn project_write_lock_does_not_project_permission_denial_as_contention() {
fs::set_permissions(&agent_directory, fs::Permissions::from_mode(0o500))
.expect("去掉控制目录写权限");
let error =
acquire_project_write_lock(&root, "file.write").expect_err("只读控制目录必须挡住取锁");
let outcome = acquire_project_write_lock(&root, "file.write");
fs::set_permissions(&agent_directory, original).expect("恢复控制目录权限");
// CI 容器以 root 运行,0o500 目录照样可以创建文件;此时本用例的前提不成立,
// 直接跳过。分类判据本身另有不依赖 ACL 环境的纯函数用例覆盖。
let Err(error) = outcome else {
return;
};
assert!(
!error.starts_with("项目正在被其他写操作占用:"),
"权限拒绝不得投影成写锁争用:{error}"