mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-08-03 01:06:58 -04:00
Replace the entire shell-based testsuite with Python. runtests.py
already drove the suite (it had replaced runtests.sh earlier); this
converts all 60 test scripts from *.test shell to *_test.py and adds
testsuite/rsyncfns.py as the shared helper module -- the Python
counterpart of the now-removed rsync.fns.
runtests.py:
* Discovers and runs both *.test and *_test.py; dispatches the
Python tests via the same python3 that runs the harness.
* Extends PYTHONPATH so tests can `import rsyncfns`.
testsuite/rsyncfns.py provides everything the ports need:
* environment wiring (scratchdir / srcdir / TOOLDIR / RSYNC /
TLS_ARGS, and HOME pointed at the per-test scratch dir);
* result reporting -- test_fail / test_skipped / test_xfail mapping
to the 0 / 1 / 77 / 78 exit-code convention;
* the transfer-and-verify helpers checkit, checkdiff, verify_dirs,
rsync_ls_lR, check_perms and the v_filt output filter;
* fixture builders hands_setup, build_symlinks, build_rsyncd_conf,
make_data_file, cp_p / cp_touch, makepath / rmtree.
All 60 tests are converted, including the four split-variant tests
that share one source via a Makefile-built symlink (chown/chown-fake,
devices/devices-fake, xattrs/xattrs-hlink, exclude/exclude-lsh);
Makefile.in's CHECK_SYMLINKS now points at the *_test.py names.
The dead rsync.fns shell library is removed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
# Python rewrite of testsuite/safe-links.test.
|
|
#
|
|
# --safe-links must drop symlinks whose target escapes the transfer root.
|
|
# In-tree symlinks survive; escape-attempt symlinks (../../..., a/a/../../...)
|
|
# must NOT appear at the destination at all.
|
|
|
|
import os
|
|
|
|
from rsyncfns import TMPDIR, is_a_link, run_rsync, test_fail
|
|
|
|
|
|
def assert_symlink(path):
|
|
if not is_a_link(path):
|
|
test_fail(f"File {path} is not a symlink")
|
|
|
|
|
|
def assert_notexist(path):
|
|
if os.path.exists(path):
|
|
test_fail(f"File {path} exists")
|
|
if os.path.islink(path):
|
|
test_fail(f"File {path} exists as a symlink")
|
|
|
|
|
|
os.chdir(TMPDIR)
|
|
|
|
os.mkdir("from")
|
|
os.mkdir("from/safe")
|
|
os.mkdir("from/unsafe")
|
|
os.mkdir("from/safe/files")
|
|
os.mkdir("from/safe/links")
|
|
|
|
open("from/safe/files/file1", "w").close()
|
|
open("from/safe/files/file2", "w").close()
|
|
open("from/unsafe/unsafefile", "w").close()
|
|
|
|
os.symlink("../files/file1", "from/safe/links/file1")
|
|
os.symlink("../files/file2", "from/safe/links/file2")
|
|
os.symlink("../../unsafe/unsafefile", "from/safe/links/unsafefile")
|
|
os.symlink("a/a/a/../../../unsafe2", "from/safe/links/unsafe2")
|
|
|
|
print("rsync with relative path and --safe-links")
|
|
run_rsync('-avv', '--safe-links', 'from/safe/', 'to')
|
|
|
|
assert_symlink("to/links/file1")
|
|
assert_symlink("to/links/file2")
|
|
assert_notexist("to/links/unsafefile")
|
|
assert_notexist("to/links/unsafe2")
|