Skip to content

Commit ad3bec3

Browse files
authored
Merge pull request #85 from bbockelm/stress_test
Add stress test (and small fixes)
2 parents d75b46d + d359f7f commit ad3bec3

File tree

9 files changed

+96
-13
lines changed

9 files changed

+96
-13
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ jobs:
2929
- uses: actions/checkout@v3
3030
with:
3131
submodules: recursive
32+
- uses: actions/setup-go@v5
33+
with:
34+
go-version: '1.23.5'
3235
- name: install deps
3336
run: |
3437
sudo curl -L https://xrootd.web.cern.ch/repo/RPM-GPG-KEY.txt -o /etc/apt/trusted.gpg.d/xrootd.asc

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ if( BUILD_TESTING )
115115
target_link_libraries(XrdHTTPServerTesting XrdHTTPServerObj)
116116
target_include_directories(XrdHTTPServerTesting INTERFACE ${XRootD_INCLUDE_DIRS})
117117

118+
find_program(GoWrk go-wrk HINTS "$ENV{HOME}/go/bin")
119+
if( NOT GoWrk )
120+
# Try installing the go-wrk variable to generate a reasonable stress test
121+
execute_process( COMMAND go install github.com/bbockelm/go-wrk@92dbe19
122+
RESULT_VARIABLE go_install_result )
123+
if( go_install_result EQUAL 0 )
124+
find_program(GoWrk go-wrk HINTS "$ENV{HOME}/go/bin")
125+
else()
126+
message(ERROR "Failed to install the go-wrk binary" )
127+
endif()
128+
endif()
129+
118130
if( NOT XROOTD_PLUGINS_EXTERNAL_GTEST )
119131
include( FetchContent )
120132
set( GTEST_URL "${CMAKE_CURRENT_SOURCE_DIR}/googletest-1.15.2.tar.gz" )

src/CurlUtil.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
using namespace XrdHTTPServer;
3636

37-
thread_local std::vector<CURL *> HandlerQueue::m_handles;
37+
thread_local std::stack<CURL *> HandlerQueue::m_handles;
3838

3939
HandlerQueue::HandlerQueue() {
4040
int filedes[2];
@@ -85,16 +85,16 @@ CURL *GetHandle(bool verbose) {
8585
}
8686

8787
CURL *HandlerQueue::GetHandle() {
88-
if (m_handles.size()) {
89-
auto result = m_handles.back();
90-
m_handles.pop_back();
88+
if (!m_handles.empty()) {
89+
CURL *result = m_handles.top();
90+
m_handles.pop();
9191
return result;
9292
}
9393

9494
return ::GetHandle(false);
9595
}
9696

97-
void HandlerQueue::RecycleHandle(CURL *curl) { m_handles.push_back(curl); }
97+
void HandlerQueue::RecycleHandle(CURL *curl) { m_handles.push(curl); }
9898

9999
void HandlerQueue::Produce(HTTPRequest *handler) {
100100
std::unique_lock<std::mutex> lk{m_mutex};
@@ -258,6 +258,7 @@ void CurlWorker::Run() {
258258
<< curl_multi_strerror(mres);
259259
m_logger.Log(LogMask::Debug, "Run", ss.str().c_str());
260260
}
261+
m_op_map.erase(curl);
261262
op->Fail("E_CURL_LIB",
262263
"Unable to add operation to the curl multi-handle");
263264
continue;

src/CurlUtil.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
#include <deque>
2323
#include <memory>
2424
#include <mutex>
25+
#include <stack>
2526
#include <unordered_map>
26-
#include <vector>
2727

2828
// Forward dec'ls
2929
typedef void CURL;
@@ -58,7 +58,7 @@ class HandlerQueue {
5858

5959
private:
6060
std::deque<HTTPRequest *> m_ops;
61-
thread_local static std::vector<CURL *> m_handles;
61+
thread_local static std::stack<CURL *> m_handles;
6262
std::condition_variable m_cv;
6363
std::mutex m_mutex;
6464
const static unsigned m_max_pending_ops{20};

src/S3Commands.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ void AmazonS3Head::parseResponse() {
605605
size_t current_newline = 0;
606606
size_t next_newline = std::string::npos;
607607
size_t last_character = headers.size();
608-
while (current_newline != std::string::npos &&
608+
while (headers.size() && current_newline != std::string::npos &&
609609
current_newline != last_character - 1) {
610610
next_newline = headers.find("\r\n", current_newline + 2);
611611
line = substring(headers, current_newline + 2, next_newline);

test/CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ add_test(NAME HTTP::basic::setup
5858
set_tests_properties(HTTP::basic::setup
5959
PROPERTIES
6060
FIXTURES_SETUP HTTP::basic
61-
ENVIRONMENT "BINARY_DIR=${CMAKE_BINARY_DIR};SOURCE_DIR=${CMAKE_SOURCE_DIR}"
61+
ENVIRONMENT "BINARY_DIR=${CMAKE_BINARY_DIR};SOURCE_DIR=${CMAKE_SOURCE_DIR};XROOTD_BINDIR=${XRootD_DATA_DIR}/../bin"
6262
)
6363

6464
add_test(NAME HTTP::basic::teardown
@@ -92,7 +92,7 @@ add_test(NAME S3::s3_basic::setup
9292
set_tests_properties(S3::s3_basic::setup
9393
PROPERTIES
9494
FIXTURES_SETUP S3::s3_basic
95-
ENVIRONMENT "BINARY_DIR=${CMAKE_BINARY_DIR};SOURCE_DIR=${CMAKE_SOURCE_DIR}"
95+
ENVIRONMENT "BINARY_DIR=${CMAKE_BINARY_DIR};SOURCE_DIR=${CMAKE_SOURCE_DIR};XROOTD_BINDIR=${XRootD_DATA_DIR}/../bin"
9696
)
9797

9898
add_test(NAME S3::s3_basic::teardown
@@ -126,3 +126,17 @@ set_tests_properties(S3::s3_basic::stress_test
126126
ENVIRONMENT "BINARY_DIR=${CMAKE_BINARY_DIR}"
127127
ATTACHED_FILES_ON_FAIL "${S3_BASIC_TEST_LOGS}"
128128
)
129+
130+
#######################################
131+
# Stress-test using the go-wrk binary #
132+
#######################################
133+
134+
add_test( NAME S3::s3_basic::gowrk_test
135+
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/s3-gowrk-test.sh" s3_basic )
136+
137+
set_tests_properties( S3::s3_basic::gowrk_test
138+
PROPERTIES
139+
FIXTURES_REQUIRED S3::s3_basic
140+
ENVIRONMENT "BINARY_DIR=${CMAKE_BINARY_DIR};WRK_BIN=${GoWrk}"
141+
ATTACHED_FILES_ON_FAIL "${S3_BASIC_TEST_LOGS}"
142+
)

test/s3-gowrk-test.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/sh
2+
3+
TEST_NAME=$1
4+
5+
if [ -z "$BINARY_DIR" ]; then
6+
echo "\$BINARY_DIR environment variable is not set; cannot run test"
7+
exit 1
8+
fi
9+
if [ ! -d "$BINARY_DIR" ]; then
10+
echo "$BINARY_DIR is not a directory; cannot run test"
11+
exit 1
12+
fi
13+
14+
echo "Running $TEST_NAME - go-wrk based stress test"
15+
16+
echo > "$BINARY_DIR/tests/$TEST_NAME/client.log"
17+
18+
if [ ! -f "$BINARY_DIR/tests/$TEST_NAME/setup.sh" ]; then
19+
echo "Test environment file $BINARY_DIR/tests/$TEST_NAME/setup.sh does not exist - cannot run test"
20+
exit 1
21+
fi
22+
. "$BINARY_DIR/tests/$TEST_NAME/setup.sh"
23+
24+
"$WRK_BIN" -c 200 -d 10 -no-vr -T 10000 -f "$PLAYBACK_FILE"

test/s3-setup.sh

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ if [ -z "$MC_BIN" ]; then
3838
exit 1
3939
fi
4040

41-
XROOTD_BIN="$(command -v xrootd)"
41+
XROOTD_BIN="$XROOTD_BINDIR/xrootd"
4242
if [ -z "XROOTD_BIN" ]; then
4343
echo "xrootd binary not found; cannot run unit test"
4444
exit 1
@@ -201,6 +201,20 @@ fi
201201
echo "Hello, World" > "$RUNDIR/hello_world.txt"
202202
"$MC_BIN" --insecure --config-dir "$MINIO_CLIENTDIR" cp "$RUNDIR/hello_world.txt" userminio/test-bucket/hello_world.txt
203203

204+
IDX=0
205+
COUNT=25
206+
while [ $IDX -ne $COUNT ]; do
207+
if ! dd if=/dev/urandom "of=$RUNDIR/test_file" bs=1024 count=1024 2> /dev/null; then
208+
echo "Failed to create random file to upload"
209+
exit 1
210+
fi
211+
if ! "$MC_BIN" --insecure --config-dir "$MINIO_CLIENTDIR" cp "$RUNDIR/test_file" "userminio/test-bucket/test_file_$IDX.random" > /dev/null; then
212+
echo "Failed to upload random file to S3 instance"
213+
exit 1
214+
fi
215+
IDX=$((IDX+1))
216+
done
217+
204218
####
205219
# Starting XRootD config with S3 backend
206220
####
@@ -274,6 +288,10 @@ while [ -z "$XROOTD_URL" ]; do
274288
sleep 1
275289
XROOTD_URL=$(grep "Xrd_ProtLoad: enabling port" "$BINARY_DIR/tests/$TEST_NAME/server.log" | grep 'for protocol XrdHttp' | awk '{print $7}')
276290
IDX=$(($IDX+1))
291+
if ! kill -0 "$XROOTD_PID" 2>/dev/null; then
292+
echo "xrootd process (PID $XROOTD_PID) failed to start" >&2
293+
exit 1
294+
fi
277295
if [ $IDX -gt 1 ]; then
278296
echo "Waiting for xrootd to start ($IDX seconds so far) ..."
279297
fi
@@ -285,8 +303,16 @@ done
285303
XROOTD_URL="https://$(hostname):$XROOTD_URL/"
286304
echo "xrootd started at $XROOTD_URL"
287305

306+
IDX=0
307+
touch "$RUNDIR/playback.txt"
308+
while [ $IDX -ne $COUNT ]; do
309+
echo "$XROOTD_URL/test/test_file_$IDX.random" >> "$RUNDIR/playback.txt"
310+
IDX=$((IDX+1))
311+
done
312+
288313
cat >> "$BINARY_DIR/tests/$TEST_NAME/setup.sh" <<EOF
289314
XROOTD_PID=$XROOTD_PID
290315
XROOTD_URL=$XROOTD_URL
291316
BUCKET_NAME=$BUCKET_NAME
317+
PLAYBACK_FILE=$RUNDIR/playback.txt
292318
EOF

test/xrdhttp-setup.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ fi
2121

2222
echo "Setting up HTTP server for $TEST_NAME test"
2323

24-
XROOTD_BIN="$(command -v xrootd)"
25-
24+
XROOTD_BIN="$XROOTD_BINDIR/xrootd"
2625
if [ -z "XROOTD_BIN" ]; then
2726
echo "xrootd binary not found; cannot run unit test"
2827
exit 1
@@ -183,6 +182,10 @@ while [ -z "$XROOTD_URL" ]; do
183182
sleep 1
184183
XROOTD_URL=$(grep "Xrd_ProtLoad: enabling port" "$BINARY_DIR/tests/$TEST_NAME/server.log" | grep 'for protocol XrdHttp' | awk '{print $7}')
185184
IDX=$(($IDX+1))
185+
if ! kill -0 "$XROOTD_PID" 2>/dev/null; then
186+
echo "xrootd process (PID $XROOTD_PID) failed to start" >&2
187+
exit 1
188+
fi
186189
if [ $IDX -gt 1 ]; then
187190
echo "Waiting for xrootd to start ($IDX seconds so far) ..."
188191
fi

0 commit comments

Comments
 (0)