mirror of
https://github.com/containers/podman.git
synced 2025-07-04 10:10:32 +08:00
CI: system tests: make random_free_port() parallel-safe
...by using a crude port lock-and-reserve mechanism. This is a small cherrypick from code that has been working in #23275 over dozens of CI runs. Am separating out into a small PR because it's stable, harmless to serial runs, and will simplify the eventual review of #23275. Closes: #23488 Signed-off-by: Ed Santiago <santiago@redhat.com>
This commit is contained in:
@ -41,6 +41,9 @@ if [ $(id -u) -eq 0 ]; then
|
||||
_LOG_PROMPT='#'
|
||||
fi
|
||||
|
||||
# Used in helpers.network, needed here in teardown
|
||||
PORT_LOCK_DIR=$BATS_SUITE_TMPDIR/reserved-ports
|
||||
|
||||
###############################################################################
|
||||
# BEGIN tools for fetching & caching test images
|
||||
#
|
||||
@ -205,6 +208,14 @@ function defer-assertion-failures() {
|
||||
function basic_teardown() {
|
||||
echo "# [teardown]" >&2
|
||||
|
||||
# Free any ports reserved by our test
|
||||
if [[ -d $PORT_LOCK_DIR ]]; then
|
||||
mylocks=$(grep -wlr $BATS_SUITE_TEST_NUMBER $PORT_LOCK_DIR || true)
|
||||
if [[ -n "$mylocks" ]]; then
|
||||
rm -f $mylocks
|
||||
fi
|
||||
fi
|
||||
|
||||
immediate-assertion-failures
|
||||
# Unlike normal tests teardown will not exit on first command failure
|
||||
# but rather only uses the return code of the teardown function.
|
||||
|
@ -273,6 +273,36 @@ function ether_get_name() {
|
||||
|
||||
### Ports and Ranges ###########################################################
|
||||
|
||||
# reserve_port() - create a lock file reserving a port, or return false
|
||||
function reserve_port() {
|
||||
local port=$1
|
||||
|
||||
mkdir -p $PORT_LOCK_DIR
|
||||
local lockfile=$PORT_LOCK_DIR/$port
|
||||
local locktmp=$PORT_LOCK_DIR/.$port.$$
|
||||
echo $BATS_SUITE_TEST_NUMBER >$locktmp
|
||||
|
||||
if ln $locktmp $lockfile; then
|
||||
rm -f $locktmp
|
||||
return
|
||||
fi
|
||||
# Port already reserved
|
||||
rm -f $locktmp
|
||||
false
|
||||
}
|
||||
|
||||
# unreserve_port() - free a temporarily-reserved port
|
||||
function unreserve_port() {
|
||||
local port=$1
|
||||
|
||||
local lockfile=$PORT_LOCK_DIR/$port
|
||||
-e $lockfile || die "Cannot unreserve non-reserved port $port"
|
||||
assert "$(< $lockfile)" = "$BATS_SUITE_TEST_NUMBER" \
|
||||
"Port $port is not reserved by this test"
|
||||
rm -f $lockfile
|
||||
}
|
||||
|
||||
|
||||
# random_free_port() - Get unbound port with pseudorandom number
|
||||
# $1: Optional, dash-separated interval, [5000, 5999] by default
|
||||
# $2: Optional binding address, any IPv4 address by default
|
||||
@ -284,9 +314,14 @@ function random_free_port() {
|
||||
|
||||
local port
|
||||
for port in $(shuf -i ${range}); do
|
||||
if port_is_free $port $address $protocol; then
|
||||
echo $port
|
||||
return
|
||||
# First make sure no other tests are using it
|
||||
if reserve_port $port; then
|
||||
if port_is_free $port $address $protocol; then
|
||||
echo $port
|
||||
return
|
||||
fi
|
||||
|
||||
unreserve_port $port
|
||||
fi
|
||||
done
|
||||
|
||||
@ -308,8 +343,13 @@ function random_free_port_range() {
|
||||
local lastport=
|
||||
for i in $(seq 1 $((size - 1))); do
|
||||
lastport=$((firstport + i))
|
||||
if ! reserve_port $lastport; then
|
||||
lastport=
|
||||
break
|
||||
fi
|
||||
if ! port_is_free $lastport $address $protocol; then
|
||||
echo "# port $lastport is in use; trying another." >&3
|
||||
unreserve_port $lastport
|
||||
lastport=
|
||||
break
|
||||
fi
|
||||
@ -319,6 +359,8 @@ function random_free_port_range() {
|
||||
return
|
||||
fi
|
||||
|
||||
unreserve_port $firstport
|
||||
|
||||
maxtries=$((maxtries - 1))
|
||||
done
|
||||
|
||||
|
@ -22,6 +22,9 @@ rc=0
|
||||
PODMAN_TMPDIR=$(mktemp -d --tmpdir=${TMPDIR:-/tmp} podman_helper_tests.XXXXXX)
|
||||
trap 'rm -rf $PODMAN_TMPDIR' 0
|
||||
|
||||
# Used by random_free_port.
|
||||
PORT_LOCK_DIR=$PODMAN_TMPDIR/reserved-ports
|
||||
|
||||
###############################################################################
|
||||
# BEGIN test the parse_table helper
|
||||
|
||||
|
Reference in New Issue
Block a user