Skip to content

Commit a02682b

Browse files
committed
test: add a shared symlink capability guard
Whether a symlink can be created isn't decided by the platform alone: on Windows it needs Developer Mode or SeCreateSymbolicLinkPrivilege.
1 parent 04960cf commit a02682b

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

test/lib/helper.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
"GIT_REPO",
2020
"GIT_DAEMON_PORT",
2121
"xfail_if_raises",
22+
"symlinks_supported",
23+
"requires_symlinks",
2224
]
2325

2426
import contextlib
@@ -29,6 +31,7 @@
2931
import logging
3032
import os
3133
import os.path as osp
34+
from stat import S_ISLNK, ST_MODE
3235
import subprocess
3336
import sys
3437
import tempfile
@@ -491,6 +494,28 @@ def _executable(self, basename):
491494
raise RuntimeError(f"no regular file or symlink {path!r}")
492495

493496

497+
def symlinks_supported() -> bool:
498+
"""Check whether this process can actually create a symlink.
499+
500+
On Windows the platform alone doesn't decide it: creating a symlink needs either
501+
Developer Mode or SeCreateSymbolicLinkPrivilege, and an unprivileged process gets
502+
OSError (WinError 1314) instead.
503+
"""
504+
with tempfile.TemporaryDirectory(prefix="gitpython-symlink-check-") as temp_dir:
505+
link_path = osp.join(temp_dir, "link")
506+
try:
507+
os.symlink("missing-target", link_path)
508+
except (NotImplementedError, OSError):
509+
return False
510+
return S_ISLNK(os.lstat(link_path)[ST_MODE])
511+
512+
513+
requires_symlinks = pytest.mark.skipif(
514+
not symlinks_supported(),
515+
reason="symlinks are unavailable, or need privileges this process doesn't have",
516+
)
517+
518+
494519
@contextlib.contextmanager
495520
def xfail_if_raises(
496521
condition: bool,

0 commit comments

Comments
 (0)