aboutsummaryrefslogtreecommitdiff
path: root/src/integration/test_support.rs
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-17 22:43:35 +0200
committerGitHub <noreply@github.com>2026-09-17 22:43:35 +0200
commit14351f121f6fc8c84b7c6c6eda78ad210e93cfcb (patch)
treeab2773993ac4f012e8dc52f757a7109b3af8b4d5 /src/integration/test_support.rs
parent101ccc20d3c6483a38ed9e0a1239b2ab908b1704 (diff)
test: skip windows symlink tests without symlink privilege (#4311)
Windows refuses file symlinks with ERROR_PRIVILEGE_NOT_HELD (1314) unless the test process is elevated or Developer Mode is enabled, which broke non-admin local runs. Share a helper that reports the missing privilege so the two symlink tests skip only the symlink-dependent assertions.
Diffstat (limited to 'src/integration/test_support.rs')
-rw-r--r--src/integration/test_support.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/integration/test_support.rs b/src/integration/test_support.rs
new file mode 100644
index 00000000..638beb00
--- /dev/null
+++ b/src/integration/test_support.rs
@@ -0,0 +1,49 @@
+//! Shared helpers for integration tests.
+
+use std::path::Path;
+
+/// Windows refuses file symlinks with `ERROR_PRIVILEGE_NOT_HELD` when the
+/// process is neither elevated nor running with Developer Mode enabled.
+#[cfg(windows)]
+const ERROR_PRIVILEGE_NOT_HELD: i32 = 1314;
+
+#[cfg(windows)]
+fn symlink_privilege_denied(error: &std::io::Error) -> bool {
+ error.raw_os_error() == Some(ERROR_PRIVILEGE_NOT_HELD)
+}
+
+/// Create a file symlink, returning `false` when Windows denied the symlink
+/// privilege. Callers skip symlink-only assertions on `false` instead of
+/// failing an ordinary non-elevated local test run.
+#[cfg(unix)]
+pub(super) fn symlink_file(target: &Path, link: &Path) -> bool {
+ std::os::unix::fs::symlink(target, link).expect("create symlink");
+ true
+}
+
+#[cfg(windows)]
+pub(super) fn symlink_file(target: &Path, link: &Path) -> bool {
+ match std::os::windows::fs::symlink_file(target, link) {
+ Ok(()) => true,
+ Err(error) if symlink_privilege_denied(&error) => {
+ eprintln!("skipping symlink test: Windows denied SeCreateSymbolicLinkPrivilege");
+ false
+ }
+ Err(error) => panic!("create symlink {}: {error}", link.display()),
+ }
+}
+
+#[cfg(all(test, windows))]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn symlink_privilege_error_is_detected() {
+ assert!(symlink_privilege_denied(
+ &std::io::Error::from_raw_os_error(ERROR_PRIVILEGE_NOT_HELD)
+ ));
+ assert!(!symlink_privilege_denied(
+ &std::io::Error::from_raw_os_error(/* ERROR_ACCESS_DENIED */ 5)
+ ));
+ }
+}