ci: enforce BSD and Solaris profiles

This commit is contained in:
Zen Dodd committed 2026-10-10 09:16:06 +10:00
1 parent 6e45b4ac3b
commit 15e7c0447e
6 files changed
+66 -25

No files matched your search

+5 -3
View File
@@ -51,12 +51,13 @@ jobs:
./configure --with-rrsync \
-disable-zstd --disable-md2man --disable-xxhash --disable-lz4 --disable-idn \
--enable-roll-simd --enable-roll-asm --enable-md5-asm
make
make check-progs
./rsync --version
make check
./testsuite/runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
RSYNC_TEST_PROFILES=pipe,non-asan,root,self-peer,freebsd,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --receipt=test-results/freebsd-pipe.json -j 8
RSYNC_TEST_PROFILES=non-asan,root,self-peer,freebsd,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --use-tcp --receipt=test-results/freebsd-tcp.json -j 8
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 45
@@ -69,3 +70,4 @@ jobs:
rsyncd.conf.5
rrsync.1
rrsync
test-results/*.json
+5 -3
View File
@@ -50,12 +50,13 @@ jobs:
run: |
uname -a
./configure --with-rrsync --disable-zstd --disable-md2man --disable-xxhash --disable-lz4 --disable-idn
make
make check-progs
./rsync --version
make check
./testsuite/runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
RSYNC_TEST_PROFILES=pipe,non-asan,root,self-peer,netbsd,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --receipt=test-results/netbsd-pipe.json -j 8
RSYNC_TEST_PROFILES=non-asan,root,self-peer,netbsd,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --use-tcp --receipt=test-results/netbsd-tcp.json -j 8
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 45
@@ -68,3 +69,4 @@ jobs:
rsyncd.conf.5
rrsync.1
rrsync
test-results/*.json
+7 -5
View File
@@ -51,7 +51,7 @@ jobs:
export AUTOCONF_VERSION=2.71
export AUTOMAKE_VERSION=1.16
./configure --with-rrsync --disable-zstd --disable-md2man --disable-xxhash --disable-lz4 --disable-idn
make
make check-progs
./rsync --version
# The flipper (symlink-race) tests are excluded on OpenBSD, as on the
# fleet's OpenBSD box: this kernel has a connect()-under-rename-load
@@ -60,18 +60,19 @@ jobs:
# dev-notes/openbsd-connect-lost-wakeup-report.txt); the protections
# they exercise are verified on the Linux/BSD boxes.
export RSYNC_EXCLUDE=acl-symlink-race,sender-readlink-atfd,sender-remove-source-secure
make check
RSYNC_TEST_PROFILES=pipe,non-asan,root,self-peer,openbsd,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --receipt=test-results/openbsd-pipe.json -j 8
# The --use-tcp daemon tests run at -j2 here (vs -j8 elsewhere): this
# job runs inside a nested VM, and at -j8 the many concurrent loopback
# daemons occasionally lose a connection-handshake timing race under
# that resource pressure, hanging one test to the 300s timeout. It is
# an environment artifact, not an rsync bug (the handshake is
# deadlock-free and unreproducible elsewhere, even pinned to 1 CPU at
# -j8); -j2 keeps the VM from over-subscribing. The pipe `make check`
# above stays at the default parallelism.
./testsuite/runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 2
# -j8); -j2 keeps the VM from over-subscribing. The pipe pass above
# stays at the default parallelism.
RSYNC_TEST_PROFILES=non-asan,root,self-peer,openbsd,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --use-tcp --receipt=test-results/openbsd-tcp.json -j 2
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 45
@@ -84,3 +85,4 @@ jobs:
rsyncd.conf.5
rrsync.1
rrsync
test-results/*.json
+5 -3
View File
@@ -49,12 +49,13 @@ jobs:
run: |
uname -a
./configure --with-rrsync -disable-zstd --disable-md2man --disable-xxhash --disable-lz4 --disable-idn
make
make check-progs
./rsync --version
make check
./testsuite/runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
RSYNC_TEST_PROFILES=pipe,non-asan,root,self-peer,solaris,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --receipt=test-results/solaris-pipe.json -j 8
RSYNC_TEST_PROFILES=non-asan,root,self-peer,solaris,no-idn,no-xxhash,no-zstd-threads ./testsuite/runtests.py --rsync-bin="$PWD/rsync" --use-tcp --receipt=test-results/solaris-tcp.json -j 8
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
- name: save artifact
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 45
@@ -67,3 +68,4 @@ jobs:
rsyncd.conf.5
rrsync.1
rrsync
test-results/*.json
+10 -5
View File
@@ -302,13 +302,18 @@ def push_argv(target: Target, staging: str) -> list[str]:
def parse_workflow_profiles(workflow: str, make_target: str = "check") -> str | None:
path = WORKFLOWS / workflow
try:
text = path.read_text()
lines = path.read_text().splitlines()
except OSError:
return None
rx = re.compile(r"RSYNC_TEST_PROFILES=(\S+).*?\s+make\s+"
+ re.escape(make_target) + r"'?\s*$", re.M)
match = rx.search(text)
return match.group(1) if match else None
make_call = re.compile(r'\bmake\s+' + re.escape(make_target) + r'(?:\s|[\'\"]|$)')
for line in lines:
match = re.search(r'RSYNC_TEST_PROFILES=(\S+)', line)
if not match:
continue
direct = make_target == 'check' and 'runtests.py' in line and '--use-tcp' not in line
if direct or make_call.search(line):
return match.group(1)
return None
def tcp_profiles(workflow: str) -> str | None:
+34 -6
View File
@@ -22,6 +22,13 @@ PROFILE_ASSIGNMENT = re.compile(
r'RSYNC_TEST_PROFILES=(\S*\$\{\{\s*matrix\.profiles\s*\}\}\S*|\S+)')
MATRIX_PROFILE = re.compile(r'\$\{\{\s*matrix\.profiles\s*\}\}')
MATRIX_PROFILE_VALUE = re.compile(r'^\s+profiles:\s+(\S+)\s*$')
PLATFORM_PROFILES = {'non-asan', 'root', 'self-peer', 'no-idn', 'no-xxhash', 'no-zstd-threads'}
PLATFORM_WORKFLOWS = {
'freebsd-build.yml': PLATFORM_PROFILES | {'freebsd'},
'netbsd-build.yml': PLATFORM_PROFILES | {'netbsd'},
'openbsd-build.yml': PLATFORM_PROFILES | {'openbsd'},
'solaris-build.yml': PLATFORM_PROFILES | {'solaris'},
}
def profile_specs(line, matrix_profiles):
@@ -52,14 +59,27 @@ for path in workflows:
matrix_profiles = sorted(match.group(1) for line in lines
if (match := MATRIX_PROFILE_VALUE.match(line)))
profile_lines = [line for line in lines if 'RSYNC_TEST_PROFILES=' in line]
for line in profile_lines:
for value in profile_specs(line, matrix_profiles):
for name in value.split(','):
runtests.load_profile(SRC / 'testsuite' / 'profiles' / f'{name}.json', known_tests)
references += 1
specs = [value for line in profile_lines for value in profile_specs(line, matrix_profiles)]
names = {name for value in specs for name in value.split(',')}
for value in specs:
for name in value.split(','):
runtests.load_profile(SRC / 'testsuite' / 'profiles' / f'{name}.json', known_tests)
references += 1
required = PLATFORM_WORKFLOWS.get(path.name)
if required:
missing = required - names
if missing:
test_fail(f'{path.name}: missing profiles: {", ".join(sorted(missing))}')
if not any('test-results/*.json' in line for line in lines):
test_fail(f'{path.name}: profile receipts are not retained')
if not any('if: always()' in line for line in lines):
test_fail(f'{path.name}: failed profile receipts are not retained')
pipe = next((line for line in profile_lines
if line.rstrip().endswith('make check') or line.rstrip().endswith("make check'")), None)
if '--use-tcp' not in line and ('runtests.py' in line
or line.rstrip().endswith('make check')
or line.rstrip().endswith("make check'"))), None)
if not pipe:
continue
tcp = next((line for line in profile_lines if '--use-tcp' in line), None)
@@ -73,6 +93,8 @@ for path in workflows:
actual = {tuple(value.split(',')) for value in profile_specs(tcp, matrix_profiles)}
if actual != expected:
test_fail(f'{path.name}: TCP profiles differ from pipe profiles')
if required and ('--receipt=' not in pipe or '--receipt=' not in tcp):
test_fail(f'{path.name}: profiled transport has no receipt')
if workflows and not references:
test_fail('no workflow profile references found')
@@ -137,5 +159,11 @@ if workflows:
for target in fleet:
if error := fleettest.validate_target_capabilities(target):
test_fail(error)
required = PLATFORM_WORKFLOWS.get(target.workflow)
if required:
pipe_profiles = set(fleettest.target_profiles(target, 'pipe').split(','))
tcp_profiles = set(fleettest.target_profiles(target, 'tcp').split(','))
if pipe_profiles != required | {'pipe'} or tcp_profiles != required:
test_fail(f'{target.name}: fleet profiles differ from workflow')
print(f'ok: {references} workflow profile references')