Skip to content

Commit

Permalink
Merge pull request #23595 from edsantiago/parallel-safe-random-free-port
Browse files Browse the repository at this point in the history
CI: system tests: make random_free_port() parallel-safe
  • Loading branch information
openshift-merge-bot[bot] authored Aug 16, 2024
2 parents f69ede1 + 420bd16 commit 8c132cc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
11 changes: 11 additions & 0 deletions test/system/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down Expand Up @@ -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.
Expand Down
48 changes: 45 additions & 3 deletions test/system/helpers.network.bash
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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
Expand All @@ -319,6 +359,8 @@ function random_free_port_range() {
return
fi

unreserve_port $firstport

maxtries=$((maxtries - 1))
done

Expand Down
3 changes: 3 additions & 0 deletions test/system/helpers.t
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 8c132cc

Please sign in to comment.