Skip to content

Commit de0d8db

Browse files
committed
Fix macOS test failures and wire dynamic cluster ports to XrdCl tests.
Load cluster ports from ports.env in TestEnv, re-patch metalinks on each cluster start, and harden TLS/GSI/HTTP harnesses plus a few XrdCl tests for macOS and interrupted runs. Assisted-by: Cursor:Composer-2.5 CursorAI
1 parent 266c1f1 commit de0d8db

11 files changed

Lines changed: 306 additions & 38 deletions

File tree

tests/XRootD/gsi.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function setup_gsi() {
2424
}
2525

2626
function teardown_gsi() {
27-
pwd && ls && rm authdb gridmap proxy.{crt,crtp}
27+
rm -f authdb gridmap proxy.crt proxy.crtp iproxy.crt rproxy.crt
2828
}
2929

3030
function test_gsi() {

tests/XRootD/http.sh

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -472,11 +472,38 @@ function test_http() {
472472
local payload="$1"
473473
local status=""
474474
local rc=0
475-
exec 3<>"/dev/tcp/${smugglingHost}/${smugglingPort}"
476-
printf '%s' "$payload" >&3
477-
IFS= read -r -t 10 status <&3 || rc=$?
478-
exec 3<&-
479-
status="${status//$'\r'/}"
475+
476+
# macOS ships bash 3.2 without /dev/tcp; use python3 when available.
477+
if command -v python3 >/dev/null 2>&1; then
478+
status=$(printf '%s' "$payload" | _SMUGGLING_HOST="$smugglingHost" _SMUGGLING_PORT="$smugglingPort" python3 -c '
479+
import os, socket, sys
480+
host = os.environ["_SMUGGLING_HOST"]
481+
port = int(os.environ["_SMUGGLING_PORT"])
482+
payload = sys.stdin.buffer.read()
483+
s = socket.create_connection((host, port), timeout=10)
484+
s.sendall(payload)
485+
try:
486+
s.shutdown(socket.SHUT_WR)
487+
except OSError:
488+
pass
489+
buf = b""
490+
while b"\n" not in buf and len(buf) < 8192:
491+
chunk = s.recv(4096)
492+
if not chunk:
493+
break
494+
buf += chunk
495+
s.close()
496+
if buf:
497+
sys.stdout.write(buf.split(b"\n", 1)[0].decode("latin-1", "replace").rstrip("\r"))
498+
' ) || rc=$?
499+
else
500+
exec 3<>"/dev/tcp/${smugglingHost}/${smugglingPort}"
501+
printf '%s' "$payload" >&3
502+
IFS= read -r -t 10 status <&3 || rc=$?
503+
exec 3<&-
504+
status="${status//$'\r'/}"
505+
fi
506+
480507
if [[ -n "${status}" ]]; then
481508
printf '%s' "${status}"
482509
elif (( rc > 128 )); then

tests/XrdCl/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ if(NOT ENABLE_SERVER_TESTS)
1616
return()
1717
endif()
1818

19+
set(XRDCL_CLUSTER_TEST_ENV "XRDTEST_PORTS_ENV=${CMAKE_BINARY_DIR}/tests/cluster/ports.env")
20+
1921
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tmp")
2022

2123
add_executable(xrdcl-cluster-tests
@@ -34,7 +36,8 @@ target_link_libraries(xrdcl-cluster-tests
3436
XrdTestUtils GTest::gtest GTest::gtest_main)
3537

3638
gtest_discover_tests(xrdcl-cluster-tests TEST_PREFIX XrdCl::
37-
PROPERTIES DEPENDS XRootD_Cluster FIXTURES_REQUIRED XRootD_Cluster DISCOVERY_TIMEOUT 10)
39+
PROPERTIES DEPENDS XRootD_Cluster FIXTURES_REQUIRED XRootD_Cluster
40+
ENVIRONMENT "${XRDCL_CLUSTER_TEST_ENV}" DISCOVERY_TIMEOUT 10)
3841

3942
# tests to be run in serial, otherwise they are problematic
4043
set(SERIAL_TESTS_FILES
@@ -54,5 +57,6 @@ foreach(i ${SERIAL_TESTS_FILES})
5457
XrdTestUtils GTest::gtest GTest::gtest_main)
5558

5659
gtest_discover_tests(${i}-tests TEST_PREFIX XrdCl::
57-
PROPERTIES DEPENDS XRootD_Cluster FIXTURES_REQUIRED XRootD_Cluster RUN_SERIAL 1 DISCOVERY_TIMEOUT 10)
60+
PROPERTIES DEPENDS XRootD_Cluster FIXTURES_REQUIRED XRootD_Cluster RUN_SERIAL 1
61+
ENVIRONMENT "${XRDCL_CLUSTER_TEST_ENV}" DISCOVERY_TIMEOUT 10)
5862
endforeach()

tests/XrdCl/XrdClFileCopyTest.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ void FileCopyTest::CopyTestFunc( bool thirdParty )
355355
PropertyList properties, results;
356356
FileSystem fs( manager2 );
357357

358+
// Remove any leftover targets from a previous interrupted run.
359+
fs.Rm( targetPath );
360+
remove( localFile.c_str() );
361+
sync();
362+
358363
//----------------------------------------------------------------------------
359364
// Copy from a ZIP archive
360365
//----------------------------------------------------------------------------
@@ -530,6 +535,7 @@ void FileCopyTest::CopyTestFunc( bool thirdParty )
530535
//----------------------------------------------------------------------------
531536
// Copy to local fs
532537
//----------------------------------------------------------------------------
538+
remove( localFile.c_str() );
533539
results.Clear();
534540
properties.Set( "source", sourceURL );
535541
properties.Set( "target", "file://localhost" + localFile );

tests/XrdCl/XrdClLocalFileHandlerTest.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "XrdSys/XrdSysPlatform.hh"
2222

2323
#include <climits>
24+
#include <algorithm>
2425
#include <sys/types.h>
2526
#include <sys/stat.h>
2627
#include <fcntl.h>
@@ -533,6 +534,14 @@ TEST_F(LocalFileHandlerTest, XAttrTest)
533534
//----------------------------------------------------------------------------
534535
resp.clear();
535536
EXPECT_XRDST_OK( f.ListXAttr( resp ) );
537+
#ifdef __APPLE__
538+
// macOS may attach system xattrs such as com.apple.provenance.
539+
resp.erase( std::remove_if( resp.begin(), resp.end(),
540+
[]( const XAttr &a ) {
541+
return a.name.compare( 0, 10, "com.apple." ) == 0;
542+
} ),
543+
resp.end() );
544+
#endif
536545
EXPECT_EQ( resp.size(), 2u );
537546
vid = resp[0].name == "version" ? 0 : 1;
538547
int cid = vid == 0 ? 1 : 0;

tests/cluster/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ file(COPY mvdata DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
1818

1919
add_test(NAME XRootD::cluster::start
2020
COMMAND sh -c "cp -r ${CMAKE_CURRENT_SOURCE_DIR}/mvdata ${CMAKE_CURRENT_BINARY_DIR} \
21-
&& ${CMAKE_CURRENT_SOURCE_DIR}/setup.sh start")
21+
&& ${CMAKE_CURRENT_SOURCE_DIR}/setup.sh start \
22+
|| (${CMAKE_CURRENT_SOURCE_DIR}/setup.sh stop; exit 1)")
2223
set_tests_properties(XRootD::cluster::start
2324
PROPERTIES ENVIRONMENT "${XRDENV}" FIXTURES_SETUP XRootD_Cluster)
2425

tests/cluster/setup.sh

Lines changed: 85 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ HOST_SRV1=root://localhost:${XRD_PORT_SRV1}
7777
HOST_SRV2=root://localhost:${XRD_PORT_SRV2}
7878
HOST_SRV3=root://localhost:${XRD_PORT_SRV3}
7979
HOST_SRV4=root://localhost:${XRD_PORT_SRV4}
80+
XRDTEST_MAINSERVERURL=localhost:${XRD_PORT_METAMAN}
81+
XRDTEST_MANAGER1URL=localhost:${XRD_PORT_MAN1}
82+
XRDTEST_MANAGER2URL=localhost:${XRD_PORT_MAN2}
83+
XRDTEST_SERVER1URL=localhost:${XRD_PORT_SRV1}
84+
XRDTEST_SERVER2URL=localhost:${XRD_PORT_SRV2}
85+
XRDTEST_SERVER3URL=localhost:${XRD_PORT_SRV3}
86+
XRDTEST_SERVER4URL=localhost:${XRD_PORT_SRV4}
87+
XRDTEST_DISKSERVERURL=localhost:${XRD_PORT_METAMAN}
88+
XRDTEST_LOCALDATAPATH=$(cd "${DATAFOLDER}" && pwd)
8089
EOF
8190
}
8291

@@ -118,10 +127,23 @@ patch_metalink_ports() {
118127
-e "s/localhost:10944/localhost:${XRD_PORT_SRV2}/g" \
119128
-e "s/localhost:10945/localhost:${XRD_PORT_SRV3}/g" \
120129
-e "s/localhost:10946/localhost:${XRD_PORT_SRV4}/g" \
130+
-e "s/localhost:${PREV_XRD_PORT_SRV1}/localhost:${XRD_PORT_SRV1}/g" \
131+
-e "s/localhost:${PREV_XRD_PORT_SRV2}/localhost:${XRD_PORT_SRV2}/g" \
132+
-e "s/localhost:${PREV_XRD_PORT_SRV3}/localhost:${XRD_PORT_SRV3}/g" \
133+
-e "s/localhost:${PREV_XRD_PORT_SRV4}/localhost:${XRD_PORT_SRV4}/g" \
121134
"${file}"
122135
done
123136
}
124137

138+
patch_all_metalink_ports() {
139+
local dir
140+
141+
for dir in "${DATAFOLDER}"/*/data/metalink; do
142+
[[ -d "${dir}" ]] || continue
143+
patch_metalink_ports "${dir}"/*
144+
done
145+
}
146+
125147
filenames=("1db882c8-8cd6-4df1-941f-ce669bad3458.dat"
126148
"3c9a9dd8-bc75-422c-b12c-f00604486cc1.dat"
127149
"7235b5d1-cede-4700-a8f9-596506b4cc38.dat"
@@ -213,7 +235,6 @@ generate(){
213235
mkdir -p ${DATAFOLDER}/${i}/data/metalink
214236
cp ${PREDEF}/input*.meta* ${DATAFOLDER}/${i}/data/metalink/
215237
cp ${PREDEF}/ml*.meta* ${DATAFOLDER}/${i}/data/metalink/
216-
patch_metalink_ports ${DATAFOLDER}/${i}/data/metalink/*
217238
fi
218239

219240
# download the test files for 'srv2' and add another instance on 1099
@@ -249,12 +270,73 @@ generate(){
249270
rm -rf ${TMPDATAFOLDER}
250271
}
251272

273+
kill_pidfile() {
274+
local pidfile=$1
275+
local pid wait_count
276+
277+
[[ -s "${pidfile}" ]] || return 0
278+
pid=$(ps -o pid= "$(cat "${pidfile}")" 2>/dev/null | tr -d ' ')
279+
[[ -n "${pid}" ]] || return 0
280+
kill -s TERM "${pid}" 2>/dev/null || true
281+
for ((wait_count = 0; wait_count < 50; wait_count++)); do
282+
ps -p "${pid}" >/dev/null 2>&1 || return 0
283+
sleep 0.1
284+
done
285+
kill -s KILL "${pid}" 2>/dev/null || true
286+
}
287+
288+
stop() {
289+
local i
290+
291+
set +e
292+
for i in "${servernames[@]}"; do
293+
[[ -d "${i}" ]] || continue
294+
kill_pidfile "${i}/cmsd.pid"
295+
kill_pidfile "${i}/xrootd.pid"
296+
rm -rf "${i}"
297+
done
298+
rm -f "${PORTS_ENV}"
299+
set -e
300+
}
301+
252302
start(){
303+
PREV_XRD_PORT_SRV1=10943
304+
PREV_XRD_PORT_SRV2=10944
305+
PREV_XRD_PORT_SRV3=10945
306+
PREV_XRD_PORT_SRV4=10946
307+
if [[ -f "${PORTS_ENV}" ]]; then
308+
# shellcheck disable=SC1091
309+
source "${PORTS_ENV}"
310+
PREV_XRD_PORT_SRV1=${XRD_PORT_SRV1}
311+
PREV_XRD_PORT_SRV2=${XRD_PORT_SRV2}
312+
PREV_XRD_PORT_SRV3=${XRD_PORT_SRV3}
313+
PREV_XRD_PORT_SRV4=${XRD_PORT_SRV4}
314+
fi
315+
316+
stop
317+
253318
allocate_ports
254319
write_configs
255320
write_ports_env
256321
generate
322+
patch_all_metalink_ports
323+
324+
local need_cleanup=0
325+
start_interrupt_cleanup() {
326+
need_cleanup=1
327+
}
328+
start_exit_cleanup() {
329+
if [[ ${need_cleanup} -eq 1 ]]; then
330+
stop
331+
fi
332+
}
333+
334+
trap start_interrupt_cleanup INT TERM HUP
335+
trap start_exit_cleanup EXIT
336+
257337
set -x
338+
need_cleanup=1
339+
258340
# start for each component
259341
for i in "${servernames[@]}"; do
260342
${XROOTD} -b -k fifo -n ${i} -l xrootd.log -s xrootd.pid -c ${i}.cfg
@@ -266,17 +348,8 @@ start(){
266348
done
267349

268350
sleep 1
269-
}
270-
271-
stop() {
272-
for i in "${servernames[@]}"; do
273-
if [[ -d "${i}" ]]; then
274-
kill -s TERM $(cat ${i}/cmsd.pid)
275-
kill -s TERM $(cat ${i}/xrootd.pid)
276-
rm -rf "${i}"
277-
fi
278-
done
279-
rm -f "${PORTS_ENV}"
351+
need_cleanup=0
352+
trap - EXIT INT TERM HUP
280353
}
281354

282355
insertFileInfo() {

tests/cluster/test.sh

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/usr/bin/env bash
22

3+
SETUP_SH="$(cd "$(dirname "$0")" && pwd)/setup.sh"
4+
35
: ${ADLER32:=$(command -v xrdadler32)}
46
: ${CRC32C:=$(command -v xrdcrc32c)}
57
: ${XRDCP:=$(command -v xrdcp)}
@@ -60,8 +62,37 @@ done
6062
# This script assumes that ${host} exports an empty / as read/write.
6163
# It also assumes that any authentication required is already setup.
6264

65+
RMTDATADIR="/srvdata"
66+
LCLDATADIR="${PWD}/localdata" # client folder
67+
68+
cleanup_local_files() {
69+
local i
70+
for ((i = 0; i < ${#host_names[@]}; i++)); do
71+
rm -rf ${LCLDATADIR}/${host_names[i]}.dat
72+
rm -rf ${LCLDATADIR}/${host_names[i]}.ref
73+
done
74+
}
75+
76+
stop_cluster() {
77+
[[ -x "${SETUP_SH}" ]] && "${SETUP_SH}" stop || true
78+
}
79+
80+
fixture_cleanup() {
81+
local rc=$?
82+
83+
cleanup_local_files
84+
if [[ ${rc} -ne 0 ]]; then
85+
echo 1>&2 "Stopping cluster after test failure or interruption."
86+
stop_cluster
87+
fi
88+
return ${rc}
89+
}
90+
6391
set -e
6492

93+
trap fixture_cleanup EXIT
94+
trap 'stop_cluster; exit 130' INT TERM HUP
95+
6596
${XRDCP} --version
6697

6798
for ((i = 0; i < ${#host_names[@]}; i++)); do
@@ -83,9 +114,6 @@ ${XRDFS} ${HOST_METAMAN} stat /
83114
${XRDFS} ${HOST_METAMAN} statvfs /
84115
${XRDFS} ${HOST_METAMAN} spaceinfo /
85116

86-
RMTDATADIR="/srvdata"
87-
LCLDATADIR="${PWD}/localdata" # client folder
88-
89117
mkdir -p ${LCLDATADIR}
90118

91119
assert_xrdmapc_json() {
@@ -104,16 +132,6 @@ assert_xrdmapc_json() {
104132

105133
}
106134

107-
cleanup() {
108-
echo "Error occurred. Cleaning up..."
109-
local i
110-
for ((i = 0; i < ${#host_names[@]}; i++)); do
111-
rm -rf ${LCLDATADIR}/${host_names[i]}.dat
112-
rm -rf ${LCLDATADIR}/${host_names[i]}.ref
113-
done
114-
}
115-
trap "cleanup; exit 1" ABRT
116-
117135
assert_xrdmapc_json
118136

119137
# create local files with random contents using OpenSSL

tests/common/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@ add_library(XrdTestUtils SHARED
55

66
target_link_libraries(XrdTestUtils ZLIB::ZLIB XrdCl XrdUtils)
77

8+
target_compile_definitions(XrdTestUtils PRIVATE
9+
XRDTEST_DEFAULT_PORTS_ENV="${CMAKE_BINARY_DIR}/tests/cluster/ports.env"
10+
XRDTEST_DEFAULT_LOCAL_DATA_PATH="${CMAKE_BINARY_DIR}/tests/cluster/data")
11+
812
target_include_directories(XrdTestUtils
913
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)

0 commit comments

Comments
 (0)