Files
rsync/testsuite/daemon-config_test.py
Andrew Tridgell 702a8f61b7 testsuite: cover daemon access-control, config includes, --stop-at
Target the lowest-coverage rsync files identified from a merged (pipe + proto29/30
+ tcp) gcov report:

  daemon-access-ip  hosts allow / hosts deny with exact-IP and CIDR patterns over
                    --use-tcp, exercising access.c make_mask/match_address/
                    match_binary (19% -> 62% lines), plus client --address
                    (socket.c try_bind_local). require_tcp.
  daemon-config     the &include rsyncd.conf directive (params.c include_config/
                    parse_directives, 48% -> 60%) and a module with a missing path
                    (clientserver.c path_failure).
  stop-time         --stop-at future/past (options.c parse_time) and --stop-after
                    (options.c 59% -> 64%).

Merged scoped coverage: lines 67.3%->68.3%, functions 87.5%->88.4%.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 07:44:12 +10:00

53 lines
1.8 KiB
Python

#!/usr/bin/env python3
"""Daemon coverage: the &include config directive (params.c include_config /
parse_directives) and a module whose path doesn't exist (clientserver.c
path_failure).
Uses a hand-written rsyncd.conf because &include is a directive line, not a
`name = value` parameter.
"""
import subprocess
from rsyncfns import (
FROMDIR, SCRATCHDIR,
make_tree, rmtree, rsync_argv, start_test_daemon, test_fail,
)
DAEMON_PORT = 12893
src = FROMDIR
rmtree(src)
make_tree(src, depth=2)
inc = SCRATCHDIR / 'included.conf'
inc.write_text(f"[inc-mod]\n\tpath = {src}\n\tread only = yes\n\tcomment = via-include\n")
conf = SCRATCHDIR / 'daemon-config.conf'
conf.write_text(
f"pid file = {SCRATCHDIR}/rsyncd.pid\n"
"use chroot = no\n"
"hosts allow = localhost 127.0.0.0/8\n"
f"log file = {SCRATCHDIR}/rsyncd.log\n"
f"&include {inc}\n"
f"\n[badpath]\n\tpath = {SCRATCHDIR}/no-such-dir\n\tread only = yes\n"
)
url = start_test_daemon(conf, DAEMON_PORT)
# &include pulled in inc-mod: it must be listable and present in the module list.
proc = subprocess.run(rsync_argv('-r', f'{url}inc-mod/'),
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if proc.returncode != 0:
test_fail(f"&include-defined module not reachable: {proc.stderr}")
proc = subprocess.run(rsync_argv(url), capture_output=True, text=True)
if 'inc-mod' not in proc.stdout:
test_fail(f"&include-defined module absent from the listing:\n{proc.stdout}")
# A module whose path does not exist must fail the connection (path_failure).
proc = subprocess.run(rsync_argv('-r', f'{url}badpath/'),
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True)
if proc.returncode == 0:
test_fail("a module with a non-existent path unexpectedly served a connection")
print("daemon-config: &include directive + bad-path failure verified")