mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-06-08 14:15:46 -04:00
These daemon tests confirmed refusals/exclusions but accepted the allowed
transfers on exit status alone, so a transfer that exited cleanly while moving
nothing would pass:
daemon-refuse allowed() imported verify_dirs but never called it; now it
confirms the allowed push/pull actually populated the dest.
daemon-filter pull()/the incoming push ignored their exit status, and the
outgoing-chmod loop iterated only files that exist -- a
zero-file pull passed vacuously. Check the codes and require
at least one file to have been mode-checked.
daemon run_and_check's unused `expected` param is dropped; the
hidden-module and glob listings now compare the exact set of
listed paths (catching a leaked extra path), replacing the
per-path containment check and the dead normalise() helper
whose regex never matched the -r listing format anyway.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Daemon coverage: refuse options (a named option, a wildcard, and the
|
|
allow-list negation form).
|
|
|
|
daemon-refuse-compress_test.py covers the basic case; this widens it to a
|
|
different named option, a wildcard pattern, and the "* !a !v" allow-list idiom
|
|
documented in rsyncd.conf.5.
|
|
"""
|
|
|
|
import subprocess
|
|
|
|
from rsyncfns import (
|
|
FROMDIR, SCRATCHDIR,
|
|
make_tree, makepath, rmtree, rsync_argv, run_rsync, start_test_daemon,
|
|
test_fail, verify_dirs, write_daemon_conf,
|
|
)
|
|
|
|
DAEMON_PORT = 12891
|
|
|
|
src = FROMDIR
|
|
rmtree(src)
|
|
make_tree(src, depth=3)
|
|
|
|
deldir = SCRATCHDIR / 'deldest'
|
|
makepath(deldir)
|
|
|
|
conf = write_daemon_conf([
|
|
('refuse-delete', {'path': deldir, 'read only': 'no',
|
|
'refuse options': 'delete'}),
|
|
('refuse-wild', {'path': src, 'read only': 'yes',
|
|
'refuse options': 'checksum*'}),
|
|
('only-av', {'path': src, 'read only': 'yes',
|
|
'refuse options': '* !a !v'}),
|
|
])
|
|
url = start_test_daemon(conf, DAEMON_PORT)
|
|
|
|
|
|
def refused(args, what):
|
|
proc = subprocess.run(rsync_argv(*args),
|
|
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
|
|
text=True)
|
|
if proc.returncode == 0:
|
|
test_fail(f"{what} was not refused")
|
|
return proc.stderr
|
|
|
|
|
|
def allowed(args, what, expected=None, actual=None):
|
|
proc = subprocess.run(rsync_argv(*args),
|
|
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
|
|
text=True)
|
|
if proc.returncode not in (0, 23):
|
|
test_fail(f"{what} was unexpectedly refused: {proc.stderr}")
|
|
# A 0/23 exit alone doesn't prove the transfer happened; verify the data
|
|
# actually landed for the allowed cases.
|
|
if expected is not None:
|
|
verify_dirs(expected, actual, label=what)
|
|
|
|
|
|
# --- a named refused option (delete) ----------------------------------------
|
|
refused(['-a', '--delete', f'{src}/', f'{url}refuse-delete/'],
|
|
"--delete on a refuse=delete module")
|
|
allowed(['-a', f'{src}/', f'{url}refuse-delete/'],
|
|
"plain push to a refuse=delete module", src, deldir)
|
|
|
|
# --- a wildcard refused option (checksum*) ----------------------------------
|
|
dest = SCRATCHDIR / 'wilddest'
|
|
makepath(dest)
|
|
refused(['-a', '--checksum', f'{url}refuse-wild/', f'{dest}/'],
|
|
"--checksum on a refuse=checksum* module")
|
|
|
|
# --- the "* !a !v" allow-list: -av allowed, -z refused ----------------------
|
|
rmtree(dest)
|
|
makepath(dest)
|
|
allowed(['-av', f'{url}only-av/', f'{dest}/'], "-av on an allow-list module",
|
|
src, dest)
|
|
refused(['-avz', f'{url}only-av/', f'{dest}/'],
|
|
"-z on an allow-list module")
|
|
|
|
print("daemon-refuse: named / wildcard / allow-list refuse options verified")
|