Files
freebsd/usr.sbin/syslogd/tests/syslogd_forwarded_format_test.sh
Mark Johnston 560c22937b syslogd/tests: Address races
I occasionally see failures in the syslogd test suite.  The problem is
that the tests are racy: they send a message using logger(1), then
immediately check whether the message was logged to a log file.  If the
syslogd instance under test doesn't get a chance to run before the
second step, the test fails.

This change reworks things to avoid the race while minimizing the amount
of time sleeping.
1) Each test uses a single logfile, so have them use a new common
   variable, SYSLOGD_LOGFILE, instead of something test-specific.
2) In syslogd_start(), if the configuration references SYSLOGD_LOGFILE,
   wait for it to be created by syslogd before returning.
3) Add a helper syslogd_check_log(), to check for a given log entry in
   the last line of SYSLOGD_LOGFILE, instead of using atf_check
   directly.
4) In syslogd_check_log(), poll the logfile until the desired log entry
   appears, or the test times out.

With this change, I was able to run the tests 1000 times in a loop with
4-way parallelism without seeing any test failures.  Without the change
I usually get a failure within 10 loops.

Reviewed by:	jlduran
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D54779
2026-01-22 15:50:25 +00:00

230 lines
6.3 KiB
Bash

#-
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2024 Michal Scigocki <[email protected]>
#
. $(atf_get_srcdir)/syslogd_format_test_common.sh
SERVER_1_PORT="5140"
SERVER_2_PORT="5141"
# Forwarded Message Tests
# Two servers, one sending syslog messages to the other over UDP
setup_forwarded_format_test()
{
local format="$1"
local pcapfile="$2"
confirm_INET_support_or_skip
# Begin packet capture for single packet
tcpdump --immediate-mode -c 1 -i lo0 -w "${pcapfile}" \
dst port "${SERVER_1_PORT}" &
tcpdump_pid="$!"
# Start first server: receive UDP, log to file
printf "user.debug\t${SYSLOGD_LOGFILE}\n" > "$(config_filename ${SERVER_1_PORT})"
syslogd_start_on_port "${SERVER_1_PORT}" -O "${format}"
# Start second server: send UDP, log to first server
printf "user.debug\[email protected]:${SERVER_1_PORT}\n" \
> "$(config_filename ${SERVER_2_PORT})"
syslogd_start_on_port "${SERVER_2_PORT}" -O "${format}"
# Send test syslog message
syslogd_log -4 -p user.debug -t "${TAG}" -h 127.0.0.1 \
-P "${SERVER_2_PORT}" -H "${HOSTNAME}" "${MSG}"
wait "${tcpdump_pid}" # Wait for packet capture to finish
}
atf_test_case "O_flag_bsd_forwarded" "cleanup"
O_flag_bsd_forwarded_head()
{
atf_set descr "bsd format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_bsd_forwarded_body()
{
local format="bsd"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
atf_expect_fail \
"PR 220246 syslog -O bsd deviates from RFC 3164 recommendations"
syslogd_check_log "${REGEX_RFC3164_LOGFILE}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_bsd_forwarded_cleanup()
{
syslogd_stop_on_ports \
"${SERVER_1_PORT}" \
"${SERVER_2_PORT}"
}
atf_test_case "O_flag_rfc3164_forwarded" "cleanup"
O_flag_rfc3164_forwarded_head()
{
atf_set descr "rfc3164 format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_rfc3164_forwarded_body()
{
local format="rfc3164"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
atf_expect_fail \
"PR 220246 syslog -O rfc3164 deviates from RFC 3164 recommendations"
syslogd_check_log "${REGEX_RFC3164_LOGFILE}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_rfc3164_forwarded_cleanup()
{
syslogd_stop_on_ports \
"${SERVER_1_PORT}" \
"${SERVER_2_PORT}"
}
atf_test_case "O_flag_rfc3164strict_forwarded" "cleanup"
O_flag_rfc3164strict_forwarded_head()
{
atf_set descr "rfc3164-strict format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_rfc3164strict_forwarded_body()
{
local format="rfc3164-strict"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
syslogd_check_log "${REGEX_RFC3164_LOGFILE}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_rfc3164strict_forwarded_cleanup()
{
syslogd_stop_on_ports \
"${SYSLOGD_UDP_PORT_1}" \
"${SYSLOGD_UDP_PORT_2}"
}
atf_test_case "O_flag_syslog_forwarded" "cleanup"
O_flag_syslog_forwarded_head()
{
atf_set descr "syslog format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_syslog_forwarded_body()
{
local format="syslog"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
syslogd_check_log "${REGEX_RFC5424_LOGFILE}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC5424_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_syslog_forwarded_cleanup()
{
syslogd_stop_on_ports \
"${SERVER_1_PORT}" \
"${SERVER_2_PORT}"
}
atf_test_case "O_flag_rfc5424_forwarded" "cleanup"
O_flag_rfc5424_forwarded_head()
{
atf_set descr "rfc5424 format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_rfc5424_forwarded_body()
{
local format="rfc5424"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
syslogd_check_log "${REGEX_RFC5424_LOGFILE}"
atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC5424_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_rfc5424_forwarded_cleanup()
{
syslogd_stop_on_ports \
"${SERVER_1_PORT}" \
"${SERVER_2_PORT}"
}
# Legacy bsd/rfc3164 format tests
# The legacy syntax was introduced in FreeBSD PR 7055, circa 1998
atf_test_case "O_flag_bsd_forwarded_legacy" "cleanup"
O_flag_bsd_forwarded_legacy_head()
{
atf_set descr "legacy bsd format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_bsd_forwarded_legacy_body()
{
local format="bsd"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
syslogd_check_log "${REGEX_RFC3164_LEGACY_LOGFILE}"
atf_check -s exit:0 -e ignore \
-o match:"${REGEX_RFC3164_LEGACY_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_bsd_forwarded_legacy_cleanup()
{
syslogd_stop_on_ports \
"${SERVER_1_PORT}" \
"${SERVER_2_PORT}"
}
atf_test_case "O_flag_rfc3164_forwarded_legacy" "cleanup"
O_flag_rfc3164_forwarded_legacy_head()
{
atf_set descr \
"legacy rfc3164 format test on a forwarded syslog message"
set_common_atf_metadata
}
O_flag_rfc3164_forwarded_legacy_body()
{
local format="rfc3164"
local pcapfile="${PWD}/${format}_forwarded.pcap"
setup_forwarded_format_test "${format}" "${pcapfile}"
syslogd_check_log "${REGEX_RFC3164_LEGACY_LOGFILE}"
atf_check -s exit:0 -e ignore \
-o match:"${REGEX_RFC3164_LEGACY_PAYLOAD}" \
tcpdump -A -r "${pcapfile}"
}
O_flag_rfc3164_forwarded_legacy_cleanup()
{
syslogd_stop_on_ports \
"${SERVER_1_PORT}" \
"${SERVER_2_PORT}"
}
atf_init_test_cases()
{
atf_add_test_case "O_flag_bsd_forwarded"
atf_add_test_case "O_flag_rfc3164_forwarded"
atf_add_test_case "O_flag_rfc3164strict_forwarded"
atf_add_test_case "O_flag_syslog_forwarded"
atf_add_test_case "O_flag_rfc5424_forwarded"
atf_add_test_case "O_flag_bsd_forwarded_legacy"
atf_add_test_case "O_flag_rfc3164_forwarded_legacy"
}